From f44f3aacbf522776f417cc0dda74acf935871f94 Mon Sep 17 00:00:00 2001 From: David Biancolin Date: Tue, 24 Sep 2019 03:04:27 +0000 Subject: [PATCH] [FireChip] Allow users to register new EndpointBinders in P --- .../scala/DefaultFireSimEnvironment.scala | 16 ++-- .../src/main/scala/EndpointBinders.scala | 92 +++++++++++++++++++ .../src/main/scala/TargetConfigs.scala | 2 + .../firechip/src/main/scala/Targets.scala | 12 +-- 4 files changed, 110 insertions(+), 12 deletions(-) create mode 100644 generators/firechip/src/main/scala/EndpointBinders.scala diff --git a/generators/firechip/src/main/scala/DefaultFireSimEnvironment.scala b/generators/firechip/src/main/scala/DefaultFireSimEnvironment.scala index 80750f52..6bb53ed6 100644 --- a/generators/firechip/src/main/scala/DefaultFireSimEnvironment.scala +++ b/generators/firechip/src/main/scala/DefaultFireSimEnvironment.scala @@ -1,3 +1,5 @@ +//See LICENSE for license details. + package firesim.firesim import chisel3._ @@ -18,19 +20,21 @@ import midas.models.{FASEDEndpoint, FasedAXI4Edge} import firesim.endpoints._ import firesim.configs.MemModelKey -// Creates a wrapper module that instantiates endpoints based on the scala type -// of the Target (_not_ its IO). This avoids needing to duplicate environments -// (essentially test harnesses) for each target type, +// Creates a wrapper FireSim harness module that instantiates endpoints based +// on the scala type of the Target (_not_ its IO). This avoids needing to +// duplicate harnesses (essentially test harnesses) for each target. // -// You could just as well create a custom environment (essentially, test -// harness) module that instantiates endpoints explicitly, or add methods to +// You could just as well create a custom harness module that instantiates +// endpoints explicitly, or add methods to // your target traits that instantiate the endpoint there (i.e., akin to // SimAXI4Mem). Since cake traits live in Rocket Chip it was easiest to match // on the types rather than change trait code. +// Determines the number of times to instantiate the DUT in the harness. +// Subsumes legacy supernode support case object NumNodes extends Field[Int](1) -class DefaultFireSimEnvironment[T <: LazyModule](dutGen: () => T)(implicit val p: Parameters) extends RawModule { +class DefaultFireSimHarness[T <: LazyModule](dutGen: () => T)(implicit val p: Parameters) extends RawModule { val clock = IO(Input(Clock())) val reset = WireInit(false.B) withClockAndReset(clock, reset) { diff --git a/generators/firechip/src/main/scala/EndpointBinders.scala b/generators/firechip/src/main/scala/EndpointBinders.scala new file mode 100644 index 00000000..631ad6d9 --- /dev/null +++ b/generators/firechip/src/main/scala/EndpointBinders.scala @@ -0,0 +1,92 @@ +//See LICENSE for license details. + +package firesim.firesim + +import chisel3._ +import chisel3.experimental.RawModule + +import freechips.rocketchip.config.{Field, Parameters, 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, PeekPokeEndpoint} +import midas.models.{FASEDEndpoint, FasedAXI4Edge} +import firesim.endpoints._ +import firesim.configs.MemModelKey + + +// A sequence of partial functions that match on the type the DUT (_not_ it's +// IO) to generate an appropriate endpoint. You can add your own endpoint by prepending +// a custom PartialFunction to this Seq +case object EndpointBinders extends Field[Seq[PartialFunction[Any, Seq[IsEndpoint]]]](Seq()) + +// Config sugar that accepts a partial function and prepends it to EndpointBinders +class RegisterEndpointBinder(pf: =>PartialFunction[Any, Seq[IsEndpoint]]) extends Config((site, here, up) => { + case EndpointBinders => pf +: up(EndpointBinders, site) +}) + +// Default FireSim Endpoint binders follow +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/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index 91580a29..9906b24e 100644 --- a/generators/firechip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/src/main/scala/TargetConfigs.scala @@ -107,6 +107,7 @@ class FireSimRocketChipConfig extends Config( new WithPerfCounters ++ new WithoutClockGating ++ new WithDefaultMemModel ++ + new WithDefaultFireSimEndpoints ++ new freechips.rocketchip.system.DefaultConfig) class WithNDuplicatedRocketCores(n: Int) extends Config((site, here, up) => { @@ -149,6 +150,7 @@ class FireSimBoomConfig extends Config( new WithDefaultMemModel ++ new boom.common.WithLargeBooms ++ new boom.common.WithNBoomCores(1) ++ + new WithDefaultFireSimEndpoints ++ new freechips.rocketchip.system.BaseConfig ) diff --git a/generators/firechip/src/main/scala/Targets.scala b/generators/firechip/src/main/scala/Targets.scala index 6eac228d..3db3fecc 100644 --- a/generators/firechip/src/main/scala/Targets.scala +++ b/generators/firechip/src/main/scala/Targets.scala @@ -61,7 +61,7 @@ class FireSimModuleImp[+L <: FireSimDUT](l: L) extends SubsystemModuleImp(l) with HasTraceIOImp with CanHaveMultiCycleRegfileImp -class FireSim(implicit p: Parameters) extends DefaultFireSimEnvironment(() => new FireSimDUT) +class FireSim(implicit p: Parameters) extends DefaultFireSimHarness(() => new FireSimDUT) class FireSimNoNICDUT(implicit p: Parameters) extends Subsystem with HasHierarchicalBusTopology @@ -86,7 +86,7 @@ class FireSimNoNICModuleImp[+L <: FireSimNoNICDUT](l: L) extends SubsystemModule with CanHaveMultiCycleRegfileImp -class FireSimNoNIC(implicit p: Parameters) extends DefaultFireSimEnvironment(() => new FireSimNoNICDUT) +class FireSimNoNIC(implicit p: Parameters) extends DefaultFireSimHarness(() => new FireSimNoNICDUT) class FireBoomDUT(implicit p: Parameters) extends Subsystem with HasHierarchicalBusTopology @@ -113,7 +113,7 @@ class FireBoomModuleImp[+L <: FireBoomDUT](l: L) extends SubsystemModuleImp(l) with ExcludeInvalidBoomAssertions with CanHaveMultiCycleRegfileImp -class FireBoom(implicit p: Parameters) extends DefaultFireSimEnvironment(() => new FireBoomDUT) +class FireBoom(implicit p: Parameters) extends DefaultFireSimHarness(() => new FireBoomDUT) class FireBoomNoNICDUT(implicit p: Parameters) extends Subsystem with HasHierarchicalBusTopology @@ -138,7 +138,7 @@ class FireBoomNoNICModuleImp[+L <: FireBoomNoNICDUT](l: L) extends SubsystemModu with ExcludeInvalidBoomAssertions with CanHaveMultiCycleRegfileImp -class FireBoomNoNIC(implicit p: Parameters) extends DefaultFireSimEnvironment(() => new FireBoomNoNICDUT) +class FireBoomNoNIC(implicit p: Parameters) extends DefaultFireSimHarness(() => new FireBoomNoNICDUT) class FireSimTraceGen(implicit p: Parameters) extends BaseSubsystem with HasHierarchicalBusTopology @@ -151,5 +151,5 @@ class FireSimTraceGenModuleImp(outer: FireSimTraceGen) extends BaseSubsystemModu with HasTraceGenTilesModuleImp with CanHaveMasterAXI4MemPortModuleImp -// Supernoded-ness comes from setting p(NumNodes) (see DefaultFiresimEnvironment) to something > 1 -class FireSimSupernode(implicit p: Parameters) extends DefaultFireSimEnvironment(() => new FireSimDUT) +// Supernoded-ness comes from setting p(NumNodes) (see DefaultFiresimHarness) to something > 1 +class FireSimSupernode(implicit p: Parameters) extends DefaultFireSimHarness(() => new FireSimDUT)