Reorganize into bringup/simple | Bump sifive-blocks
This commit is contained in:
85
fpga/src/main/scala/vcu118/Configs.scala
Normal file
85
fpga/src/main/scala/vcu118/Configs.scala
Normal file
@@ -0,0 +1,85 @@
|
||||
package chipyard.fpga.vcu118
|
||||
|
||||
import sys.process._
|
||||
|
||||
import freechips.rocketchip.config.{Config}
|
||||
import freechips.rocketchip.subsystem.{SystemBusKey, PeripheryBusKey, ControlBusKey, ExtMem}
|
||||
import freechips.rocketchip.devices.debug.{DebugModuleKey, ExportDebug, JTAG}
|
||||
import freechips.rocketchip.devices.tilelink.{DevNullParams, BootROMLocated}
|
||||
import freechips.rocketchip.diplomacy.{DTSModel, DTSTimebase, RegionType, AddressSet}
|
||||
import freechips.rocketchip.tile.{XLen}
|
||||
|
||||
import sifive.blocks.devices.spi.{PeripherySPIKey, SPIParams}
|
||||
import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTParams}
|
||||
|
||||
import sifive.fpgashells.shell.{DesignKey}
|
||||
import sifive.fpgashells.shell.xilinx.{VCU118ShellPMOD, VCU118DDRSize}
|
||||
|
||||
class WithDefaultPeripherals extends Config((site, here, up) => {
|
||||
case PeripheryUARTKey => List(UARTParams(address = BigInt(0x64000000L)))
|
||||
case PeripherySPIKey => List(SPIParams(rAddress = BigInt(0x64001000L)))
|
||||
case VCU118ShellPMOD => "SDIO"
|
||||
})
|
||||
|
||||
class WithSystemModifications extends Config((site, here, up) => {
|
||||
case DebugModuleKey => None // disable debug module
|
||||
case ExportDebug => up(ExportDebug).copy(protocols = Set(JTAG)) // don't generate HTIF DTS
|
||||
case SystemBusKey => up(SystemBusKey).copy(
|
||||
errorDevice = Some(DevNullParams(
|
||||
Seq(AddressSet(0x3000, 0xfff)),
|
||||
maxAtomic=site(XLen)/8,
|
||||
maxTransfer=128,
|
||||
region = RegionType.TRACKED)))
|
||||
case PeripheryBusKey => up(PeripheryBusKey, site).copy(dtsFrequency =
|
||||
Some(BigDecimal(site(FPGAFrequencyKey)*1000000).setScale(0, BigDecimal.RoundingMode.HALF_UP).toBigInt))
|
||||
case ControlBusKey => up(ControlBusKey, site).copy(
|
||||
errorDevice = None)
|
||||
case DTSTimebase => BigInt(1000000)
|
||||
case BootROMLocated(x) => up(BootROMLocated(x), site).map { p =>
|
||||
// invoke makefile for sdboot
|
||||
val freqMHz = site(FPGAFrequencyKey).toInt * 1000000
|
||||
val make = s"make -C fpga/src/main/resources/vcu118/sdboot PBUS_CLK=${freqMHz} bin"
|
||||
require (make.! == 0, "Failed to build bootrom")
|
||||
p.copy(hang = 0x10000, contentFileName = s"./fpga/src/main/resources/vcu118/sdboot/build/sdboot.bin")
|
||||
}
|
||||
case ExtMem => up(ExtMem, site).map(x => x.copy(master = x.master.copy(size = site(VCU118DDRSize))))
|
||||
})
|
||||
|
||||
class AbstractVCU118Config extends Config(
|
||||
new WithUART ++
|
||||
new WithSPISDCard ++
|
||||
new WithDDRMem ++
|
||||
new WithUARTIOPassthrough ++
|
||||
new WithSPIIOPassthrough ++
|
||||
new WithTLIOPassthrough ++
|
||||
new WithDefaultPeripherals ++
|
||||
new WithSystemModifications ++ // remove debug module, setup busses, use sdboot bootrom, setup ext. mem. size
|
||||
new freechips.rocketchip.subsystem.WithoutTLMonitors ++
|
||||
new chipyard.config.WithNoSubsystemDrivenClocks ++
|
||||
new chipyard.config.WithPeripheryBusFrequencyAsDefault ++
|
||||
new chipyard.config.WithL2TLBs(1024) ++
|
||||
new freechips.rocketchip.subsystem.WithNMemoryChannels(1) ++
|
||||
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++
|
||||
new chipyard.WithMulticlockCoherentBusTopology ++
|
||||
new freechips.rocketchip.system.BaseConfig)
|
||||
|
||||
class RocketVCU118Config extends Config(
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new AbstractVCU118Config)
|
||||
|
||||
class BoomVCU118Config extends Config(
|
||||
new WithFPGAFrequency(75) ++
|
||||
new boom.common.WithNLargeBooms(1) ++
|
||||
new AbstractVCU118Config)
|
||||
|
||||
class WithFPGAFrequency(MHz: Double) extends Config((site, here, up) => {
|
||||
case FPGAFrequencyKey => MHz
|
||||
})
|
||||
|
||||
class WithFPGAFreq25MHz extends WithFPGAFrequency(25)
|
||||
class WithFPGAFreq50MHz extends WithFPGAFrequency(50)
|
||||
class WithFPGAFreq75MHz extends WithFPGAFrequency(75)
|
||||
class WithFPGAFreq100MHz extends WithFPGAFrequency(100)
|
||||
51
fpga/src/main/scala/vcu118/HarnessBinders.scala
Normal file
51
fpga/src/main/scala/vcu118/HarnessBinders.scala
Normal file
@@ -0,0 +1,51 @@
|
||||
package chipyard.fpga.vcu118
|
||||
|
||||
import chisel3._
|
||||
import chisel3.experimental.{BaseModule}
|
||||
|
||||
import freechips.rocketchip.util.{HeterogeneousBag}
|
||||
import freechips.rocketchip.tilelink.{TLBundle}
|
||||
|
||||
import sifive.blocks.devices.uart.{HasPeripheryUARTModuleImp, UARTPortIO}
|
||||
import sifive.blocks.devices.spi.{HasPeripherySPI, SPIPortIO}
|
||||
|
||||
import chipyard.{CanHaveMasterTLMemPort, HasHarnessSignalReferences}
|
||||
import chipyard.harness.{OverrideHarnessBinder}
|
||||
|
||||
/*** UART ***/
|
||||
class WithUART extends OverrideHarnessBinder({
|
||||
(system: HasPeripheryUARTModuleImp, th: BaseModule with HasHarnessSignalReferences, ports: Seq[UARTPortIO]) => {
|
||||
th match { case vcu118th: VCU118FPGATestHarnessImp => {
|
||||
vcu118th.vcu118Outer.io_uart_bb.bundle <> ports.head
|
||||
} }
|
||||
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
/*** SPI ***/
|
||||
class WithSPISDCard extends OverrideHarnessBinder({
|
||||
(system: HasPeripherySPI, th: BaseModule with HasHarnessSignalReferences, ports: Seq[SPIPortIO]) => {
|
||||
th match { case vcu118th: VCU118FPGATestHarnessImp => {
|
||||
vcu118th.vcu118Outer.io_spi_bb.bundle <> ports.head
|
||||
} }
|
||||
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
/*** Experimental DDR ***/
|
||||
class WithDDRMem extends OverrideHarnessBinder({
|
||||
(system: CanHaveMasterTLMemPort, th: BaseModule with HasHarnessSignalReferences, ports: Seq[HeterogeneousBag[TLBundle]]) => {
|
||||
th match { case vcu118th: VCU118FPGATestHarnessImp => {
|
||||
require(ports.size == 1)
|
||||
|
||||
val bundles = vcu118th.vcu118Outer.ddrClient.out.map(_._1)
|
||||
val ddrClientBundle = Wire(new HeterogeneousBag(bundles.map(_.cloneType)))
|
||||
bundles.zip(ddrClientBundle).foreach { case (bundle, io) => bundle <> io }
|
||||
ddrClientBundle <> ports.head
|
||||
} }
|
||||
|
||||
Nil
|
||||
}
|
||||
})
|
||||
52
fpga/src/main/scala/vcu118/IOBinders.scala
Normal file
52
fpga/src/main/scala/vcu118/IOBinders.scala
Normal file
@@ -0,0 +1,52 @@
|
||||
package chipyard.fpga.vcu118
|
||||
|
||||
import chisel3._
|
||||
import chisel3.experimental.{IO, DataMirror}
|
||||
|
||||
import freechips.rocketchip.diplomacy.{ResourceBinding, Resource, ResourceAddress, InModuleBody}
|
||||
import freechips.rocketchip.subsystem.{BaseSubsystem}
|
||||
import freechips.rocketchip.util.{HeterogeneousBag}
|
||||
import freechips.rocketchip.tilelink.{TLBundle}
|
||||
|
||||
import sifive.blocks.devices.uart.{HasPeripheryUARTModuleImp}
|
||||
import sifive.blocks.devices.spi.{HasPeripherySPI, HasPeripherySPIModuleImp, MMCDevice}
|
||||
|
||||
import chipyard.{CanHaveMasterTLMemPort}
|
||||
import chipyard.iobinders.{OverrideIOBinder, OverrideLazyIOBinder}
|
||||
|
||||
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 WithSPIIOPassthrough extends OverrideLazyIOBinder({
|
||||
(system: HasPeripherySPI) => {
|
||||
// attach resource to 1st SPI
|
||||
ResourceBinding {
|
||||
Resource(new MMCDevice(system.tlSpiNodes.head.device, 1), "reg").bind(ResourceAddress(0))
|
||||
}
|
||||
|
||||
InModuleBody {
|
||||
system.asInstanceOf[BaseSubsystem].module match { case 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 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)
|
||||
}
|
||||
})
|
||||
144
fpga/src/main/scala/vcu118/TestHarness.scala
Normal file
144
fpga/src/main/scala/vcu118/TestHarness.scala
Normal file
@@ -0,0 +1,144 @@
|
||||
package chipyard.fpga.vcu118
|
||||
|
||||
import chisel3._
|
||||
import chisel3.experimental.{IO}
|
||||
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.config._
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.tilelink._
|
||||
|
||||
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.{HasHarnessSignalReferences, HasTestHarnessFunctions, BuildTop, CanHaveMasterTLMemPort, ChipTop}
|
||||
import chipyard.iobinders.{HasIOBinders}
|
||||
import chipyard.harness.{ApplyHarnessBinders}
|
||||
|
||||
case object FPGAFrequencyKey extends Field[Double](100.0)
|
||||
|
||||
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
|
||||
val harnessSysPLL = dp(PLLFactoryKey)()
|
||||
sys_clock.get() match {
|
||||
case Some(x : SysClockVCU118PlacedOverlay) => {
|
||||
harnessSysPLL := x.node
|
||||
}
|
||||
}
|
||||
|
||||
// create and connect to the dutClock
|
||||
val dutClock = ClockSinkNode(freqMHz = dp(FPGAFrequencyKey))
|
||||
val dutWrangler = LazyModule(new ResetWrangler)
|
||||
val dutGroup = ClockGroup()
|
||||
dutClock := dutWrangler.node := dutGroup := harnessSysPLL
|
||||
|
||||
// connect ref clock to dummy sink node
|
||||
ref_clock.get() match {
|
||||
case Some(x : RefClockVCU118PlacedOverlay) => {
|
||||
val sink = ClockSinkNode(Seq(ClockSinkParameters()))
|
||||
sink := x.node
|
||||
}
|
||||
}
|
||||
|
||||
/*** UART ***/
|
||||
|
||||
// 1st UART goes to the VCU118 dedicated UART
|
||||
|
||||
val io_uart_bb = BundleBridgeSource(() => (new UARTPortIO(dp(PeripheryUARTKey).head)))
|
||||
dp(UARTOverlayKey).head.place(UARTDesignInput(io_uart_bb))
|
||||
|
||||
/*** SPI ***/
|
||||
|
||||
// 1st SPI goes to the VCU118 SDIO port
|
||||
|
||||
val io_spi_bb = BundleBridgeSource(() => (new SPIPortIO(dp(PeripherySPIKey).head)))
|
||||
dp(SPIOverlayKey).head.place(SPIDesignInput(dp(PeripherySPIKey).head, io_spi_bb))
|
||||
|
||||
/*** DDR ***/
|
||||
|
||||
val ddrPlaced = dp(DDROverlayKey).head.place(DDRDesignInput(dp(ExtMem).get.master.base, dutWrangler.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)
|
||||
}
|
||||
|
||||
class VCU118FPGATestHarnessImp(_outer: VCU118FPGATestHarness) extends LazyRawModuleImp(_outer) with HasHarnessSignalReferences {
|
||||
|
||||
val vcu118Outer = _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
|
||||
|
||||
childClock := harnessClock
|
||||
childReset := harnessReset
|
||||
|
||||
// harness binders are non-lazy
|
||||
_outer.topDesign match { case d: HasTestHarnessFunctions =>
|
||||
d.harnessFunctions.foreach(_(this))
|
||||
}
|
||||
_outer.topDesign match { case d: HasIOBinders =>
|
||||
ApplyHarnessBinders(this, d.lazySystem, d.portMap)
|
||||
}
|
||||
}
|
||||
@@ -1,39 +1,24 @@
|
||||
package chipyard.fpga.vcu118.bringup
|
||||
|
||||
import math.min
|
||||
import sys.process._
|
||||
|
||||
import freechips.rocketchip.config._
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.devices.debug._
|
||||
import freechips.rocketchip.devices.tilelink._
|
||||
import freechips.rocketchip.config.{Config}
|
||||
import freechips.rocketchip.diplomacy.{DTSModel, DTSTimebase, RegionType, AddressSet, ResourceBinding, Resource, ResourceAddress}
|
||||
import freechips.rocketchip.system._
|
||||
import freechips.rocketchip.tile._
|
||||
|
||||
import sifive.blocks.devices.gpio._
|
||||
import sifive.blocks.devices.pwm._
|
||||
import sifive.blocks.devices.spi._
|
||||
import sifive.blocks.devices.uart._
|
||||
import sifive.blocks.devices.i2c._
|
||||
import sifive.blocks.devices.gpio.{PeripheryGPIOKey, GPIOParams}
|
||||
import sifive.blocks.devices.i2c.{PeripheryI2CKey, I2CParams}
|
||||
import sifive.blocks.devices.spi.{PeripherySPIKey, SPIParams}
|
||||
import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTParams}
|
||||
|
||||
import sifive.fpgashells.shell.{DesignKey}
|
||||
import sifive.fpgashells.shell.xilinx.{VCU118ShellPMOD, VCU118DDRSize}
|
||||
|
||||
import chipyard.{BuildTop}
|
||||
|
||||
import chipyard.harness._
|
||||
import chipyard.fpga.vcu118.{RocketVCU118Config, BoomVCU118Config}
|
||||
|
||||
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 PeripheryUARTKey => up(PeripheryUARTKey, site) ++ List(UARTParams(address = BigInt(0x64003000L)))
|
||||
case PeripherySPIKey => up(PeripherySPIKey, site) ++ List(SPIParams(rAddress = BigInt(0x64004000L)))
|
||||
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)
|
||||
@@ -49,60 +34,19 @@ class WithBringupPeripherals extends Config((site, here, up) => {
|
||||
}
|
||||
})
|
||||
|
||||
class SmallModifications extends Config((site, here, up) => {
|
||||
case DebugModuleKey => None // disable debug module
|
||||
case ExportDebug => up(ExportDebug).copy(protocols = Set(JTAG)) // don't generate HTIF DTS
|
||||
case SystemBusKey => up(SystemBusKey).copy(
|
||||
errorDevice = Some(DevNullParams(
|
||||
Seq(AddressSet(0x3000, 0xfff)),
|
||||
maxAtomic=site(XLen)/8,
|
||||
maxTransfer=128,
|
||||
region = RegionType.TRACKED)))
|
||||
case PeripheryBusKey => up(PeripheryBusKey, site).copy(dtsFrequency =
|
||||
Some(BigDecimal(site(DUTFrequencyKey)*1000000).setScale(0, BigDecimal.RoundingMode.HALF_UP).toBigInt))
|
||||
case ControlBusKey => up(ControlBusKey, site).copy(
|
||||
errorDevice = None)
|
||||
case DTSTimebase => BigInt(1000000)
|
||||
})
|
||||
|
||||
class WithBootROM extends Config((site, here, up) => {
|
||||
case BootROMLocated(x) => up(BootROMLocated(x), site).map { p =>
|
||||
// invoke makefile for sdboot
|
||||
val freqMHz = site(DUTFrequencyKey).toInt * 1000000
|
||||
val make = s"make -C fpga/src/main/resources/vcu118/sdboot PBUS_CLK=${freqMHz} bin"
|
||||
require (make.! == 0, "Failed to build bootrom")
|
||||
p.copy(hang = 0x10000, contentFileName = s"./fpga/src/main/resources/vcu118/sdboot/build/sdboot.bin")
|
||||
}
|
||||
})
|
||||
|
||||
class WithExtMemSetToDDR extends Config((site, here, up) => {
|
||||
case ExtMem => up(ExtMem, site).map(x => x.copy(master = x.master.copy(size = site(VCU118DDRSize))))
|
||||
})
|
||||
|
||||
class FakeBringupConfig extends Config(
|
||||
new SmallModifications ++
|
||||
class WithBringupAdditions extends Config(
|
||||
new WithBringupUART ++
|
||||
new WithBringupSPI ++
|
||||
new WithBringupI2C ++
|
||||
new WithBringupGPIO ++
|
||||
new WithBringupDDR ++
|
||||
new WithUARTIOPassthrough ++
|
||||
new WithSPIIOPassthrough ++
|
||||
new WithI2CIOPassthrough ++
|
||||
new WithGPIOIOPassthrough ++
|
||||
new WithTLIOPassthrough ++
|
||||
new WithBringupPeripherals)
|
||||
|
||||
class RocketBringupConfig extends Config(
|
||||
new WithBringupPeripherals ++
|
||||
new WithExtMemSetToDDR ++ // set the external mem port size properly
|
||||
new freechips.rocketchip.subsystem.WithoutTLMonitors ++
|
||||
new chipyard.config.WithNoSubsystemDrivenClocks ++
|
||||
new chipyard.config.WithPeripheryBusFrequencyAsDefault ++
|
||||
new WithBootROM ++ // use local bootrom
|
||||
new chipyard.config.WithL2TLBs(1024) ++
|
||||
new freechips.rocketchip.subsystem.WithNMemoryChannels(1) ++
|
||||
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||
//new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++
|
||||
new chipyard.WithMulticlockCoherentBusTopology ++
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new freechips.rocketchip.system.BaseConfig)
|
||||
new RocketVCU118Config)
|
||||
|
||||
class BoomBringupConfig extends Config(
|
||||
new WithBringupPeripherals ++
|
||||
new BoomVCU118Config)
|
||||
|
||||
@@ -4,15 +4,11 @@ import chisel3._
|
||||
import chisel3.experimental.{attach}
|
||||
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import chipsalliance.rocketchip.config.{Parameters, Field}
|
||||
|
||||
import sifive.fpgashells.shell._
|
||||
import sifive.fpgashells.ip.xilinx._
|
||||
import sifive.fpgashells.shell.xilinx._
|
||||
|
||||
import sifive.blocks.devices.gpio._
|
||||
|
||||
|
||||
import chipyard.fpga.vcu118.{FMCPMap}
|
||||
|
||||
/* Connect the I2C to certain FMC pins */
|
||||
|
||||
@@ -3,33 +3,21 @@ package chipyard.fpga.vcu118.bringup
|
||||
import chisel3._
|
||||
import chisel3.experimental.{Analog, IO, BaseModule}
|
||||
|
||||
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.blocks.devices.uart.{HasPeripheryUARTModuleImp, UARTPortIO}
|
||||
import sifive.blocks.devices.spi.{HasPeripherySPI, SPIPortIO}
|
||||
import sifive.blocks.devices.i2c.{HasPeripheryI2CModuleImp, I2CPort}
|
||||
import sifive.blocks.devices.gpio.{HasPeripheryGPIOModuleImp, GPIOPortIO}
|
||||
|
||||
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.{CanHaveMasterTLMemPort, HasHarnessSignalReferences}
|
||||
import chipyard.harness._
|
||||
import chipyard.{HasHarnessSignalReferences}
|
||||
import chipyard.harness.{ComposeHarnessBinder, OverrideHarnessBinder}
|
||||
|
||||
/*** UART ***/
|
||||
class WithBringupUART extends OverrideHarnessBinder({
|
||||
class WithBringupUART extends ComposeHarnessBinder({
|
||||
(system: HasPeripheryUARTModuleImp, th: BaseModule with 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
|
||||
vcu118th.bringupOuter.io_fmc_uart_bb.bundle <> ports.last
|
||||
} }
|
||||
|
||||
Nil
|
||||
@@ -37,13 +25,12 @@ class WithBringupUART extends OverrideHarnessBinder({
|
||||
})
|
||||
|
||||
/*** SPI ***/
|
||||
class WithBringupSPI extends OverrideHarnessBinder({
|
||||
class WithBringupSPI extends ComposeHarnessBinder({
|
||||
(system: HasPeripherySPI, th: BaseModule with 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
|
||||
vcu118th.bringupOuter.io_adi_spi_bb.bundle <> ports.last
|
||||
} }
|
||||
|
||||
Nil
|
||||
@@ -56,7 +43,7 @@ class WithBringupI2C extends OverrideHarnessBinder({
|
||||
th match { case vcu118th: BringupVCU118FPGATestHarnessImp => {
|
||||
require(ports.size == 1)
|
||||
|
||||
vcu118th.outer.io_i2c_bb.bundle <> ports.head
|
||||
vcu118th.bringupOuter.io_i2c_bb.bundle <> ports.head
|
||||
} }
|
||||
|
||||
Nil
|
||||
@@ -67,7 +54,7 @@ class WithBringupI2C extends OverrideHarnessBinder({
|
||||
class WithBringupGPIO extends OverrideHarnessBinder({
|
||||
(system: HasPeripheryGPIOModuleImp, th: BaseModule with HasHarnessSignalReferences, ports: Seq[GPIOPortIO]) => {
|
||||
th match { case vcu118th: BringupVCU118FPGATestHarnessImp => {
|
||||
(vcu118th.outer.io_gpio_bb zip ports).map { case (bb_io, dut_io) =>
|
||||
(vcu118th.bringupOuter.io_gpio_bb zip ports).map { case (bb_io, dut_io) =>
|
||||
bb_io.bundle <> dut_io
|
||||
}
|
||||
} }
|
||||
@@ -75,19 +62,3 @@ class WithBringupGPIO extends OverrideHarnessBinder({
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
/*** Experimental DDR ***/
|
||||
class WithBringupDDR extends OverrideHarnessBinder({
|
||||
(system: CanHaveMasterTLMemPort, th: BaseModule with 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
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,43 +1,12 @@
|
||||
package chipyard.fpga.vcu118.bringup
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util.experimental.{BoringUtils}
|
||||
import chisel3.experimental.{Analog, IO, DataMirror}
|
||||
import chisel3.experimental.{IO, DataMirror}
|
||||
|
||||
import freechips.rocketchip.config._
|
||||
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike, ResourceBinding, Resource, ResourceAddress, InModuleBody}
|
||||
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.{HasPeripheryGPIOModuleImp}
|
||||
import sifive.blocks.devices.i2c.{HasPeripheryI2CModuleImp}
|
||||
|
||||
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, OverrideLazyIOBinder}
|
||||
|
||||
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)
|
||||
}
|
||||
})
|
||||
import chipyard.iobinders.{OverrideIOBinder}
|
||||
|
||||
class WithGPIOIOPassthrough extends OverrideIOBinder({
|
||||
(system: HasPeripheryGPIOModuleImp) => {
|
||||
@@ -49,25 +18,6 @@ class WithGPIOIOPassthrough extends OverrideIOBinder({
|
||||
}
|
||||
})
|
||||
|
||||
class WithSPIIOPassthrough extends OverrideLazyIOBinder({
|
||||
(system: HasPeripherySPI) => {
|
||||
// attach resource to 1st SPI
|
||||
ResourceBinding {
|
||||
Resource(new MMCDevice(system.tlSpiNodes.head.device, 1), "reg").bind(ResourceAddress(0))
|
||||
}
|
||||
|
||||
InModuleBody {
|
||||
system.asInstanceOf[BaseSubsystem].module match { case 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 WithI2CIOPassthrough extends OverrideIOBinder({
|
||||
(system: HasPeripheryI2CModuleImp) => {
|
||||
val io_i2c_pins_temp = system.i2c.zipWithIndex.map { case (dio, i) => IO(dio.cloneType).suggestName(s"i2c_$i") }
|
||||
@@ -77,11 +27,3 @@ class WithI2CIOPassthrough extends OverrideIOBinder({
|
||||
(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)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
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.config._
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.tilelink._
|
||||
|
||||
import sifive.fpgashells.shell.xilinx._
|
||||
@@ -18,100 +17,31 @@ import sifive.blocks.devices.spi._
|
||||
import sifive.blocks.devices.i2c._
|
||||
import sifive.blocks.devices.gpio._
|
||||
|
||||
import chipyard.harness._
|
||||
import chipyard.{HasHarnessSignalReferences, HasTestHarnessFunctions, BuildTop, CanHaveMasterTLMemPort, ChipTop}
|
||||
import chipyard.iobinders.{HasIOBinders}
|
||||
import chipyard.fpga.vcu118.{VCU118FPGATestHarness, VCU118FPGATestHarnessImp}
|
||||
|
||||
case object DUTFrequencyKey extends Field[Double](100.0)
|
||||
|
||||
class BringupVCU118FPGATestHarness(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
|
||||
val harnessSysPLL = dp(PLLFactoryKey)()
|
||||
sys_clock.get() match {
|
||||
case Some(x : SysClockVCU118PlacedOverlay) => {
|
||||
harnessSysPLL := x.node
|
||||
}
|
||||
}
|
||||
|
||||
// create and connect to the dutClock
|
||||
val dutClock = ClockSinkNode(freqMHz = dp(DUTFrequencyKey))
|
||||
val dutWrangler = LazyModule(new ResetWrangler)
|
||||
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
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
// connect ref clock to dummy sink node
|
||||
ref_clock.get() match {
|
||||
case Some(x : RefClockVCU118PlacedOverlay) => {
|
||||
val sink = ClockSinkNode(Seq(ClockSinkParameters()))
|
||||
sink := x.node
|
||||
}
|
||||
}
|
||||
|
||||
// extra overlays
|
||||
class BringupVCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118FPGATestHarness {
|
||||
|
||||
/*** 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
|
||||
// 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))
|
||||
val io_fmc_uart_bb = BundleBridgeSource(() => (new UARTPortIO(dp(PeripheryUARTKey).last)))
|
||||
dp(UARTOverlayKey).last.place(UARTDesignInput(io_fmc_uart_bb))
|
||||
|
||||
/*** 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))
|
||||
val io_adi_spi_bb = BundleBridgeSource(() => (new SPIPortIO(dp(PeripherySPIKey).last)))
|
||||
dp(SPIOverlayKey).last.place(SPIDesignInput(dp(PeripherySPIKey).last, io_adi_spi_bb))
|
||||
|
||||
/*** I2C ***/
|
||||
|
||||
@@ -123,7 +53,7 @@ class BringupVCU118FPGATestHarness(override implicit val p: Parameters) extends
|
||||
/*** GPIO ***/
|
||||
|
||||
val gpio = Seq.tabulate(dp(PeripheryGPIOKey).size)(i => {
|
||||
val maxGPIOSupport = 32
|
||||
val maxGPIOSupport = 32 // max gpio per gpio chip
|
||||
val names = BringupGPIOs.names.slice(maxGPIOSupport*i, maxGPIOSupport*(i+1))
|
||||
Overlay(GPIOOverlayKey, new BringupGPIOVCU118ShellPlacer(this, GPIOShellInput(), names))
|
||||
})
|
||||
@@ -133,62 +63,10 @@ class BringupVCU118FPGATestHarness(override implicit val p: Parameters) extends
|
||||
placer.place(GPIODesignInput(params, io_gpio_bb(i)))
|
||||
}
|
||||
|
||||
/*** DDR ***/
|
||||
|
||||
val ddrPlaced = dp(DDROverlayKey).head.place(DDRDesignInput(dp(ExtMem).get.master.base, dutWrangler.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 BringupVCU118FPGATestHarnessImp(this)
|
||||
}
|
||||
|
||||
class BringupVCU118FPGATestHarnessImp(_outer: BringupVCU118FPGATestHarness) 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
|
||||
|
||||
childClock := harnessClock
|
||||
childReset := harnessReset
|
||||
|
||||
// harness binders are non-lazy
|
||||
_outer.topDesign match { case d: HasTestHarnessFunctions =>
|
||||
d.harnessFunctions.foreach(_(this))
|
||||
}
|
||||
_outer.topDesign match { case d: HasIOBinders =>
|
||||
ApplyHarnessBinders(this, d.lazySystem, d.portMap)
|
||||
}
|
||||
class BringupVCU118FPGATestHarnessImp(_outer: BringupVCU118FPGATestHarness) extends VCU118FPGATestHarnessImp(_outer) {
|
||||
val bringupOuter = _outer
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user