Pipe through AXI4 MMIO and Slave ports to ChipTop | IOBinders fix

* Fixes bug with AXI4 MMIO ports not being generated properly due to
   IOBinders issue. Additionally adds IOCells to AXI4 ports so that they
   appear in ChipTop
 * Change IOBinders to also require passing p: Parameters
   to child functions. Serialization of type targets via ClassTags fails
   for compound types, so we cannot use `BaseSubsystem with HasSomeTrait`
   as the type target in OverrideIOBinders.
This commit is contained in:
Jerry Zhao
2020-06-30 12:26:26 -07:00
parent 863e68ff30
commit 863f723708
7 changed files with 132 additions and 88 deletions

View File

@@ -287,6 +287,11 @@ jobs:
steps: steps:
- prepare-rtl: - prepare-rtl:
project-key: "chipyard-spiflashread" project-key: "chipyard-spiflashread"
prepare-chipyard-mmios:
executor: main-env
steps:
- prepare-rtl:
project-key: "chipyard-mmios"
chipyard-rocket-run-tests: chipyard-rocket-run-tests:
executor: main-env executor: main-env
steps: steps:
@@ -531,6 +536,10 @@ workflows:
- install-riscv-toolchain - install-riscv-toolchain
- install-verilator - install-verilator
- prepare-chipyard-mmios:
requires:
- install-riscv-toolchain
# Run the respective tests # Run the respective tests
# Run the example tests # Run the example tests

View File

@@ -47,23 +47,25 @@ LOCAL_FIRESIM_DIR=$LOCAL_CHIPYARD_DIR/sims/firesim/sim
# key value store to get the build strings # key value store to get the build strings
declare -A mapping declare -A mapping
mapping["chipyard-rocket"]="SUB_PROJECT=chipyard" mapping["chipyard-rocket"]=""
mapping["chipyard-sha3"]="SUB_PROJECT=chipyard CONFIG=Sha3RocketConfig" mapping["chipyard-sha3"]=" CONFIG=Sha3RocketConfig"
mapping["chipyard-streaming-fir"]="SUB_PROJECT=chipyard CONFIG=StreamingFIRRocketConfig" mapping["chipyard-streaming-fir"]=" CONFIG=StreamingFIRRocketConfig"
mapping["chipyard-streaming-passthrough"]="SUB_PROJECT=chipyard CONFIG=StreamingPassthroughRocketConfig" mapping["chipyard-streaming-passthrough"]=" CONFIG=StreamingPassthroughRocketConfig"
mapping["chipyard-hetero"]="SUB_PROJECT=chipyard CONFIG=LargeBoomAndRocketConfig" mapping["chipyard-hetero"]=" CONFIG=LargeBoomAndRocketConfig"
mapping["chipyard-boom"]="SUB_PROJECT=chipyard CONFIG=SmallBoomConfig" mapping["chipyard-boom"]=" CONFIG=SmallBoomConfig"
mapping["chipyard-blkdev"]="SUB_PROJECT=chipyard CONFIG=SimBlockDeviceRocketConfig" mapping["chipyard-blkdev"]=" CONFIG=SimBlockDeviceRocketConfig"
mapping["chipyard-hwacha"]="SUB_PROJECT=chipyard CONFIG=HwachaRocketConfig" mapping["chipyard-hwacha"]=" CONFIG=HwachaRocketConfig"
mapping["chipyard-gemmini"]="SUB_PROJECT=chipyard CONFIG=GemminiRocketConfig" mapping["chipyard-gemmini"]=" CONFIG=GemminiRocketConfig"
mapping["chipyard-ariane"]="SUB_PROJECT=chipyard CONFIG=ArianeConfig" mapping["chipyard-ariane"]=" CONFIG=ArianeConfig"
mapping["chipyard-spiflashread"]="SUB_PROJECT=chipyard CONFIG=LargeSPIFlashROMRocketConfig" mapping["chipyard-spiflashread"]=" CONFIG=LargeSPIFlashROMRocketConfig"
mapping["chipyard-spiflashwrite"]="SUB_PROJECT=chipyard CONFIG=SmallSPIFlashRocketConfig" mapping["chipyard-spiflashwrite"]=" CONFIG=SmallSPIFlashRocketConfig"
mapping["tracegen"]="SUB_PROJECT=chipyard CONFIG=NonBlockingTraceGenL2Config TOP=TraceGenSystem" mapping["chipyard-mmios"]=" CONFIG=MMIORocketConfig verilog"
mapping["tracegen-boom"]="SUB_PROJECT=chipyard CONFIG=BoomTraceGenConfig TOP=TraceGenSystem" mapping["tracegen"]=" CONFIG=NonBlockingTraceGenL2Config TOP=TraceGenSystem"
mapping["chipyard-nvdla"]="SUB_PROJECT=chipyard CONFIG=SmallNVDLARocketConfig" mapping["tracegen-boom"]=" CONFIG=BoomTraceGenConfig TOP=TraceGenSystem"
mapping["chipyard-nvdla"]=" CONFIG=SmallNVDLARocketConfig"
mapping["firesim"]="SCALA_TEST=firesim.firesim.RocketNICF1Tests" mapping["firesim"]="SCALA_TEST=firesim.firesim.RocketNICF1Tests"
mapping["firesim-multiclock"]="SCALA_TEST=firesim.firesim.RocketMulticlockF1Tests" mapping["firesim-multiclock"]="SCALA_TEST=firesim.firesim.RocketMulticlockF1Tests"
mapping["fireboom"]="SCALA_TEST=firesim.firesim.BoomF1Tests" mapping["fireboom"]="SCALA_TEST=firesim.firesim.BoomF1Tests"
mapping["icenet"]="SUB_PROJECT=icenet" mapping["icenet"]="SUB_PROJECT=icenet"
mapping["testchipip"]="SUB_PROJECT=testchipip" mapping["testchipip"]="SUB_PROJECT=testchipip"

