diff --git a/fpga/Makefile b/fpga/Makefile index 643e0c67..e6bc426a 100644 --- a/fpga/Makefile +++ b/fpga/Makefile @@ -19,11 +19,11 @@ include $(base_dir)/variables.mk # default variables to build the arty example SUB_PROJECT := fpga SBT_PROJECT := fpga_platforms -MODEL := VCU118FPGATestHarness -VLOG_MODEL := VCU118FPGATestHarness -MODEL_PACKAGE := chipyard.fpga.vcu118 +MODEL := BringupVCU118FPGATestHarness +VLOG_MODEL := BringupVCU118FPGATestHarness +MODEL_PACKAGE := chipyard.fpga.vcu118.bringup CONFIG := FakeBringupConfig -CONFIG_PACKAGE := chipyard.fpga.vcu118 +CONFIG_PACKAGE := chipyard.fpga.vcu118.bringup GENERATOR_PACKAGE := chipyard TB := none # unused TOP := ChipTop diff --git a/fpga/src/main/scala/vcu118/BringupGPIOs.scala b/fpga/src/main/scala/vcu118/bringup/BringupGPIOs.scala similarity index 100% rename from fpga/src/main/scala/vcu118/BringupGPIOs.scala rename to fpga/src/main/scala/vcu118/bringup/BringupGPIOs.scala diff --git a/fpga/src/main/scala/vcu118/Configs.scala b/fpga/src/main/scala/vcu118/bringup/Configs.scala similarity index 85% rename from fpga/src/main/scala/vcu118/Configs.scala rename to fpga/src/main/scala/vcu118/bringup/Configs.scala index efb2c551..9a34b198 100644 --- a/fpga/src/main/scala/vcu118/Configs.scala +++ b/fpga/src/main/scala/vcu118/bringup/Configs.scala @@ -1,5 +1,4 @@ -// See LICENSE for license details. -package chipyard.fpga.vcu118 +package chipyard.fpga.vcu118.bringup import math.min @@ -29,12 +28,12 @@ class WithBringupPeripherals extends Config((site, here, up) => { case PeripheryUARTKey => List( UARTParams(address = BigInt(0x64000000L)), UARTParams(address = BigInt(0x64003000L))) -// case PeripherySPIKey => List( -// SPIParams(rAddress = BigInt(0x64001000L)), -// SPIParams(rAddress = BigInt(0x64004000L))) -// case VCU118ShellPMOD => "SDIO" -// case PeripheryI2CKey => List( -// I2CParams(address = BigInt(0x64005000L))) + case PeripherySPIKey => List( + SPIParams(rAddress = BigInt(0x64001000L)), + SPIParams(rAddress = BigInt(0x64004000L))) + case VCU118ShellPMOD => "SDIO" + case PeripheryI2CKey => List( + I2CParams(address = BigInt(0x64005000L))) case PeripheryGPIOKey => { if (BringupGPIOs.width > 0) { require(BringupGPIOs.width <= 64) // currently only support 64 GPIOs (change addrs to get more) @@ -71,14 +70,16 @@ class SmallModifications extends Config((site, here, up) => { class FakeBringupConfig extends Config( new WithBringupUART ++ - //new WithBringupSPI ++ - //new WithBringupI2C ++ - //new WithBringupGPIO ++ + new WithBringupSPI ++ + new WithBringupI2C ++ + new WithBringupGPIO ++ + new WithBringupDDR ++ new WithUARTIOPassthrough ++ - //new WithSPICells ++ - //new WithI2CCells ++ - //new chipyard.iobinders.WithGPIOCells ++ - //new WithBringupDDR ++ + new WithSPIIOPassthrough ++ + //new WithMMCSPIDTS ++ + new WithI2CIOPassthrough ++ + new WithGPIOIOPassthrough ++ + new WithTLIOPassthrough ++ new WithBringupPeripherals ++ new chipyard.config.WithNoSubsystemDrivenClocks ++ new chipyard.config.WithPeripheryBusFrequencyAsDefault ++ diff --git a/fpga/src/main/scala/vcu118/CustomOverlays.scala b/fpga/src/main/scala/vcu118/bringup/CustomOverlays.scala similarity index 100% rename from fpga/src/main/scala/vcu118/CustomOverlays.scala rename to fpga/src/main/scala/vcu118/bringup/CustomOverlays.scala diff --git a/fpga/src/main/scala/vcu118/bringup/HarnessBinders.scala b/fpga/src/main/scala/vcu118/bringup/HarnessBinders.scala new file mode 100644 index 00000000..efe805cd --- /dev/null +++ b/fpga/src/main/scala/vcu118/bringup/HarnessBinders.scala @@ -0,0 +1,94 @@ +package chipyard.fpga.vcu118.bringup + +import chisel3._ +import chisel3.experimental.{Analog, IO} + +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.config.{Parameters, Field} +import freechips.rocketchip.subsystem.{ExtMem, BaseSubsystem} +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.util._ + +import sifive.fpgashells.shell.xilinx._ +import sifive.fpgashells.ip.xilinx._ +import sifive.fpgashells.shell._ +import sifive.fpgashells.clocks._ + +import sifive.blocks.devices.uart._ +import sifive.blocks.devices.spi._ +import sifive.blocks.devices.i2c._ +import sifive.blocks.devices.gpio._ + +import chipyard.fpga.vcu118.bringup.{BringupGPIOs, BringupUARTVCU118ShellPlacer, BringupSPIVCU118ShellPlacer, BringupI2CVCU118ShellPlacer, BringupGPIOVCU118ShellPlacer} +import chipyard.{CanHaveMasterTLMemPort, HasHarnessSignalReferences} +import chipyard.harness._ + +/*** UART ***/ +class WithBringupUART extends OverrideHarnessBinder({ + (system: HasPeripheryUARTModuleImp, th: HasHarnessSignalReferences, ports: Seq[UARTPortIO]) => { + th match { case vcu118th: BringupVCU118FPGATestHarnessImp => { + require(ports.size == 2) + + vcu118th.outer.io_uart_bb.bundle <> ports.head + vcu118th.outer.io_uart_bb_2.bundle <> ports.last + } } + + Nil + } +}) + +/*** SPI ***/ +class WithBringupSPI extends OverrideHarnessBinder({ + (system: HasPeripherySPIModuleImp, th: HasHarnessSignalReferences, ports: Seq[SPIPortIO]) => { + th match { case vcu118th: BringupVCU118FPGATestHarnessImp => { + require(ports.size == 2) + + vcu118th.outer.io_spi_bb.bundle <> ports.head + vcu118th.outer.io_spi_bb_2.bundle <> ports.last + } } + + Nil + } +}) + +/*** I2C ***/ +class WithBringupI2C extends OverrideHarnessBinder({ + (system: HasPeripheryI2CModuleImp, th: HasHarnessSignalReferences, ports: Seq[I2CPort]) => { + th match { case vcu118th: BringupVCU118FPGATestHarnessImp => { + require(ports.size == 1) + + vcu118th.outer.io_i2c_bb.bundle <> ports.head + } } + + Nil + } +}) + +/*** GPIO ***/ +class WithBringupGPIO extends OverrideHarnessBinder({ + (system: HasPeripheryGPIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[GPIOPortIO]) => { + th match { case vcu118th: BringupVCU118FPGATestHarnessImp => { + (vcu118th.outer.io_gpio_bb zip ports).map { case (bb_io, dut_io) => + bb_io.bundle <> dut_io + } + } } + + Nil + } +}) + +/*** Experimental DDR ***/ +class WithBringupDDR extends OverrideHarnessBinder({ + (system: CanHaveMasterTLMemPort, th: HasHarnessSignalReferences, ports: Seq[HeterogeneousBag[TLBundle]]) => { + th match { case vcu118th: BringupVCU118FPGATestHarnessImp => { + require(ports.size == 1) + + val bundles = vcu118th.outer.ddrClient.out.map(_._1) + val ddrClientBundle = Wire(new freechips.rocketchip.util.HeterogeneousBag(bundles.map(_.cloneType))) + bundles.zip(ddrClientBundle).foreach { case (bundle, io) => bundle <> io } + ddrClientBundle <> ports.head + } } + + Nil + } +}) diff --git a/fpga/src/main/scala/vcu118/bringup/IOBinders.scala b/fpga/src/main/scala/vcu118/bringup/IOBinders.scala new file mode 100644 index 00000000..d10f5500 --- /dev/null +++ b/fpga/src/main/scala/vcu118/bringup/IOBinders.scala @@ -0,0 +1,90 @@ +package chipyard.fpga.vcu118.bringup + +import chisel3._ +import chisel3.util.experimental.{BoringUtils} +import chisel3.experimental.{Analog, IO, DataMirror} + +import freechips.rocketchip.config._ +import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike, ResourceBinding, Resource, ResourceAddress} +import freechips.rocketchip.devices.debug._ +import freechips.rocketchip.jtag.{JTAGIO} +import freechips.rocketchip.subsystem._ +import freechips.rocketchip.system.{SimAXIMem} +import freechips.rocketchip.amba.axi4.{AXI4Bundle, AXI4SlaveNode, AXI4MasterNode, AXI4EdgeParameters} +import freechips.rocketchip.util._ +import freechips.rocketchip.groundtest.{GroundTestSubsystemModuleImp, GroundTestSubsystem} +import freechips.rocketchip.tilelink.{TLBundle} + +import sifive.blocks.devices.gpio._ +import sifive.blocks.devices.uart._ +import sifive.blocks.devices.spi._ +import sifive.blocks.devices.i2c._ +import tracegen.{TraceGenSystemModuleImp} + +import barstools.iocell.chisel._ + +import testchipip._ +import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly} + +import chipyard.{GlobalResetSchemeKey, CanHaveMasterTLMemPort} +import chipyard.iobinders.{OverrideIOBinder} + +class WithUARTIOPassthrough extends OverrideIOBinder({ + (system: HasPeripheryUARTModuleImp) => { + val io_uart_pins_temp = system.uart.zipWithIndex.map { case (dio, i) => IO(dio.cloneType).suggestName(s"uart_$i") } + (io_uart_pins_temp zip system.uart).map { case (io, sysio) => + io <> sysio + } + (io_uart_pins_temp, Nil) + } +}) + +class WithGPIOIOPassthrough extends OverrideIOBinder({ + (system: HasPeripheryGPIOModuleImp) => { + val io_gpio_pins_temp = system.gpio.zipWithIndex.map { case (dio, i) => IO(dio.cloneType).suggestName(s"gpio_$i") } + (io_gpio_pins_temp zip system.gpio).map { case (io, sysio) => + io <> sysio + } + (io_gpio_pins_temp, Nil) + } +}) + +class WithSPIIOPassthrough extends OverrideIOBinder({ + (system: HasPeripherySPIModuleImp) => { + val io_spi_pins_temp = system.spi.zipWithIndex.map { case (dio, i) => IO(dio.cloneType).suggestName(s"spi_$i") } + (io_spi_pins_temp zip system.spi).map { case (io, sysio) => + io <> sysio + } + (io_spi_pins_temp, Nil) + } +}) + +//class WithMMCSPIDTS extends OverrideIOBinder({ +// (system: HasPeripherySPI) => { +// +// val mmcDev = new MMCDevice(system.tlspi.head.device, 1) +// ResourceBinding { +// Resource(mmcDev, "reg").bind(ResourceAddress(0)) +// } +// +// (Nil, Nil) +// } +//}) + +class WithI2CIOPassthrough extends OverrideIOBinder({ + (system: HasPeripheryI2CModuleImp) => { + val io_i2c_pins_temp = system.i2c.zipWithIndex.map { case (dio, i) => IO(dio.cloneType).suggestName(s"i2c_$i") } + (io_i2c_pins_temp zip system.i2c).map { case (io, sysio) => + io <> sysio + } + (io_i2c_pins_temp, Nil) + } +}) + +class WithTLIOPassthrough extends OverrideIOBinder({ + (system: CanHaveMasterTLMemPort) => { + val io_tl_mem_pins_temp = IO(DataMirror.internal.chiselTypeClone[HeterogeneousBag[TLBundle]](system.mem_tl)).suggestName("tl_slave") + io_tl_mem_pins_temp <> system.mem_tl + (Seq(io_tl_mem_pins_temp), Nil) + } +}) diff --git a/fpga/src/main/scala/vcu118/TestHarness.scala b/fpga/src/main/scala/vcu118/bringup/TestHarness.scala similarity index 74% rename from fpga/src/main/scala/vcu118/TestHarness.scala rename to fpga/src/main/scala/vcu118/bringup/TestHarness.scala index ea8d4b0c..28e42e3c 100644 --- a/fpga/src/main/scala/vcu118/TestHarness.scala +++ b/fpga/src/main/scala/vcu118/bringup/TestHarness.scala @@ -1,4 +1,4 @@ -package chipyard.fpga.vcu118 +package chipyard.fpga.vcu118.bringup import chisel3._ import chisel3.experimental.{Analog, IO} @@ -18,13 +18,12 @@ import sifive.blocks.devices.spi._ import sifive.blocks.devices.i2c._ import sifive.blocks.devices.gpio._ -import chipyard.fpga.vcu118.bringup.{BringupGPIOs, BringupUARTVCU118ShellPlacer, BringupSPIVCU118ShellPlacer, BringupI2CVCU118ShellPlacer, BringupGPIOVCU118ShellPlacer} import chipyard.harness._ -import chipyard.{HasHarnessSignalReferences, HasTestHarnessFunctions, BuildTop} +import chipyard.{HasHarnessSignalReferences, HasTestHarnessFunctions, BuildTop, CanHaveMasterTLMemPort, ChipTop} case object DUTFrequencyKey extends Field[Double](100.0) -class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118ShellBasicOverlays { +class BringupVCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118ShellBasicOverlays { def dp = designParameters @@ -81,6 +80,8 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118S /*** UART ***/ + require(dp(PeripheryUARTKey).size == 2) + // 1st UART goes to the VCU118 dedicated UART // BundleBridgeSource is a was for Diplomacy to connect something from very deep in the design @@ -95,6 +96,29 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118S val io_uart_bb_2 = BundleBridgeSource(() => (new UARTPortIO(dp(PeripheryUARTKey).last))) dp(UARTOverlayKey).last.place(UARTDesignInput(io_uart_bb_2)) + /*** SPI ***/ + + require(dp(PeripherySPIKey).size == 2) + + // 1st SPI goes to the VCU118 SDIO port + + val io_spi_bb = BundleBridgeSource(() => (new SPIPortIO(dp(PeripherySPIKey).head))) + val sdio_placed = dp(SPIOverlayKey).head.place(SPIDesignInput(dp(PeripherySPIKey).head, io_spi_bb)) + + // 2nd SPI goes to the ADI port + + val adi = Overlay(SPIOverlayKey, new BringupSPIVCU118ShellPlacer(this, SPIShellInput())) + + val io_spi_bb_2 = BundleBridgeSource(() => (new SPIPortIO(dp(PeripherySPIKey).last))) + val adi_placed = dp(SPIOverlayKey).last.place(SPIDesignInput(dp(PeripherySPIKey).last, io_spi_bb_2)) + + /*** I2C ***/ + + val i2c = Overlay(I2COverlayKey, new BringupI2CVCU118ShellPlacer(this, I2CShellInput())) + + val io_i2c_bb = BundleBridgeSource(() => (new I2CPort)) + dp(I2COverlayKey).head.place(I2CDesignInput(io_i2c_bb)) + /*** GPIO ***/ val gpio = Seq.tabulate(dp(PeripheryGPIOKey).size)(i => { @@ -108,11 +132,25 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118S placer.place(GPIODesignInput(params, io_gpio_bb(i))) } + /*** DDR ***/ + + val ddrWrangler = LazyModule(new ResetWrangler) + val ddrPlaced = dp(DDROverlayKey).head.place(DDRDesignInput(dp(ExtMem).get.master.base, ddrWrangler.node, harnessSysPLL)) + + // connect 1 mem. channel to the FPGA DDR + val inParams = topDesign match { case td: ChipTop => + td.lazySystem match { case lsys: CanHaveMasterTLMemPort => + lsys.memTLNode.edges.in(0) + } + } + val ddrClient = TLClientNode(Seq(inParams.master)) + ddrPlaced.overlayOutput.ddr := ddrClient + // module implementation - override lazy val module = new VCU118FPGATestHarnessImp(this) + override lazy val module = new BringupVCU118FPGATestHarnessImp(this) } -class VCU118FPGATestHarnessImp(_outer: VCU118FPGATestHarness) extends LazyRawModuleImp(_outer) with HasHarnessSignalReferences { +class BringupVCU118FPGATestHarnessImp(_outer: BringupVCU118FPGATestHarness) extends LazyRawModuleImp(_outer) with HasHarnessSignalReferences { val outer = _outer