diff --git a/fpga/Makefile b/fpga/Makefile index f3f6308b..643e0c67 100644 --- a/fpga/Makefile +++ b/fpga/Makefile @@ -26,7 +26,7 @@ CONFIG := FakeBringupConfig CONFIG_PACKAGE := chipyard.fpga.vcu118 GENERATOR_PACKAGE := chipyard TB := none # unused -TOP := VCU118Platform +TOP := ChipTop # setup the board to use BOARD ?= arty diff --git a/fpga/src/main/scala/vcu118/Configs.scala b/fpga/src/main/scala/vcu118/Configs.scala index feaa0484..efb2c551 100644 --- a/fpga/src/main/scala/vcu118/Configs.scala +++ b/fpga/src/main/scala/vcu118/Configs.scala @@ -73,11 +73,11 @@ class FakeBringupConfig extends Config( new WithBringupUART ++ //new WithBringupSPI ++ //new WithBringupI2C ++ - new WithBringupGPIO ++ - new chipyard.iobinders.WithUARTIOCells ++ + //new WithBringupGPIO ++ + new WithUARTIOPassthrough ++ //new WithSPICells ++ //new WithI2CCells ++ - new chipyard.iobinders.WithGPIOCells ++ + //new chipyard.iobinders.WithGPIOCells ++ //new WithBringupDDR ++ new WithBringupPeripherals ++ new chipyard.config.WithNoSubsystemDrivenClocks ++ diff --git a/fpga/src/main/scala/vcu118/TestHarness.scala b/fpga/src/main/scala/vcu118/TestHarness.scala index d371aced..ea8d4b0c 100644 --- a/fpga/src/main/scala/vcu118/TestHarness.scala +++ b/fpga/src/main/scala/vcu118/TestHarness.scala @@ -20,14 +20,31 @@ import sifive.blocks.devices.gpio._ import chipyard.fpga.vcu118.bringup.{BringupGPIOs, BringupUARTVCU118ShellPlacer, BringupSPIVCU118ShellPlacer, BringupI2CVCU118ShellPlacer, BringupGPIOVCU118ShellPlacer} import chipyard.harness._ -import chipyard.{HasHarnessSignalReferences, HasTestHarnessFunctions} +import chipyard.{HasHarnessSignalReferences, HasTestHarnessFunctions, BuildTop} case object DUTFrequencyKey extends Field[Double](100.0) -class VCU118FPGATestHarness(override implicit val p: Parameters) extends ChipyardVCU118Shell with HasHarnessSignalReferences { +class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118ShellBasicOverlays { def dp = designParameters + val pmod_is_sdio = p(VCU118ShellPMOD) == "SDIO" + val jtag_location = Some(if (pmod_is_sdio) "FMC_J2" else "PMOD_J52") + + // Order matters; ddr depends on sys_clock + val uart = Overlay(UARTOverlayKey, new UARTVCU118ShellPlacer(this, UARTShellInput())) + val sdio = if (pmod_is_sdio) Some(Overlay(SPIOverlayKey, new SDIOVCU118ShellPlacer(this, SPIShellInput()))) else None + val jtag = Overlay(JTAGDebugOverlayKey, new JTAGDebugVCU118ShellPlacer(this, JTAGDebugShellInput(location = jtag_location))) + val cjtag = Overlay(cJTAGDebugOverlayKey, new cJTAGDebugVCU118ShellPlacer(this, cJTAGDebugShellInput())) + 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 topDesign = LazyModule(p(BuildTop)(dp)) + + // place all clocks in the shell + dp(ClockInputOverlayKey).foreach { _.place(ClockInputDesignInput()) } + /*** Connect/Generate clocks ***/ // connect to the PLL that will generate multiple clocks @@ -44,13 +61,13 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends Chipyar val dutGroup = ClockGroup() dutClock := dutWrangler.node := dutGroup := harnessSysPLL - InModuleBody { - topDesign.module match { case td: LazyModuleImp => { - td.clock := dutClock.in.head._1.clock - td.reset := dutClock.in.head._1.reset - } - } - } + //InModuleBody { + // topDesign.module match { case td: LazyModuleImp => { + // td.clock := dutClock.in.head._1.clock + // td.reset := dutClock.in.head._1.reset + // } + // } + //} // connect ref clock to dummy sink node ref_clock.get() match { @@ -60,20 +77,75 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends Chipyar } } - lazy val harnessClock = InModuleBody { - dutClock.in.head._1.clock - }.getWrappedValue - lazy val harnessReset = InModuleBody { - WireInit(dutClock.in.head._1.reset) - }.getWrappedValue - lazy val dutReset = harnessReset - lazy val success = InModuleBody { false.B }.getWrappedValue + // extra overlays - topDesign match { case d: HasTestHarnessFunctions => - InModuleBody { - d.harnessFunctions.foreach(_(this)) - } - ApplyHarnessBinders(this, d.lazySystem, d.portMap.toMap) + /*** UART ***/ + + // 1st UART goes to the VCU118 dedicated UART + + // BundleBridgeSource is a was for Diplomacy to connect something from very deep in the design + // to somewhere much, much higher. For ex. tunneling trace from the tile to the very top level. + val io_uart_bb = BundleBridgeSource(() => (new UARTPortIO(dp(PeripheryUARTKey).head))) + dp(UARTOverlayKey).head.place(UARTDesignInput(io_uart_bb)) + + // 2nd UART goes to the FMC UART + + val uart_fmc = Overlay(UARTOverlayKey, new BringupUARTVCU118ShellPlacer(this, UARTShellInput())) + + val io_uart_bb_2 = BundleBridgeSource(() => (new UARTPortIO(dp(PeripheryUARTKey).last))) + dp(UARTOverlayKey).last.place(UARTDesignInput(io_uart_bb_2)) + + /*** GPIO ***/ + + val gpio = Seq.tabulate(dp(PeripheryGPIOKey).size)(i => { + val maxGPIOSupport = 32 + val names = BringupGPIOs.names.slice(maxGPIOSupport*i, maxGPIOSupport*(i+1)) + Overlay(GPIOOverlayKey, new BringupGPIOVCU118ShellPlacer(this, GPIOShellInput(), names)) + }) + + val io_gpio_bb = dp(PeripheryGPIOKey).map { p => BundleBridgeSource(() => (new GPIOPortIO(p))) } + (dp(GPIOOverlayKey) zip dp(PeripheryGPIOKey)).zipWithIndex.map { case ((placer, params), i) => + placer.place(GPIODesignInput(params, io_gpio_bb(i))) } + + // module implementation + override lazy val module = new VCU118FPGATestHarnessImp(this) } +class VCU118FPGATestHarnessImp(_outer: VCU118FPGATestHarness) extends LazyRawModuleImp(_outer) with HasHarnessSignalReferences { + + val outer = _outer + + val reset = IO(Input(Bool())) + _outer.xdc.addPackagePin(reset, "L19") + _outer.xdc.addIOStandard(reset, "LVCMOS12") + + val reset_ibuf = Module(new IBUF) + reset_ibuf.io.I := reset + + val sysclk: Clock = _outer.sys_clock.get() match { + case Some(x: SysClockVCU118PlacedOverlay) => x.clock + } + + val powerOnReset: Bool = PowerOnResetFPGAOnly(sysclk) + _outer.sdc.addAsyncPath(Seq(powerOnReset)) + + val ereset: Bool = _outer.chiplink.get() match { + case Some(x: ChipLinkVCU118PlacedOverlay) => !x.ereset_n + case _ => false.B + } + + _outer.pllReset := (reset_ibuf.io.O || powerOnReset || ereset) + + // cy stuff + val harnessClock = _outer.dutClock.in.head._1.clock + val harnessReset = WireInit(_outer.dutClock.in.head._1.reset) + val dutReset = harnessReset + val success = false.B + + // harness binders are non-lazy + _outer.topDesign match { case d: HasTestHarnessFunctions => + d.harnessFunctions.foreach(_(this)) + ApplyHarnessBinders(this, d.lazySystem, p(HarnessBinders), d.portMap.toMap) + } +}