View File

@@ -70,12 +70,13 @@ abstract class BaseChipTop()(implicit val p: Parameters) extends RawModule with
val lSystem = p(BuildSystem)(p).suggestName("system") val lSystem = p(BuildSystem)(p).suggestName("system")
val system = withClockAndReset(systemClock, systemReset) { Module(lSystem.module) } val system = withClockAndReset(systemClock, systemReset) { Module(lSystem.module) }
// Call all of the IOBinders and provide them with a default clock and reset // Call all of the IOBinders and provide them with a default clock and reset
withClockAndReset(systemClock, systemReset) { withClockAndReset(systemClock, systemReset) {
// Call each IOBinder on both the lazyModule instance and the module // Call each IOBinder on both the lazyModule instance and the module
// instance. Generally, an IOBinder PF should only be defined on one, so // instance. Generally, an IOBinder PF should only be defined on one, so
// this should not lead to two invocations. // this should not lead to two invocations.
val (_ports, _iocells, _harnessFunctions) = p(IOBinders).values.flatMap(f => f(lSystem) ++ f(system)).unzip3 val (_ports, _iocells, _harnessFunctions) = p(IOBinders).values.flatMap(f => f(lSystem, p) ++ f(system, p)).unzip3
// We ignore _ports for now... // We ignore _ports for now...
iocells ++= _iocells.flatten iocells ++= _iocells.flatten
harnessFunctions ++= _harnessFunctions.flatten harnessFunctions ++= _harnessFunctions.flatten

View File

@@ -9,7 +9,7 @@ import freechips.rocketchip.diplomacy.{LazyModule}
import freechips.rocketchip.devices.debug._ import freechips.rocketchip.devices.debug._
import freechips.rocketchip.subsystem._ import freechips.rocketchip.subsystem._
import freechips.rocketchip.system.{SimAXIMem} import freechips.rocketchip.system.{SimAXIMem}
import freechips.rocketchip.amba.axi4.{AXI4Bundle, AXI4SlaveNode, AXI4EdgeParameters} import freechips.rocketchip.amba.axi4.{AXI4Bundle, AXI4SlaveNode, AXI4MasterNode, AXI4EdgeParameters}
import freechips.rocketchip.util._ import freechips.rocketchip.util._
import freechips.rocketchip.groundtest.{GroundTestSubsystemModuleImp, GroundTestSubsystem} import freechips.rocketchip.groundtest.{GroundTestSubsystemModuleImp, GroundTestSubsystem}
@@ -48,17 +48,17 @@ type TestHarnessFunction = (chipyard.TestHarness) => Seq[Any]
// 3. An optional function to call inside the test harness (e.g. to connect the IOs) // 3. An optional function to call inside the test harness (e.g. to connect the IOs)
type IOBinderTuple = (Seq[Data], Seq[IOCell], Option[TestHarnessFunction]) type IOBinderTuple = (Seq[Data], Seq[IOCell], Option[TestHarnessFunction])
case object IOBinders extends Field[Map[String, (Any) => Seq[IOBinderTuple]]]( case object IOBinders extends Field[Map[String, (Any, Parameters) => Seq[IOBinderTuple]]](
Map[String, (Any) => Seq[IOBinderTuple]]().withDefaultValue((Any) => Nil) Map[String, (Any, Parameters) => Seq[IOBinderTuple]]().withDefaultValue((Any, Parameters) => Nil)
) )
// This macro overrides previous matches on some Top mixin. This is useful for // This macro overrides previous matches on some Top mixin. This is useful for
// binders which drive IO, since those typically cannot be composed // binders which drive IO, since those typically cannot be composed
class OverrideIOBinder[T](fn: => (T) => Seq[IOBinderTuple])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { class OverrideIOBinder[T](fn: => (T, Parameters) => Seq[IOBinderTuple])(implicit tag: ClassTag[T]) extends Config((site, here, up) => {
case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString -> case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString ->
((t: Any) => { ((t: Any, p: Parameters) => {
t match { t match {
case system: T => fn(system) case system: T => fn(system, p)
case _ => Nil case _ => Nil
} }
}) })
@@ -67,12 +67,12 @@ class OverrideIOBinder[T](fn: => (T) => Seq[IOBinderTuple])(implicit tag: ClassT
// This macro composes with previous matches on some Top mixin. This is useful for // This macro composes with previous matches on some Top mixin. This is useful for
// annotation-like binders, since those can typically be composed // annotation-like binders, since those can typically be composed
class ComposeIOBinder[T](fn: => (T) => Seq[IOBinderTuple])(implicit tag: ClassTag[T]) extends Config((site, here, up) => { class ComposeIOBinder[T](fn: => (T, Parameters) => Seq[IOBinderTuple])(implicit tag: ClassTag[T]) extends Config((site, here, up) => {
case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString -> case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString ->
((t: Any) => { ((t: Any, p: Parameters) => {
t match { t match {
case system: T => (up(IOBinders, site)(tag.runtimeClass.toString)(system) case system: T => (up(IOBinders, site)(tag.runtimeClass.toString)(system, p)
++ fn(system)) ++ fn(system, p))
case _ => Nil case _ => Nil
} }
}) })
@@ -185,10 +185,19 @@ object AddIOCells {
(port, ios) (port, ios)
} }
def axi4(io: Seq[AXI4Bundle], node: AXI4SlaveNode): Seq[(AXI4Bundle, AXI4EdgeParameters, Seq[IOCell])] = { def axi4(io: Seq[AXI4Bundle], node: AXI4SlaveNode, name: String): Seq[(AXI4Bundle, AXI4EdgeParameters, Seq[IOCell])] = {
io.zip(node.in).zipWithIndex.map{ case ((mem_axi4, (_, edge)), i) => { io.zip(node.in).zipWithIndex.map{ case ((mem_axi4, (_, edge)), i) => {
val (port, ios) = IOCell.generateIOFromSignal(mem_axi4, Some(s"iocell_mem_axi4_${i}")) val (port, ios) = IOCell.generateIOFromSignal(mem_axi4, Some(s"iocell_${name}_axi4_slave_${i}"))
port.suggestName(s"mem_axi4_${i}") port.suggestName(s"${name}_axi4_slave_${i}")
(port, edge, ios)
}}
}
def axi4(io: Seq[AXI4Bundle], node: AXI4MasterNode, name: String): Seq[(AXI4Bundle, AXI4EdgeParameters, Seq[IOCell])] = {
io.zip(node.out).zipWithIndex.map{ case ((mem_axi4, (_, edge)), i) => {
//val (port, ios) = IOCell.generateIOFromSignal(mem_axi4, Some(s"iocell_${name}_axi4_master_${i}"))
val port = IO(Flipped(AXI4Bundle(edge.bundle)))
val ios = IOCell.generateFromSignal(mem_axi4, port, Some(s"iocell_${name}_axi4_master_${i}"))
port.suggestName(s"${name}_axi4_master_${i}")
(port, edge, ios) (port, edge, ios)
}} }}
} }
@@ -202,7 +211,7 @@ object AddIOCells {
// DOC include start: WithGPIOTiedOff // DOC include start: WithGPIOTiedOff
class WithGPIOTiedOff extends OverrideIOBinder({ class WithGPIOTiedOff extends OverrideIOBinder({
(system: HasPeripheryGPIOModuleImp) => { (system: HasPeripheryGPIOModuleImp, p) => {
val (ports2d, ioCells2d) = AddIOCells.gpio(system.gpio) val (ports2d, ioCells2d) = AddIOCells.gpio(system.gpio)
val harnessFn = (th: chipyard.TestHarness) => { ports2d.flatten.foreach(_ <> AnalogConst(0)); Nil } val harnessFn = (th: chipyard.TestHarness) => { ports2d.flatten.foreach(_ <> AnalogConst(0)); Nil }
Seq((ports2d.flatten, ioCells2d.flatten, Some(harnessFn))) Seq((ports2d.flatten, ioCells2d.flatten, Some(harnessFn)))
@@ -211,7 +220,7 @@ class WithGPIOTiedOff extends OverrideIOBinder({
// DOC include end: WithGPIOTiedOff // DOC include end: WithGPIOTiedOff
class WithUARTAdapter extends OverrideIOBinder({ class WithUARTAdapter extends OverrideIOBinder({
(system: HasPeripheryUARTModuleImp) => { (system: HasPeripheryUARTModuleImp, p) => {
val (ports, ioCells2d) = AddIOCells.uart(system.uart) val (ports, ioCells2d) = AddIOCells.uart(system.uart)
val harnessFn = (th: chipyard.TestHarness) => { UARTAdapter.connect(ports)(system.p); Nil } val harnessFn = (th: chipyard.TestHarness) => { UARTAdapter.connect(ports)(system.p); Nil }
Seq((ports, ioCells2d.flatten, Some(harnessFn))) Seq((ports, ioCells2d.flatten, Some(harnessFn)))
@@ -219,7 +228,7 @@ class WithUARTAdapter extends OverrideIOBinder({
}) })
class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideIOBinder({ class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideIOBinder({
(system: HasPeripherySPIFlashModuleImp) => { (system: HasPeripherySPIFlashModuleImp, p) => {
val (ports, ioCells2d) = AddIOCells.spi(system.qspi, "qspi") val (ports, ioCells2d) = AddIOCells.spi(system.qspi, "qspi")
val harnessFn = (th: chipyard.TestHarness) => { SimSPIFlashModel.connect(ports, th.reset, rdOnly)(system.p); Nil } val harnessFn = (th: chipyard.TestHarness) => { SimSPIFlashModel.connect(ports, th.reset, rdOnly)(system.p); Nil }
Seq((ports, ioCells2d.flatten, Some(harnessFn))) Seq((ports, ioCells2d.flatten, Some(harnessFn)))
@@ -227,7 +236,7 @@ class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideIOBinder({
}) })
class WithSimBlockDevice extends OverrideIOBinder({ class WithSimBlockDevice extends OverrideIOBinder({
(system: CanHavePeripheryBlockDeviceModuleImp) => system.bdev.map { bdev => (system: CanHavePeripheryBlockDeviceModuleImp, p) => system.bdev.map { bdev =>
val (port, ios) = AddIOCells.blockDev(bdev) val (port, ios) = AddIOCells.blockDev(bdev)
val harnessFn = (th: chipyard.TestHarness) => { val harnessFn = (th: chipyard.TestHarness) => {
SimBlockDevice.connect(th.clock, th.reset.asBool, Some(port))(system.p) SimBlockDevice.connect(th.clock, th.reset.asBool, Some(port))(system.p)
@@ -238,7 +247,7 @@ class WithSimBlockDevice extends OverrideIOBinder({
}) })
class WithBlockDeviceModel extends OverrideIOBinder({ class WithBlockDeviceModel extends OverrideIOBinder({
(system: CanHavePeripheryBlockDeviceModuleImp) => system.bdev.map { bdev => (system: CanHavePeripheryBlockDeviceModuleImp, p) => system.bdev.map { bdev =>
val (port, ios) = AddIOCells.blockDev(bdev) val (port, ios) = AddIOCells.blockDev(bdev)
val harnessFn = (th: chipyard.TestHarness) => { val harnessFn = (th: chipyard.TestHarness) => {
BlockDeviceModel.connect(Some(port))(system.p) BlockDeviceModel.connect(Some(port))(system.p)
@@ -249,11 +258,11 @@ class WithBlockDeviceModel extends OverrideIOBinder({
}) })
class WithLoopbackNIC extends OverrideIOBinder({ class WithLoopbackNIC extends OverrideIOBinder({
(system: CanHavePeripheryIceNICModuleImp) => system.connectNicLoopback(); Nil (system: CanHavePeripheryIceNICModuleImp, p) => system.connectNicLoopback(); Nil
}) })
class WithSimNIC extends OverrideIOBinder({ class WithSimNIC extends OverrideIOBinder({
(system: CanHavePeripheryIceNICModuleImp) => system.connectSimNetwork(system.clock, system.reset.asBool); Nil (system: CanHavePeripheryIceNICModuleImp, p) => system.connectSimNetwork(system.clock, system.reset.asBool); Nil
}) })
// Note: The parameters instance is accessible only through the BaseSubsystem // Note: The parameters instance is accessible only through the BaseSubsystem
@@ -262,16 +271,16 @@ class WithSimNIC extends OverrideIOBinder({
// accessible to the IOBinder // accessible to the IOBinder
// DOC include start: WithSimAXIMem // DOC include start: WithSimAXIMem
class WithSimAXIMem extends OverrideIOBinder({ class WithSimAXIMem extends OverrideIOBinder({
(system: CanHaveMasterAXI4MemPort with BaseSubsystem) => { (system: CanHaveMasterAXI4MemPort, p) => {
val peiTuples = AddIOCells.axi4(system.mem_axi4, system.memAXI4Node) val peiTuples = AddIOCells.axi4(system.mem_axi4, system.memAXI4Node, "mem")
// TODO: we are inlining the connectMem method of SimAXIMem because // TODO: we are inlining the connectMem method of SimAXIMem because
// it takes in a dut rather than seq of axi4 ports // it takes in a dut rather than seq of axi4 ports
val harnessFn = (th: chipyard.TestHarness) => { val harnessFn = (th: chipyard.TestHarness) => {
peiTuples.map { case (port, edge, ios) => peiTuples.map { case (port, edge, ios) =>
val mem = LazyModule(new SimAXIMem(edge, size = system.p(ExtMem).get.master.size)(system.p)) val mem = LazyModule(new SimAXIMem(edge, size = p(ExtMem).get.master.size)(p))
Module(mem.module).suggestName("mem") Module(mem.module).suggestName("mem")
mem.io_axi4.head <> port mem.io_axi4.head <> port
} }
Nil Nil
} }
Seq((peiTuples.map(_._1), peiTuples.flatMap(_._3), Some(harnessFn))) Seq((peiTuples.map(_._1), peiTuples.flatMap(_._3), Some(harnessFn)))
@@ -280,12 +289,12 @@ class WithSimAXIMem extends OverrideIOBinder({
// DOC include end: WithSimAXIMem // DOC include end: WithSimAXIMem
class WithBlackBoxSimMem extends OverrideIOBinder({ class WithBlackBoxSimMem extends OverrideIOBinder({
(system: CanHaveMasterAXI4MemPort with BaseSubsystem) => { (system: CanHaveMasterAXI4MemPort, p) => {
val peiTuples = AddIOCells.axi4(system.mem_axi4, system.memAXI4Node) val peiTuples = AddIOCells.axi4(system.mem_axi4, system.memAXI4Node, "mem")
val harnessFn = (th: chipyard.TestHarness) => { val harnessFn = (th: chipyard.TestHarness) => {
peiTuples.map { case (port, edge, ios) => peiTuples.map { case (port, edge, ios) =>
val memSize = system.p(ExtMem).get.master.size val memSize = p(ExtMem).get.master.size
val lineSize = system.p(CacheBlockBytes) val lineSize = p(CacheBlockBytes)
val mem = Module(new SimDRAM(memSize, lineSize, edge.bundle)) val mem = Module(new SimDRAM(memSize, lineSize, edge.bundle))
mem.io.axi <> port mem.io.axi <> port
mem.io.clock := th.clock mem.io.clock := th.clock
@@ -298,15 +307,26 @@ class WithBlackBoxSimMem extends OverrideIOBinder({
}) })
class WithSimAXIMMIO extends OverrideIOBinder({ class WithSimAXIMMIO extends OverrideIOBinder({
(system: CanHaveMasterAXI4MMIOPort with BaseSubsystem) => SimAXIMem.connectMMIO(system)(system.p); Nil (system: CanHaveMasterAXI4MMIOPort, p) => {
val peiTuples = AddIOCells.axi4(system.mmio_axi4, system.mmioAXI4Node, "mmio_mem")
val harnessFn = (th: chipyard.TestHarness) => {
peiTuples.zipWithIndex.map { case ((port, edge, ios), i) =>
val mmio_mem = LazyModule(new SimAXIMem(edge, size = 4096)(p))
Module(mmio_mem.module).suggestName(s"mmio_mem_${i}")
mmio_mem.io_axi4.head <> port
}
Nil
}
Seq((peiTuples.map(_._1), peiTuples.flatMap(_._3), Some(harnessFn)))
}
}) })
class WithDontTouchPorts extends OverrideIOBinder({ class WithDontTouchPorts extends OverrideIOBinder({
(system: DontTouch) => system.dontTouchPorts(); Nil (system: DontTouch, p) => system.dontTouchPorts(); Nil
}) })
class WithTieOffInterrupts extends OverrideIOBinder({ class WithTieOffInterrupts extends OverrideIOBinder({
(system: HasExtInterruptsModuleImp) => { (system: HasExtInterruptsModuleImp, p) => {
val (port, ioCells) = IOCell.generateIOFromSignal(system.interrupts, Some("iocell_interrupts")) val (port, ioCells) = IOCell.generateIOFromSignal(system.interrupts, Some("iocell_interrupts"))
port.suggestName("interrupts") port.suggestName("interrupts")
val harnessFn = (th: chipyard.TestHarness) => { port := 0.U; Nil } val harnessFn = (th: chipyard.TestHarness) => { port := 0.U; Nil }
@@ -315,26 +335,21 @@ class WithTieOffInterrupts extends OverrideIOBinder({
}) })
class WithTieOffL2FBusAXI extends OverrideIOBinder({ class WithTieOffL2FBusAXI extends OverrideIOBinder({
(system: CanHaveSlaveAXI4Port with BaseSubsystem) => { (system: CanHaveSlaveAXI4Port, p) => {
system.l2_frontend_bus_axi4.foreach(axi => { val peiTuples = AddIOCells.axi4(system.l2_frontend_bus_axi4, system.l2FrontendAXI4Node, "l2_fbus")
axi.tieoff() val harnessFn = (th: chipyard.TestHarness) => {
experimental.DataMirror.directionOf(axi.ar.ready) match { peiTuples.zipWithIndex.map { case ((port, edge, ios), i) =>
case ActualDirection.Input => port := DontCare // tieoff doesn't completely tie-off, for some reason
axi.r.bits := DontCare port.tieoff()
axi.b.bits := DontCare
case ActualDirection.Output =>
axi.aw.bits := DontCare
axi.ar.bits := DontCare
axi.w.bits := DontCare
case _ => throw new Exception("Unknown AXI port direction")
} }
}) Nil
Nil }
Seq((peiTuples.map(_._1), peiTuples.flatMap(_._3), Some(harnessFn)))
} }
}) })
class WithTiedOffDebug extends OverrideIOBinder({ class WithTiedOffDebug extends OverrideIOBinder({
(system: HasPeripheryDebugModuleImp) => { (system: HasPeripheryDebugModuleImp, p) => {
val (psdPort, resetctrlOpt, debugPortOpt, ioCells) = val (psdPort, resetctrlOpt, debugPortOpt, ioCells) =
AddIOCells.debug(system.psd, system.resetctrl, system.debug)(system.p) AddIOCells.debug(system.psd, system.resetctrl, system.debug)(system.p)
val harnessFn = (th: chipyard.TestHarness) => { val harnessFn = (th: chipyard.TestHarness) => {
@@ -352,7 +367,7 @@ class WithTiedOffDebug extends OverrideIOBinder({
}) })
class WithSimDebug extends OverrideIOBinder({ class WithSimDebug extends OverrideIOBinder({
(system: HasPeripheryDebugModuleImp) => { (system: HasPeripheryDebugModuleImp, p) => {
val (psdPort, resetctrlPortOpt, debugPortOpt, ioCells) = val (psdPort, resetctrlPortOpt, debugPortOpt, ioCells) =
AddIOCells.debug(system.psd, system.resetctrl, system.debug)(system.p) AddIOCells.debug(system.psd, system.resetctrl, system.debug)(system.p)
val harnessFn = (th: chipyard.TestHarness) => { val harnessFn = (th: chipyard.TestHarness) => {
@@ -367,7 +382,7 @@ class WithSimDebug extends OverrideIOBinder({
}) })
class WithTiedOffSerial extends OverrideIOBinder({ class WithTiedOffSerial extends OverrideIOBinder({
(system: CanHavePeripherySerialModuleImp) => system.serial.map({ serial => (system: CanHavePeripherySerialModuleImp, p) => system.serial.map({ serial =>
val (port, ioCells) = AddIOCells.serial(serial) val (port, ioCells) = AddIOCells.serial(serial)
val harnessFn = (th: chipyard.TestHarness) => { val harnessFn = (th: chipyard.TestHarness) => {
SerialAdapter.tieoff(port) SerialAdapter.tieoff(port)
@@ -378,7 +393,7 @@ class WithTiedOffSerial extends OverrideIOBinder({
}) })
class WithSimSerial extends OverrideIOBinder({ class WithSimSerial extends OverrideIOBinder({
(system: CanHavePeripherySerialModuleImp) => system.serial.map({ serial => (system: CanHavePeripherySerialModuleImp, p) => system.serial.map({ serial =>
val (port, ioCells) = AddIOCells.serial(serial) val (port, ioCells) = AddIOCells.serial(serial)
val harnessFn = (th: chipyard.TestHarness) => { val harnessFn = (th: chipyard.TestHarness) => {
val ser_success = SerialAdapter.connectSimSerial(port, th.clock, th.harnessReset) val ser_success = SerialAdapter.connectSimSerial(port, th.clock, th.harnessReset)
@@ -390,7 +405,7 @@ class WithSimSerial extends OverrideIOBinder({
}) })
class WithTraceGenSuccessBinder extends OverrideIOBinder({ class WithTraceGenSuccessBinder extends OverrideIOBinder({
(system: TraceGenSystemModuleImp) => { (system: TraceGenSystemModuleImp, p) => {
val (successPort, ioCells) = IOCell.generateIOFromSignal(system.success, Some("iocell_success")) val (successPort, ioCells) = IOCell.generateIOFromSignal(system.success, Some("iocell_success"))
successPort.suggestName("success") successPort.suggestName("success")
val harnessFn = (th: chipyard.TestHarness) => { when (successPort) { th.success := true.B }; Nil } val harnessFn = (th: chipyard.TestHarness) => { when (successPort) { th.success := true.B }; Nil }
@@ -399,7 +414,7 @@ class WithTraceGenSuccessBinder extends OverrideIOBinder({
}) })
class WithSimDromajoBridge extends ComposeIOBinder({ class WithSimDromajoBridge extends ComposeIOBinder({
(system: CanHaveTraceIOModuleImp) => { (system: CanHaveTraceIOModuleImp, p) => {
system.traceIO match { case Some(t) => t.traces.map(tileTrace => SimDromajoBridge(tileTrace)(system.p)) } system.traceIO match { case Some(t) => t.traces.map(tileTrace => SimDromajoBridge(tileTrace)(system.p)) }
Nil Nil
} }

View File

@@ -542,3 +542,21 @@ class LargeNVDLARocketConfig extends Config(
new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ new freechips.rocketchip.subsystem.WithCoherentBusTopology ++
new freechips.rocketchip.system.BaseConfig) new freechips.rocketchip.system.BaseConfig)
class MMIORocketConfig extends Config(
new chipyard.iobinders.WithUARTAdapter ++
new chipyard.iobinders.WithTieOffInterrupts ++
new chipyard.iobinders.WithBlackBoxSimMem ++
new chipyard.iobinders.WithTiedOffDebug ++
new chipyard.iobinders.WithSimSerial ++
new chipyard.iobinders.WithTieOffL2FBusAXI ++ // Tie-off the incoming MMIO port
new chipyard.iobinders.WithSimAXIMMIO ++ // Attach a simulated memory to the outwards MMIO port
new testchipip.WithTSI ++
new chipyard.config.WithBootROM ++
new chipyard.config.WithUART ++
new chipyard.config.WithL2TLBs(1024) ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++
new freechips.rocketchip.system.BaseConfig)

View File

@@ -35,29 +35,28 @@ object MainMemoryConsts {
} }
class WithSerialBridge extends OverrideIOBinder({ class WithSerialBridge extends OverrideIOBinder({
(system: CanHavePeripherySerialModuleImp) => (system: CanHavePeripherySerialModuleImp, p) =>
system.serial.foreach(s => SerialBridge(system.clock, s, MainMemoryConsts.globalName)(system.p)); Nil system.serial.foreach(s => SerialBridge(system.clock, s, MainMemoryConsts.globalName)(p)); Nil
}) })
class WithNICBridge extends OverrideIOBinder({ class WithNICBridge extends OverrideIOBinder({
(system: CanHavePeripheryIceNICModuleImp) => (system: CanHavePeripheryIceNICModuleImp, p) =>
system.net.foreach(n => NICBridge(system.clock, n)(system.p)); Nil system.net.foreach(n => NICBridge(system.clock, n)(p)); Nil
}) })
class WithUARTBridge extends OverrideIOBinder({ class WithUARTBridge extends OverrideIOBinder({
(system: HasPeripheryUARTModuleImp) => (system: HasPeripheryUARTModuleImp, p) =>
system.uart.foreach(u => UARTBridge(system.clock, u)(system.p)); Nil system.uart.foreach(u => UARTBridge(system.clock, u)(p)); Nil
}) })
class WithBlockDeviceBridge extends OverrideIOBinder({ class WithBlockDeviceBridge extends OverrideIOBinder({
(system: CanHavePeripheryBlockDeviceModuleImp) => (system: CanHavePeripheryBlockDeviceModuleImp, p) =>
system.bdev.foreach(b => BlockDevBridge(system.clock, b, system.reset.toBool)(system.p)); Nil system.bdev.foreach(b => BlockDevBridge(system.clock, b, system.reset.toBool)(p)); Nil
}) })
class WithFASEDBridge extends OverrideIOBinder({ class WithFASEDBridge extends OverrideIOBinder({
(system: CanHaveMasterAXI4MemPort with BaseSubsystem) => { (system: CanHaveMasterAXI4MemPort, p) => {
implicit val p = system.p
(system.mem_axi4 zip system.memAXI4Node.in).foreach({ case (axi4, (_, edge)) => (system.mem_axi4 zip system.memAXI4Node.in).foreach({ case (axi4, (_, edge)) =>
val nastiKey = NastiParameters(axi4.r.bits.data.getWidth, val nastiKey = NastiParameters(axi4.r.bits.data.getWidth,
axi4.ar.bits.addr.getWidth, axi4.ar.bits.addr.getWidth,
@@ -73,26 +72,26 @@ class WithFASEDBridge extends OverrideIOBinder({
}) })
class WithTracerVBridge extends ComposeIOBinder({ class WithTracerVBridge extends ComposeIOBinder({
(system: CanHaveTraceIOModuleImp) => (system: CanHaveTraceIOModuleImp, p) =>
system.traceIO.foreach(_.traces.map(tileTrace => TracerVBridge(tileTrace)(system.p))); Nil system.traceIO.foreach(_.traces.map(tileTrace => TracerVBridge(tileTrace)(p))); Nil
}) })
class WithDromajoBridge extends ComposeIOBinder({ class WithDromajoBridge extends ComposeIOBinder({
(system: CanHaveTraceIOModuleImp) => { (system: CanHaveTraceIOModuleImp, p) => {
system.traceIO.foreach(_.traces.map(tileTrace => DromajoBridge(tileTrace)(system.p))); Nil system.traceIO.foreach(_.traces.map(tileTrace => DromajoBridge(tileTrace)(p))); Nil
} }
}) })
class WithTraceGenBridge extends OverrideIOBinder({ class WithTraceGenBridge extends OverrideIOBinder({
(system: TraceGenSystemModuleImp) => (system: TraceGenSystemModuleImp, p) =>
GroundTestBridge(system.clock, system.success)(system.p); Nil GroundTestBridge(system.clock, system.success)(system.p); Nil
}) })
class WithFireSimMultiCycleRegfile extends ComposeIOBinder({ class WithFireSimMultiCycleRegfile extends ComposeIOBinder({
(system: HasTilesModuleImp) => { (system: HasTilesModuleImp, p) => {
system.outer.tiles.map { system.outer.tiles.map {
case r: RocketTile => { case r: RocketTile => {
annotate(MemModelAnnotation(r.module.core.rocketImpl.rf.rf)) annotate(MemModelAnnotation(r.module.core.rocketImpl.rf.rf))
@@ -116,13 +115,13 @@ class WithFireSimMultiCycleRegfile extends ComposeIOBinder({
}) })
class WithTiedOffSystemGPIO extends OverrideIOBinder({ class WithTiedOffSystemGPIO extends OverrideIOBinder({
(system: HasPeripheryGPIOModuleImp) => (system: HasPeripheryGPIOModuleImp, p) =>
system.gpio.foreach(_.pins.foreach(_.i.ival := false.B)); Nil system.gpio.foreach(_.pins.foreach(_.i.ival := false.B)); Nil
}) })
class WithTiedOffSystemDebug extends OverrideIOBinder({ class WithTiedOffSystemDebug extends OverrideIOBinder({
(system: HasPeripheryDebugModuleImp) => { (system: HasPeripheryDebugModuleImp, p) => {
Debug.tieoffDebug(system.debug, system.resetctrl, Some(system.psd))(system.p) Debug.tieoffDebug(system.debug, system.resetctrl, Some(system.psd))(p)
// tieoffDebug doesn't actually tie everything off :/ // tieoffDebug doesn't actually tie everything off :/
system.debug.foreach { d => system.debug.foreach { d =>
d.clockeddmi.foreach({ cdmi => cdmi.dmi.req.bits := DontCare }) d.clockeddmi.foreach({ cdmi => cdmi.dmi.req.bits := DontCare })
@@ -133,7 +132,7 @@ class WithTiedOffSystemDebug extends OverrideIOBinder({
}) })
class WithTiedOffSystemInterrupts extends OverrideIOBinder({ class WithTiedOffSystemInterrupts extends OverrideIOBinder({
(system: HasExtInterruptsModuleImp) => (system: HasExtInterruptsModuleImp, p) =>
system.interrupts := 0.U; Nil system.interrupts := 0.U; Nil
}) })