From 708a5fb9a610c6f003d3d78f3657cd8f125f879f Mon Sep 17 00:00:00 2001 From: Jerry Zhao Date: Sun, 23 Feb 2020 22:53:14 -0800 Subject: [PATCH] Address generator unification PR reviews --- .gitignore | 1 + docs/Advanced-Concepts/Chip-Communication.rst | 2 +- .../Configs-Parameters-Mixins.rst | 4 +- docs/Customization/IOBinders.rst | 25 +++++ docs/Customization/Memory-Hierarchy.rst | 102 ++---------------- docs/Customization/index.rst | 1 + docs/Makefile | 2 +- .../FPGA-Accelerated-Simulation.rst | 56 +++------- .../chipyard/src/main/scala/IOBinders.scala | 80 +++++++------- .../src/main/scala/RocketConfigs.scala | 6 +- .../src/main/scala/TracegenConfigs.scala | 1 + .../src/main/scala/BridgeBinders.scala | 18 ++-- .../firechip/src/main/scala/FireSim.scala | 38 +++++++ .../src/main/scala/TargetConfigs.scala | 16 +-- .../firechip/src/main/scala/Targets.scala | 43 -------- generators/icenet | 2 +- sims/firesim | 2 +- 17 files changed, 153 insertions(+), 246 deletions(-) create mode 100644 docs/Customization/IOBinders.rst create mode 100644 generators/firechip/src/main/scala/FireSim.scala delete mode 100644 generators/firechip/src/main/scala/Targets.scala diff --git a/.gitignore b/.gitignore index e2c66082..47cb4d87 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ bootrom/* +docs/warnings.txt /Makefrag.pkgs target *.jar diff --git a/docs/Advanced-Concepts/Chip-Communication.rst b/docs/Advanced-Concepts/Chip-Communication.rst index fe9b6f57..596ccd6d 100644 --- a/docs/Advanced-Concepts/Chip-Communication.rst +++ b/docs/Advanced-Concepts/Chip-Communication.rst @@ -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 diff --git a/docs/Chipyard-Basics/Configs-Parameters-Mixins.rst b/docs/Chipyard-Basics/Configs-Parameters-Mixins.rst index e72a7444..f490d2a1 100644 --- a/docs/Chipyard-Basics/Configs-Parameters-Mixins.rst +++ b/docs/Chipyard-Basics/Configs-Parameters-Mixins.rst @@ -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`` 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. diff --git a/docs/Customization/IOBinders.rst b/docs/Customization/IOBinders.rst new file mode 100644 index 00000000..798987b1 --- /dev/null +++ b/docs/Customization/IOBinders.rst @@ -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. diff --git a/docs/Customization/Memory-Hierarchy.rst b/docs/Customization/Memory-Hierarchy.rst index 26bce436..99cc9f77 100644 --- a/docs/Customization/Memory-Hierarchy.rst +++ b/docs/Customization/Memory-Hierarchy.rst @@ -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 diff --git a/docs/Customization/index.rst b/docs/Customization/index.rst index c5ec5778..496f4c0a 100644 --- a/docs/Customization/index.rst +++ b/docs/Customization/index.rst @@ -42,3 +42,4 @@ We recommend reading all these pages in order. Hit next to get started! Memory-Hierarchy Boot-Process Firrtl-Transforms + IOBinders diff --git a/docs/Makefile b/docs/Makefile index adea9f26..fe9f0963 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -2,7 +2,7 @@ # # You can set these variables from the command line. -SPHINXOPTS = +SPHINXOPTS = -w warnings.txt SPHINXBUILD = python -msphinx SPHINXPROJ = Chipyard SOURCEDIR = . diff --git a/docs/Simulation/FPGA-Accelerated-Simulation.rst b/docs/Simulation/FPGA-Accelerated-Simulation.rst index 6964ee57..89c0a939 100644 --- a/docs/Simulation/FPGA-Accelerated-Simulation.rst +++ b/docs/Simulation/FPGA-Accelerated-Simulation.rst @@ -44,47 +44,19 @@ familiar with FireSim, please return to the `FireSim Docs `__, 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. diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index 327db301..22715aaf 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -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 }) diff --git a/generators/chipyard/src/main/scala/RocketConfigs.scala b/generators/chipyard/src/main/scala/RocketConfigs.scala index 6066f86f..2e0f856a 100644 --- a/generators/chipyard/src/main/scala/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/RocketConfigs.scala @@ -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 diff --git a/generators/chipyard/src/main/scala/TracegenConfigs.scala b/generators/chipyard/src/main/scala/TracegenConfigs.scala index 0e3457f0..1e9be623 100644 --- a/generators/chipyard/src/main/scala/TracegenConfigs.scala +++ b/generators/chipyard/src/main/scala/TracegenConfigs.scala @@ -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( diff --git a/generators/firechip/src/main/scala/BridgeBinders.scala b/generators/firechip/src/main/scala/BridgeBinders.scala index 8561d7a1..9a19e6ef 100644 --- a/generators/firechip/src/main/scala/BridgeBinders.scala +++ b/generators/firechip/src/main/scala/BridgeBinders.scala @@ -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 => { diff --git a/generators/firechip/src/main/scala/FireSim.scala b/generators/firechip/src/main/scala/FireSim.scala new file mode 100644 index 00000000..884dbbf3 --- /dev/null +++ b/generators/firechip/src/main/scala/FireSim.scala @@ -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)) + } + } +} diff --git a/generators/firechip/src/main/scala/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index 11916662..dcc5be90 100644 --- a/generators/firechip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/src/main/scala/TargetConfigs.scala @@ -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 //***************************************************************** diff --git a/generators/firechip/src/main/scala/Targets.scala b/generators/firechip/src/main/scala/Targets.scala deleted file mode 100644 index 6961782a..00000000 --- a/generators/firechip/src/main/scala/Targets.scala +++ /dev/null @@ -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 diff --git a/generators/icenet b/generators/icenet index 4980d3a3..e235801c 160000 --- a/generators/icenet +++ b/generators/icenet @@ -1 +1 @@ -Subproject commit 4980d3a311e487419f2e6358d678c18b7ff3ffe4 +Subproject commit e235801c4c7088a303dd2136e02fb9548b4ec2f8 diff --git a/sims/firesim b/sims/firesim index c771d114..59885ac8 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit c771d1143a98dd19f1c4a842cc8a572b5e54de98 +Subproject commit 59885ac828e5433ae6fea7490a7c100a6ea63155