[firechip] Support registration of custom endpoint binders
This commit is contained in:
@@ -1,84 +0,0 @@
|
||||
//See LICENSE for license details.
|
||||
|
||||
package firesim.firesim
|
||||
|
||||
import chisel3._
|
||||
import chisel3.experimental.RawModule
|
||||
|
||||
import freechips.rocketchip.config.{Field, Parameters}
|
||||
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
|
||||
|
||||
// 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 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 DefaultFireSimHarness[T <: LazyModule](dutGen: () => T)(implicit val p: Parameters) extends RawModule {
|
||||
val clock = IO(Input(Clock()))
|
||||
val reset = WireInit(false.B)
|
||||
withClockAndReset(clock, reset) {
|
||||
// Instantiate multiple instances of the DUT to implement supernode
|
||||
val targets = Seq.fill(p(NumNodes))(Module(LazyModule(dutGen()).module))
|
||||
val peekPokeEndpoint = PeekPokeEndpoint(reset)
|
||||
// A Seq of partial functions that will instantiate the right endpoint only
|
||||
// if that Mixin trait is present in the target's class instance
|
||||
//
|
||||
// TODO: If we like this PF approach, register them in the config instead of centralizing them here
|
||||
val endpointBinders = Seq[PartialFunction[Any, Seq[IsEndpoint]]](
|
||||
{ case t: HasPeripheryDebugModuleImp =>
|
||||
t.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()
|
||||
},
|
||||
{ case t: HasPeripherySerialModuleImp => Seq(SerialEndpoint(t.serial)) },
|
||||
{ case t: HasPeripheryIceNICModuleImpValidOnly => Seq(NICEndpoint(t.net)) },
|
||||
{ case t: HasPeripheryUARTModuleImp => t.uart.map(u => UARTEndpoint(u)) },
|
||||
{ case t: HasPeripheryBlockDeviceModuleImp => Seq(BlockDevEndpoint(t.bdev, reset)) },
|
||||
{ case t: CanHaveMasterAXI4MemPortModuleImp =>
|
||||
(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, reset, p(MemModelKey)(fasedP))(fasedP)
|
||||
})
|
||||
}).toSeq
|
||||
},
|
||||
{ case t: HasTraceIOImp => TracerVEndpoint(t.traceIO) }
|
||||
)
|
||||
// Apply each partial function to each DUT instance
|
||||
for ((target) <- targets) {
|
||||
endpointBinders.map(_.lift).flatMap(elaborator => elaborator(target))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,8 @@
|
||||
package firesim.firesim
|
||||
|
||||
import chisel3._
|
||||
import chisel3.experimental.RawModule
|
||||
|
||||
import freechips.rocketchip.config.{Field, Parameters, Config}
|
||||
import freechips.rocketchip.config.{Field, Config}
|
||||
import freechips.rocketchip.diplomacy.{LazyModule}
|
||||
import freechips.rocketchip.devices.debug.HasPeripheryDebugModuleImp
|
||||
import freechips.rocketchip.subsystem.{CanHaveMasterAXI4MemPortModuleImp}
|
||||
@@ -15,23 +14,12 @@ import testchipip.{HasPeripherySerialModuleImp, HasPeripheryBlockDeviceModuleImp
|
||||
import icenet.HasPeripheryIceNICModuleImpValidOnly
|
||||
|
||||
import junctions.{NastiKey, NastiParameters}
|
||||
import midas.widgets.{IsEndpoint, PeekPokeEndpoint}
|
||||
import midas.widgets.{IsEndpoint}
|
||||
import midas.models.{FASEDEndpoint, FasedAXI4Edge}
|
||||
import firesim.endpoints._
|
||||
import firesim.configs.MemModelKey
|
||||
import firesim.util.RegisterEndpointBinder
|
||||
|
||||
|
||||
// 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
|
||||
|
||||
@@ -19,6 +19,7 @@ import tracegen.TraceGenKey
|
||||
import icenet._
|
||||
|
||||
import firesim.endpoints._
|
||||
import firesim.util.{WithNumNodes}
|
||||
import firesim.configs.WithDefaultMemModel
|
||||
|
||||
class WithBootROM extends Config((site, here, up) => {
|
||||
@@ -174,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) ++
|
||||
|
||||
@@ -14,6 +14,7 @@ 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}
|
||||
|
||||
Submodule sims/firesim updated: 9eaa0dc850...bb38ab9023
Reference in New Issue
Block a user