diff --git a/generators/firechip/src/main/scala/EndpointBinders.scala b/generators/firechip/src/main/scala/EndpointBinders.scala new file mode 100644 index 00000000..0450f8f3 --- /dev/null +++ b/generators/firechip/src/main/scala/EndpointBinders.scala @@ -0,0 +1,80 @@ +//See LICENSE for license details. + +package firesim.firesim + +import chisel3._ + +import freechips.rocketchip.config.{Field, Config} +import freechips.rocketchip.diplomacy.{LazyModule} +import freechips.rocketchip.devices.debug.HasPeripheryDebugModuleImp +import freechips.rocketchip.subsystem.{CanHaveMasterAXI4MemPortModuleImp} +import sifive.blocks.devices.uart.HasPeripheryUARTModuleImp + +import testchipip.{HasPeripherySerialModuleImp, HasPeripheryBlockDeviceModuleImp} +import icenet.HasPeripheryIceNICModuleImpValidOnly + +import junctions.{NastiKey, NastiParameters} +import midas.widgets.{IsEndpoint} +import midas.models.{FASEDEndpoint, FasedAXI4Edge} +import firesim.endpoints._ +import firesim.configs.MemModelKey +import firesim.util.RegisterEndpointBinder + +class WithTiedOffDebug extends RegisterEndpointBinder({ case target: HasPeripheryDebugModuleImp => + target.debug.clockeddmi.foreach({ cdmi => + cdmi.dmi.req.valid := false.B + cdmi.dmi.req.bits := DontCare + cdmi.dmi.resp.ready := false.B + cdmi.dmiClock := false.B.asClock + cdmi.dmiReset := false.B + }) + Seq() +}) + +class WithSerialEndpoint extends RegisterEndpointBinder({ + case target: HasPeripherySerialModuleImp => Seq(SerialEndpoint(target.serial)(target.p)) +}) + +class WithNICEndpoint extends RegisterEndpointBinder({ + case target: HasPeripheryIceNICModuleImpValidOnly => Seq(NICEndpoint(target.net)(target.p)) +}) + +class WithUARTEndpoint extends RegisterEndpointBinder({ + case target: HasPeripheryUARTModuleImp => target.uart.map(u => UARTEndpoint(u)(target.p)) +}) + +class WithBlockDeviceEndpoint extends RegisterEndpointBinder({ + case target: HasPeripheryBlockDeviceModuleImp => Seq(BlockDevEndpoint(target.bdev, target.reset.toBool)(target.p)) +}) + +class WithFASEDEndpoint extends RegisterEndpointBinder({ + case t: CanHaveMasterAXI4MemPortModuleImp => + implicit val p = t.p + (t.mem_axi4 zip t.outer.memAXI4Node).flatMap({ case (io, node) => + (io zip node.in).map({ case (axi4Bundle, (_, edge)) => + val nastiKey = NastiParameters(axi4Bundle.r.bits.data.getWidth, + axi4Bundle.ar.bits.addr.getWidth, + axi4Bundle.ar.bits.id.getWidth) + val fasedP = p.alterPartial({ + case NastiKey => nastiKey + case FasedAXI4Edge => Some(edge) + }) + FASEDEndpoint(axi4Bundle, t.reset.toBool, p(MemModelKey)(fasedP))(fasedP) + }) + }).toSeq +}) + +class WithTracerVEndpoint extends RegisterEndpointBinder({ + case target: HasTraceIOImp => TracerVEndpoint(target.traceIO)(target.p) +}) + +// Shorthand to register all of the provided endpoints above +class WithDefaultFireSimEndpoints extends Config( + new WithTiedOffDebug ++ + new WithSerialEndpoint ++ + new WithNICEndpoint ++ + new WithUARTEndpoint ++ + new WithBlockDeviceEndpoint ++ + new WithFASEDEndpoint ++ + new WithTracerVEndpoint +) diff --git a/generators/firechip/src/main/scala/SimConfigs.scala b/generators/firechip/src/main/scala/SimConfigs.scala index 937c2877..06e6aa93 100644 --- a/generators/firechip/src/main/scala/SimConfigs.scala +++ b/generators/firechip/src/main/scala/SimConfigs.scala @@ -3,8 +3,6 @@ package firesim.firesim import freechips.rocketchip.config.{Parameters, Config, Field} -import midas.{EndpointKey} -import midas.widgets.{EndpointMap} import midas.models._ import firesim.endpoints._ @@ -19,40 +17,26 @@ import firesim.configs._ * reconstruct what is in a particular AGFI. These tags are also used to * determine which driver to build. *******************************************************************************/ -class FireSimConfig extends Config( - new WithSerialWidget ++ - new WithUARTWidget ++ - new WithSimpleNICWidget ++ - new WithBlockDevWidget ++ - new WithDefaultMemModel ++ - new WithTracerVWidget ++ - new BasePlatformConfig) +class FireSimConfig extends Config(new BasePlatformConfig) class FireSimClockDivConfig extends Config( - new WithDefaultMemModel(clockDivision = 2) ++ new FireSimConfig) class FireSimDDR3Config extends Config( - new FCFS16GBQuadRank ++ new FireSimConfig) class FireSimDDR3LLC4MBConfig extends Config( - new FCFS16GBQuadRankLLC4MB ++ new FireSimConfig) class FireSimDDR3FRFCFSConfig extends Config( - new FRFCFS16GBQuadRank ++ new FireSimConfig) class FireSimDDR3FRFCFSLLC4MBConfig extends Config( - new FRFCFS16GBQuadRankLLC4MB ++ new FireSimConfig) class FireSimDDR3FRFCFSLLC4MB3ClockDivConfig extends Config( - new FRFCFS16GBQuadRankLLC4MB3Div ++ new FireSimConfig) class Midas2Config extends Config( new WithMultiCycleRamModels ++ new FireSimConfig) - diff --git a/generators/firechip/src/main/scala/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index ddfb2548..0e31bb56 100644 --- a/generators/firechip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/src/main/scala/TargetConfigs.scala @@ -12,12 +12,16 @@ import freechips.rocketchip.subsystem._ import freechips.rocketchip.devices.tilelink.BootROMParams import freechips.rocketchip.devices.debug.DebugModuleParams import boom.common.BoomTilesKey -import testchipip.{WithBlockDevice, BlockDeviceKey, BlockDeviceConfig} +import testchipip.{BlockDeviceKey, BlockDeviceConfig} import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTParams} import scala.math.{min, max} import tracegen.TraceGenKey import icenet._ +import firesim.endpoints._ +import firesim.util.{WithNumNodes} +import firesim.configs.WithDefaultMemModel + class WithBootROM extends Config((site, here, up) => { case BootROMParams => { val chipyardBootROM = new File(s"./generators/testchipip/bootrom/bootrom.rv${site(XLen)}.img") @@ -37,12 +41,14 @@ class WithPeripheryBusFrequency(freq: BigInt) extends Config((site, here, up) => }) class WithUARTKey extends Config((site, here, up) => { - case PeripheryUARTKey => List(UARTParams( + case PeripheryUARTKey => List(UARTParams( address = BigInt(0x54000000L), nTxEntries = 256, nRxEntries = 256)) }) +class WithBlockDevice extends Config(new testchipip.WithBlockDevice) + class WithNICKey extends Config((site, here, up) => { case NICKey => NICConfig( inBufFlits = 8192, @@ -101,6 +107,8 @@ class FireSimRocketChipConfig extends Config( new WithRocketL2TLBs(1024) ++ new WithPerfCounters ++ new WithoutClockGating ++ + new WithDefaultMemModel ++ + new WithDefaultFireSimEndpoints ++ new freechips.rocketchip.system.DefaultConfig) class WithNDuplicatedRocketCores(n: Int) extends Config((site, here, up) => { @@ -140,8 +148,10 @@ class FireSimBoomConfig extends Config( new WithBlockDevice ++ new WithBoomL2TLBs(1024) ++ new WithoutClockGating ++ + new WithDefaultMemModel ++ new boom.common.WithLargeBooms ++ new boom.common.WithNBoomCores(1) ++ + new WithDefaultFireSimEndpoints ++ new freechips.rocketchip.system.BaseConfig ) @@ -165,9 +175,6 @@ class FireSimBoomQuadCoreConfig extends Config( //********************************************************************************** //* Supernode Configurations //*********************************************************************************/ -class WithNumNodes(n: Int) extends Config((pname, site, here) => { - case NumNodes => n -}) class SupernodeFireSimRocketChipConfig extends Config( new WithNumNodes(4) ++ diff --git a/generators/firechip/src/main/scala/TargetMixins.scala b/generators/firechip/src/main/scala/TargetMixins.scala index f36cf021..0c7d2eb9 100644 --- a/generators/firechip/src/main/scala/TargetMixins.scala +++ b/generators/firechip/src/main/scala/TargetMixins.scala @@ -1,6 +1,7 @@ package firesim.firesim import chisel3._ +import chisel3.util.Cat import chisel3.experimental.annotate import freechips.rocketchip.config.{Field, Parameters} import freechips.rocketchip.diplomacy._ @@ -12,62 +13,8 @@ import freechips.rocketchip.subsystem._ import freechips.rocketchip.rocket.TracedInstruction import firesim.endpoints.{TraceOutputTop, DeclockedTracedInstruction} -import midas.models.AXI4BundleWithEdge import midas.targetutils.{ExcludeInstanceAsserts, MemModelAnnotation} -/** Copied from RC and modified to change the IO type of the Imp to include the Diplomatic edges - * associated with each port. This drives FASED functional model sizing - */ -trait CanHaveFASEDOptimizedMasterAXI4MemPort { this: BaseSubsystem => - val module: CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp - - val memAXI4Node = p(ExtMem).map { case MemoryPortParams(memPortParams, nMemoryChannels) => - val portName = "axi4" - val device = new MemoryDevice - - val memAXI4Node = AXI4SlaveNode(Seq.tabulate(nMemoryChannels) { channel => - val base = AddressSet.misaligned(memPortParams.base, memPortParams.size) - val filter = AddressSet(channel * mbus.blockBytes, ~((nMemoryChannels-1) * mbus.blockBytes)) - - AXI4SlavePortParameters( - slaves = Seq(AXI4SlaveParameters( - address = base.flatMap(_.intersect(filter)), - resources = device.reg, - regionType = RegionType.UNCACHED, // cacheable - executable = true, - supportsWrite = TransferSizes(1, mbus.blockBytes), - supportsRead = TransferSizes(1, mbus.blockBytes), - interleavedId = Some(0))), // slave does not interleave read responses - beatBytes = memPortParams.beatBytes) - }) - - memAXI4Node := mbus.toDRAMController(Some(portName)) { - AXI4UserYanker() := AXI4IdIndexer(memPortParams.idBits) := TLToAXI4() - } - - memAXI4Node - } -} - -/** Actually generates the corresponding IO in the concrete Module */ -trait CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp extends LazyModuleImp { - val outer: CanHaveFASEDOptimizedMasterAXI4MemPort - - val mem_axi4 = outer.memAXI4Node.map(x => IO(HeterogeneousBag(AXI4BundleWithEdge.fromNode(x.in)))) - (mem_axi4 zip outer.memAXI4Node) foreach { case (io, node) => - (io zip node.in).foreach { case (io, (bundle, _)) => io <> bundle } - } - - def connectSimAXIMem() { - (mem_axi4 zip outer.memAXI4Node).foreach { case (io, node) => - (io zip node.in).foreach { case (io, (_, edge)) => - val mem = LazyModule(new SimAXIMem(edge, size = p(ExtMem).get.master.size)) - Module(mem.module).io.axi4.head <> io - } - } - } -} - /* Wires out tile trace ports to the top; and wraps them in a Bundle that the * TracerV endpoint can match on. */ @@ -95,7 +42,7 @@ trait HasTraceIOImp extends LazyModuleImp { // Enabled to test TracerV trace capture if (p(PrintTracePort)) { val traceprint = Wire(UInt(512.W)) - traceprint := traceIO.asUInt + traceprint := Cat(traceIO.traces.map(_.asUInt)) printf("TRACEPORT: %x\n", traceprint) } } diff --git a/generators/firechip/src/main/scala/Targets.scala b/generators/firechip/src/main/scala/Targets.scala index 37c1f2b1..7ce143dd 100644 --- a/generators/firechip/src/main/scala/Targets.scala +++ b/generators/firechip/src/main/scala/Targets.scala @@ -6,6 +6,7 @@ import freechips.rocketchip.subsystem._ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.devices.tilelink._ +import freechips.rocketchip.devices.debug.HasPeripheryDebugModuleImp import freechips.rocketchip.config.Parameters import freechips.rocketchip.util.{HeterogeneousBag} import freechips.rocketchip.amba.axi4.AXI4Bundle @@ -13,13 +14,19 @@ import freechips.rocketchip.config.{Field, Parameters} import freechips.rocketchip.diplomacy.LazyModule import utilities.{Subsystem, SubsystemModuleImp} import icenet._ +import firesim.util.DefaultFireSimHarness import testchipip._ import testchipip.SerialAdapter.SERIAL_IF_WIDTH import tracegen.{HasTraceGenTiles, HasTraceGenTilesModuleImp} import sifive.blocks.devices.uart._ -import midas.models.AXI4BundleWithEdge import java.io.File + +object FireSimValName { + implicit val valName = ValName("FireSimHarness") +} +import FireSimValName._ + /******************************************************************************* * Top level DESIGN configurations. These describe the basic instantiations of * the designs being simulated. @@ -31,11 +38,10 @@ import java.io.File * determine which driver to build. *******************************************************************************/ -class FireSim(implicit p: Parameters) extends Subsystem +class FireSimDUT(implicit p: Parameters) extends Subsystem with HasHierarchicalBusTopology - with CanHaveFASEDOptimizedMasterAXI4MemPort + with CanHaveMasterAXI4MemPort with HasPeripheryBootROM - with HasNoDebug with HasPeripherySerial with HasPeripheryUART with HasPeripheryIceNIC @@ -45,11 +51,10 @@ class FireSim(implicit p: Parameters) extends Subsystem override lazy val module = new FireSimModuleImp(this) } -class FireSimModuleImp[+L <: FireSim](l: L) extends SubsystemModuleImp(l) +class FireSimModuleImp[+L <: FireSimDUT](l: L) extends SubsystemModuleImp(l) with HasRTCModuleImp - with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp + with CanHaveMasterAXI4MemPortModuleImp with HasPeripheryBootROMModuleImp - with HasNoDebugModuleImp with HasPeripherySerialModuleImp with HasPeripheryUARTModuleImp with HasPeripheryIceNICModuleImpValidOnly @@ -57,12 +62,12 @@ class FireSimModuleImp[+L <: FireSim](l: L) extends SubsystemModuleImp(l) with HasTraceIOImp with CanHaveMultiCycleRegfileImp +class FireSim(implicit p: Parameters) extends DefaultFireSimHarness(() => new FireSimDUT) -class FireSimNoNIC(implicit p: Parameters) extends Subsystem +class FireSimNoNICDUT(implicit p: Parameters) extends Subsystem with HasHierarchicalBusTopology - with CanHaveFASEDOptimizedMasterAXI4MemPort + with CanHaveMasterAXI4MemPort with HasPeripheryBootROM - with HasNoDebug with HasPeripherySerial with HasPeripheryUART with HasPeripheryBlockDevice @@ -71,11 +76,10 @@ class FireSimNoNIC(implicit p: Parameters) extends Subsystem override lazy val module = new FireSimNoNICModuleImp(this) } -class FireSimNoNICModuleImp[+L <: FireSimNoNIC](l: L) extends SubsystemModuleImp(l) +class FireSimNoNICModuleImp[+L <: FireSimNoNICDUT](l: L) extends SubsystemModuleImp(l) with HasRTCModuleImp - with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp + with CanHaveMasterAXI4MemPortModuleImp with HasPeripheryBootROMModuleImp - with HasNoDebugModuleImp with HasPeripherySerialModuleImp with HasPeripheryUARTModuleImp with HasPeripheryBlockDeviceModuleImp @@ -83,11 +87,12 @@ class FireSimNoNICModuleImp[+L <: FireSimNoNIC](l: L) extends SubsystemModuleImp with CanHaveMultiCycleRegfileImp -class FireBoom(implicit p: Parameters) extends Subsystem +class FireSimNoNIC(implicit p: Parameters) extends DefaultFireSimHarness(() => new FireSimNoNICDUT) + +class FireBoomDUT(implicit p: Parameters) extends Subsystem with HasHierarchicalBusTopology - with CanHaveFASEDOptimizedMasterAXI4MemPort + with CanHaveMasterAXI4MemPort with HasPeripheryBootROM - with HasNoDebug with HasPeripherySerial with HasPeripheryUART with HasPeripheryIceNIC @@ -97,11 +102,10 @@ class FireBoom(implicit p: Parameters) extends Subsystem override lazy val module = new FireBoomModuleImp(this) } -class FireBoomModuleImp[+L <: FireBoom](l: L) extends SubsystemModuleImp(l) +class FireBoomModuleImp[+L <: FireBoomDUT](l: L) extends SubsystemModuleImp(l) with HasRTCModuleImp - with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp + with CanHaveMasterAXI4MemPortModuleImp with HasPeripheryBootROMModuleImp - with HasNoDebugModuleImp with HasPeripherySerialModuleImp with HasPeripheryUARTModuleImp with HasPeripheryIceNICModuleImpValidOnly @@ -110,11 +114,12 @@ class FireBoomModuleImp[+L <: FireBoom](l: L) extends SubsystemModuleImp(l) with ExcludeInvalidBoomAssertions with CanHaveMultiCycleRegfileImp -class FireBoomNoNIC(implicit p: Parameters) extends Subsystem +class FireBoom(implicit p: Parameters) extends DefaultFireSimHarness(() => new FireBoomDUT) + +class FireBoomNoNICDUT(implicit p: Parameters) extends Subsystem with HasHierarchicalBusTopology - with CanHaveFASEDOptimizedMasterAXI4MemPort + with CanHaveMasterAXI4MemPort with HasPeripheryBootROM - with HasNoDebug with HasPeripherySerial with HasPeripheryUART with HasPeripheryBlockDevice @@ -123,11 +128,10 @@ class FireBoomNoNIC(implicit p: Parameters) extends Subsystem override lazy val module = new FireBoomNoNICModuleImp(this) } -class FireBoomNoNICModuleImp[+L <: FireBoomNoNIC](l: L) extends SubsystemModuleImp(l) +class FireBoomNoNICModuleImp[+L <: FireBoomNoNICDUT](l: L) extends SubsystemModuleImp(l) with HasRTCModuleImp - with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp + with CanHaveMasterAXI4MemPortModuleImp with HasPeripheryBootROMModuleImp - with HasNoDebugModuleImp with HasPeripherySerialModuleImp with HasPeripheryUARTModuleImp with HasPeripheryBlockDeviceModuleImp @@ -135,58 +139,18 @@ class FireBoomNoNICModuleImp[+L <: FireBoomNoNIC](l: L) extends SubsystemModuleI with ExcludeInvalidBoomAssertions with CanHaveMultiCycleRegfileImp -case object NumNodes extends Field[Int] - -class SupernodeIO( - nNodes: Int, - serialWidth: Int, - bagPrototype: HeterogeneousBag[AXI4BundleWithEdge])(implicit p: Parameters) - extends Bundle { - - val serial = Vec(nNodes, new SerialIO(serialWidth)) - val mem_axi = Vec(nNodes, bagPrototype.cloneType) - val bdev = Vec(nNodes, new BlockDeviceIO) - val net = Vec(nNodes, new NICIOvonly) - val uart = Vec(nNodes, new UARTPortIO) - - override def cloneType = new SupernodeIO(nNodes, serialWidth, bagPrototype).asInstanceOf[this.type] -} - - -class FireSimSupernode(implicit p: Parameters) extends Module { - val nNodes = p(NumNodes) - val nodes = Seq.fill(nNodes) { - Module(LazyModule(new FireSim).module) - } - - val io = IO(new SupernodeIO(nNodes, SERIAL_IF_WIDTH, nodes(0).mem_axi4.get)) - - io.mem_axi.zip(nodes.map(_.mem_axi4)).foreach { - case (out, mem_axi4) => out <> mem_axi4.get - } - io.serial <> nodes.map(_.serial) - io.bdev <> nodes.map(_.bdev) - io.net <> nodes.map(_.net) - io.uart <> nodes.map(_.uart(0)) - nodes.foreach{ case n => { - n.debug.clockeddmi.get.dmi.req.valid := false.B - n.debug.clockeddmi.get.dmi.resp.ready := false.B - n.debug.clockeddmi.get.dmiClock := clock - n.debug.clockeddmi.get.dmiReset := reset.toBool - n.debug.clockeddmi.get.dmi.req.bits.data := DontCare - n.debug.clockeddmi.get.dmi.req.bits.addr := DontCare - n.debug.clockeddmi.get.dmi.req.bits.op := DontCare - } } -} +class FireBoomNoNIC(implicit p: Parameters) extends DefaultFireSimHarness(() => new FireBoomNoNICDUT) class FireSimTraceGen(implicit p: Parameters) extends BaseSubsystem with HasHierarchicalBusTopology with HasTraceGenTiles - with CanHaveFASEDOptimizedMasterAXI4MemPort { + with CanHaveMasterAXI4MemPort { override lazy val module = new FireSimTraceGenModuleImp(this) } -class FireSimTraceGenModuleImp(outer: FireSimTraceGen) - extends BaseSubsystemModuleImp(outer) - with HasTraceGenTilesModuleImp - with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp +class FireSimTraceGenModuleImp(outer: FireSimTraceGen) extends BaseSubsystemModuleImp(outer) + with HasTraceGenTilesModuleImp + with CanHaveMasterAXI4MemPortModuleImp + +// Supernoded-ness comes from setting p(NumNodes) (see DefaultFiresimHarness) to something > 1 +class FireSimSupernode(implicit p: Parameters) extends DefaultFireSimHarness(() => new FireSimDUT) diff --git a/generators/firechip/src/test/scala/ScalaTestSuite.scala b/generators/firechip/src/test/scala/ScalaTestSuite.scala index 44c4bff0..77415636 100644 --- a/generators/firechip/src/test/scala/ScalaTestSuite.scala +++ b/generators/firechip/src/test/scala/ScalaTestSuite.scala @@ -112,7 +112,7 @@ abstract class FireSimTestSuite( val resetLength = 51 val verilatedOutput = getLines(new File(outDir, s"/${verilatedLog}")) val synthPrintOutput = getLines(new File(genDir, s"/TRACEFILE"), resetLength) - assert(verilatedOutput.size == synthPrintOutput.size, "Outputs differ in length") + assert(math.abs(verilatedOutput.size - synthPrintOutput.size) <= 1, "Outputs differ in length") assert(verilatedOutput.nonEmpty) for ( (vPrint, sPrint) <- verilatedOutput.zip(synthPrintOutput) ) { assert(vPrint == sPrint) diff --git a/sims/firesim b/sims/firesim index 92fe0e4d..4769e5d8 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit 92fe0e4def4d9bde0c5c36cd9090ef8c60fd0d45 +Subproject commit 4769e5d86acf6a9508d2b5a63141dc80a6ef20a6