From 244205e2b40aee6029627f1864b96ae427946f26 Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Sun, 8 Nov 2020 17:49:32 -0800 Subject: [PATCH 1/2] Separate new sys_clk and ddr2 from TSI --- fpga/src/main/scala/vcu118/TestHarness.scala | 2 + .../main/scala/vcu118/bringup/Configs.scala | 5 +- .../scala/vcu118/bringup/CustomOverlays.scala | 142 +++--------------- .../scala/vcu118/bringup/TestHarness.scala | 17 ++- 4 files changed, 39 insertions(+), 127 deletions(-) diff --git a/fpga/src/main/scala/vcu118/TestHarness.scala b/fpga/src/main/scala/vcu118/TestHarness.scala index 3d1d438e..ae019e21 100644 --- a/fpga/src/main/scala/vcu118/TestHarness.scala +++ b/fpga/src/main/scala/vcu118/TestHarness.scala @@ -38,6 +38,8 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118S val jtagBScan = Overlay(JTAGDebugBScanOverlayKey, new JTAGDebugBScanVCU118ShellPlacer(this, JTAGDebugBScanShellInput())) val fmc = Overlay(PCIeOverlayKey, new PCIeVCU118FMCShellPlacer(this, PCIeShellInput())) val edge = Overlay(PCIeOverlayKey, new PCIeVCU118EdgeShellPlacer(this, PCIeShellInput())) + val sys_clock2 = Overlay(ClockInputOverlayKey, new SysClock2VCU118ShellPlacer(this, ClockInputShellInput())) + val ddr2 = Overlay(DDROverlayKey, new DDR2VCU118ShellPlacer(this, DDRShellInput())) val topDesign = LazyModule(p(BuildTop)(dp)) diff --git a/fpga/src/main/scala/vcu118/bringup/Configs.scala b/fpga/src/main/scala/vcu118/bringup/Configs.scala index f6e4880c..913a4fc2 100644 --- a/fpga/src/main/scala/vcu118/bringup/Configs.scala +++ b/fpga/src/main/scala/vcu118/bringup/Configs.scala @@ -19,7 +19,7 @@ import testchipip.{PeripheryTSIHostKey, TSIHostParams, TSIHostSerdesParams} import chipyard.{BuildSystem} -import chipyard.fpga.vcu118.{WithVCU118Tweaks, WithFPGAFrequency} +import chipyard.fpga.vcu118.{WithVCU118Tweaks, WithFPGAFrequency, VCU118DDR2Size} class WithBringupPeripherals extends Config((site, here, up) => { case PeripheryUARTKey => up(PeripheryUARTKey, site) ++ List(UARTParams(address = BigInt(0x64003000L))) @@ -38,6 +38,7 @@ class WithBringupPeripherals extends Config((site, here, up) => { List.empty[GPIOParams] } } + case TSIClockMaxFrequency => 100 case PeripheryTSIHostKey => List( TSIHostParams( serialIfWidth = 4, @@ -50,7 +51,7 @@ class WithBringupPeripherals extends Config((site, here, up) => { sourceId = IdRange(0, (1 << 13))))), managerPortParams = TLSlavePortParameters.v1( managers = Seq(TLSlaveParameters.v1( - address = Seq(AddressSet(0, BigInt("FFFFFFFF", 16))), + address = Seq(AddressSet(0, site(VCU118DDR2Size) - 1)), regionType = RegionType.UNCACHED, executable = true, supportsGet = TransferSizes(1, 64), diff --git a/fpga/src/main/scala/vcu118/bringup/CustomOverlays.scala b/fpga/src/main/scala/vcu118/bringup/CustomOverlays.scala index 1881d821..ef25cea3 100644 --- a/fpga/src/main/scala/vcu118/bringup/CustomOverlays.scala +++ b/fpga/src/main/scala/vcu118/bringup/CustomOverlays.scala @@ -13,7 +13,7 @@ import sifive.fpgashells.shell.xilinx._ import sifive.fpgashells.clocks._ import sifive.fpgashells.devices.xilinx.xilinxvcu118mig.{XilinxVCU118MIGPads, XilinxVCU118MIGParams, XilinxVCU118MIG} -import testchipip.{TSIHostParams, TSIHostWidgetIO} +import testchipip.{TSIHostWidgetIO} import chipyard.fpga.vcu118.{FMCPMap} @@ -152,21 +152,13 @@ class BringupGPIOVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInp case class TSIHostShellInput() case class TSIHostDesignInput( - wrangler: ClockAdapterNode, - corePLL: PLLNode, - tsiHostParams: TSIHostParams, - node: BundleBridgeSource[TSIHostWidgetIO], - vc7074gbdimm: Boolean = false + serialIfWidth: Int, + node: BundleBridgeSource[TSIHostWidgetIO] )( implicit val p: Parameters) -case class TSIHostOverlayOutput(ddr: TLInwardNode) +case class TSIHostOverlayOutput() trait TSIHostShellPlacer[Shell] extends ShellPlacer[TSIHostDesignInput, TSIHostShellInput, TSIHostOverlayOutput] -class TSIHostWithDDRIO(val w: Int, val size: BigInt) extends Bundle { - val tsi = new TSIHostWidgetIO(w) - val ddr = new XilinxVCU118MIGPads(size) -} - case object TSIHostOverlayKey extends Field[Seq[DesignPlacer[TSIHostDesignInput, TSIHostShellInput, TSIHostOverlayOutput]]](Nil) abstract class TSIHostPlacedOverlay[IO <: Data](val name: String, val di: TSIHostDesignInput, val si: TSIHostShellInput) @@ -177,43 +169,16 @@ abstract class TSIHostPlacedOverlay[IO <: Data](val name: String, val di: TSIHos case object TSIHostVCU118DDRSize extends Field[BigInt](0x40000000L * 2) // 2GB class TSIHostVCU118PlacedOverlay(val shell: BringupVCU118FPGATestHarness, name: String, val designInput: TSIHostDesignInput, val shellInput: TSIHostShellInput) - extends TSIHostPlacedOverlay[TSIHostWithDDRIO](name, designInput, shellInput) + extends TSIHostPlacedOverlay[TSIHostWidgetIO](name, designInput, shellInput) { - val size = p(TSIHostVCU118DDRSize) - - // connect the DDR - val migParams = XilinxVCU118MIGParams(address = AddressSet.misaligned(di.tsiHostParams.targetBaseAddress, size)) - val mig = LazyModule(new XilinxVCU118MIG(migParams)) - val ioNode = BundleBridgeSource(() => mig.module.io.cloneType) - val topIONode = shell { ioNode.makeSink() } - val ddrUI = shell { ClockSourceNode(freqMHz = 200) } - val areset = shell { ClockSinkNode(Seq(ClockSinkParameters())) } - areset := designInput.wrangler := ddrUI - - // since this uses a separate clk/rst need to put an async crossing - val asyncSink = LazyModule(new TLAsyncCrossingSink()) - val migClkRstNode = BundleBridgeSource(() => new Bundle { - val clock = Output(Clock()) - val reset = Output(Bool()) - }) - val topMigClkRstIONode = shell { migClkRstNode.makeSink() } - - // connect the TSI serial val tlTsiSerialSink = di.node.makeSink() - val tsiIoNode = BundleBridgeSource(() => new TSIHostWidgetIO(di.tsiHostParams.serialIfWidth)) + val tsiIoNode = BundleBridgeSource(() => new TSIHostWidgetIO(di.serialIfWidth)) val topTSIIONode = shell { tsiIoNode.makeSink() } - def overlayOutput = TSIHostOverlayOutput(ddr = mig.node) - def ioFactory = new TSIHostWithDDRIO(di.tsiHostParams.serialIfWidth, size) + def overlayOutput = TSIHostOverlayOutput() + def ioFactory = new TSIHostWidgetIO(di.serialIfWidth) InModuleBody { - // connect MIG - ioNode.bundle <> mig.module.io - - // setup async crossing - asyncSink.module.clock := migClkRstNode.bundle.clock - asyncSink.module.reset := migClkRstNode.bundle.reset - // connect TSI serial val tsiSourcePort = tsiIoNode.bundle val tsiSinkPort = tlTsiSerialSink.bundle @@ -225,48 +190,9 @@ class TSIHostVCU118PlacedOverlay(val shell: BringupVCU118FPGATestHarness, name: tsiSinkPort.serial.in.valid := tsiSourcePort.serial.in.valid tsiSourcePort.serial.in.ready := tsiSinkPort.serial.in.ready } - - // connect the DDR port - shell { InModuleBody { - require (shell.sys_clock2.get.isDefined, "Use of TSIHostVCU118Overlay depends on SysClock2VCU118Overlay") - val (sys, _) = shell.sys_clock2.get.get.overlayOutput.node.out(0) - val (ui, _) = ddrUI.out(0) - val (ar, _) = areset.in(0) - - // connect the async fifo sink to sys_clock2 - topMigClkRstIONode.bundle.clock := sys.clock - topMigClkRstIONode.bundle.reset := sys.reset - - val ddrPort = topIONode.bundle.port - io.ddr <> ddrPort - ui.clock := ddrPort.c0_ddr4_ui_clk - ui.reset := /*!ddrPort.mmcm_locked ||*/ ddrPort.c0_ddr4_ui_clk_sync_rst - ddrPort.c0_sys_clk_i := sys.clock.asUInt - ddrPort.sys_rst := sys.reset // pllReset - ddrPort.c0_ddr4_aresetn := !ar.reset - - // This was just copied from the SiFive example, but it's hard to follow. - // The pins are emitted in the following order: - // adr[0->13], we_n, cas_n, ras_n, bg, ba[0->1], reset_n, act_n, ck_c, ck_t, cke, cs_n, odt, dq[0->63], dqs_c[0->7], dqs_t[0->7], dm_dbi_n[0->7] - val allddrpins = Seq( - "AM27", "AL27", "AP26", "AP25", "AN28", "AM28", "AP28", "AP27", "AN26", "AM26", "AR28", "AR27", "AV25", "AT25", // adr[0->13] - "AV28", "AU26", "AV26", "AU27", // we_n, cas_n, ras_n, bg - "AR25", "AU28", // ba[0->1] - "BD35", "AN25", "AT27", "AT26", "AW28", "AY29", "BB29", // reset_n, act_n, ck_c, ck_t, cke, cs_n, odt - "BD30", "BE30", "BD32", "BE33", "BC33", "BD33", "BC31", "BD31", "BA32", "BB33", "BA30", "BA31", "AW31", "AW32", "AY32", "AY33", // dq[0->15] - "AV30", "AW30", "AU33", "AU34", "AT31", "AU32", "AU31", "AV31", "AR33", "AT34", "AT29", "AT30", "AP30", "AR30", "AN30", "AN31", // dq[16->31] - "BE34", "BF34", "BC35", "BC36", "BD36", "BE37", "BF36", "BF37", "BD37", "BE38", "BC39", "BD40", "BB38", "BB39", "BC38", "BD38", // dq[32->47] - "BB36", "BB37", "BA39", "BA40", "AW40", "AY40", "AY38", "AY39", "AW35", "AW36", "AU40", "AV40", "AU38", "AU39", "AV38", "AV39", // dq[48->63] - "BF31", "BA34", "AV29", "AP32", "BF35", "BF39", "BA36", "AW38", // dqs_c[0->7] - "BF30", "AY34", "AU29", "AP31", "BE35", "BE39", "BA35", "AW37", // dqs_t[0->7] - "BE32", "BB31", "AV33", "AR32", "BC34", "BE40", "AY37", "AV35") // dm_dbi_n[0->7] - - (IOPin.of(io.ddr) zip allddrpins) foreach { case (io, pin) => shell.xdc.addPackagePin(io, pin) } - } } - - shell.sdc.addGroup(pins = Seq(mig.island.module.blackbox.io.c0_ddr4_ui_clk)) } +case object TSIClockMaxFrequency extends Field[Int](50) // in MHz class BringupTSIHostVCU118PlacedOverlay(override val shell: BringupVCU118FPGATestHarness, override val name: String, override val designInput: TSIHostDesignInput, override val shellInput: TSIHostShellInput) extends TSIHostVCU118PlacedOverlay(shell, name, designInput, shellInput) { @@ -274,25 +200,25 @@ class BringupTSIHostVCU118PlacedOverlay(override val shell: BringupVCU118FPGATes shell { InModuleBody { // connect TSI signals val tsiPort = topTSIIONode.bundle - io.tsi <> tsiPort + io <> tsiPort - require(di.tsiHostParams.serialIfWidth == 4) + require(di.serialIfWidth == 4) - val clkIo = IOPin(io.tsi.serial_clock) + val clkIo = IOPin(io.serial_clock) val packagePinsWithPackageIOs = Seq( (FMCPMap("D8"), clkIo), - (FMCPMap("D17"), IOPin(io.tsi.serial.out.ready)), - (FMCPMap("D18"), IOPin(io.tsi.serial.out.valid)), - (FMCPMap("D11"), IOPin(io.tsi.serial.out.bits, 0)), - (FMCPMap("D12"), IOPin(io.tsi.serial.out.bits, 1)), - (FMCPMap("D14"), IOPin(io.tsi.serial.out.bits, 2)), - (FMCPMap("D15"), IOPin(io.tsi.serial.out.bits, 3)), - (FMCPMap("D26"), IOPin(io.tsi.serial.in.ready)), - (FMCPMap("D27"), IOPin(io.tsi.serial.in.valid)), - (FMCPMap("D20"), IOPin(io.tsi.serial.in.bits, 0)), - (FMCPMap("D21"), IOPin(io.tsi.serial.in.bits, 1)), - (FMCPMap("D23"), IOPin(io.tsi.serial.in.bits, 2)), - (FMCPMap("D24"), IOPin(io.tsi.serial.in.bits, 3))) + (FMCPMap("D17"), IOPin(io.serial.out.ready)), + (FMCPMap("D18"), IOPin(io.serial.out.valid)), + (FMCPMap("D11"), IOPin(io.serial.out.bits, 0)), + (FMCPMap("D12"), IOPin(io.serial.out.bits, 1)), + (FMCPMap("D14"), IOPin(io.serial.out.bits, 2)), + (FMCPMap("D15"), IOPin(io.serial.out.bits, 3)), + (FMCPMap("D26"), IOPin(io.serial.in.ready)), + (FMCPMap("D27"), IOPin(io.serial.in.valid)), + (FMCPMap("D20"), IOPin(io.serial.in.bits, 0)), + (FMCPMap("D21"), IOPin(io.serial.in.bits, 1)), + (FMCPMap("D23"), IOPin(io.serial.in.bits, 2)), + (FMCPMap("D24"), IOPin(io.serial.in.bits, 3))) packagePinsWithPackageIOs foreach { case (pin, io) => { shell.xdc.addPackagePin(io, pin) @@ -304,7 +230,7 @@ class BringupTSIHostVCU118PlacedOverlay(override val shell: BringupVCU118FPGATes shell.xdc.addIOB(io) } } - shell.sdc.addClock("TSI_CLK", clkIo, 50) + shell.sdc.addClock("TSI_CLK", clkIo, p(TSIClockMaxFrequency)) shell.sdc.addGroup(pins = Seq(clkIo)) shell.xdc.clockDedicatedRouteFalse(clkIo) } } @@ -314,21 +240,3 @@ class BringupTSIHostVCU118ShellPlacer(shell: BringupVCU118FPGATestHarness, val s extends TSIHostShellPlacer[BringupVCU118FPGATestHarness] { def place(designInput: TSIHostDesignInput) = new BringupTSIHostVCU118PlacedOverlay(shell, valName.name, designInput, shellInput) } - -class SysClock2VCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: ClockInputDesignInput, val shellInput: ClockInputShellInput) - extends LVDSClockInputXilinxPlacedOverlay(name, designInput, shellInput) -{ - val node = shell { ClockSourceNode(freqMHz = 250, jitterPS = 50)(ValName(name)) } - - shell { InModuleBody { - shell.xdc.addPackagePin(io.p, "AW26") - shell.xdc.addPackagePin(io.n, "AW27") - shell.xdc.addIOStandard(io.p, "DIFF_SSTL12") - shell.xdc.addIOStandard(io.n, "DIFF_SSTL12") - } } -} -class SysClock2VCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: ClockInputShellInput)(implicit val valName: ValName) - extends ClockInputShellPlacer[VCU118ShellBasicOverlays] -{ - def place(designInput: ClockInputDesignInput) = new SysClock2VCU118PlacedOverlay(shell, valName.name, designInput, shellInput) -} diff --git a/fpga/src/main/scala/vcu118/bringup/TestHarness.scala b/fpga/src/main/scala/vcu118/bringup/TestHarness.scala index 95025dc7..6a4c8e2d 100644 --- a/fpga/src/main/scala/vcu118/bringup/TestHarness.scala +++ b/fpga/src/main/scala/vcu118/bringup/TestHarness.scala @@ -19,7 +19,7 @@ import sifive.blocks.devices.gpio._ import testchipip.{HasPeripheryTSIHostWidget, PeripheryTSIHostKey, TSIHostWidgetIO, TLSinkSetter} -import chipyard.fpga.vcu118.{VCU118FPGATestHarness, VCU118FPGATestHarnessImp} +import chipyard.fpga.vcu118.{VCU118FPGATestHarness, VCU118FPGATestHarnessImp, DDR2VCU118ShellPlacer, SysClock2VCU118ShellPlacer} import chipyard.{ChipTop} @@ -71,21 +71,22 @@ class BringupVCU118FPGATestHarness(override implicit val p: Parameters) extends require(dp(PeripheryTSIHostKey).size == 1) // use the 2nd system clock for the 2nd DDR - val sys_clock2 = Overlay(ClockInputOverlayKey, new SysClock2VCU118ShellPlacer(this, ClockInputShellInput())) val sysClk2Node = dp(ClockInputOverlayKey).last.place(ClockInputDesignInput()).overlayOutput.node val ddr2PLL = dp(PLLFactoryKey)() ddr2PLL := sysClk2Node - val ddrClock = ClockSinkNode(freqMHz = dp(FPGAFrequencyKey)) - val ddrWrangler = LazyModule(new ResetWrangler) - val ddrGroup = ClockGroup() - ddrClock := ddrWrangler.node := ddrGroup := ddr2PLL + val ddr2Clock = ClockSinkNode(freqMHz = dp(FPGAFrequencyKey)) + val ddr2Wrangler = LazyModule(new ResetWrangler) + val ddr2Group = ClockGroup() + ddr2Clock := ddr2Wrangler.node := ddr2Group := ddr2PLL val tsi_host = Overlay(TSIHostOverlayKey, new BringupTSIHostVCU118ShellPlacer(this, TSIHostShellInput())) + val ddr2Node = dp(DDROverlayKey).last.place(DDRDesignInput(dp(PeripheryTSIHostKey).head.targetBaseAddress, ddr2Wrangler.node, ddr2PLL)).overlayOutput.ddr + val io_tsi_serial_bb = BundleBridgeSource(() => (new TSIHostWidgetIO(dp(PeripheryTSIHostKey).head.serialIfWidth))) - val tsiDdrNode = dp(TSIHostOverlayKey).head.place(TSIHostDesignInput(ddrWrangler.node, ddr2PLL, dp(PeripheryTSIHostKey).head, io_tsi_serial_bb)).overlayOutput.ddr + dp(TSIHostOverlayKey).head.place(TSIHostDesignInput(dp(PeripheryTSIHostKey).head.serialIfWidth, io_tsi_serial_bb)) // connect 1 mem. channel to the FPGA DDR val inTsiParams = topDesign match { case td: ChipTop => @@ -94,7 +95,7 @@ class BringupVCU118FPGATestHarness(override implicit val p: Parameters) extends } } val tsiDdrClient = TLClientNode(Seq(inTsiParams.master)) - (tsiDdrNode + (ddr2Node := TLFragmenter(8,64,holdFirstDeny=true) := TLCacheCork() := TLAtomicAutomata(passthrough=false) From 082b2304520a48c78f2a0dd1f8a98857c53df140 Mon Sep 17 00:00:00 2001 From: abejgonzalez Date: Sun, 8 Nov 2020 17:51:21 -0800 Subject: [PATCH 2/2] Add missing file --- .../main/scala/vcu118/CustomOverlays.scala | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 fpga/src/main/scala/vcu118/CustomOverlays.scala diff --git a/fpga/src/main/scala/vcu118/CustomOverlays.scala b/fpga/src/main/scala/vcu118/CustomOverlays.scala new file mode 100644 index 00000000..a58fb424 --- /dev/null +++ b/fpga/src/main/scala/vcu118/CustomOverlays.scala @@ -0,0 +1,110 @@ +package chipyard.fpga.vcu118 + +import chisel3._ + +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.config.{Parameters, Field} +import freechips.rocketchip.tilelink.{TLInwardNode, TLAsyncCrossingSink} + +import sifive.fpgashells.shell._ +import sifive.fpgashells.ip.xilinx._ +import sifive.fpgashells.shell.xilinx._ +import sifive.fpgashells.clocks._ +import sifive.fpgashells.devices.xilinx.xilinxvcu118mig.{XilinxVCU118MIGPads, XilinxVCU118MIGParams, XilinxVCU118MIG} + +class SysClock2VCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: ClockInputDesignInput, val shellInput: ClockInputShellInput) + extends LVDSClockInputXilinxPlacedOverlay(name, designInput, shellInput) +{ + val node = shell { ClockSourceNode(freqMHz = 250, jitterPS = 50)(ValName(name)) } + + shell { InModuleBody { + shell.xdc.addPackagePin(io.p, "AW26") + shell.xdc.addPackagePin(io.n, "AW27") + shell.xdc.addIOStandard(io.p, "DIFF_SSTL12") + shell.xdc.addIOStandard(io.n, "DIFF_SSTL12") + } } +} +class SysClock2VCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: ClockInputShellInput)(implicit val valName: ValName) + extends ClockInputShellPlacer[VCU118ShellBasicOverlays] +{ + def place(designInput: ClockInputDesignInput) = new SysClock2VCU118PlacedOverlay(shell, valName.name, designInput, shellInput) +} + +case object VCU118DDR2Size extends Field[BigInt](0x40000000L * 2) // 2GB +class DDR2VCU118PlacedOverlay(val shell: VCU118FPGATestHarness, name: String, val designInput: DDRDesignInput, val shellInput: DDRShellInput) + extends DDRPlacedOverlay[XilinxVCU118MIGPads](name, designInput, shellInput) +{ + val size = p(VCU118DDRSize) + + val migParams = XilinxVCU118MIGParams(address = AddressSet.misaligned(di.baseAddress, size)) + val mig = LazyModule(new XilinxVCU118MIG(migParams)) + val ioNode = BundleBridgeSource(() => mig.module.io.cloneType) + val topIONode = shell { ioNode.makeSink() } + val ddrUI = shell { ClockSourceNode(freqMHz = 200) } + val areset = shell { ClockSinkNode(Seq(ClockSinkParameters())) } + areset := designInput.wrangler := ddrUI + + // since this uses a separate clk/rst need to put an async crossing + val asyncSink = LazyModule(new TLAsyncCrossingSink()) + val migClkRstNode = BundleBridgeSource(() => new Bundle { + val clock = Output(Clock()) + val reset = Output(Bool()) + }) + val topMigClkRstIONode = shell { migClkRstNode.makeSink() } + + def overlayOutput = DDROverlayOutput(ddr = mig.node) + def ioFactory = new XilinxVCU118MIGPads(size) + + InModuleBody { + ioNode.bundle <> mig.module.io + + // setup async crossing + asyncSink.module.clock := migClkRstNode.bundle.clock + asyncSink.module.reset := migClkRstNode.bundle.reset + } + + shell { InModuleBody { + require (shell.sys_clock2.get.isDefined, "Use of DDRVCU118Overlay depends on SysClock2VCU118Overlay") + val (sys, _) = shell.sys_clock2.get.get.overlayOutput.node.out(0) + val (ui, _) = ddrUI.out(0) + val (ar, _) = areset.in(0) + + // connect the async fifo sync to sys_clock2 + topMigClkRstIONode.bundle.clock := sys.clock + topMigClkRstIONode.bundle.reset := sys.reset + + val port = topIONode.bundle.port + io <> port + ui.clock := port.c0_ddr4_ui_clk + ui.reset := /*!port.mmcm_locked ||*/ port.c0_ddr4_ui_clk_sync_rst + port.c0_sys_clk_i := sys.clock.asUInt + port.sys_rst := sys.reset // pllReset + port.c0_ddr4_aresetn := !ar.reset + + // This was just copied from the SiFive example, but it's hard to follow. + // The pins are emitted in the following order: + // adr[0->13], we_n, cas_n, ras_n, bg, ba[0->1], reset_n, act_n, ck_c, ck_t, cke, cs_n, odt, dq[0->63], dqs_c[0->7], dqs_t[0->7], dm_dbi_n[0->7] + val allddrpins = Seq( + "AM27", "AL27", "AP26", "AP25", "AN28", "AM28", "AP28", "AP27", "AN26", "AM26", "AR28", "AR27", "AV25", "AT25", // adr[0->13] + "AV28", "AU26", "AV26", "AU27", // we_n, cas_n, ras_n, bg + "AR25", "AU28", // ba[0->1] + "BD35", "AN25", "AT27", "AT26", "AW28", "AY29", "BB29", // reset_n, act_n, ck_c, ck_t, cke, cs_n, odt + "BD30", "BE30", "BD32", "BE33", "BC33", "BD33", "BC31", "BD31", "BA32", "BB33", "BA30", "BA31", "AW31", "AW32", "AY32", "AY33", // dq[0->15] + "AV30", "AW30", "AU33", "AU34", "AT31", "AU32", "AU31", "AV31", "AR33", "AT34", "AT29", "AT30", "AP30", "AR30", "AN30", "AN31", // dq[16->31] + "BE34", "BF34", "BC35", "BC36", "BD36", "BE37", "BF36", "BF37", "BD37", "BE38", "BC39", "BD40", "BB38", "BB39", "BC38", "BD38", // dq[32->47] + "BB36", "BB37", "BA39", "BA40", "AW40", "AY40", "AY38", "AY39", "AW35", "AW36", "AU40", "AV40", "AU38", "AU39", "AV38", "AV39", // dq[48->63] + "BF31", "BA34", "AV29", "AP32", "BF35", "BF39", "BA36", "AW38", // dqs_c[0->7] + "BF30", "AY34", "AU29", "AP31", "BE35", "BE39", "BA35", "AW37", // dqs_t[0->7] + "BE32", "BB31", "AV33", "AR32", "BC34", "BE40", "AY37", "AV35") // dm_dbi_n[0->7] + + (IOPin.of(io) zip allddrpins) foreach { case (io, pin) => shell.xdc.addPackagePin(io, pin) } + } } + + shell.sdc.addGroup(pins = Seq(mig.island.module.blackbox.io.c0_ddr4_ui_clk)) +} + +class DDR2VCU118ShellPlacer(shell: VCU118FPGATestHarness, val shellInput: DDRShellInput)(implicit val valName: ValName) + extends DDRShellPlacer[VCU118FPGATestHarness] { + def place(designInput: DDRDesignInput) = new DDR2VCU118PlacedOverlay(shell, valName.name, designInput, shellInput) +} +