Address generator unification PR reviews

This commit is contained in:
Jerry Zhao
2020-02-23 22:53:14 -08:00
parent 941c217fbe
commit 708a5fb9a6
17 changed files with 153 additions and 246 deletions

1
.gitignore vendored
View File

@@ -1,4 +1,5 @@
bootrom/*
docs/warnings.txt
/Makefrag.pkgs
target
*.jar

View File

@@ -109,7 +109,7 @@ reminder, to run a software RTL simulation, run:
FireSim FPGA-accelerated simulations use TSI by default as well.
If you would like to build and simulate a Chipyard configuration with a DTM configured for DMI communication, then you must tie-off the TSI interface, and instantiate the `SimDTM`. Note that we use `WithTiedOffSerial ++ WithSimDTM` instead of `WithTiedOffDebug ++ WithSimSerial`.
If you would like to build and simulate a Chipyard configuration with a DTM configured for DMI communication, then you must tie-off the TSI interface, and instantiate the `SimDTM`. Note that we use `WithTiedOffSerial ++ WithSimDebug` instead of `WithTiedOffDebug ++ WithSimSerial`.
.. literalinclude:: ../../generators/chipyard/src/main/scala/RocketConfigs.scala
:language: scala

View File

@@ -91,8 +91,8 @@ lazy module implementation performs the actual Chisel RTL elaboration.
In the ``Top`` example class, the "outer" ``Top`` instantiates the "inner"
``TopModule`` as a lazy module implementation. This delays immediate elaboration
of the module until all logical connections are determined and all configuration information is exchanged.
The ``Syatem`` outer base class, as well as the
``CanHavePeripheryX`` outer traits contain code to perform high-level logical
The ``System`` outer base class, as well as the
``CanHavePeriphery<X>`` outer traits contain code to perform high-level logical
connections. For example, the ``CanHavePeripherySerial`` outer trait contains code
to optionally lazily instantiate the ``SerialAdapter``, and connect the ``SerialAdapter``'s
TileLink node to the Front bus.

View File

@@ -0,0 +1,25 @@
IOBinders
=========
In Chipyard we use a special ``Parameters`` key, ``IOBinders`` to determine what modules to bind to the IOs of a ``Top`` in the ``TestHarness``.
.. literalinclude:: ../../generators/chipyard/src/main/scala/IOBinders.scala
:language: scala
:start-after: DOC include start: IOBinders
:end-before: DOC include end: IOBinders
This special key solves the problem of duplicating test-harnesses for each different ``Top`` type.
You could just as well create a custom harness module that attaches IOs explicitly. Instead, the IOBinders key provides a map from Scala traits to attachment behaviors.
For example, the ``WithSimAXIMemTiedOff`` IOBinder specifies that any ``Top`` which matches ``CanHaveMasterAXI4MemPortModuleImp`` will have a ``SimAXIMem`` connected.
.. literalinclude:: ../../generators/chipyard/src/main/scala/IOBinders.scala
:language: scala
:start-after: DOC include start: WithSimAXIMem
:end-before: DOC include end: WithSimAXIMem
These classes are all ``Config`` objects, which can be mixed into the configs to specify IO connection behaviors.
There are two macros for generating these ``Configs``. ``OverrideIOBinder`` overrides any existing behaviors set for a particular IO in the ``Config`` object. This macro is frequently used because typically top-level IOs drive or are driven by only one source, so a composition of ``IOBinders`` does not make sense. The ``ComposeIOBinder`` macro provides the functionality of not overriding existing behaviors.

View File

@@ -9,89 +9,30 @@ The L1 Caches
Each CPU tile has an L1 instruction cache and L1 data cache. The size and
associativity of these caches can be configured. The default ``RocketConfig``
uses 16 KiB, 4-way set-associative instruction and data caches. However,
if you use the ``NMedCores`` or ``NSmallCores`` configurations, you can
if you use the ``WithNMedCores`` or ``WithNSmallCores`` configurations, you can
configure 4 KiB direct-mapped caches for L1I and L1D.
.. code-block:: scala
class SmallRocketConfig extends Config(
new chipyard.iobinders.WithUARTAdapter ++
new chipyard.iobinders.WithTieOffInterrupts ++
new chipyard.iobinders.WithSimAXIMem ++
new chipyard.iobinders.WithTiedOffDebug ++
new chipyard.iobinders.WithSimSerial ++
new testchipip.WithTSI ++
new chipyard.config.WithNoGPIO ++
new chipyard.config.WithBootROM ++
new chipyard.config.WithUART ++
new chipyard.config.WithL2TLBs(1024) ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++
new freechips.rocketchip.subsystem.WithNSmallCores(1) ++ // small rocket cores
new freechips.rocketchip.system.BaseConfig)
class MediumRocketConfig extends Config(
new chipyard.iobinders.WithUARTAdapter ++
new chipyard.iobinders.WithTieOffInterrupts ++
new chipyard.iobinders.WithSimAXIMem ++
new chipyard.iobinders.WithTiedOffDebug ++
new chipyard.iobinders.WithSimSerial ++
new testchipip.WithTSI ++
new chipyard.config.WithNoGPIO ++
new chipyard.config.WithBootROM ++
new chipyard.config.WithUART ++
new chipyard.config.WithL2TLBs(1024) ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++
new freechips.rocketchip.subsystem.WithNMediumCores(1) ++ // Medium rocket cores
new freechips.rocketchip.system.BaseConfig)
If you only want to change the size or associativity, there are configuration
mixins for those too.
mixins for those too. See :ref:`Mixins` for how to add these to a custom ``Config``
.. code-block:: scala
import freechips.rocketchip.subsystem.{WithL1ICacheSets, WithL1DCacheSets, WithL1ICacheWays, WithL1DCacheWays}
class MyL1RocketConfig extends Config(
new freechips.rocketchip.subsystem.WithL1ICacheSets(128) ++ // change rocket I$
new freechips.rocketchip.subsystem.WithL1ICacheWays(2) ++ // change rocket I$
new freechips.rocketchip.subsystem.WithL1DCacheSets(128) ++ // change rocket D$
new freechips.rocketchip.subsystem.WithL1DCacheWays(2) ++ // change rocket D$
new RocketConfig)
You can also configure the L1 data cache as an data scratchpad instead.
However, there are some limitations on this. If you are using a data scratchpad,
you can only use a single core and you cannot give the design an external DRAM.
Note that these configurations fully remove the L2 cache and mbus.
.. code-block:: scala
class ScratchpadSmallRocketConfig extends Config(
new chipyard.iobinders.WithUARTAdapter ++
new chipyard.iobinders.WithTieOffInterrupts ++
new chipyard.iobinders.WithSimAXIMem ++
new chipyard.iobinders.WithTiedOffDebug ++
new chipyard.iobinders.WithSimSerial ++
new testchipip.WithTSI ++
new chipyard.config.WithNoGPIO ++
new chipyard.config.WithBootROM ++
new chipyard.config.WithUART ++
new chipyard.config.WithL2TLBs(1024) ++
new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++
new freechips.rocketchip.subsystem.WithNBanks(0) ++
new freechips.rocketchip.subsystem.WithScratchpadsOnly ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++
new freechips.rocketchip.subsystem.WithNSmallCores(1) ++
new freechips.rocketchip.system.BaseConfig)
.. literalinclude:: ../../generators/chipyard/src/main/scala/RocketConfigs.scala
:language: scala
:start-after: DOC include start: scratchpadrocket
:end-before: DOC include end: scratchpadrocket
This configuration fully removes the L2 cache and memory bus by setting the
@@ -121,27 +62,8 @@ To make such a configuration, you can just copy the definition of
list of included mixims.
If you want to reduce the resources used even further, you can configure
the Broadcast Hub to use a bufferless design.
.. code-block:: scala
class NoL2SmallRocketConfig extends Config(
new chipyard.iobinders.WithUARTAdapter ++
new chipyard.iobinders.WithTieOffInterrupts ++
new chipyard.iobinders.WithSimAXIMem ++
new chipyard.iobinders.WithTiedOffDebug ++
new chipyard.iobinders.WithSimSerial ++
new testchipip.WithTSI ++
new chipyard.config.WithNoGPIO ++
new chipyard.config.WithBootROM ++
new chipyard.config.WithUART ++
new chipyard.config.WithL2TLBs(1024) ++
new freechips.rocketchip.subsystem.WithBufferlessBroadcastHub ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++
new freechips.rocketchip.subsystem.WithNSmallCores(1) ++
new freechips.rocketchip.system.BaseConfig)
the Broadcast Hub to use a bufferless design. This mixin is
``freechips.rocketchip.subsystem.WithBufferlessBroadcastHub``.
The Outer Memory System
@@ -156,11 +78,7 @@ number of DRAM channels is restricted to powers of two.
.. code-block:: scala
import freechips.rocketchip.subsystem.WithNMemoryChannels
class DualChannelRocketConfig extends Config(
new freechips.rocketchip.subsystem.WithNMemoryChannels(2) ++
new RocketConfig)
new freechips.rocketchip.subsystem.WithNMemoryChannels(2)
In VCS and Verilator simulation, the DRAM is simulated using the

View File

@@ -42,3 +42,4 @@ We recommend reading all these pages in order. Hit next to get started!
Memory-Hierarchy
Boot-Process
Firrtl-Transforms
IOBinders

View File

@@ -2,7 +2,7 @@
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXOPTS = -w warnings.txt
SPHINXBUILD = python -msphinx
SPHINXPROJ = Chipyard
SOURCEDIR = .

View File

@@ -44,47 +44,19 @@ familiar with FireSim, please return to the `FireSim Docs
<https://docs.fires.im/en/latest/Initial-Setup/Setting-up-your-Manager-Instance.html#completing-setup-using-the-manager>`__,
and proceed with the rest of the tutorial.
Current Limitations:
++++++++++++++++++++
FireSim integration in Chipyard is still a work in progress. Presently, you
cannot build a FireSim simulator from any generator project in Chipyard except ``firechip``,
which properly invokes MIDAS on the target RTL.
In the interim, workaround this limitation by importing Config and Module
classes from other generator projects into FireChip. For example, assuming you Chipyard
config looks as following:
.. code-block:: scala
class CustomConfig extends Config(
new WithInclusiveCache ++
new myproject.MyCustomConfig ++
new DefaultRocketConfig
)
Then the equivalent FireChip config (in ``generators/firechip/src/main/scala/TargetConfigs.scala``) based on ``FireSimRocketChipConfig``
will look as follows:
.. code-block:: scala
class FireSimCustomConfig extends Config(
new WithBootROM ++
new WithPeripheryBusFrequency(BigInt(3200000000L)) ++
new WithExtMemSize(0x400000000L) ++ // 16GB
new WithoutTLMonitors ++
new WithUARTKey ++
new WithNICKey ++
new WithBlockDevice ++
new WithRocketL2TLBs(1024) ++
new WithPerfCounters ++
new WithoutClockGating ++
new WithInclusiveCache ++
new myproject.MyCustomConfig ++
new freechips.rocketchip.system.DefaultConfig)
Running your Design in FireSim
------------------------------
Converting a Chipyard config (one in ``chipyard/src/main/scala`` to run in FireSim is simple. We are using the same target (top) RTL, and only need to specify a new set of connection behaviors for the IOs of that module. Simply create a matching config within ``generators/firechip/src/main/scala/TargetConfigs`` that inherits your config defined in ``chipyard``.
You should then be able to refer to those classes or an alias of them in your ``DESIGN`` or ``TARGET_CONFIG``
variables. Note that if your target machine has I/O not provided in the default
FireChip targets (see ``generators/firechip/src/main/scala/Targets.scala``) you may need
to write a custom bridge.
.. literalinclude:: ../../generators/firechip/src/main/scala/TargetConfigs.scala
:language: scala
:start-after: DOC include start: firesimconfig
:end-before: DOC include end: firesimconfig
Only 3 additional config-mixins are needed.
* ``WithFireSimConfigTweaks`` modifies your design to better fit the FireSim usage model. For example, FireSim designs typically include a UART. Technically, adding this in is optional, but *strongly* recommended.
* ``WithDefaultMemModel`` sets the external memory model in the FireSim simulation. See the FireSim documentation for details.
* ``WithDefaultFireSimBridges`` sets the ``IOBinders`` key to use FireSim's Bridge system, which can drive target IOs with software bridge models running on the simulation host. See the FireSIm documnetation for details.

View File

@@ -16,34 +16,29 @@ import testchipip._
import icenet._
import tracegen.{HasTraceGenTilesModuleImp}
import scala.reflect.{ClassTag, classTag}
import scala.reflect.{ClassTag}
// System for instantiating binders 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
// bridges explicitly, or add methods to
// your target traits that instantiate the bridge 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.
// IOBinders is map between string representations of traits to the desired
// IO connection behavior for tops matching that trait. We use strings to enable
// composition and overriding of IOBinders, much like how normal Keys in the config
// system are used/ At elaboration, the testharness traverses this set of functions,
// and functions which match the type of the Top are evaluated.
// You can add your own binder by adding a new (key, fn) pair, typically by using
// the OverrideIOBinder or ComposeIOBinder macros
// A map of partial functions that match on the type the DUT (_not_ it's
// IO) to generate an appropriate bridge. You can add your own binder by adding
// a new (key, fn) pair. You should override existing pairs in this map when
// using a custom IOBinder
// Since we also want to compose this structure like the existing config system,
// use the scala string representation of the matched trait as a key
case object IOBinders extends Field[Map[String, (Clock, Bool, Bool, Any) => Seq[Any]]](Map())
// DOC include start: IOBinders
case object IOBinders extends Field[Map[String, (Clock, Bool, Bool, Any) => Seq[Any]]](
Map[String, (Clock, Bool, Bool, Any) => Seq[Any]]().withDefaultValue((c: Clock, r: Bool, s: Bool, t: Any) => Nil)
)
// This macro overrides previous matches on some Top mixin. This is useful for
// binders which modify IO, since those typically cannot be composed
class RegisterIOBinder[T](fn: => (Clock, Bool, Bool, T) => Seq[Any])(implicit tag: ClassTag[T]) extends Config((site, here, up) => {
// binders which drive IO, since those typically cannot be composed
class OverrideIOBinder[T](fn: => (Clock, Bool, Bool, T) => Seq[Any])(implicit tag: ClassTag[T]) extends Config((site, here, up) => {
case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString ->
((clock: Clock, reset: Bool, success: Bool, t: Any) => {
t match {
@@ -56,34 +51,41 @@ class RegisterIOBinder[T](fn: => (Clock, Bool, Bool, T) => Seq[Any])(implicit ta
// This macro composes with previous matches on some Top mixin. This is useful for
// annotation-like binders, since those can typically be composed
class RegisterBinder[T](fn: => (Clock, Bool, Bool, T) => Seq[Any])(implicit tag: ClassTag[T]) extends Config((site, here, up) => {
class ComposeIOBinder[T](fn: => (Clock, Bool, Bool, T) => Seq[Any])(implicit tag: ClassTag[T]) extends Config((site, here, up) => {
case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString ->
((clock: Clock, reset: Bool, success: Bool, t: Any) => {
t match {
case top: T => fn(clock, reset, success, top) ++
up(IOBinders, site).getOrElse(tag.runtimeClass.toString, (c: Clock, r: Bool, s: Bool, t: Any) => Nil)(clock, reset, success, top)
case top: T => (up(IOBinders, site)(tag.runtimeClass.toString)(clock, reset, success, top)
++ fn(clock, reset, success, top))
case _ => Nil
}
})
)
})
class WithGPIOTiedOff extends RegisterIOBinder({
// DOC include end: IOBinders
class WithGPIOTiedOff extends OverrideIOBinder({
(c, r, s, top: HasPeripheryGPIOModuleImp) => top.gpio.map(gpio => gpio.pins.map(p => p.i.ival := false.B)); Nil
})
class WithSimBlockDevice extends RegisterIOBinder({
class WithSimBlockDevice extends OverrideIOBinder({
(c, r, s, top: CanHavePeripheryBlockDeviceModuleImp) => top.connectSimBlockDevice(c, r); Nil
})
class WithBlockDeviceModel extends RegisterIOBinder({
class WithBlockDeviceModel extends OverrideIOBinder({
(c, r, s, top: CanHavePeripheryBlockDeviceModuleImp) => top.connectBlockDeviceModel(); Nil
})
class WithLoopbackNIC extends RegisterIOBinder({
class WithLoopbackNIC extends OverrideIOBinder({
(c, r, s, top: CanHavePeripheryIceNICModuleImp) => top.connectNicLoopback(); Nil
})
class WithUARTAdapter extends RegisterIOBinder({
class WithSimNIC extends OverrideIOBinder({
(c, r, s, top: CanHavePeripheryIceNICModuleImp) => top.connectSimNetwork(c, r); Nil
})
class WithUARTAdapter extends OverrideIOBinder({
(c, r, s, top: HasPeripheryUARTModuleImp) => {
val defaultBaudRate = 115200 // matches sifive-blocks uart baudrate
top.uart.zipWithIndex.foreach{ case (dut_io, i) =>
@@ -95,23 +97,25 @@ class WithUARTAdapter extends RegisterIOBinder({
}
})
class WithSimAXIMem extends RegisterIOBinder({
// DOC include start: WithSimAXIMem
class WithSimAXIMem extends OverrideIOBinder({
(c, r, s, top: CanHaveMasterAXI4MemPortModuleImp) => top.connectSimAXIMem(); Nil
})
// DOC include end: WithSimAXIMem
class WithSimAXIMMIO extends RegisterIOBinder({
class WithSimAXIMMIO extends OverrideIOBinder({
(c, r, s, top: CanHaveMasterAXI4MMIOPortModuleImp) => top.connectSimAXIMMIO(); Nil
})
class WithDontTouchPorts extends RegisterIOBinder({
class WithDontTouchPorts extends OverrideIOBinder({
(c, r, s, top: DontTouch) => top.dontTouchPorts(); Nil
})
class WithTieOffInterrupts extends RegisterIOBinder({
class WithTieOffInterrupts extends OverrideIOBinder({
(c, r, s, top: HasExtInterruptsBundle) => top.tieOffInterrupts(); Nil
})
class WithTieOffL2FBusAXI extends RegisterIOBinder({
class WithTieOffL2FBusAXI extends OverrideIOBinder({
(c, r, s, top: CanHaveSlaveAXI4PortModuleImp) => {
top.l2_frontend_bus_axi4.foreach(axi => {
axi.tieoff()
@@ -129,7 +133,7 @@ class WithTieOffL2FBusAXI extends RegisterIOBinder({
}
})
class WithTiedOffDebug extends RegisterIOBinder({
class WithTiedOffDebug extends OverrideIOBinder({
(c, r, s, top: HasPeripheryDebugModuleImp) => {
Debug.tieoffDebug(top.debug, top.psd)
// tieoffDebug doesn't actually tie everything off :/
@@ -138,7 +142,7 @@ class WithTiedOffDebug extends RegisterIOBinder({
}
})
class WithSimSerial extends RegisterIOBinder({
class WithSimSerial extends OverrideIOBinder({
(c, r, s, top: CanHavePeripherySerialModuleImp) => {
val ser_success = top.connectSimSerial()
when (ser_success) { s := true.B }
@@ -146,12 +150,12 @@ class WithSimSerial extends RegisterIOBinder({
}
})
class WithTiedOffSerial extends RegisterIOBinder({
class WithTiedOffSerial extends OverrideIOBinder({
(c, r, s, top: CanHavePeripherySerialModuleImp) => top.tieoffSerial(); Nil
})
class WithSimDTM extends RegisterIOBinder({
class WithSimDebug extends OverrideIOBinder({
(c, r, s, top: HasPeripheryDebugModuleImp) => {
val dtm_success = Wire(Bool())
top.reset := r | top.debug.map { debug => AsyncResetReg(debug.ndreset) }.getOrElse(false.B)
@@ -162,6 +166,6 @@ class WithSimDTM extends RegisterIOBinder({
})
class WithTraceGenSuccessBinder extends RegisterIOBinder({
(c, r, s, top: HasTraceGenTilesModuleImp) => s := top.success; Nil
class WithTraceGenSuccessBinder extends OverrideIOBinder({
(c, r, s, top: HasTraceGenTilesModuleImp) => when (top.success) { s := true.B }; Nil
})

View File

@@ -90,7 +90,7 @@ class jtagRocketConfig extends Config(
new chipyard.iobinders.WithUARTAdapter ++
new chipyard.iobinders.WithTieOffInterrupts ++
new chipyard.iobinders.WithSimAXIMem ++
new chipyard.iobinders.WithSimDTM ++ // add SimJtag and SimSerial, use both to drive sim
new chipyard.iobinders.WithSimDebug ++ // add SimJtag and SimSerial, use both to drive sim
new chipyard.iobinders.WithSimSerial ++
new testchipip.WithTSI ++
new chipyard.config.WithNoGPIO ++
@@ -112,7 +112,7 @@ class dmiRocketConfig extends Config(
new chipyard.iobinders.WithTieOffInterrupts ++
new chipyard.iobinders.WithSimAXIMem ++
new chipyard.iobinders.WithTiedOffSerial ++
new chipyard.iobinders.WithSimDTM ++ // add SimDTM and use it to drive simulation
new chipyard.iobinders.WithSimDebug ++ // add SimDebug and use it to drive simulation
new chipyard.config.WithNoGPIO ++
new chipyard.config.WithBootROM ++
new chipyard.config.WithUART ++
@@ -345,6 +345,7 @@ class LoopbackNICRocketConfig extends Config(
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
// DOC include start: scratchpadrocket
class ScratchpadRocketConfig extends Config(
new chipyard.iobinders.WithUARTAdapter ++
new chipyard.iobinders.WithTieOffInterrupts ++
@@ -363,3 +364,4 @@ class ScratchpadRocketConfig extends Config(
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
// DOC include end: scratchpadrocket

View File

@@ -24,6 +24,7 @@ class BoomTraceGenConfig extends Config(
new chipyard.iobinders.WithTraceGenSuccessBinder ++
new chipyard.config.WithTracegenTop ++
new tracegen.WithBoomTraceGen(List.fill(2) { DCacheParams(nMSHRs = 8, nSets = 16, nWays = 2) }) ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.system.BaseConfig)
class NonBlockingTraceGenL2Config extends Config(

View File

@@ -24,26 +24,26 @@ import tracegen.HasTraceGenTilesModuleImp
import boom.common.{BoomTile}
import chipyard.iobinders.{IOBinders, RegisterIOBinder, RegisterBinder}
import chipyard.iobinders.{IOBinders, OverrideIOBinder, ComposeIOBinder}
import chipyard.HasBoomAndRocketTilesModuleImp
class WithSerialBridge extends RegisterIOBinder({
class WithSerialBridge extends OverrideIOBinder({
(c, r, s, target: CanHavePeripherySerialModuleImp) => target.serial.map(s => SerialBridge(s)(target.p)).toSeq
})
class WithNICBridge extends RegisterIOBinder({
class WithNICBridge extends OverrideIOBinder({
(c, r, s, target: CanHavePeripheryIceNICModuleImp) => target.net.map(n => NICBridge(n)(target.p)).toSeq
})
class WithUARTBridge extends RegisterIOBinder({
class WithUARTBridge extends OverrideIOBinder({
(c, r, s, target: HasPeripheryUARTModuleImp) => target.uart.map(u => UARTBridge(u)(target.p)).toSeq
})
class WithBlockDeviceBridge extends RegisterIOBinder({
class WithBlockDeviceBridge extends OverrideIOBinder({
(c, r, s, target: CanHavePeripheryBlockDeviceModuleImp) => target.bdev.map(b => BlockDevBridge(b, target.reset.toBool)(target.p)).toSeq
})
class WithFASEDBridge extends RegisterIOBinder({
class WithFASEDBridge extends OverrideIOBinder({
(c, r, s, t: CanHaveMasterAXI4MemPortModuleImp) => {
implicit val p = t.p
(t.mem_axi4 zip t.outer.memAXI4Node).flatMap({ case (io, node) =>
@@ -58,15 +58,15 @@ class WithFASEDBridge extends RegisterIOBinder({
}
})
class WithTracerVBridge extends RegisterIOBinder({
class WithTracerVBridge extends OverrideIOBinder({
(c, r, s, target: CanHaveTraceIOModuleImp) => target.traceIO.map(t => TracerVBridge(t)(target.p)).toSeq
})
class WithTraceGenBridge extends RegisterIOBinder({
class WithTraceGenBridge extends OverrideIOBinder({
(c, r, s, target: HasTraceGenTilesModuleImp) => Seq(GroundTestBridge(target.success)(target.p))
})
class WithFireSimMultiCycleRegfile extends RegisterBinder({
class WithFireSimMultiCycleRegfile extends ComposeIOBinder({
(c, r, s, target: HasBoomAndRocketTilesModuleImp) => {
target.outer.tiles.map {
case r: RocketTile => {

View File

@@ -0,0 +1,38 @@
//See LICENSE for license details.
package firesim.firesim
import chisel3._
import freechips.rocketchip.config.{Field, Config, Parameters}
import freechips.rocketchip.diplomacy.{LazyModule}
import midas.widgets.{Bridge, PeekPokeBridge}
import chipyard.{BuildTop}
import chipyard.iobinders.{IOBinders}
// Determines the number of times to instantiate the DUT in the harness.
// Subsumes legacy supernode support
case object NumNodes extends Field[Int](1)
class WithNumNodes(n: Int) extends Config((pname, site, here) => {
case NumNodes => n
})
class FireSim(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))(p(BuildTop)(p))
val peekPokeBridge = PeekPokeBridge(reset)
// A Seq of partial functions that will instantiate the right bridge only
// if that Mixin trait is present in the target's class instance
//
// Apply each partial function to each DUT instance
for ((target) <- targets) {
p(IOBinders).values.map(fn => fn(false.B, target))
}
}
}

View File

@@ -21,7 +21,6 @@ import tracegen.TraceGenKey
import icenet._
import firesim.bridges._
import firesim.util.{WithNumNodes}
import firesim.configs._
import chipyard.{BuildTop}
import chipyard.config.ConfigValName._
@@ -106,11 +105,13 @@ class WithFireSimConfigTweaks extends Config(
//*****************************************************************
// Rocket configs, base off chipyard's RocketConfig
//*****************************************************************
// DOC include start: firesimconfig
class FireSimRocketConfig extends Config(
new WithDefaultFireSimBridges ++
new WithDefaultMemModel ++
new WithFireSimConfigTweaks ++
new chipyard.RocketConfig)
// DOC include end: firesimconfig
class FireSimQuadRocketConfig extends Config(
new WithDefaultFireSimBridges ++
@@ -119,19 +120,6 @@ class FireSimQuadRocketConfig extends Config(
new chipyard.QuadRocketConfig)
//*****************************************************************
// Sha3 rocc-accel configs, base off chipyard's Sha3RocketConfig
//*****************************************************************
class FireSimSha3RocketConfig extends Config(
new WithDefaultFireSimBridges ++
new WithDefaultMemModel ++
new WithFireSimConfigTweaks ++
new chipyard.Sha3RocketConfig)
class FireSimSha3PrintfRocketConfig extends Config(
new sha3.WithSha3Printf ++
new FireSimSha3RocketConfig)
//*****************************************************************
// Boom config, base off chipyard's LargeBoomConfig
//*****************************************************************

View File

@@ -1,43 +0,0 @@
package firesim.firesim
import chisel3._
import freechips.rocketchip._
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
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.diplomacy.LazyModule
import icenet._
import firesim.util.DefaultFireSimHarness
import testchipip._
import testchipip.SerialAdapter.SERIAL_IF_WIDTH
import tracegen.{HasTraceGenTiles, HasTraceGenTilesModuleImp}
import sifive.blocks.devices.uart._
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.
*
* In general, if you're adding or removing features from any of these, you
* should CREATE A NEW ONE, WITH A NEW NAME. This is because the manager
* will store this name as part of the tags for the AGFI, so that later you can
* reconstruct what is in a particular AGFI. These tags are also used to
* determine which driver to build.
*******************************************************************************/
class FireSim(implicit p: Parameters) extends DefaultFireSimHarness