Revamp the config system for Top/Harness (#347)
* Refactor how Configs parameterize the Top and TestHarnesses * Bump sha3, testchipip, icenet, firesim
This commit is contained in:
@@ -45,7 +45,7 @@ mapping["example"]="SUB_PROJECT=example"
|
|||||||
mapping["boomrocketexample"]="SUB_PROJECT=example CONFIG=LargeBoomAndRocketConfig"
|
mapping["boomrocketexample"]="SUB_PROJECT=example CONFIG=LargeBoomAndRocketConfig"
|
||||||
mapping["boom"]="SUB_PROJECT=example CONFIG=SmallBoomConfig"
|
mapping["boom"]="SUB_PROJECT=example CONFIG=SmallBoomConfig"
|
||||||
mapping["rocketchip"]="SUB_PROJECT=rocketchip"
|
mapping["rocketchip"]="SUB_PROJECT=rocketchip"
|
||||||
mapping["blockdevrocketchip"]="SUB_PROJECT=example CONFIG=SimBlockDeviceRocketConfig TOP=TopWithBlockDevice"
|
mapping["blockdevrocketchip"]="SUB_PROJECT=example CONFIG=SimBlockDeviceRocketConfig"
|
||||||
mapping["hwacha"]="SUB_PROJECT=example CONFIG=HwachaRocketConfig"
|
mapping["hwacha"]="SUB_PROJECT=example CONFIG=HwachaRocketConfig"
|
||||||
mapping["gemmini"]="SUB_PROJECT=example CONFIG=GemminiRocketConfig"
|
mapping["gemmini"]="SUB_PROJECT=example CONFIG=GemminiRocketConfig"
|
||||||
mapping["tracegen"]="SUB_PROJECT=tracegen CONFIG=NonBlockingTraceGenL2Config"
|
mapping["tracegen"]="SUB_PROJECT=tracegen CONFIG=NonBlockingTraceGenL2Config"
|
||||||
|
|||||||
111
docs/Advanced-Concepts/CDEs.rst
Normal file
111
docs/Advanced-Concepts/CDEs.rst
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
.. _cdes:
|
||||||
|
|
||||||
|
Context-Dependent-Environments
|
||||||
|
========================================
|
||||||
|
|
||||||
|
Readers may notice that the parameterization system frequently uses ``(site, here, up)``.
|
||||||
|
This construct is an artifact of the "context-dependent-environment" system which Chipyard and Rocket Chip both leverage for powerful composable hardware configuration.
|
||||||
|
|
||||||
|
The CDE parameterization system provides different "Views" of a single global parameterization. The syntax for accessing a ``Field`` within a ``View`` is ``my_view(MyKey, site_view)``, where ``site_view`` is a "global" view that will be passed recursively into various functions and key-lookups in the call-stack of ``my_view(MyKey, site_view)``.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Rocket Chip based designs will frequently use ``val p: Parameters`` and ``p(SomeKey)`` to lookup the value of a key. ``Parameters`` is just a subclass of the ``View`` abstract class, and ``p(SomeKey)`` really expands into ``p(SomeKey, p)``. This is because we consider the call ``p(SomeKey)`` to be the "site", or "source" of the original key query, so we need to pass in the view of the configuration provided by ``p`` recursively to future calls through the ``site`` argument.
|
||||||
|
|
||||||
|
Consider the following example using CDEs.
|
||||||
|
|
||||||
|
.. code:: scala
|
||||||
|
|
||||||
|
case object SomeKeyX extends Field[Boolean](false) // default is false
|
||||||
|
case object SomeKeyY extends Field[Boolean](false) // default is false
|
||||||
|
case object SomeKeyZ extends Field[Boolean](false) // default is false
|
||||||
|
|
||||||
|
class WithX(b: Boolean) extends Config((site, here, up) => {
|
||||||
|
case SomeKeyX => b
|
||||||
|
}
|
||||||
|
|
||||||
|
class WithY(b: Boolean) extends Config((site, here, up) => {
|
||||||
|
case SomeKeyY => b
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
When forming a query based on a ``Parameters`` object, like ``p(SomeKeyX)``, the configuration system traverses the "chain" of mixins until it finds a partial function which is defined at the key, and then returns that value.
|
||||||
|
|
||||||
|
.. code:: scala
|
||||||
|
|
||||||
|
val params = Config(new WithX(true) ++ new WithY(true)) // "chain" together mixins
|
||||||
|
params(SomeKeyX) // evaluates to true
|
||||||
|
params(SomeKeyY) // evaluates to true
|
||||||
|
params(SomeKeyZ) // evaluates to false
|
||||||
|
|
||||||
|
In this example, the evaluation of ``params(SomeKeyX)`` will terminate in the partial function defined in ``WithX(true)``, while the evaluation of ``params(SomeKeyY)`` will terminate in the partial function defined in ``WithY(true)``. Note that when no partial functions match, the evaluation will return the default value for that parameter.
|
||||||
|
|
||||||
|
The real power of CDEs arises from the ``(site, here, up)`` parameters to the partial functions, which provide useful "views" into the global parameterization that the partial functions may access to determine a parameterization.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Additional information on the motivations for CDEs can be found in Chapter 2 of `Henry Cook's Thesis <https://www2.eecs.berkeley.edu/Pubs/TechRpts/2016/EECS-2016-89.pdf>`_ .
|
||||||
|
|
||||||
|
|
||||||
|
Site
|
||||||
|
~~~~
|
||||||
|
|
||||||
|
``site`` provides a ``View`` of the "source" of the original parameter query.
|
||||||
|
|
||||||
|
.. code:: scala
|
||||||
|
|
||||||
|
class WithXEqualsYSite extends Config((site, here, up) => {
|
||||||
|
case SomeKeyX => site(SomeKeyY) // expands to site(SomeKeyY, site)
|
||||||
|
}
|
||||||
|
|
||||||
|
val params_1 = Config(new WithXEqualsYSite ++ new WithY(true))
|
||||||
|
val params_2 = Config(new WithY(true) ++ new WithXEqualsYSite)
|
||||||
|
params_1(SomeKeyX) // evaluates to true
|
||||||
|
params_2(SomeKeyX) // evaluates to true
|
||||||
|
|
||||||
|
|
||||||
|
In this example, the partial function in ``WithXEqualsYSite`` will look up the value of ``SomeKeyY`` in the original ``params_N`` object, which becomes ``site`` in each call in the recursive traversal.
|
||||||
|
|
||||||
|
|
||||||
|
Here
|
||||||
|
~~~~
|
||||||
|
|
||||||
|
``here`` provides a ``View`` of the locally defined Config, which typically just contains some partial function.
|
||||||
|
|
||||||
|
.. code:: scala
|
||||||
|
|
||||||
|
class WithXEqualsYHere extends Config((site, here, up) => {
|
||||||
|
case SomeKeyY => false
|
||||||
|
case SomeKeyX => here(SomeKeyY, site)
|
||||||
|
}
|
||||||
|
|
||||||
|
val params_1 = Config(new WithXEqualsYHere ++ new WithY(true))
|
||||||
|
val params_2 = Config(new WithY(true) ++ new WithXEqualsYHere)
|
||||||
|
|
||||||
|
params_1(SomeKeyX) // evaluates to false
|
||||||
|
params_2(SomeKeyX) // evaluates to false
|
||||||
|
|
||||||
|
In this example, note that although our final parameterization in ``params_2`` has ``SomeKeyY`` set to ``true``, the call to ``here(SomeKeyY, site)`` only looks in the local partial function defined in ``WithXEqualsYHere``. Note that we pass ``site`` to ``here`` since ``site`` may be used in the recursive call.
|
||||||
|
|
||||||
|
|
||||||
|
Up
|
||||||
|
~~~~
|
||||||
|
|
||||||
|
``up`` provides a ``View`` of the previously defined set of partial functions in the "chain" of partial functions. This is useful when we want to lookup a previously set value for some key, but not the final value for that key.
|
||||||
|
|
||||||
|
.. code:: scala
|
||||||
|
|
||||||
|
class WithXEqualsYUp extends Config((site, here, up) => {
|
||||||
|
case SomeKeyX => up(SomeKeyY, site)
|
||||||
|
}
|
||||||
|
|
||||||
|
val params_1 = Config(new WithXEqualsYUp ++ new WithY(true))
|
||||||
|
val params_2 = Config(new WithY(true) ++ new WithXEqualsYUp)
|
||||||
|
|
||||||
|
params_1(SomeKeyX) // evaluates to true
|
||||||
|
params_2(SomeKeyX) // evaluates to false
|
||||||
|
|
||||||
|
In this example, note how ``up(SomeKeyY, site)`` in ``WithXEqualsYUp`` will refer to *either* the the partial function defining ``SomeKeyY`` in ``WithY(true)`` *or* the default value for ``SomeKeyY`` provided in the original ``case object SomeKeyY`` definition, *depending on the order in which the mixins were used*. Since the order of mixins affects the the order of the ``View`` traversal, ``up`` provides a different ``View`` of the parameterization in ``params_1`` and ``params_2``.
|
||||||
|
|
||||||
|
|
||||||
|
Also note that again, ``site`` must be recursively passed through the call to ``up``.
|
||||||
|
|
||||||
|
|
||||||
@@ -12,3 +12,5 @@ They expect you to know about Chisel, Parameters, Configs, etc.
|
|||||||
Chip-Communication
|
Chip-Communication
|
||||||
Debugging-RTL
|
Debugging-RTL
|
||||||
Resources
|
Resources
|
||||||
|
CDEs
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ Hit next to get started!
|
|||||||
:caption: Chipyard Basics:
|
:caption: Chipyard Basics:
|
||||||
|
|
||||||
Chipyard-Components
|
Chipyard-Components
|
||||||
|
Development-Ecosystem
|
||||||
Configs-Parameters-Mixins
|
Configs-Parameters-Mixins
|
||||||
Initial-Repo-Setup
|
Initial-Repo-Setup
|
||||||
|
|
||||||
|
|||||||
@@ -1,261 +0,0 @@
|
|||||||
.. _adding-an-accelerator:
|
|
||||||
|
|
||||||
Adding an Accelerator/Device
|
|
||||||
===============================
|
|
||||||
|
|
||||||
Accelerators or custom IO devices can be added to your SoC in several ways:
|
|
||||||
|
|
||||||
* MMIO Peripheral (a.k.a TileLink-Attached Accelerator)
|
|
||||||
* Tightly-Coupled RoCC Accelerator
|
|
||||||
|
|
||||||
These approaches differ in the method of the communication between the processor and the custom block.
|
|
||||||
|
|
||||||
With the TileLink-Attached approach, the processor communicates with MMIO peripherals through memory-mapped registers.
|
|
||||||
|
|
||||||
In contrast, the processor communicates with a RoCC accelerators through a custom protocol and custom non-standard ISA instructions reserved in the RISC-V ISA encoding space.
|
|
||||||
Each core can have up to four accelerators that are controlled by custom instructions and share resources with the CPU.
|
|
||||||
RoCC coprocessor instructions have the following form.
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
|
|
||||||
customX rd, rs1, rs2, funct
|
|
||||||
|
|
||||||
The X will be a number 0-3, and determines the opcode of the instruction, which controls which accelerator an instruction will be routed to.
|
|
||||||
The ``rd``, ``rs1``, and ``rs2`` fields are the register numbers of the destination register and two source registers.
|
|
||||||
The ``funct`` field is a 7-bit integer that the accelerator can use to distinguish different instructions from each other.
|
|
||||||
|
|
||||||
Note that communication through a RoCC interface requires a custom software toolchain, whereas MMIO peripherals can use that standard toolchain with appropriate driver support.
|
|
||||||
|
|
||||||
Integrating into the Generator Build System
|
|
||||||
-------------------------------------------
|
|
||||||
|
|
||||||
While developing, you want to include Chisel code in a submodule so that it can be shared by different projects.
|
|
||||||
To add a submodule to the Chipyard framework, make sure that your project is organized as follows.
|
|
||||||
|
|
||||||
.. code-block:: none
|
|
||||||
|
|
||||||
yourproject/
|
|
||||||
build.sbt
|
|
||||||
src/main/scala/
|
|
||||||
YourFile.scala
|
|
||||||
|
|
||||||
Put this in a git repository and make it accessible.
|
|
||||||
Then add it as a submodule to under the following directory hierarchy: ``generators/yourproject``.
|
|
||||||
|
|
||||||
.. code-block:: shell
|
|
||||||
|
|
||||||
cd generators/
|
|
||||||
git submodule add https://git-repository.com/yourproject.git
|
|
||||||
|
|
||||||
Then add ``yourproject`` to the Chipyard top-level build.sbt file.
|
|
||||||
|
|
||||||
.. code-block:: scala
|
|
||||||
|
|
||||||
lazy val yourproject = (project in file("generators/yourproject")).settings(commonSettings).dependsOn(rocketchip)
|
|
||||||
|
|
||||||
You can then import the classes defined in the submodule in a new project if
|
|
||||||
you add it as a dependency. For instance, if you want to use this code in
|
|
||||||
the ``example`` project, change the final line in build.sbt to the following.
|
|
||||||
|
|
||||||
.. code-block:: scala
|
|
||||||
|
|
||||||
lazy val example = (project in file(".")).settings(commonSettings).dependsOn(testchipip, yourproject)
|
|
||||||
|
|
||||||
MMIO Peripheral
|
|
||||||
------------------
|
|
||||||
|
|
||||||
The easiest way to create a TileLink peripheral is to use the ``TLRegisterRouter``, which abstracts away the details of handling the TileLink protocol and provides a convenient interface for specifying memory-mapped registers.
|
|
||||||
To create a RegisterRouter-based peripheral, you will need to specify a parameter case class for the configuration settings, a bundle trait with the extra top-level ports, and a module implementation containing the actual RTL.
|
|
||||||
In this case we use a submodule ``PWMBase`` to actually perform the pulse-width modulation. The ``PWMModule`` class only creates the registers and hooks them
|
|
||||||
up using ``regmap``.
|
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/example/src/main/scala/PWM.scala
|
|
||||||
:language: scala
|
|
||||||
:start-after: DOC include start: PWM generic traits
|
|
||||||
:end-before: DOC include end: PWM generic traits
|
|
||||||
|
|
||||||
Once you have these classes, you can construct the final peripheral by extending the ``TLRegisterRouter`` and passing the proper arguments.
|
|
||||||
The first set of arguments determines where the register router will be placed in the global address map and what information will be put in its device tree entry.
|
|
||||||
The second set of arguments is the IO bundle constructor, which we create by extending ``TLRegBundle`` with our bundle trait.
|
|
||||||
The final set of arguments is the module constructor, which we create by extends ``TLRegModule`` with our module trait.
|
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/example/src/main/scala/PWM.scala
|
|
||||||
:language: scala
|
|
||||||
:start-after: DOC include start: PWMTL
|
|
||||||
:end-before: DOC include end: PWMTL
|
|
||||||
|
|
||||||
The full module code can be found in ``generators/example/src/main/scala/PWM.scala``.
|
|
||||||
|
|
||||||
After creating the module, we need to hook it up to our SoC.
|
|
||||||
Rocket Chip accomplishes this using the cake pattern.
|
|
||||||
This basically involves placing code inside traits.
|
|
||||||
In the Rocket Chip cake, there are two kinds of traits: a ``LazyModule`` trait and a module implementation trait.
|
|
||||||
|
|
||||||
The ``LazyModule`` trait runs setup code that must execute before all the hardware gets elaborated.
|
|
||||||
For a simple memory-mapped peripheral, this just involves connecting the peripheral's TileLink node to the MMIO crossbar.
|
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/example/src/main/scala/PWM.scala
|
|
||||||
:language: scala
|
|
||||||
:start-after: DOC include start: HasPeripheryPWMTL
|
|
||||||
:end-before: DOC include end: HasPeripheryPWMTL
|
|
||||||
|
|
||||||
Note that the ``PWMTL`` class we created from the register router is itself a ``LazyModule``.
|
|
||||||
Register routers have a TileLink node simply named "node", which we can hook up to the Rocket Chip bus.
|
|
||||||
This will automatically add address map and device tree entries for the peripheral.
|
|
||||||
|
|
||||||
The module implementation trait is where we instantiate our PWM module and connect it to the rest of the SoC.
|
|
||||||
Since this module has an extra `pwmout` output, we declare that in this trait, using Chisel's multi-IO functionality.
|
|
||||||
We then connect the ``PWMTL``'s pwmout to the pwmout we declared.
|
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/example/src/main/scala/PWM.scala
|
|
||||||
:language: scala
|
|
||||||
:start-after: DOC include start: HasPeripheryPWMTLModuleImp
|
|
||||||
:end-before: DOC include end: HasPeripheryPWMTLModuleImp
|
|
||||||
|
|
||||||
Now we want to mix our traits into the system as a whole.
|
|
||||||
This code is from ``generators/example/src/main/scala/Top.scala``.
|
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/example/src/main/scala/Top.scala
|
|
||||||
:language: scala
|
|
||||||
:start-after: DOC include start: TopWithPWMTL
|
|
||||||
:end-before: DOC include end: TopWithPWMTL
|
|
||||||
|
|
||||||
Just as we need separate traits for ``LazyModule`` and module implementation, we need two classes to build the system.
|
|
||||||
The ``Top`` classes already have the basic peripherals included for us, so we will just extend those.
|
|
||||||
|
|
||||||
The ``Top`` class includes the pre-elaboration code and also a ``lazy val`` to produce the module implementation (hence ``LazyModule``).
|
|
||||||
The ``TopModule`` class is the actual RTL that gets synthesized.
|
|
||||||
|
|
||||||
Next, we need to add a configuration mixin in ``generators/example/src/main/scala/ConfigMixins.scala`` that tells the ``TestHarness`` to instantiate ``TopWithPWMTL`` instead of the default ``Top``.
|
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
|
|
||||||
:language: scala
|
|
||||||
:start-after: DOC include start: WithPWMTop
|
|
||||||
:end-before: DOC include end: WithPWMTop
|
|
||||||
|
|
||||||
And finally, we create a configuration class in ``generators/example/src/main/scala/Configs.scala`` that uses this mixin.
|
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/example/src/main/scala/RocketConfigs.scala
|
|
||||||
:language: scala
|
|
||||||
:start-after: DOC include start: PWMRocketConfig
|
|
||||||
:end-before: DOC include end: PWMRocketConfig
|
|
||||||
|
|
||||||
Now we can test that the PWM is working. The test program is in ``tests/pwm.c``.
|
|
||||||
|
|
||||||
.. literalinclude:: ../../tests/pwm.c
|
|
||||||
:language: c
|
|
||||||
|
|
||||||
This just writes out to the registers we defined earlier.
|
|
||||||
The base of the module's MMIO region is at 0x2000.
|
|
||||||
This will be printed out in the address map portion when you generated the verilog code.
|
|
||||||
|
|
||||||
Compiling this program with make produces a ``pwm.riscv`` executable.
|
|
||||||
|
|
||||||
Now with all of that done, we can go ahead and run our simulation.
|
|
||||||
|
|
||||||
.. code-block:: shell
|
|
||||||
|
|
||||||
cd sims/verilator
|
|
||||||
make CONFIG=PWMRocketConfig TOP=TopWithPWMTL
|
|
||||||
./simulator-example-PWMRocketConfig ../../tests/pwm.riscv
|
|
||||||
|
|
||||||
Adding a RoCC Accelerator
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
RoCC accelerators are lazy modules that extend the ``LazyRoCC`` class.
|
|
||||||
Their implementation should extends the ``LazyRoCCModule`` class.
|
|
||||||
|
|
||||||
.. code-block:: scala
|
|
||||||
|
|
||||||
class CustomAccelerator(opcodes: OpcodeSet)
|
|
||||||
(implicit p: Parameters) extends LazyRoCC(opcodes) {
|
|
||||||
override lazy val module = new CustomAcceleratorModule(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
class CustomAcceleratorModule(outer: CustomAccelerator)
|
|
||||||
extends LazyRoCCModuleImp(outer) {
|
|
||||||
val cmd = Queue(io.cmd)
|
|
||||||
// The parts of the command are as follows
|
|
||||||
// inst - the parts of the instruction itself
|
|
||||||
// opcode
|
|
||||||
// rd - destination register number
|
|
||||||
// rs1 - first source register number
|
|
||||||
// rs2 - second source register number
|
|
||||||
// funct
|
|
||||||
// xd - is the destination register being used?
|
|
||||||
// xs1 - is the first source register being used?
|
|
||||||
// xs2 - is the second source register being used?
|
|
||||||
// rs1 - the value of source register 1
|
|
||||||
// rs2 - the value of source register 2
|
|
||||||
...
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
The ``opcodes`` parameter for ``LazyRoCC`` is the set of custom opcodes that will map to this accelerator.
|
|
||||||
More on this in the next subsection.
|
|
||||||
|
|
||||||
The ``LazyRoCC`` class contains two TLOutputNode instances, ``atlNode`` and ``tlNode``.
|
|
||||||
The former connects into a tile-local arbiter along with the backside of the L1 instruction cache.
|
|
||||||
The latter connects directly to the L1-L2 crossbar.
|
|
||||||
The corresponding Tilelink ports in the module implementation's IO bundle are ``atl`` and ``tl``, respectively.
|
|
||||||
|
|
||||||
The other interfaces available to the accelerator are ``mem``, which provides access to the L1 cache;
|
|
||||||
``ptw`` which provides access to the page-table walker;
|
|
||||||
the ``busy`` signal, which indicates when the accelerator is still handling an instruction;
|
|
||||||
and the ``interrupt`` signal, which can be used to interrupt the CPU.
|
|
||||||
|
|
||||||
Look at the examples in ``generators/rocket-chip/src/main/scala/tile/LazyRocc.scala`` for detailed information on the different IOs.
|
|
||||||
|
|
||||||
Adding RoCC accelerator to Config
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
RoCC accelerators can be added to a core by overriding the ``BuildRoCC`` parameter in the configuration.
|
|
||||||
This takes a sequence of functions producing ``LazyRoCC`` objects, one for each accelerator you wish to add.
|
|
||||||
|
|
||||||
For instance, if we wanted to add the previously defined accelerator and route custom0 and custom1 instructions to it, we could do the following.
|
|
||||||
|
|
||||||
.. code-block:: scala
|
|
||||||
|
|
||||||
class WithCustomAccelerator extends Config((site, here, up) => {
|
|
||||||
case BuildRoCC => Seq((p: Parameters) => LazyModule(
|
|
||||||
new CustomAccelerator(OpcodeSet.custom0 | OpcodeSet.custom1)(p)))
|
|
||||||
})
|
|
||||||
|
|
||||||
class CustomAcceleratorConfig extends Config(
|
|
||||||
new WithCustomAccelerator ++ new RocketConfig)
|
|
||||||
|
|
||||||
To add RoCC instructions in your program, use the RoCC C macros provided in ``tests/rocc.h``. You can find examples in the files ``tests/accum.c`` and ``charcount.c``.
|
|
||||||
|
|
||||||
Adding a DMA port
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
For IO devices or accelerators (like a disk or network driver), instead of
|
|
||||||
having the CPU poll data from the device, we may want to have the device write
|
|
||||||
directly to the coherent memory system instead. For example, here is a device
|
|
||||||
that writes zeros to the memory at a configured address.
|
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/example/src/main/scala/InitZero.scala
|
|
||||||
:language: scala
|
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/example/src/main/scala/Top.scala
|
|
||||||
:language: scala
|
|
||||||
:start-after: DOC include start: TopWithInitZero
|
|
||||||
:end-before: DOC include end: TopWithInitZero
|
|
||||||
|
|
||||||
We use ``TLHelper.makeClientNode`` to create a TileLink client node for us.
|
|
||||||
We then connect the client node to the memory system through the front bus (fbus).
|
|
||||||
For more info on creating TileLink client nodes, take a look at :ref:`Client Node`.
|
|
||||||
|
|
||||||
Once we've created our top-level module including the DMA widget, we can create a configuration for it as we did before.
|
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
|
|
||||||
:language: scala
|
|
||||||
:start-after: DOC include start: WithInitZero
|
|
||||||
:end-before: DOC include end: WithInitZero
|
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/example/src/main/scala/RocketConfigs.scala
|
|
||||||
:language: scala
|
|
||||||
:start-after: DOC include start: InitZeroRocketConfig
|
|
||||||
:end-before: DOC include end: InitZeroRocketConfig
|
|
||||||
|
|
||||||
|
|
||||||
59
docs/Customization/Custom-Chisel.rst
Normal file
59
docs/Customization/Custom-Chisel.rst
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
.. _custom_chisel:
|
||||||
|
|
||||||
|
Integrating Custom Chisel Projects into the Generator Build System
|
||||||
|
==================================================================
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
This section assumes integration of custom Chisel through git submodules.
|
||||||
|
While it is possible to directly commit custom Chisel into the Chipyard framework,
|
||||||
|
we heavily recommend managing custom code through git submodules. Using submodules decouples
|
||||||
|
development of custom features from development on the Chipyard framework.
|
||||||
|
|
||||||
|
|
||||||
|
While developing, you want to include Chisel code in a submodule so that it can be shared by different projects.
|
||||||
|
To add a submodule to the Chipyard framework, make sure that your project is organized as follows.
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
yourproject/
|
||||||
|
build.sbt
|
||||||
|
src/main/scala/
|
||||||
|
YourFile.scala
|
||||||
|
|
||||||
|
Put this in a git repository and make it accessible.
|
||||||
|
Then add it as a submodule to under the following directory hierarchy: ``generators/yourproject``.
|
||||||
|
|
||||||
|
The ``build.sbt`` is a minimal file which describes metadata for a Chisel project.
|
||||||
|
For a simple project, the ``build.sbt`` can even be empty, but below we provide an example
|
||||||
|
build.sbt.
|
||||||
|
|
||||||
|
.. code-block:: scala
|
||||||
|
|
||||||
|
organization := "edu.berkeley.cs"
|
||||||
|
|
||||||
|
version := "1.0"
|
||||||
|
|
||||||
|
name := "yourproject"
|
||||||
|
|
||||||
|
scalaVersion := "2.12.4"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
cd generators/
|
||||||
|
git submodule add https://git-repository.com/yourproject.git
|
||||||
|
|
||||||
|
Then add ``yourproject`` to the Chipyard top-level build.sbt file.
|
||||||
|
|
||||||
|
.. code-block:: scala
|
||||||
|
|
||||||
|
lazy val yourproject = (project in file("generators/yourproject")).settings(commonSettings).dependsOn(rocketchip)
|
||||||
|
|
||||||
|
You can then import the classes defined in the submodule in a new project if
|
||||||
|
you add it as a dependency. For instance, if you want to use this code in
|
||||||
|
the ``example`` project, change the final line in build.sbt to the following.
|
||||||
|
|
||||||
|
.. code-block:: scala
|
||||||
|
|
||||||
|
lazy val example = (project in file(".")).settings(commonSettings).dependsOn(testchipip, yourproject)
|
||||||
39
docs/Customization/DMA-Devices.rst
Normal file
39
docs/Customization/DMA-Devices.rst
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
.. _dma-devices:
|
||||||
|
|
||||||
|
Adding a DMA Device
|
||||||
|
===================
|
||||||
|
|
||||||
|
DMA devices are Tilelink widgets which act as masters. In other words,
|
||||||
|
DMA devices can send their own read and write requests to the chip's memory
|
||||||
|
system.
|
||||||
|
|
||||||
|
For IO devices or accelerators (like a disk or network driver), instead of
|
||||||
|
having the CPU poll data from the device, we may want to have the device write
|
||||||
|
directly to the coherent memory system instead. For example, here is a device
|
||||||
|
that writes zeros to the memory at a configured address.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/example/src/main/scala/InitZero.scala
|
||||||
|
:language: scala
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/example/src/main/scala/Top.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: Top
|
||||||
|
:end-before: DOC include end: Top
|
||||||
|
|
||||||
|
We use ``TLHelper.makeClientNode`` to create a TileLink client node for us.
|
||||||
|
We then connect the client node to the memory system through the front bus (fbus).
|
||||||
|
For more info on creating TileLink client nodes, take a look at :ref:`Client Node`.
|
||||||
|
|
||||||
|
Once we've created our top-level module including the DMA widget, we can create a configuration for it as we did before.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: WithInitZero
|
||||||
|
:end-before: DOC include end: WithInitZero
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/example/src/main/scala/RocketConfigs.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: InitZeroRocketConfig
|
||||||
|
:end-before: DOC include end: InitZeroRocketConfig
|
||||||
|
|
||||||
|
|
||||||
@@ -8,8 +8,7 @@ design flows. Fortunately, both Chisel and Chipyard provide extensive
|
|||||||
support for Verilog integration.
|
support for Verilog integration.
|
||||||
|
|
||||||
Here, we will examine the process of incorporating an MMIO peripheral
|
Here, we will examine the process of incorporating an MMIO peripheral
|
||||||
(similar to the PWM example from the previous section) that uses a
|
that uses a Verilog implementation of Greatest Common Denominator (GCD)
|
||||||
Verilog implementation of Greatest Common Denominator (GCD)
|
|
||||||
algorithm. There are a few steps to adding a Verilog peripheral:
|
algorithm. There are a few steps to adding a Verilog peripheral:
|
||||||
|
|
||||||
* Adding a Verilog resource file to the project
|
* Adding a Verilog resource file to the project
|
||||||
@@ -58,7 +57,7 @@ and Verilog sources follow the prescribed directory layout.
|
|||||||
build.sbt
|
build.sbt
|
||||||
src/main/
|
src/main/
|
||||||
scala/
|
scala/
|
||||||
GCDMMIOBlackBox.scala
|
GCD.scala
|
||||||
resources/
|
resources/
|
||||||
vsrc/
|
vsrc/
|
||||||
GCDMMIOBlackBox.v
|
GCDMMIOBlackBox.v
|
||||||
@@ -89,7 +88,7 @@ as the bitwidth of the GCD calculation does in this example.
|
|||||||
|
|
||||||
**Chisel BlackBox Definition**
|
**Chisel BlackBox Definition**
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/example/src/main/scala/GCDMMIOBlackBox.scala
|
.. literalinclude:: ../../generators/example/src/main/scala/GCD.scala
|
||||||
:language: scala
|
:language: scala
|
||||||
:start-after: DOC include start: GCD blackbox
|
:start-after: DOC include start: GCD blackbox
|
||||||
:end-before: DOC include end: GCD blackbox
|
:end-before: DOC include end: GCD blackbox
|
||||||
@@ -102,54 +101,32 @@ diplomatic memory mapping on the system bus, we still have to
|
|||||||
integrate the peripheral at the Chisel level by mixing
|
integrate the peripheral at the Chisel level by mixing
|
||||||
peripheral-specific traits into a ``TLRegisterRouter``. The ``params``
|
peripheral-specific traits into a ``TLRegisterRouter``. The ``params``
|
||||||
member and ``HasRegMap`` base trait should look familiar from the
|
member and ``HasRegMap`` base trait should look familiar from the
|
||||||
previous memory-mapped PWM device example.
|
previous memory-mapped GCD device example.
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/example/src/main/scala/GCDMMIOBlackBox.scala
|
.. literalinclude:: ../../generators/example/src/main/scala/GCD.scala
|
||||||
:language: scala
|
:language: scala
|
||||||
:start-after: DOC include start: GCD instance regmap
|
:start-after: DOC include start: GCD instance regmap
|
||||||
:end-before: DOC include end: GCD instance regmap
|
:end-before: DOC include end: GCD instance regmap
|
||||||
|
|
||||||
Advanced Features of RegField Entries
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
One significant difference from the PWM example is in the peripheral's
|
Defining a Chip with a BlackBox
|
||||||
memory map. ``RegField`` exposes polymorphic ``r`` and ``w`` methods
|
|
||||||
that allow read- and write-only memory-mapped registers to be
|
|
||||||
interfaced to hardware in multiple ways.
|
|
||||||
|
|
||||||
* ``RegField.r(2, status)`` is used to create a 2-bit, read-only register that captures the current value of the ``status`` signal when read.
|
|
||||||
* ``RegField.r(params.width, gcd)`` "connects" the decoupled handshaking interface ``gcd`` to a read-only memory-mapped register. When this register is read via MMIO, the ``ready`` signal is asserted. This is in turn connected to ``output_ready`` on the Verilog blackbox through the glue logic.
|
|
||||||
* ``RegField.w(params.width, x)`` exposes a plain register (much like those in the PWM example) via MMIO, but makes it write-only.
|
|
||||||
* ``RegField.w(params.width, y)`` associates the decoupled interface signal ``y`` with a write-only memory-mapped register, causing ``y.valid`` to be asserted when the register is written.
|
|
||||||
|
|
||||||
Since the ready/valid signals of ``y`` are connected to the
|
|
||||||
``input_ready`` and ``input_valid`` signals of the blackbox,
|
|
||||||
respectively, this register map and glue logic has the effect of
|
|
||||||
triggering the GCD algorithm when ``y`` is written. Therefore, the
|
|
||||||
algorithm is set up by first writing ``x`` and then performing a
|
|
||||||
triggering write to ``y``. Polling can be used for status checks.
|
|
||||||
|
|
||||||
Defining a Chip with a GCD Peripheral
|
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
As with the PWM example, a few more pieces are needed to tie the system together.
|
Since we've parameterized the GCD instantiation to choose between the
|
||||||
|
Chisel and the verilog module, creating a config is easy.
|
||||||
|
|
||||||
**Composing traits into a complete cake pattern peripheral**
|
.. literalinclude:: ../../generators/example/src/main/scala/RocketConfigs.scala
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/example/src/main/scala/GCDMMIOBlackBox.scala
|
|
||||||
:language: scala
|
:language: scala
|
||||||
:start-after: DOC include start: GCD cake
|
:start-after: DOC include start: GCDAXI4BlackBoxRocketConfig
|
||||||
:end-before: DOC include end: GCD cake
|
:end-before: DOC include end: GCDAXI4BlackBoxRocketConfig
|
||||||
|
|
||||||
Note the differences arising due to the fact that this peripheral has
|
You can play with the parameterization of the mixin to choose a TL/AXI4, BlackBox/Chisel
|
||||||
no top-level IO. To build a complete system, a new ``Top`` and new
|
version of the GCD.
|
||||||
``Config`` objects are added in a manner exactly analogous to the PWM
|
|
||||||
example.
|
|
||||||
|
|
||||||
Software Testing
|
Software Testing
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
The GCD module has a slightly more complex interface, so polling is
|
The GCD module has a more complex interface, so polling is
|
||||||
used to check the status of the device before each triggering read or
|
used to check the status of the device before each triggering read or
|
||||||
write.
|
write.
|
||||||
|
|
||||||
|
|||||||
106
docs/Customization/Keys-Traits-Configs.rst
Normal file
106
docs/Customization/Keys-Traits-Configs.rst
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
.. _keys-traits-configs:
|
||||||
|
|
||||||
|
Keys, Traits, and Configs
|
||||||
|
=========================
|
||||||
|
|
||||||
|
You have probably seen snippets of Chisel referencing Keys, Traits, and Configs by this point.
|
||||||
|
This section aims to elucidate the interactions between these Chisel/Scala components, and provide
|
||||||
|
best practices for how these should be used to create a parameterized design and configure it.
|
||||||
|
|
||||||
|
We will continue to use the GCD example.
|
||||||
|
|
||||||
|
Keys
|
||||||
|
----
|
||||||
|
|
||||||
|
Keys specify some parameter which controls some custom widget. Keys should typically be implemented as **Option types**, with a default value of ``None`` that means no change in the system. In other words, the default behavior when the user does not explicitly set the key should be a no-op.
|
||||||
|
|
||||||
|
Keys should be defined and documented in sub-projects, since they generally deal with some specific block, and not system-level integration. (We make an exception for the example GCD widget).
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/example/src/main/scala/GCD.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: GCD key
|
||||||
|
:end-before: DOC include end: GCD key
|
||||||
|
|
||||||
|
The object within a key is typically a ``case class XXXParams``, which defines a set of parameters which some block accepts. For example, the GCD widget's ``GCDParams`` parameterizes its address, operand widths, whether the widget should be connected by Tilelink or AXI4, and whether the widget should use the blackbox-verilog implementation, or the Chisel implementation.
|
||||||
|
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/example/src/main/scala/GCD.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: GCD params
|
||||||
|
:end-before: DOC include end: GCD params
|
||||||
|
|
||||||
|
Accessing the value stored in the key is easy in Chisel, as long as the ``implicit p: Parameters`` object is being passed through to the relevant module. For example, ``p(GCDKey).get.address`` returns the address field of ``GCDParams``. Note this only works if ``GCDKey`` was not set to ``None``, so your Chisel should check for that case!
|
||||||
|
|
||||||
|
Traits
|
||||||
|
------
|
||||||
|
|
||||||
|
Typically, most custom blocks will need to modify the behavior of some pre-existing block. For example, the GCD widget needs the ``Top`` module to instantiate and connect the widget via Tilelink, generate a top-level ``gcd_busy`` port, and connect that to the module as well. Traits let us do this without modifying the existing code for the ``Top``, and enables compartmentalization of code for different custom blocks.
|
||||||
|
|
||||||
|
Top-level traits specify that the ``Top`` has been parameterized to read some custom Key and optionally instantiate and connect a widget defined by that Key. Traits **should not** mandate the instantiation of custom logic. In other words, traits should be written with ``CanHave`` semantics, where the default behavior when the Key is unset is a no-op.
|
||||||
|
|
||||||
|
Top-level traits should be defined and documented in subprojects, alongside their corresponding Keys. The traits should then be added to the ``Top`` being used by Chipyard.
|
||||||
|
|
||||||
|
Below we see the traits for the GCD example. The Lazy trait connects the GCD module to the Diplomacy graph, while the Implementation trait causes the ``Top`` to instantiate an additional port and concretely connect it to the GCD module.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/example/src/main/scala/GCD.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: GCD lazy trait
|
||||||
|
:end-before: DOC include end: GCD imp trait
|
||||||
|
|
||||||
|
These traits are added to the default ``Top`` in Chipyard.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/example/src/main/scala/Top.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: Top
|
||||||
|
:end-before: DOC include end: Top
|
||||||
|
|
||||||
|
Mixins
|
||||||
|
------
|
||||||
|
|
||||||
|
Mixins set the keys to a non-default value. Together, the collection of Mixins which define a configuration generate the values for all the keys used by the generator.
|
||||||
|
|
||||||
|
For example, the ``WithGCDMixin`` is parameterized by the type of GCD widget you want to instantiate. When this mixin is added to a config, the ``GCDKey`` is set to a instance of ``GCDParams``, informing the previously mentioned traits to instantiate and connect the GCD widget appropriately.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: GCD mixin
|
||||||
|
:end-before: DOC include end: GCD mixin
|
||||||
|
|
||||||
|
We can use this mixin when composing our configs.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/example/src/main/scala/RocketConfigs.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: GCDTLRocketConfig
|
||||||
|
:end-before: DOC include end: GCDTLRocketConfig
|
||||||
|
|
||||||
|
|
||||||
|
BuildTop
|
||||||
|
--------
|
||||||
|
|
||||||
|
The ``BuildTop`` key is special, because sometimes, we need to instantiate ``TestHarness`` modules to interface with a custom widget. The ``BuildTop`` key provides a function which can call some method of the Top to instantiate these ``TestHarness`` modules. Since the ``BuildTop`` key is called from the ``TestHarness``, these modules will appear in the ``TestHarness``. The config system also lets the ``BuildTop`` key look recursively into previous definitions of itself. This enables composability of the ``Top`` configurations.
|
||||||
|
|
||||||
|
For example, conside a config that contains the mixins ``WithGPIO ++ WithTSI``. We need to instantiate the TSI serial adapter, and connect it to the ``success`` signal of our ``TestHarness``. We also need to instantiate the GPIO pins, and tie their inputs to 0 in the ``TestHarness``, since we currently cannot drive the GPIOs in simulation.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: tsi mixin
|
||||||
|
:end-before: DOC include end: tsi mixin
|
||||||
|
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: gpio mixin
|
||||||
|
:end-before: DOC include end: gpio mixin
|
||||||
|
|
||||||
|
When ``WithGPIO ++ WithTSI`` is evaluated right to left, the call to ``up(BuildTop, site)`` in ``WithGPIO`` will reference the function defined in the ``BuildTop`` key of ``WithTSI``. Thus, at elaboration time, when the ``BuildTop`` function is called by the ``TestHarness``, first the ``BuildTop`` function in ``WithTSI`` will be evaluated. This connects the ``success`` signal of the ``TestHarness`` to the ``SerialAdapter`` enabled by ``WithTSI``. Then, the rest of the code in the ``BuildTop`` function of ``WithGPIO`` will execute, tieing off the top-level GPIO input pins. Thus the evaluation of the ``BuildTop`` functions in a completed config is "right-to-left", matching how the evaluation of the mixins at compile-time is also "right-to-left".
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
Note that in some cases, the ordering and duplication of mixins which extend ``BuildTop`` will have unintended consequences.
|
||||||
|
For example, ``WithTSI ++ WithTSI`` will attempt to generate and connect two ``SimSerial`` widgets in the ``TestHarness``,
|
||||||
|
which will likely break the simulation.
|
||||||
|
In general, you should avoid attaching multiple mixins which interface to the same top-level ports.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Readers who want more information on the configuration system may be interested in reading :ref:`cdes`.
|
||||||
|
|
||||||
|
|
||||||
142
docs/Customization/MMIO-Peripherals.rst
Normal file
142
docs/Customization/MMIO-Peripherals.rst
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
.. _mmio-accelerators:
|
||||||
|
|
||||||
|
MMIO Peripherals
|
||||||
|
==================
|
||||||
|
|
||||||
|
The easiest way to create a MMIO peripheral is to use the ``TLRegisterRouter`` or ``AXI4RegisterRouter`` widgets, which abstracts away the details of handling the interconnect protocols and provides a convenient interface for specifying memory-mapped registers. Since Chipyard and Rocket Chip SoCs primarily use Tilelink as the on-chip interconnect protocol, this section will primarily focus on designing Tilelink-based peripherals. However, see ``generators/example/src/main/scala/GCD.scala`` for how an example AXI4 based peripheral is defined and connected to the Tilelink graph through converters.
|
||||||
|
|
||||||
|
To create a RegisterRouter-based peripheral, you will need to specify a parameter case class for the configuration settings, a bundle trait with the extra top-level ports, and a module implementation containing the actual RTL.
|
||||||
|
|
||||||
|
For this example, we will show how to connect a MMIO peripheral which computes the GCD.
|
||||||
|
The full code can be found in ``generators/example/src/main/scala/GCD.scala``.
|
||||||
|
|
||||||
|
In this case we use a submodule ``GCDMMIOChiselModule`` to actually perform the GCD. The ``GCDModule`` class only creates the registers and hooks them up using ``regmap``.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/example/src/main/scala/GCD.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: GCD chisel
|
||||||
|
:end-before: DOC include end: GCD chisel
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/example/src/main/scala/GCD.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: GCD instance regmap
|
||||||
|
:end-before: DOC include end: GCD instance regmap
|
||||||
|
|
||||||
|
Advanced Features of RegField Entries
|
||||||
|
-------------------------------------
|
||||||
|
|
||||||
|
``RegField`` exposes polymorphic ``r`` and ``w`` methods
|
||||||
|
that allow read- and write-only memory-mapped registers to be
|
||||||
|
interfaced to hardware in multiple ways.
|
||||||
|
|
||||||
|
* ``RegField.r(2, status)`` is used to create a 2-bit, read-only register that captures the current value of the ``status`` signal when read.
|
||||||
|
* ``RegField.r(params.width, gcd)`` "connects" the decoupled handshaking interface ``gcd`` to a read-only memory-mapped register. When this register is read via MMIO, the ``ready`` signal is asserted. This is in turn connected to ``output_ready`` on the GCD module through the glue logic.
|
||||||
|
* ``RegField.w(params.width, x)`` exposes a plain register via MMIO, but makes it write-only.
|
||||||
|
* ``RegField.w(params.width, y)`` associates the decoupled interface signal ``y`` with a write-only memory-mapped register, causing ``y.valid`` to be asserted when the register is written.
|
||||||
|
|
||||||
|
Since the ready/valid signals of ``y`` are connected to the
|
||||||
|
``input_ready`` and ``input_valid`` signals of the GCD module,
|
||||||
|
respectively, this register map and glue logic has the effect of
|
||||||
|
triggering the GCD algorithm when ``y`` is written. Therefore, the
|
||||||
|
algorithm is set up by first writing ``x`` and then performing a
|
||||||
|
triggering write to ``y``. Polling can be used for status checks.
|
||||||
|
|
||||||
|
|
||||||
|
Connecting by TileLink
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Once you have these classes, you can construct the final peripheral by extending the ``TLRegisterRouter`` and passing the proper arguments.
|
||||||
|
The first set of arguments determines where the register router will be placed in the global address map and what information will be put in its device tree entry.
|
||||||
|
The second set of arguments is the IO bundle constructor, which we create by extending ``TLRegBundle`` with our bundle trait.
|
||||||
|
The final set of arguments is the module constructor, which we create by extends ``TLRegModule`` with our module trait.
|
||||||
|
Notice how we can create an analogous AXI4 version of our peripheral.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/example/src/main/scala/GCD.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: GCD router
|
||||||
|
:end-before: DOC include end: GCD router
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Top-level Traits
|
||||||
|
----------------
|
||||||
|
|
||||||
|
After creating the module, we need to hook it up to our SoC.
|
||||||
|
Rocket Chip accomplishes this using the cake pattern.
|
||||||
|
This basically involves placing code inside traits.
|
||||||
|
In the Rocket Chip cake, there are two kinds of traits: a ``LazyModule`` trait and a module implementation trait.
|
||||||
|
|
||||||
|
The ``LazyModule`` trait runs setup code that must execute before all the hardware gets elaborated.
|
||||||
|
For a simple memory-mapped peripheral, this just involves connecting the peripheral's TileLink node to the MMIO crossbar.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/example/src/main/scala/GCD.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: GCD lazy trait
|
||||||
|
:end-before: DOC include end: GCD lazy trait
|
||||||
|
|
||||||
|
Note that the ``GCDTL`` class we created from the register router is itself a ``LazyModule``.
|
||||||
|
Register routers have a TileLink node simply named "node", which we can hook up to the Rocket Chip bus.
|
||||||
|
This will automatically add address map and device tree entries for the peripheral.
|
||||||
|
Also observe how we have to place additional AXI4 buffers and converters for the AXI4 version of this peripheral.
|
||||||
|
|
||||||
|
For peripherals which instantiate a concrete module, or which need to be connected to concrete IOs or wires, a matching concrete trait is necessary. We will make our GCD example output a ``gcd_busy`` signal as a top-level port to demonstrate. In the concrete module implementation trait, we instantiate the top level IO (a concrete object) and wire it to the IO of our lazy module.
|
||||||
|
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/example/src/main/scala/GCD.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: GCD imp trait
|
||||||
|
:end-before: DOC include end: GCD imp trait
|
||||||
|
|
||||||
|
Constructing the Top and Config
|
||||||
|
-------------------------------
|
||||||
|
|
||||||
|
Now we want to mix our traits into the system as a whole.
|
||||||
|
This code is from ``generators/example/src/main/scala/Top.scala``.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/example/src/main/scala/Top.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: Top
|
||||||
|
:end-before: DOC include end: Top
|
||||||
|
|
||||||
|
Just as we need separate traits for ``LazyModule`` and module implementation, we need two classes to build the system.
|
||||||
|
The ``Top`` class contains the set of traits which parameterize and define the ``Top``. Typically these traits will optionally add IOs or peripherals to the ``Top``.
|
||||||
|
The ``Top`` class includes the pre-elaboration code and also a ``lazy val`` to produce the module implementation (hence ``LazyModule``).
|
||||||
|
The ``TopModule`` class is the actual RTL that gets synthesized.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
And finally, we create a configuration class in ``generators/example/src/main/scala/Configs.scala`` that uses the ``WithGCD`` mixin defined earlier.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: GCD mixin
|
||||||
|
:end-before: DOC include end: GCD mixin
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/example/src/main/scala/RocketConfigs.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: GCDTLRocketConfig
|
||||||
|
:end-before: DOC include end: GCDTLRocketConfig
|
||||||
|
|
||||||
|
Testing
|
||||||
|
-------
|
||||||
|
|
||||||
|
Now we can test that the GCD is working. The test program is in ``tests/gcd.c``.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../tests/gcd.c
|
||||||
|
:language: c
|
||||||
|
|
||||||
|
This just writes out to the registers we defined earlier.
|
||||||
|
The base of the module's MMIO region is at 0x2000 by default.
|
||||||
|
This will be printed out in the address map portion when you generate the verilog code.
|
||||||
|
You can also see how this changes the emitted ``.json`` addressmap files in ``generated-src``.
|
||||||
|
|
||||||
|
Compiling this program with ``make`` produces a ``gcd.riscv`` executable.
|
||||||
|
|
||||||
|
Now with all of that done, we can go ahead and run our simulation.
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
cd sims/verilator
|
||||||
|
make CONFIG=GCDTLRocketConfig BINARY=../../tests/gcd.riscv run-binary
|
||||||
|
|
||||||
|
|
||||||
70
docs/Customization/RoCC-Accelerators.rst
Normal file
70
docs/Customization/RoCC-Accelerators.rst
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
.. _rocc-accelerators:
|
||||||
|
|
||||||
|
Adding a RoCC Accelerator
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
RoCC accelerators are lazy modules that extend the ``LazyRoCC`` class.
|
||||||
|
Their implementation should extends the ``LazyRoCCModule`` class.
|
||||||
|
|
||||||
|
.. code-block:: scala
|
||||||
|
|
||||||
|
class CustomAccelerator(opcodes: OpcodeSet)
|
||||||
|
(implicit p: Parameters) extends LazyRoCC(opcodes) {
|
||||||
|
override lazy val module = new CustomAcceleratorModule(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
class CustomAcceleratorModule(outer: CustomAccelerator)
|
||||||
|
extends LazyRoCCModuleImp(outer) {
|
||||||
|
val cmd = Queue(io.cmd)
|
||||||
|
// The parts of the command are as follows
|
||||||
|
// inst - the parts of the instruction itself
|
||||||
|
// opcode
|
||||||
|
// rd - destination register number
|
||||||
|
// rs1 - first source register number
|
||||||
|
// rs2 - second source register number
|
||||||
|
// funct
|
||||||
|
// xd - is the destination register being used?
|
||||||
|
// xs1 - is the first source register being used?
|
||||||
|
// xs2 - is the second source register being used?
|
||||||
|
// rs1 - the value of source register 1
|
||||||
|
// rs2 - the value of source register 2
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
The ``opcodes`` parameter for ``LazyRoCC`` is the set of custom opcodes that will map to this accelerator.
|
||||||
|
More on this in the next subsection.
|
||||||
|
|
||||||
|
The ``LazyRoCC`` class contains two TLOutputNode instances, ``atlNode`` and ``tlNode``.
|
||||||
|
The former connects into a tile-local arbiter along with the backside of the L1 instruction cache.
|
||||||
|
The latter connects directly to the L1-L2 crossbar.
|
||||||
|
The corresponding Tilelink ports in the module implementation's IO bundle are ``atl`` and ``tl``, respectively.
|
||||||
|
|
||||||
|
The other interfaces available to the accelerator are ``mem``, which provides access to the L1 cache;
|
||||||
|
``ptw`` which provides access to the page-table walker;
|
||||||
|
the ``busy`` signal, which indicates when the accelerator is still handling an instruction;
|
||||||
|
and the ``interrupt`` signal, which can be used to interrupt the CPU.
|
||||||
|
|
||||||
|
Look at the examples in ``generators/rocket-chip/src/main/scala/tile/LazyRocc.scala`` for detailed information on the different IOs.
|
||||||
|
|
||||||
|
Adding RoCC accelerator to Config
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
RoCC accelerators can be added to a core by overriding the ``BuildRoCC`` parameter in the configuration.
|
||||||
|
This takes a sequence of functions producing ``LazyRoCC`` objects, one for each accelerator you wish to add.
|
||||||
|
|
||||||
|
For instance, if we wanted to add the previously defined accelerator and route custom0 and custom1 instructions to it, we could do the following.
|
||||||
|
|
||||||
|
.. code-block:: scala
|
||||||
|
|
||||||
|
class WithCustomAccelerator extends Config((site, here, up) => {
|
||||||
|
case BuildRoCC => Seq((p: Parameters) => LazyModule(
|
||||||
|
new CustomAccelerator(OpcodeSet.custom0 | OpcodeSet.custom1)(p)))
|
||||||
|
})
|
||||||
|
|
||||||
|
class CustomAcceleratorConfig extends Config(
|
||||||
|
new WithCustomAccelerator ++
|
||||||
|
new RocketConfig)
|
||||||
|
|
||||||
|
To add RoCC instructions in your program, use the RoCC C macros provided in ``tests/rocc.h``. You can find examples in the files ``tests/accum.c`` and ``charcount.c``.
|
||||||
|
|
||||||
27
docs/Customization/RoCC-or-MMIO.rst
Normal file
27
docs/Customization/RoCC-or-MMIO.rst
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
.. _rocc-vs-mmio:
|
||||||
|
|
||||||
|
RoCC vs MMIO
|
||||||
|
------------
|
||||||
|
|
||||||
|
Accelerators or custom IO devices can be added to your SoC in several ways:
|
||||||
|
|
||||||
|
* MMIO Peripheral (a.k.a TileLink-Attached Accelerator)
|
||||||
|
* Tightly-Coupled RoCC Accelerator
|
||||||
|
|
||||||
|
These approaches differ in the method of the communication between the processor and the custom block.
|
||||||
|
|
||||||
|
With the TileLink-Attached approach, the processor communicates with MMIO peripherals through memory-mapped registers.
|
||||||
|
|
||||||
|
In contrast, the processor communicates with a RoCC accelerators through a custom protocol and custom non-standard ISA instructions reserved in the RISC-V ISA encoding space.
|
||||||
|
Each core can have up to four accelerators that are controlled by custom instructions and share resources with the CPU.
|
||||||
|
RoCC coprocessor instructions have the following form.
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
customX rd, rs1, rs2, funct
|
||||||
|
|
||||||
|
The X will be a number 0-3, and determines the opcode of the instruction, which controls which accelerator an instruction will be routed to.
|
||||||
|
The ``rd``, ``rs1``, and ``rs2`` fields are the register numbers of the destination register and two source registers.
|
||||||
|
The ``funct`` field is a 7-bit integer that the accelerator can use to distinguish different instructions from each other.
|
||||||
|
|
||||||
|
Note that communication through a RoCC interface requires a custom software toolchain, whereas MMIO peripherals can use that standard toolchain with appropriate driver support.
|
||||||
@@ -3,18 +3,41 @@ Customization
|
|||||||
|
|
||||||
These guides will walk you through customization of your system-on-chip:
|
These guides will walk you through customization of your system-on-chip:
|
||||||
|
|
||||||
- Contructing heterogenous systems-on-chip using the Chipyard generators and configuration system.
|
- Contructing heterogenous systems-on-chip using the existing Chipyard generators and configuration system.
|
||||||
|
|
||||||
- Adding custom accelerators to your system-on-chip.
|
- How to include your custom Chisel sources in the Chipyard build system
|
||||||
|
|
||||||
Hit next to get started!
|
- Adding custom RoCC accelerators to an existing Chipyard core (BOOM or Rocket)
|
||||||
|
|
||||||
|
- Adding custom MMIO widgets to the Chipyard memory system by Tilelink or AXI4, with custom Top-level IOs
|
||||||
|
|
||||||
|
- Standard practices for using Keys, Traits, and Configs to parameterize your design
|
||||||
|
|
||||||
|
- Customizing the memory hierarchy
|
||||||
|
|
||||||
|
- Connect widgets which act as TileLink masters
|
||||||
|
|
||||||
|
- Adding custom blackboxed verilog to a Chipyard design
|
||||||
|
|
||||||
|
We also provide information on:
|
||||||
|
|
||||||
|
- The boot process for Chipyard SoCs
|
||||||
|
|
||||||
|
- Examples of FIRRTL transforms used in Chipyard, and where they are specified
|
||||||
|
|
||||||
|
We recommend reading all these pages in order. Hit next to get started!
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
:caption: Customization:
|
:caption: Customization:
|
||||||
|
|
||||||
Heterogeneous-SoCs
|
Heterogeneous-SoCs
|
||||||
Adding-An-Accelerator
|
Custom-Chisel
|
||||||
|
RoCC-or-MMIO
|
||||||
|
RoCC-Accelerators
|
||||||
|
MMIO-Peripherals
|
||||||
|
Keys-Traits-Configs
|
||||||
|
DMA-Devices
|
||||||
Incorporating-Verilog-Blocks
|
Incorporating-Verilog-Blocks
|
||||||
Memory-Hierarchy
|
Memory-Hierarchy
|
||||||
Boot-Process
|
Boot-Process
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ The ``software`` directory of the generator includes the aforementioned library
|
|||||||
The Gemmini generator generates a C header file based on the generator parameters. This header files gets compiled together with the matrix multiplication library to tune library performance. The generated header file can be found under ``software/gemmini-rocc-tests/include/gemmini_params.h``
|
The Gemmini generator generates a C header file based on the generator parameters. This header files gets compiled together with the matrix multiplication library to tune library performance. The generated header file can be found under ``software/gemmini-rocc-tests/include/gemmini_params.h``
|
||||||
|
|
||||||
Build and Run Gemmini Tests
|
Build and Run Gemmini Tests
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
To build Gemmini tests:
|
To build Gemmini tests:
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,6 @@ this mixin is shown here:
|
|||||||
:end-before: DOC include end: Sha3Rocket
|
:end-before: DOC include end: Sha3Rocket
|
||||||
|
|
||||||
The SHA3 example baremetal and Linux tests are located in the SHA3 repository.
|
The SHA3 example baremetal and Linux tests are located in the SHA3 repository.
|
||||||
Please refer to its `README.md<https://github.com/ucb-bar/sha3/blob/master/README.md>`__ for more information on how to run/build the tests.
|
Please refer to its `README.md <https://github.com/ucb-bar/sha3/blob/master/README.md>`_ for more information on how to run/build the tests.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,17 +20,11 @@ To integrate one of these devices in your SoC, you will need to define a custom
|
|||||||
|
|
||||||
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
|
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
|
||||||
:language: scala
|
:language: scala
|
||||||
:start-after: DOC include start: WithGPIO
|
:start-after: DOC include start: gpio mixin
|
||||||
:end-before: DOC include end: WithGPIO
|
:end-before: DOC include end: gpio mixin
|
||||||
|
|
||||||
Additionally, if the device requires top-level IOs, you will need to define a mixin to change the top-level configuration of your SoC.
|
Additionally, if the device requires top-level IOs, you will need to define a mixin to change the top-level configuration of your SoC.
|
||||||
When adding a top-level IO, you should also be aware of whether it interacts with the test-harness.
|
When adding a top-level IO, you should also be aware of whether it interacts with the test-harness.
|
||||||
For example, a GPIO device would require a GPIO pin, and therefore we would write a mixin to augment the top level as follows:
|
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
|
|
||||||
:language: scala
|
|
||||||
:start-after: DOC include start: WithGPIOTop
|
|
||||||
:end-before: DOC include end: WithGPIOTop
|
|
||||||
|
|
||||||
This example instantiates a top-level module with include GPIO ports (``TopWithGPIO``), and then ties-off the GPIO port inputs to 0 (``false.B``).
|
This example instantiates a top-level module with include GPIO ports (``TopWithGPIO``), and then ties-off the GPIO port inputs to 0 (``false.B``).
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ This depends on what you are planning to do with Chipyard.
|
|||||||
|
|
||||||
* If you intend to run a full-system FireSim simulation, go to :ref:`firesim-sim-intro` and follow the instructions.
|
* If you intend to run a full-system FireSim simulation, go to :ref:`firesim-sim-intro` and follow the instructions.
|
||||||
|
|
||||||
* If you intend to add a new accelerator, go to :ref:`adding-an-accelerator` and follow the instructions.
|
* If you intend to add a new accelerator, go to :ref:`customization` and follow the instructions.
|
||||||
|
|
||||||
* If you want to learn about the structure of Chipyard, go to :ref:`chipyard-components`.
|
* If you want to learn about the structure of Chipyard, go to :ref:`chipyard-components`.
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ module GCDMMIOBlackBox
|
|||||||
input [WIDTH-1:0] y,
|
input [WIDTH-1:0] y,
|
||||||
input output_ready,
|
input output_ready,
|
||||||
output output_valid,
|
output output_valid,
|
||||||
output reg [WIDTH-1:0] gcd
|
output reg [WIDTH-1:0] gcd,
|
||||||
|
output busy
|
||||||
);
|
);
|
||||||
// DOC include end: GCD portlist
|
// DOC include end: GCD portlist
|
||||||
|
|
||||||
@@ -21,6 +22,7 @@ module GCDMMIOBlackBox
|
|||||||
|
|
||||||
assign input_ready = state == S_IDLE;
|
assign input_ready = state == S_IDLE;
|
||||||
assign output_valid = state == S_DONE;
|
assign output_valid = state == S_DONE;
|
||||||
|
assign busy = state != S_IDLE;
|
||||||
|
|
||||||
always @(posedge clock) begin
|
always @(posedge clock) begin
|
||||||
if (reset)
|
if (reset)
|
||||||
|
|||||||
@@ -9,54 +9,72 @@ import freechips.rocketchip.config.{Config}
|
|||||||
// ---------------------
|
// ---------------------
|
||||||
|
|
||||||
class SmallBoomConfig extends Config(
|
class SmallBoomConfig extends Config(
|
||||||
new WithTop ++ // use normal top
|
new WithTSI ++ // use testchipip serial offchip link
|
||||||
|
new WithNoGPIO ++ // no top-level GPIO pins (overrides default set in sifive-blocks)
|
||||||
new WithBootROM ++ // use testchipip bootrom
|
new WithBootROM ++ // use testchipip bootrom
|
||||||
new WithUART ++ // add a UART
|
new WithUART ++ // add a UART
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++ // no top-level mmio master port (overrides default set in rocketchip)
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level mmio slave port (overrides default set in rocketchip)
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++ // use SiFive L2 cache
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++ // use SiFive L2 cache
|
||||||
new boom.common.WithSmallBooms ++ // 1-wide BOOM
|
new boom.common.WithSmallBooms ++ // 1-wide BOOM
|
||||||
new boom.common.WithNBoomCores(1) ++ // single-core
|
new boom.common.WithNBoomCores(1) ++ // single-core
|
||||||
new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system
|
new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system
|
||||||
|
|
||||||
class MediumBoomConfig extends Config(
|
class MediumBoomConfig extends Config(
|
||||||
new WithTop ++
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new boom.common.WithMediumBooms ++ // 2-wide BOOM
|
new boom.common.WithMediumBooms ++ // 2-wide BOOM
|
||||||
new boom.common.WithNBoomCores(1) ++
|
new boom.common.WithNBoomCores(1) ++
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
|
|
||||||
class LargeBoomConfig extends Config(
|
class LargeBoomConfig extends Config(
|
||||||
new WithTop ++
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new boom.common.WithLargeBooms ++ // 3-wide BOOM
|
new boom.common.WithLargeBooms ++ // 3-wide BOOM
|
||||||
new boom.common.WithNBoomCores(1) ++
|
new boom.common.WithNBoomCores(1) ++
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
|
|
||||||
class MegaBoomConfig extends Config(
|
class MegaBoomConfig extends Config(
|
||||||
new WithTop ++
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new boom.common.WithMegaBooms ++ // 4-wide BOOM
|
new boom.common.WithMegaBooms ++ // 4-wide BOOM
|
||||||
new boom.common.WithNBoomCores(1) ++
|
new boom.common.WithNBoomCores(1) ++
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
|
|
||||||
class DualSmallBoomConfig extends Config(
|
class DualSmallBoomConfig extends Config(
|
||||||
new WithTop ++
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new boom.common.WithSmallBooms ++
|
new boom.common.WithSmallBooms ++
|
||||||
new boom.common.WithNBoomCores(2) ++ // dual-core
|
new boom.common.WithNBoomCores(2) ++ // dual-core
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
|
|
||||||
class SmallRV32BoomConfig extends Config(
|
class SmallRV32BoomConfig extends Config(
|
||||||
new WithTop ++
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new boom.common.WithoutBoomFPU ++ // no fp
|
new boom.common.WithoutBoomFPU ++ // no fp
|
||||||
new boom.common.WithBoomRV32 ++ // rv32 (32bit)
|
new boom.common.WithBoomRV32 ++ // rv32 (32bit)
|
||||||
@@ -65,9 +83,12 @@ class SmallRV32BoomConfig extends Config(
|
|||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
|
|
||||||
class HwachaLargeBoomConfig extends Config(
|
class HwachaLargeBoomConfig extends Config(
|
||||||
new WithTop ++
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new hwacha.DefaultHwachaConfig ++ // use Hwacha vector accelerator
|
new hwacha.DefaultHwachaConfig ++ // use Hwacha vector accelerator
|
||||||
new boom.common.WithLargeBooms ++ // 3-wide BOOM
|
new boom.common.WithLargeBooms ++ // 3-wide BOOM
|
||||||
@@ -75,11 +96,16 @@ class HwachaLargeBoomConfig extends Config(
|
|||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
|
|
||||||
class LoopbackNICBoomConfig extends Config(
|
class LoopbackNICBoomConfig extends Config(
|
||||||
new WithIceNIC ++
|
new WithTSI ++
|
||||||
new WithLoopbackNICTop ++
|
new WithNoGPIO ++
|
||||||
|
new WithLoopbackNIC ++ // loopback the NIC
|
||||||
|
new WithIceNIC ++ // add IceNIC
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new boom.common.WithLargeBooms ++ // 3-wide BOOM
|
new boom.common.WithLargeBooms ++
|
||||||
new boom.common.WithNBoomCores(1) ++
|
new boom.common.WithNBoomCores(1) ++
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,10 @@ import freechips.rocketchip.config.{Field, Parameters, Config}
|
|||||||
import freechips.rocketchip.subsystem.{SystemBusKey, RocketTilesKey, WithRoccExample, WithNMemoryChannels, WithNBigCores, WithRV32, CacheBlockBytes}
|
import freechips.rocketchip.subsystem.{SystemBusKey, RocketTilesKey, WithRoccExample, WithNMemoryChannels, WithNBigCores, WithRV32, CacheBlockBytes}
|
||||||
import freechips.rocketchip.diplomacy.{LazyModule, ValName}
|
import freechips.rocketchip.diplomacy.{LazyModule, ValName}
|
||||||
import freechips.rocketchip.devices.tilelink.BootROMParams
|
import freechips.rocketchip.devices.tilelink.BootROMParams
|
||||||
import freechips.rocketchip.tile.{RocketTileParams, MaxHartIdBits, XLen, BuildRoCC, TileKey, LazyRoCC}
|
import freechips.rocketchip.devices.debug.{Debug}
|
||||||
|
import freechips.rocketchip.tile.{XLen, BuildRoCC, TileKey, LazyRoCC, RocketTileParams, MaxHartIdBits}
|
||||||
import freechips.rocketchip.rocket.{RocketCoreParams, MulDivParams, DCacheParams, ICacheParams}
|
import freechips.rocketchip.rocket.{RocketCoreParams, MulDivParams, DCacheParams, ICacheParams}
|
||||||
|
import freechips.rocketchip.util.{AsyncResetReg}
|
||||||
|
|
||||||
import boom.common.{BoomTilesKey}
|
import boom.common.{BoomTilesKey}
|
||||||
|
|
||||||
@@ -33,23 +35,30 @@ import ConfigValName._
|
|||||||
// Common Parameter Mixins
|
// Common Parameter Mixins
|
||||||
// -----------------------
|
// -----------------------
|
||||||
|
|
||||||
/**
|
|
||||||
* Class to specify where the BootRom file is (from `rebar` top)
|
|
||||||
*/
|
|
||||||
class WithBootROM extends Config((site, here, up) => {
|
class WithBootROM extends Config((site, here, up) => {
|
||||||
case BootROMParams => BootROMParams(
|
case BootROMParams => BootROMParams(
|
||||||
contentFileName = s"./bootrom/bootrom.rv${site(XLen)}.img")
|
contentFileName = s"./bootrom/bootrom.rv${site(XLen)}.img")
|
||||||
})
|
})
|
||||||
|
|
||||||
// DOC include start: WithGPIO
|
// DOC include start: gpio mixin
|
||||||
/**
|
|
||||||
* Class to add in GPIO
|
|
||||||
*/
|
|
||||||
class WithGPIO extends Config((site, here, up) => {
|
class WithGPIO extends Config((site, here, up) => {
|
||||||
case PeripheryGPIOKey => Seq(
|
case PeripheryGPIOKey => Seq(
|
||||||
GPIOParams(address = 0x10012000, width = 4, includeIOF = false))
|
GPIOParams(address = 0x10012000, width = 4, includeIOF = false))
|
||||||
|
case BuildTop => (clock: Clock, reset: Bool, p: Parameters, success: Bool) => {
|
||||||
|
val top = up(BuildTop, site)(clock, reset, p, success)
|
||||||
|
// TODO: Currently FIRRTL will error if the GPIO input
|
||||||
|
// pins are unconnected, so tie them to 0.
|
||||||
|
// In future IO cell blackboxes will replace this with
|
||||||
|
// more correct functionality
|
||||||
|
for (gpio <- top.gpio) {
|
||||||
|
for (pin <- gpio.pins) {
|
||||||
|
pin.i.ival := false.B
|
||||||
|
}
|
||||||
|
}
|
||||||
|
top
|
||||||
|
}
|
||||||
})
|
})
|
||||||
// DOC include end: WithGPIO
|
// DOC include end: gpio mixin
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to add in UART
|
* Class to add in UART
|
||||||
@@ -59,92 +68,58 @@ class WithUART extends Config((site, here, up) => {
|
|||||||
UARTParams(address = 0x54000000L, nTxEntries = 256, nRxEntries = 256))
|
UARTParams(address = 0x54000000L, nTxEntries = 256, nRxEntries = 256))
|
||||||
})
|
})
|
||||||
|
|
||||||
// -----------------------------------------------
|
|
||||||
// BOOM and/or Rocket Top Level System Parameter Mixins
|
|
||||||
// -----------------------------------------------
|
|
||||||
|
|
||||||
/**
|
class WithNoGPIO extends Config((site, here, up) => {
|
||||||
* Class to specify a "plain" top level BOOM and/or Rocket system
|
case PeripheryGPIOKey => Seq()
|
||||||
*/
|
})
|
||||||
class WithTop extends Config((site, here, up) => {
|
|
||||||
case BuildTop => (clock: Clock, reset: Bool, p: Parameters) => {
|
// DOC include start: tsi mixin
|
||||||
Module(LazyModule(new Top()(p)).module)
|
class WithTSI extends Config((site, here, up) => {
|
||||||
|
case SerialKey => true
|
||||||
|
case BuildTop => (clock: Clock, reset: Bool, p: Parameters, success: Bool) => {
|
||||||
|
val top = up(BuildTop, site)(clock, reset, p, success)
|
||||||
|
success := top.connectSimSerial()
|
||||||
|
top
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// DOC include end: tsi mixin
|
||||||
|
|
||||||
|
class WithDTM extends Config((site, here, up) => {
|
||||||
|
case BuildTop => (clock: Clock, reset: Bool, p: Parameters, success: Bool) => {
|
||||||
|
val top = up(BuildTop, site)(clock, reset, p, success)
|
||||||
|
top.reset := reset.asBool | top.debug.map { debug => AsyncResetReg(debug.ndreset) }.getOrElse(false.B)
|
||||||
|
Debug.connectDebug(top.debug, top.psd, clock, reset.asBool, success)(p)
|
||||||
|
top
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
// DOC include start: GCD mixin
|
||||||
* Class to specify a top level BOOM and/or Rocket system with DTM
|
class WithGCD(useAXI4: Boolean, useBlackBox: Boolean) extends Config((site, here, up) => {
|
||||||
*/
|
case GCDKey => Some(GCDParams(useAXI4 = useAXI4, useBlackBox = useBlackBox))
|
||||||
class WithDTMTop extends Config((site, here, up) => {
|
|
||||||
case BuildTopWithDTM => (clock: Clock, reset: Bool, p: Parameters) => {
|
|
||||||
Module(LazyModule(new TopWithDTM()(p)).module)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
// DOC include end: GCD mixin
|
||||||
|
|
||||||
/**
|
class WithBlockDeviceModel extends Config((site, here, up) => {
|
||||||
* Class to specify a top level BOOM and/or Rocket system with PWM
|
case BuildTop => (clock: Clock, reset: Bool, p: Parameters, success: Bool) => {
|
||||||
*/
|
val top = up(BuildTop, site)(clock, reset, p, success)
|
||||||
// DOC include start: WithPWMTop
|
|
||||||
class WithPWMTop extends Config((site, here, up) => {
|
|
||||||
case BuildTop => (clock: Clock, reset: Bool, p: Parameters) =>
|
|
||||||
Module(LazyModule(new TopWithPWMTL()(p)).module)
|
|
||||||
})
|
|
||||||
// DOC include end: WithPWMTop
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class to specify a top level BOOM and/or Rocket system with a PWM AXI4
|
|
||||||
*/
|
|
||||||
class WithPWMAXI4Top extends Config((site, here, up) => {
|
|
||||||
case BuildTop => (clock: Clock, reset: Bool, p: Parameters) =>
|
|
||||||
Module(LazyModule(new TopWithPWMAXI4()(p)).module)
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class to specify a top level BOOM and/or Rocket system with a TL-attached GCD device
|
|
||||||
*/
|
|
||||||
class WithGCDTop extends Config((site, here, up) => {
|
|
||||||
case BuildTop => (clock: Clock, reset: Bool, p: Parameters) =>
|
|
||||||
Module(LazyModule(new TopWithGCD()(p)).module)
|
|
||||||
})
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class to specify a top level BOOM and/or Rocket system with a block device
|
|
||||||
*/
|
|
||||||
class WithBlockDeviceModelTop extends Config((site, here, up) => {
|
|
||||||
case BuildTop => (clock: Clock, reset: Bool, p: Parameters) => {
|
|
||||||
val top = Module(LazyModule(new TopWithBlockDevice()(p)).module)
|
|
||||||
top.connectBlockDeviceModel()
|
top.connectBlockDeviceModel()
|
||||||
top
|
top
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
class WithSimBlockDevice extends Config((site, here, up) => {
|
||||||
* Class to specify a top level BOOM and/or Rocket system with a simulator block device
|
case BuildTop => (clock: Clock, reset: Bool, p: Parameters, success: Bool) => {
|
||||||
*/
|
val top = up(BuildTop, site)(clock, reset, p, success)
|
||||||
class WithSimBlockDeviceTop extends Config((site, here, up) => {
|
|
||||||
case BuildTop => (clock: Clock, reset: Bool, p: Parameters) => {
|
|
||||||
val top = Module(LazyModule(new TopWithBlockDevice()(p)).module)
|
|
||||||
top.connectSimBlockDevice(clock, reset)
|
top.connectSimBlockDevice(clock, reset)
|
||||||
top
|
top
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// DOC include start: WithGPIOTop
|
// DOC include start: WithInitZero
|
||||||
/**
|
class WithInitZero(base: BigInt, size: BigInt) extends Config((site, here, up) => {
|
||||||
* Class to specify a top level BOOM and/or Rocket system with GPIO
|
case InitZeroKey => Some(InitZeroConfig(base, size))
|
||||||
*/
|
|
||||||
class WithGPIOTop extends Config((site, here, up) => {
|
|
||||||
case BuildTop => (clock: Clock, reset: Bool, p: Parameters) => {
|
|
||||||
val top = Module(LazyModule(new TopWithGPIO()(p)).module)
|
|
||||||
for (gpio <- top.gpio) {
|
|
||||||
for (pin <- gpio.pins) {
|
|
||||||
pin.i.ival := false.B
|
|
||||||
}
|
|
||||||
}
|
|
||||||
top
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
// DOC include end: WithGPIOTop
|
// DOC include end: WithInitZero
|
||||||
|
|
||||||
// ------------------
|
// ------------------
|
||||||
// Multi-RoCC Support
|
// Multi-RoCC Support
|
||||||
@@ -184,16 +159,6 @@ class WithMultiRoCCHwacha(harts: Int*) extends Config((site, here, up) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// DOC include start: WithInitZero
|
|
||||||
class WithInitZero(base: BigInt, size: BigInt) extends Config((site, here, up) => {
|
|
||||||
case InitZeroKey => InitZeroConfig(base, size)
|
|
||||||
})
|
|
||||||
|
|
||||||
class WithInitZeroTop extends Config((site, here, up) => {
|
|
||||||
case BuildTop => (clock: Clock, reset: Bool, p: Parameters) =>
|
|
||||||
Module(LazyModule(new TopWithInitZero()(p)).module)
|
|
||||||
})
|
|
||||||
// DOC include end: WithInitZero
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mixin to add a small Rocket core to the system as a "control" core.
|
* Mixin to add a small Rocket core to the system as a "control" core.
|
||||||
@@ -227,15 +192,15 @@ class WithControlCore extends Config((site, here, up) => {
|
|||||||
|
|
||||||
class WithIceNIC(inBufFlits: Int = 1800, usePauser: Boolean = false)
|
class WithIceNIC(inBufFlits: Int = 1800, usePauser: Boolean = false)
|
||||||
extends Config((site, here, up) => {
|
extends Config((site, here, up) => {
|
||||||
case NICKey => NICConfig(
|
case NICKey => Some(NICConfig(
|
||||||
inBufFlits = inBufFlits,
|
inBufFlits = inBufFlits,
|
||||||
usePauser = usePauser,
|
usePauser = usePauser,
|
||||||
checksumOffload = true)
|
checksumOffload = true))
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithLoopbackNICTop extends Config((site, here, up) => {
|
class WithLoopbackNIC extends Config((site, here, up) => {
|
||||||
case BuildTop => (clock: Clock, reset: Bool, p: Parameters) => {
|
case BuildTop => (clock: Clock, reset: Bool, p: Parameters, success: Bool) => {
|
||||||
val top = Module(LazyModule(new TopWithIceNIC()(p)).module)
|
val top = up(BuildTop, site)(clock, reset, p, success)
|
||||||
top.connectNicLoopback()
|
top.connectNicLoopback()
|
||||||
top
|
top
|
||||||
}
|
}
|
||||||
|
|||||||
200
generators/example/src/main/scala/GCD.scala
Normal file
200
generators/example/src/main/scala/GCD.scala
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
package example
|
||||||
|
|
||||||
|
import chisel3._
|
||||||
|
import chisel3.util._
|
||||||
|
import chisel3.experimental.{IntParam, BaseModule}
|
||||||
|
import freechips.rocketchip.amba.axi4._
|
||||||
|
import freechips.rocketchip.subsystem.BaseSubsystem
|
||||||
|
import freechips.rocketchip.config.{Parameters, Field}
|
||||||
|
import freechips.rocketchip.diplomacy._
|
||||||
|
import freechips.rocketchip.regmapper.{HasRegMap, RegField}
|
||||||
|
import freechips.rocketchip.tilelink._
|
||||||
|
import freechips.rocketchip.util.UIntIsOneOf
|
||||||
|
|
||||||
|
// DOC include start: GCD params
|
||||||
|
case class GCDParams(
|
||||||
|
address: BigInt = 0x2000,
|
||||||
|
width: Int = 32,
|
||||||
|
useAXI4: Boolean = false,
|
||||||
|
useBlackBox: Boolean = true)
|
||||||
|
// DOC include end: GCD params
|
||||||
|
|
||||||
|
// DOC include start: GCD key
|
||||||
|
case object GCDKey extends Field[Option[GCDParams]](None)
|
||||||
|
// DOC include end: GCD key
|
||||||
|
|
||||||
|
class GCDIO(val w: Int) extends Bundle {
|
||||||
|
val clock = Input(Clock())
|
||||||
|
val reset = Input(Bool())
|
||||||
|
val input_ready = Output(Bool())
|
||||||
|
val input_valid = Input(Bool())
|
||||||
|
val x = Input(UInt(w.W))
|
||||||
|
val y = Input(UInt(w.W))
|
||||||
|
val output_ready = Input(Bool())
|
||||||
|
val output_valid = Output(Bool())
|
||||||
|
val gcd = Output(UInt(w.W))
|
||||||
|
val busy = Output(Bool())
|
||||||
|
}
|
||||||
|
|
||||||
|
trait GCDTopIO extends Bundle {
|
||||||
|
val gcd_busy = Output(Bool())
|
||||||
|
}
|
||||||
|
|
||||||
|
trait HasGCDIO extends BaseModule {
|
||||||
|
val w: Int
|
||||||
|
val io = IO(new GCDIO(w))
|
||||||
|
}
|
||||||
|
|
||||||
|
// DOC include start: GCD blackbox
|
||||||
|
class GCDMMIOBlackBox(val w: Int) extends BlackBox(Map("WIDTH" -> IntParam(w))) with HasBlackBoxResource
|
||||||
|
with HasGCDIO
|
||||||
|
{
|
||||||
|
addResource("/vsrc/GCDMMIOBlackBox.v")
|
||||||
|
}
|
||||||
|
// DOC include end: GCD blackbox
|
||||||
|
|
||||||
|
// DOC include start: GCD chisel
|
||||||
|
class GCDMMIOChiselModule(val w: Int) extends Module
|
||||||
|
with HasGCDIO
|
||||||
|
{
|
||||||
|
val s_idle :: s_run :: s_done :: Nil = Enum(3)
|
||||||
|
|
||||||
|
val state = RegInit(s_idle)
|
||||||
|
val tmp = Reg(UInt(w.W))
|
||||||
|
val gcd = Reg(UInt(w.W))
|
||||||
|
|
||||||
|
io.input_ready := state === s_idle
|
||||||
|
io.output_valid := state === s_done
|
||||||
|
io.gcd := gcd
|
||||||
|
|
||||||
|
when (state === s_idle && io.input_valid) {
|
||||||
|
state := s_run
|
||||||
|
} .elsewhen (state === s_run && tmp === 0.U) {
|
||||||
|
state := s_done
|
||||||
|
} .elsewhen (state === s_done && io.output_ready) {
|
||||||
|
state := s_idle
|
||||||
|
}
|
||||||
|
|
||||||
|
when (state === s_idle && io.input_valid) {
|
||||||
|
gcd := io.x
|
||||||
|
tmp := io.y
|
||||||
|
} .elsewhen (state === s_run) {
|
||||||
|
when (gcd > tmp) {
|
||||||
|
gcd := gcd - tmp
|
||||||
|
} .otherwise {
|
||||||
|
tmp := tmp - gcd
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
io.busy := state =/= s_idle
|
||||||
|
}
|
||||||
|
// DOC include end: GCD chisel
|
||||||
|
|
||||||
|
// DOC include start: GCD instance regmap
|
||||||
|
|
||||||
|
trait GCDModule extends HasRegMap {
|
||||||
|
val io: GCDTopIO
|
||||||
|
|
||||||
|
implicit val p: Parameters
|
||||||
|
def params: GCDParams
|
||||||
|
val clock: Clock
|
||||||
|
val reset: Reset
|
||||||
|
|
||||||
|
|
||||||
|
// How many clock cycles in a PWM cycle?
|
||||||
|
val x = Reg(UInt(params.width.W))
|
||||||
|
val y = Wire(new DecoupledIO(UInt(params.width.W)))
|
||||||
|
val gcd = Wire(new DecoupledIO(UInt(params.width.W)))
|
||||||
|
val status = Wire(UInt(2.W))
|
||||||
|
|
||||||
|
val impl = if (params.useBlackBox) {
|
||||||
|
Module(new GCDMMIOBlackBox(params.width))
|
||||||
|
} else {
|
||||||
|
Module(new GCDMMIOChiselModule(params.width))
|
||||||
|
}
|
||||||
|
|
||||||
|
impl.io.clock := clock
|
||||||
|
impl.io.reset := reset.asBool
|
||||||
|
|
||||||
|
impl.io.x := x
|
||||||
|
impl.io.y := y.bits
|
||||||
|
impl.io.input_valid := y.valid
|
||||||
|
y.ready := impl.io.input_ready
|
||||||
|
|
||||||
|
gcd.bits := impl.io.gcd
|
||||||
|
gcd.valid := impl.io.output_valid
|
||||||
|
impl.io.output_ready := gcd.ready
|
||||||
|
|
||||||
|
status := Cat(impl.io.input_ready, impl.io.output_ready)
|
||||||
|
io.gcd_busy := impl.io.busy
|
||||||
|
|
||||||
|
regmap(
|
||||||
|
0x00 -> Seq(
|
||||||
|
RegField.r(2, status)), // a read-only register capturing current status
|
||||||
|
0x04 -> Seq(
|
||||||
|
RegField.w(params.width, x)), // a plain, write-only register
|
||||||
|
0x08 -> Seq(
|
||||||
|
RegField.w(params.width, y)), // write-only, y.valid is set on write
|
||||||
|
0x0C -> Seq(
|
||||||
|
RegField.r(params.width, gcd))) // read-only, gcd.ready is set on read
|
||||||
|
}
|
||||||
|
// DOC include end: GCD instance regmap
|
||||||
|
|
||||||
|
// DOC include start: GCD router
|
||||||
|
class GCDTL(params: GCDParams, beatBytes: Int)(implicit p: Parameters)
|
||||||
|
extends TLRegisterRouter(
|
||||||
|
params.address, "gcd", Seq("ucbbar,gcd"),
|
||||||
|
beatBytes = beatBytes)(
|
||||||
|
new TLRegBundle(params, _) with GCDTopIO)(
|
||||||
|
new TLRegModule(params, _, _) with GCDModule)
|
||||||
|
|
||||||
|
class GCDAXI4(params: GCDParams, beatBytes: Int)(implicit p: Parameters)
|
||||||
|
extends AXI4RegisterRouter(
|
||||||
|
params.address,
|
||||||
|
beatBytes=beatBytes)(
|
||||||
|
new AXI4RegBundle(params, _) with GCDTopIO)(
|
||||||
|
new AXI4RegModule(params, _, _) with GCDModule)
|
||||||
|
// DOC include end: GCD router
|
||||||
|
|
||||||
|
// DOC include start: GCD lazy trait
|
||||||
|
trait CanHavePeripheryGCD { this: BaseSubsystem =>
|
||||||
|
private val portName = "gcd"
|
||||||
|
|
||||||
|
// Only build if we are using the TL (nonAXI4) version
|
||||||
|
val gcd = p(GCDKey) match {
|
||||||
|
case Some(params) => {
|
||||||
|
if (params.useAXI4) {
|
||||||
|
val gcd = LazyModule(new GCDAXI4(params, pbus.beatBytes)(p))
|
||||||
|
pbus.toSlave(Some(portName)) {
|
||||||
|
gcd.node :=
|
||||||
|
AXI4Buffer () :=
|
||||||
|
TLToAXI4 () :=
|
||||||
|
// toVariableWidthSlave doesn't use holdFirstDeny, which TLToAXI4() needsx
|
||||||
|
TLFragmenter(pbus.beatBytes, pbus.blockBytes, holdFirstDeny = true)
|
||||||
|
}
|
||||||
|
Some(gcd)
|
||||||
|
} else {
|
||||||
|
val gcd = LazyModule(new GCDTL(params, pbus.beatBytes)(p))
|
||||||
|
pbus.toVariableWidthSlave(Some(portName)) { gcd.node }
|
||||||
|
Some(gcd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case None => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// DOC include end: GCD lazy trait
|
||||||
|
|
||||||
|
// DOC include start: GCD imp trait
|
||||||
|
trait CanHavePeripheryGCDModuleImp extends LazyModuleImp {
|
||||||
|
val outer: CanHavePeripheryGCD
|
||||||
|
val gcd_busy = outer.gcd match {
|
||||||
|
case Some(gcd) => {
|
||||||
|
val busy = IO(Output(Bool()))
|
||||||
|
busy := gcd.module.io.gcd_busy
|
||||||
|
Some(busy)
|
||||||
|
}
|
||||||
|
case None => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DOC include end: GCD imp trait
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
package example
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
import chisel3.core.{IntParam, Reset}
|
|
||||||
import freechips.rocketchip.amba.axi4._
|
|
||||||
import freechips.rocketchip.subsystem.BaseSubsystem
|
|
||||||
import freechips.rocketchip.config.{Parameters, Field}
|
|
||||||
import freechips.rocketchip.diplomacy._
|
|
||||||
import freechips.rocketchip.regmapper.{HasRegMap, RegField}
|
|
||||||
import freechips.rocketchip.tilelink._
|
|
||||||
import freechips.rocketchip.util.UIntIsOneOf
|
|
||||||
|
|
||||||
// DOC include start: GCD blackbox
|
|
||||||
class GCDMMIOBlackBox(w: Int) extends BlackBox(Map("WIDTH" -> IntParam(w))) with HasBlackBoxResource {
|
|
||||||
val io = IO(new Bundle {
|
|
||||||
val clock = Input(Clock())
|
|
||||||
val reset = Input(Bool())
|
|
||||||
val input_ready = Output(Bool())
|
|
||||||
val input_valid = Input(Bool())
|
|
||||||
val x = Input(UInt(w.W))
|
|
||||||
val y = Input(UInt(w.W))
|
|
||||||
val output_ready = Input(Bool())
|
|
||||||
val output_valid = Output(Bool())
|
|
||||||
val gcd = Output(UInt(w.W))
|
|
||||||
})
|
|
||||||
|
|
||||||
addResource("/vsrc/GCDMMIOBlackBox.v")
|
|
||||||
}
|
|
||||||
// DOC include end: GCD blackbox
|
|
||||||
|
|
||||||
// DOC include start: GCD instance regmap
|
|
||||||
case class GCDParams(address: BigInt, beatBytes: Int, width: Int)
|
|
||||||
|
|
||||||
trait GCDModule extends HasRegMap {
|
|
||||||
implicit val p: Parameters
|
|
||||||
def params: GCDParams
|
|
||||||
val clock: Clock
|
|
||||||
val reset: Reset
|
|
||||||
|
|
||||||
val impl = Module(new GCDMMIOBlackBox(params.width))
|
|
||||||
|
|
||||||
// How many clock cycles in a PWM cycle?
|
|
||||||
val x = Reg(UInt(params.width.W))
|
|
||||||
val y = Wire(new DecoupledIO(impl.io.y))
|
|
||||||
val gcd = Wire(new DecoupledIO(impl.io.gcd))
|
|
||||||
val status = Cat(impl.io.input_ready, impl.io.output_valid)
|
|
||||||
|
|
||||||
impl.io.clock := clock
|
|
||||||
impl.io.reset := reset.asBool
|
|
||||||
impl.io.x := x
|
|
||||||
impl.io.y := y.bits
|
|
||||||
impl.io.input_valid := y.valid
|
|
||||||
y.ready := impl.io.input_ready
|
|
||||||
|
|
||||||
gcd.bits := impl.io.gcd
|
|
||||||
gcd.valid := impl.io.output_valid
|
|
||||||
impl.io.output_ready := gcd.ready
|
|
||||||
|
|
||||||
regmap(
|
|
||||||
0x00 -> Seq(
|
|
||||||
RegField.r(2, status)), // a read-only register capturing current status
|
|
||||||
0x04 -> Seq(
|
|
||||||
RegField.w(params.width, x)), // a plain, write-only register
|
|
||||||
0x08 -> Seq(
|
|
||||||
RegField.w(params.width, y)), // write-only, y.valid is set on write
|
|
||||||
0x0C -> Seq(
|
|
||||||
RegField.r(params.width, gcd))) // read-only, gcd.ready is set on read
|
|
||||||
}
|
|
||||||
// DOC include end: GCD instance regmap
|
|
||||||
|
|
||||||
// DOC include start: GCD cake
|
|
||||||
class GCD(c: GCDParams)(implicit p: Parameters)
|
|
||||||
extends TLRegisterRouter(
|
|
||||||
c.address, "gcd", Seq("ucbbar,gcd"),
|
|
||||||
beatBytes = c.beatBytes)(
|
|
||||||
new TLRegBundle(c, _))(
|
|
||||||
new TLRegModule(c, _, _) with GCDModule)
|
|
||||||
|
|
||||||
trait HasPeripheryGCD { this: BaseSubsystem =>
|
|
||||||
implicit val p: Parameters
|
|
||||||
|
|
||||||
private val address = 0x2000
|
|
||||||
private val portName = "gcd"
|
|
||||||
private val gcdWidth = 32
|
|
||||||
|
|
||||||
val gcd = LazyModule(new GCD(
|
|
||||||
GCDParams(address, pbus.beatBytes, gcdWidth))(p))
|
|
||||||
|
|
||||||
pbus.toVariableWidthSlave(Some(portName)) { gcd.node }
|
|
||||||
}
|
|
||||||
|
|
||||||
trait HasPeripheryGCDModuleImp extends LazyModuleImp {
|
|
||||||
implicit val p: Parameters
|
|
||||||
val outer: HasPeripheryGCD
|
|
||||||
}
|
|
||||||
|
|
||||||
// DOC include end: GCD cake
|
|
||||||
@@ -9,10 +9,13 @@ import freechips.rocketchip.config.{Config}
|
|||||||
// ---------------------
|
// ---------------------
|
||||||
|
|
||||||
class LargeBoomAndRocketConfig extends Config(
|
class LargeBoomAndRocketConfig extends Config(
|
||||||
new WithTop ++ // default top
|
new WithTSI ++ // use testchipip serial offchip link
|
||||||
|
new WithNoGPIO ++ // no top-level GPIO pins (overrides default set in sifive-blocks)
|
||||||
new WithBootROM ++ // default bootrom
|
new WithBootROM ++ // default bootrom
|
||||||
new WithUART ++ // add a UART
|
new WithUART ++ // add a UART
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++ // use SiFive l2
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++ // use SiFive l2
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++ // no top-level MMIO master port (overrides default set in rocketchip)
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level MMIO slave port (overrides default set in rocketchip)
|
||||||
new boom.common.WithRenumberHarts ++ // avoid hartid overlap
|
new boom.common.WithRenumberHarts ++ // avoid hartid overlap
|
||||||
new boom.common.WithLargeBooms ++ // 3-wide boom
|
new boom.common.WithLargeBooms ++ // 3-wide boom
|
||||||
new boom.common.WithNBoomCores(1) ++ // single-core boom
|
new boom.common.WithNBoomCores(1) ++ // single-core boom
|
||||||
@@ -20,10 +23,13 @@ class LargeBoomAndRocketConfig extends Config(
|
|||||||
new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system
|
new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system
|
||||||
|
|
||||||
class SmallBoomAndRocketConfig extends Config(
|
class SmallBoomAndRocketConfig extends Config(
|
||||||
new WithTop ++
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new boom.common.WithRenumberHarts ++
|
new boom.common.WithRenumberHarts ++
|
||||||
new boom.common.WithSmallBooms ++ // 1-wide boom
|
new boom.common.WithSmallBooms ++ // 1-wide boom
|
||||||
new boom.common.WithNBoomCores(1) ++
|
new boom.common.WithNBoomCores(1) ++
|
||||||
@@ -32,11 +38,14 @@ class SmallBoomAndRocketConfig extends Config(
|
|||||||
|
|
||||||
// DOC include start: BoomAndRocketWithHwacha
|
// DOC include start: BoomAndRocketWithHwacha
|
||||||
class HwachaLargeBoomAndHwachaRocketConfig extends Config(
|
class HwachaLargeBoomAndHwachaRocketConfig extends Config(
|
||||||
new WithTop ++
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
new hwacha.DefaultHwachaConfig ++ // add hwacha to all harts
|
new hwacha.DefaultHwachaConfig ++ // add hwacha to all harts
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new boom.common.WithRenumberHarts ++
|
new boom.common.WithRenumberHarts ++
|
||||||
new boom.common.WithLargeBooms ++
|
new boom.common.WithLargeBooms ++
|
||||||
new boom.common.WithNBoomCores(1) ++
|
new boom.common.WithNBoomCores(1) ++
|
||||||
@@ -45,10 +54,13 @@ class HwachaLargeBoomAndHwachaRocketConfig extends Config(
|
|||||||
// DOC include end: BoomAndRocketWithHwacha
|
// DOC include end: BoomAndRocketWithHwacha
|
||||||
|
|
||||||
class RoccLargeBoomAndRoccRocketConfig extends Config(
|
class RoccLargeBoomAndRoccRocketConfig extends Config(
|
||||||
new WithTop ++
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
new freechips.rocketchip.subsystem.WithRoccExample ++ // add example rocc accelerator to all harts
|
new freechips.rocketchip.subsystem.WithRoccExample ++ // add example rocc accelerator to all harts
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new boom.common.WithRenumberHarts ++
|
new boom.common.WithRenumberHarts ++
|
||||||
new boom.common.WithLargeBooms ++
|
new boom.common.WithLargeBooms ++
|
||||||
@@ -57,9 +69,12 @@ class RoccLargeBoomAndRoccRocketConfig extends Config(
|
|||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
|
|
||||||
class DualLargeBoomAndRocketConfig extends Config(
|
class DualLargeBoomAndRocketConfig extends Config(
|
||||||
new WithTop ++
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new boom.common.WithRenumberHarts ++
|
new boom.common.WithRenumberHarts ++
|
||||||
new boom.common.WithLargeBooms ++
|
new boom.common.WithLargeBooms ++
|
||||||
@@ -69,10 +84,13 @@ class DualLargeBoomAndRocketConfig extends Config(
|
|||||||
|
|
||||||
// DOC include start: DualBoomAndRocketOneHwacha
|
// DOC include start: DualBoomAndRocketOneHwacha
|
||||||
class DualLargeBoomAndHwachaRocketConfig extends Config(
|
class DualLargeBoomAndHwachaRocketConfig extends Config(
|
||||||
new WithTop ++
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new WithMultiRoCC ++ // support heterogeneous rocc
|
new WithMultiRoCC ++ // support heterogeneous rocc
|
||||||
new WithMultiRoCCHwacha(2) ++ // put hwacha on hart-2 (rocket)
|
new WithMultiRoCCHwacha(2) ++ // put hwacha on hart-2 (rocket)
|
||||||
new boom.common.WithRenumberHarts ++
|
new boom.common.WithRenumberHarts ++
|
||||||
@@ -83,10 +101,13 @@ class DualLargeBoomAndHwachaRocketConfig extends Config(
|
|||||||
// DOC include end: DualBoomAndRocketOneHwacha
|
// DOC include end: DualBoomAndRocketOneHwacha
|
||||||
|
|
||||||
class LargeBoomAndRV32RocketConfig extends Config(
|
class LargeBoomAndRV32RocketConfig extends Config(
|
||||||
new WithTop ++
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new boom.common.WithRenumberHarts ++
|
new boom.common.WithRenumberHarts ++
|
||||||
new boom.common.WithLargeBooms ++
|
new boom.common.WithLargeBooms ++
|
||||||
new boom.common.WithNBoomCores(1) ++
|
new boom.common.WithNBoomCores(1) ++
|
||||||
@@ -96,10 +117,13 @@ class LargeBoomAndRV32RocketConfig extends Config(
|
|||||||
|
|
||||||
// DOC include start: DualBoomAndRocket
|
// DOC include start: DualBoomAndRocket
|
||||||
class DualLargeBoomAndDualRocketConfig extends Config(
|
class DualLargeBoomAndDualRocketConfig extends Config(
|
||||||
new WithTop ++
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new boom.common.WithRenumberHarts ++
|
new boom.common.WithRenumberHarts ++
|
||||||
new boom.common.WithLargeBooms ++
|
new boom.common.WithLargeBooms ++
|
||||||
new boom.common.WithNBoomCores(2) ++ // 2 boom cores
|
new boom.common.WithNBoomCores(2) ++ // 2 boom cores
|
||||||
@@ -108,10 +132,13 @@ class DualLargeBoomAndDualRocketConfig extends Config(
|
|||||||
// DOC include end: DualBoomAndRocket
|
// DOC include end: DualBoomAndRocket
|
||||||
|
|
||||||
class MultiCoreWithControlCoreConfig extends Config(
|
class MultiCoreWithControlCoreConfig extends Config(
|
||||||
new WithTop ++
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new WithControlCore ++ // add small control core (last hartid)
|
new WithControlCore ++ // add small control core (last hartid)
|
||||||
new boom.common.WithRenumberHarts ++
|
new boom.common.WithRenumberHarts ++
|
||||||
new boom.common.WithLargeBooms ++
|
new boom.common.WithLargeBooms ++
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, IdRange}
|
|||||||
import testchipip.TLHelper
|
import testchipip.TLHelper
|
||||||
|
|
||||||
case class InitZeroConfig(base: BigInt, size: BigInt)
|
case class InitZeroConfig(base: BigInt, size: BigInt)
|
||||||
case object InitZeroKey extends Field[InitZeroConfig]
|
case object InitZeroKey extends Field[Option[InitZeroConfig]](None)
|
||||||
|
|
||||||
class InitZero(implicit p: Parameters) extends LazyModule {
|
class InitZero(implicit p: Parameters) extends LazyModule {
|
||||||
val node = TLHelper.makeClientNode(
|
val node = TLHelper.makeClientNode(
|
||||||
@@ -18,7 +18,7 @@ class InitZero(implicit p: Parameters) extends LazyModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class InitZeroModuleImp(outer: InitZero) extends LazyModuleImp(outer) {
|
class InitZeroModuleImp(outer: InitZero) extends LazyModuleImp(outer) {
|
||||||
val config = p(InitZeroKey)
|
val config = p(InitZeroKey).get
|
||||||
|
|
||||||
val (mem, edge) = outer.node.out(0)
|
val (mem, edge) = outer.node.out(0)
|
||||||
val addrBits = edge.bundle.addressBits
|
val addrBits = edge.bundle.addressBits
|
||||||
@@ -57,13 +57,11 @@ class InitZeroModuleImp(outer: InitZero) extends LazyModuleImp(outer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasPeripheryInitZero { this: BaseSubsystem =>
|
trait CanHavePeripheryInitZero { this: BaseSubsystem =>
|
||||||
implicit val p: Parameters
|
implicit val p: Parameters
|
||||||
|
|
||||||
val initZero = LazyModule(new InitZero()(p))
|
p(InitZeroKey) .map { k =>
|
||||||
fbus.fromPort(Some("init-zero"))() := initZero.node
|
val initZero = LazyModule(new InitZero()(p))
|
||||||
}
|
fbus.fromPort(Some("init-zero"))() := initZero.node
|
||||||
|
}
|
||||||
trait HasPeripheryInitZeroModuleImp extends LazyModuleImp {
|
|
||||||
// Don't need anything here
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,134 +0,0 @@
|
|||||||
package example
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.util._
|
|
||||||
import freechips.rocketchip.amba.axi4._
|
|
||||||
import freechips.rocketchip.subsystem.BaseSubsystem
|
|
||||||
import freechips.rocketchip.config.{Parameters, Field}
|
|
||||||
import freechips.rocketchip.diplomacy._
|
|
||||||
import freechips.rocketchip.regmapper.{HasRegMap, RegField}
|
|
||||||
import freechips.rocketchip.tilelink._
|
|
||||||
import freechips.rocketchip.util.UIntIsOneOf
|
|
||||||
|
|
||||||
// DOC include start: PWM generic traits
|
|
||||||
case class PWMParams(address: BigInt, beatBytes: Int)
|
|
||||||
|
|
||||||
class PWMBase(w: Int) extends Module {
|
|
||||||
val io = IO(new Bundle {
|
|
||||||
val pwmout = Output(Bool())
|
|
||||||
val period = Input(UInt(w.W))
|
|
||||||
val duty = Input(UInt(w.W))
|
|
||||||
val enable = Input(Bool())
|
|
||||||
})
|
|
||||||
|
|
||||||
// The counter should count up until period is reached
|
|
||||||
val counter = Reg(UInt(w.W))
|
|
||||||
|
|
||||||
when (counter >= (io.period - 1.U)) {
|
|
||||||
counter := 0.U
|
|
||||||
} .otherwise {
|
|
||||||
counter := counter + 1.U
|
|
||||||
}
|
|
||||||
|
|
||||||
// If PWM is enabled, pwmout is high when counter < duty
|
|
||||||
// If PWM is not enabled, it will always be low
|
|
||||||
io.pwmout := io.enable && (counter < io.duty)
|
|
||||||
}
|
|
||||||
|
|
||||||
trait PWMBundle extends Bundle {
|
|
||||||
val pwmout = Output(Bool())
|
|
||||||
}
|
|
||||||
|
|
||||||
trait PWMModule extends HasRegMap {
|
|
||||||
val io: PWMBundle
|
|
||||||
implicit val p: Parameters
|
|
||||||
def params: PWMParams
|
|
||||||
|
|
||||||
// How many clock cycles in a PWM cycle?
|
|
||||||
val period = Reg(UInt(32.W))
|
|
||||||
// For how many cycles should the clock be high?
|
|
||||||
val duty = Reg(UInt(32.W))
|
|
||||||
// Is the PWM even running at all?
|
|
||||||
val enable = RegInit(false.B)
|
|
||||||
|
|
||||||
val base = Module(new PWMBase(32))
|
|
||||||
io.pwmout := base.io.pwmout
|
|
||||||
base.io.period := period
|
|
||||||
base.io.duty := duty
|
|
||||||
base.io.enable := enable
|
|
||||||
|
|
||||||
regmap(
|
|
||||||
0x00 -> Seq(
|
|
||||||
RegField(32, period)),
|
|
||||||
0x04 -> Seq(
|
|
||||||
RegField(32, duty)),
|
|
||||||
0x08 -> Seq(
|
|
||||||
RegField(1, enable)))
|
|
||||||
}
|
|
||||||
// DOC include end: PWM generic traits
|
|
||||||
|
|
||||||
// DOC include start: PWMTL
|
|
||||||
class PWMTL(c: PWMParams)(implicit p: Parameters)
|
|
||||||
extends TLRegisterRouter(
|
|
||||||
c.address, "pwm", Seq("ucbbar,pwm"),
|
|
||||||
beatBytes = c.beatBytes)(
|
|
||||||
new TLRegBundle(c, _) with PWMBundle)(
|
|
||||||
new TLRegModule(c, _, _) with PWMModule)
|
|
||||||
// DOC include end: PWMTL
|
|
||||||
|
|
||||||
class PWMAXI4(c: PWMParams)(implicit p: Parameters)
|
|
||||||
extends AXI4RegisterRouter(c.address, beatBytes = c.beatBytes)(
|
|
||||||
new AXI4RegBundle(c, _) with PWMBundle)(
|
|
||||||
new AXI4RegModule(c, _, _) with PWMModule)
|
|
||||||
|
|
||||||
// DOC include start: HasPeripheryPWMTL
|
|
||||||
trait HasPeripheryPWMTL { this: BaseSubsystem =>
|
|
||||||
implicit val p: Parameters
|
|
||||||
|
|
||||||
private val address = 0x2000
|
|
||||||
private val portName = "pwm"
|
|
||||||
|
|
||||||
val pwm = LazyModule(new PWMTL(
|
|
||||||
PWMParams(address, pbus.beatBytes))(p))
|
|
||||||
|
|
||||||
pbus.toVariableWidthSlave(Some(portName)) { pwm.node }
|
|
||||||
}
|
|
||||||
// DOC include end: HasPeripheryPWMTL
|
|
||||||
|
|
||||||
// DOC include start: HasPeripheryPWMTLModuleImp
|
|
||||||
trait HasPeripheryPWMTLModuleImp extends LazyModuleImp {
|
|
||||||
implicit val p: Parameters
|
|
||||||
val outer: HasPeripheryPWMTL
|
|
||||||
|
|
||||||
val pwmout = IO(Output(Bool()))
|
|
||||||
|
|
||||||
pwmout := outer.pwm.module.io.pwmout
|
|
||||||
}
|
|
||||||
// DOC include end: HasPeripheryPWMTLModuleImp
|
|
||||||
|
|
||||||
trait HasPeripheryPWMAXI4 { this: BaseSubsystem =>
|
|
||||||
implicit val p: Parameters
|
|
||||||
|
|
||||||
private val address = 0x2000
|
|
||||||
private val portName = "pwm"
|
|
||||||
|
|
||||||
val pwm = LazyModule(new PWMAXI4(
|
|
||||||
PWMParams(address, pbus.beatBytes))(p))
|
|
||||||
|
|
||||||
pbus.toSlave(Some(portName)) {
|
|
||||||
pwm.node :=
|
|
||||||
AXI4Buffer () :=
|
|
||||||
TLToAXI4() :=
|
|
||||||
// toVariableWidthSlave doesn't use holdFirstDeny, which TLToAXI4() needs
|
|
||||||
TLFragmenter(pbus.beatBytes, pbus.blockBytes, holdFirstDeny = true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait HasPeripheryPWMAXI4ModuleImp extends LazyModuleImp {
|
|
||||||
implicit val p: Parameters
|
|
||||||
val outer: HasPeripheryPWMAXI4
|
|
||||||
|
|
||||||
val pwmout = IO(Output(Bool()))
|
|
||||||
|
|
||||||
pwmout := outer.pwm.module.io.pwmout
|
|
||||||
}
|
|
||||||
@@ -9,17 +9,23 @@ import freechips.rocketchip.config.{Config}
|
|||||||
// --------------
|
// --------------
|
||||||
|
|
||||||
class RocketConfig extends Config(
|
class RocketConfig extends Config(
|
||||||
new WithTop ++ // use default top
|
new WithTSI ++ // use testchipip serial offchip link
|
||||||
|
new WithNoGPIO ++ // no top-level GPIO pins (overrides default set in sifive-blocks)
|
||||||
new WithBootROM ++ // use default bootrom
|
new WithBootROM ++ // use default bootrom
|
||||||
new WithUART ++ // add a UART
|
new WithUART ++ // add a UART
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++ // no top-level MMIO master port (overrides default set in rocketchip)
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level MMIO slave port (overrides default set in rocketchip)
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++ // use Sifive L2 cache
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++ // use Sifive L2 cache
|
||||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // single rocket-core
|
new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // single rocket-core
|
||||||
new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system
|
new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system
|
||||||
|
|
||||||
class HwachaRocketConfig extends Config(
|
class HwachaRocketConfig extends Config(
|
||||||
new WithTop ++
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new hwacha.DefaultHwachaConfig ++ // use Hwacha vector accelerator
|
new hwacha.DefaultHwachaConfig ++ // use Hwacha vector accelerator
|
||||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||||
@@ -27,9 +33,12 @@ class HwachaRocketConfig extends Config(
|
|||||||
|
|
||||||
// DOC include start: GemminiRocketConfig
|
// DOC include start: GemminiRocketConfig
|
||||||
class GemminiRocketConfig extends Config(
|
class GemminiRocketConfig extends Config(
|
||||||
new WithTop ++
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new gemmini.DefaultGemminiConfig ++ // use Gemmini systolic array GEMM accelerator
|
new gemmini.DefaultGemminiConfig ++ // use Gemmini systolic array GEMM accelerator
|
||||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||||
@@ -37,9 +46,12 @@ class GemminiRocketConfig extends Config(
|
|||||||
// DOC include end: GemminiRocketConfig
|
// DOC include end: GemminiRocketConfig
|
||||||
|
|
||||||
class RoccRocketConfig extends Config(
|
class RoccRocketConfig extends Config(
|
||||||
new WithTop ++
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new freechips.rocketchip.subsystem.WithRoccExample ++ // use example RoCC-based accelerator
|
new freechips.rocketchip.subsystem.WithRoccExample ++ // use example RoCC-based accelerator
|
||||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||||
@@ -47,10 +59,13 @@ class RoccRocketConfig extends Config(
|
|||||||
|
|
||||||
// DOC include start: JtagRocket
|
// DOC include start: JtagRocket
|
||||||
class jtagRocketConfig extends Config(
|
class jtagRocketConfig extends Config(
|
||||||
new WithDTMTop ++ // use top with dtm
|
new WithDTM ++ // use top with dtm
|
||||||
new freechips.rocketchip.subsystem.WithJtagDTM ++ // add jtag+DTM module to coreplex
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new freechips.rocketchip.subsystem.WithJtagDTM ++ // enable communicating with the DTM using jtag
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
@@ -58,100 +73,127 @@ class jtagRocketConfig extends Config(
|
|||||||
|
|
||||||
// DOC include start: DmiRocket
|
// DOC include start: DmiRocket
|
||||||
class dmiRocketConfig extends Config(
|
class dmiRocketConfig extends Config(
|
||||||
new WithDTMTop ++ // use top with dtm
|
new WithDTM ++ // use top with dtm
|
||||||
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
// DOC include end: DmiRocket
|
// DOC include end: DmiRocket
|
||||||
|
|
||||||
// DOC include start: PWMRocketConfig
|
// DOC include start: GCDTLRocketConfig
|
||||||
class PWMRocketConfig extends Config(
|
class GCDTLRocketConfig extends Config(
|
||||||
new WithPWMTop ++ // use top with tilelink-controlled PWM
|
new WithTSI ++
|
||||||
new WithBootROM ++
|
new WithNoGPIO ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new WithGCD(useAXI4=false, useBlackBox=false) ++ // Use GCD Chisel, connect Tilelink
|
||||||
|
new WithBootROM ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
// DOC include end: PWMRocketConfig
|
// DOC include end: GCDTLRocketConfig
|
||||||
|
|
||||||
class PWMAXI4RocketConfig extends Config(
|
// DOC include start: GCDAXI4BlackBoxRocketConfig
|
||||||
new WithPWMAXI4Top ++ // use top with axi4-controlled PWM
|
class GCDAXI4BlackBoxRocketConfig extends Config(
|
||||||
new WithBootROM ++
|
new WithTSI ++
|
||||||
new WithUART ++
|
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
|
||||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
|
||||||
|
|
||||||
class GCDRocketConfig extends Config( // add MMIO GCD module
|
|
||||||
new WithGCDTop ++
|
|
||||||
new WithBootROM ++
|
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new WithNoGPIO ++
|
||||||
|
new WithGCD(useAXI4=true, useBlackBox=true) ++ // Use GCD blackboxed verilog, connect by AXI4->Tilelink
|
||||||
|
new WithBootROM ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
|
// DOC include end: GCDAXI4BlackBoxRocketConfig
|
||||||
|
|
||||||
class SimBlockDeviceRocketConfig extends Config(
|
class SimBlockDeviceRocketConfig extends Config(
|
||||||
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new testchipip.WithBlockDevice ++ // add block-device module to peripherybus
|
new testchipip.WithBlockDevice ++ // add block-device module to peripherybus
|
||||||
new WithSimBlockDeviceTop ++ // use top with block-device IOs and connect to simblockdevice
|
new WithSimBlockDevice ++ // use top with block-device IOs and connect to simblockdevice
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
|
|
||||||
class BlockDeviceModelRocketConfig extends Config(
|
class BlockDeviceModelRocketConfig extends Config(
|
||||||
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new testchipip.WithBlockDevice ++ // add block-device module to periphery bus
|
new testchipip.WithBlockDevice ++ // add block-device module to periphery bus
|
||||||
new WithBlockDeviceModelTop ++ // use top with block-device IOs and connect to a blockdevicemodel
|
new WithBlockDeviceModel ++ // use top with block-device IOs and connect to a blockdevicemodel
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
|
|
||||||
// DOC include start: GPIORocketConfig
|
// DOC include start: GPIORocketConfig
|
||||||
class GPIORocketConfig extends Config(
|
class GPIORocketConfig extends Config(
|
||||||
|
new WithTSI ++
|
||||||
new WithGPIO ++ // add GPIOs to the peripherybus
|
new WithGPIO ++ // add GPIOs to the peripherybus
|
||||||
new WithGPIOTop ++ // use top with GPIOs
|
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
// DOC include end: GPIORocketConfig
|
// DOC include end: GPIORocketConfig
|
||||||
|
|
||||||
class DualCoreRocketConfig extends Config(
|
class DualCoreRocketConfig extends Config(
|
||||||
new WithTop ++
|
new WithTSI ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new WithNoGPIO ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new freechips.rocketchip.subsystem.WithNBigCores(2) ++ // dual-core (2 RocketTiles)
|
new freechips.rocketchip.subsystem.WithNBigCores(2) ++ // dual-core (2 RocketTiles)
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
|
|
||||||
class RV32RocketConfig extends Config(
|
class RV32RocketConfig extends Config(
|
||||||
new WithTop ++
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new freechips.rocketchip.subsystem.WithRV32 ++ // set RocketTiles to be 32-bit
|
new freechips.rocketchip.subsystem.WithRV32 ++ // set RocketTiles to be 32-bit
|
||||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
|
|
||||||
class GB1MemoryRocketConfig extends Config(
|
class GB1MemoryRocketConfig extends Config(
|
||||||
new WithTop ++
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new freechips.rocketchip.subsystem.WithExtMemSize((1<<30) * 1L) ++ // use 2GB simulated external memory
|
new freechips.rocketchip.subsystem.WithExtMemSize((1<<30) * 1L) ++ // use 1GB simulated external memory
|
||||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
|
|
||||||
// DOC include start: Sha3Rocket
|
// DOC include start: Sha3Rocket
|
||||||
class Sha3RocketConfig extends Config(
|
class Sha3RocketConfig extends Config(
|
||||||
new WithTop ++
|
new WithTSI ++
|
||||||
|
new WithNoGPIO ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new sha3.WithSha3Accel ++ // add SHA3 rocc accelerator
|
new sha3.WithSha3Accel ++ // add SHA3 rocc accelerator
|
||||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||||
@@ -160,20 +202,27 @@ class Sha3RocketConfig extends Config(
|
|||||||
|
|
||||||
// DOC include start: InitZeroRocketConfig
|
// DOC include start: InitZeroRocketConfig
|
||||||
class InitZeroRocketConfig extends Config(
|
class InitZeroRocketConfig extends Config(
|
||||||
new WithInitZero(0x88000000L, 0x1000L) ++
|
new WithInitZero(0x88000000L, 0x1000L) ++ // add InitZero
|
||||||
new WithInitZeroTop ++
|
new WithNoGPIO ++
|
||||||
|
new WithTSI ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
// DOC include end: InitZeroRocketConfig
|
// DOC include end: InitZeroRocketConfig
|
||||||
|
|
||||||
class LoopbackNICRocketConfig extends Config(
|
class LoopbackNICRocketConfig extends Config(
|
||||||
|
new WithTSI ++
|
||||||
new WithIceNIC ++
|
new WithIceNIC ++
|
||||||
new WithLoopbackNICTop ++
|
new WithNoGPIO ++
|
||||||
|
new WithLoopbackNIC ++
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
new WithUART ++
|
new WithUART ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
|
|||||||
@@ -10,12 +10,22 @@ import freechips.rocketchip.config.{Field, Parameters}
|
|||||||
import freechips.rocketchip.util.GeneratorApp
|
import freechips.rocketchip.util.GeneratorApp
|
||||||
import freechips.rocketchip.devices.debug.{Debug}
|
import freechips.rocketchip.devices.debug.{Debug}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Why do we need this?
|
||||||
|
*/
|
||||||
|
import ConfigValName._
|
||||||
|
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
// BOOM and/or Rocket Test Harness
|
// BOOM and/or Rocket Test Harness
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
|
|
||||||
case object BuildTop extends Field[(Clock, Bool, Parameters) => TopModule[Top]]
|
case object BuildTop extends Field[(Clock, Bool, Parameters, Bool) => TopModule[Top]](
|
||||||
case object BuildTopWithDTM extends Field[(Clock, Bool, Parameters) => TopWithDTMModule[TopWithDTM]]
|
(clock: Clock, reset: Bool, p: Parameters, success: Bool) => {
|
||||||
|
val top = Module(LazyModule(new Top()(p)).suggestName("top").module)
|
||||||
|
top.debug.map { debug => debug := DontCare }
|
||||||
|
top
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test harness using TSI to bringup the system
|
* Test harness using TSI to bringup the system
|
||||||
@@ -25,48 +35,8 @@ class TestHarness(implicit val p: Parameters) extends Module {
|
|||||||
val success = Output(Bool())
|
val success = Output(Bool())
|
||||||
})
|
})
|
||||||
|
|
||||||
// force Chisel to rename module
|
val dut = p(BuildTop)(clock, reset.toBool, p, io.success)
|
||||||
override def desiredName = "TestHarness"
|
|
||||||
|
|
||||||
val dut = p(BuildTop)(clock, reset.toBool, p)
|
|
||||||
|
|
||||||
dut.debug.foreach(_ := DontCare)
|
|
||||||
dut.connectSimAXIMem()
|
|
||||||
dut.connectSimAXIMMIO()
|
|
||||||
dut.dontTouchPorts()
|
|
||||||
dut.tieOffInterrupts()
|
|
||||||
dut.l2_frontend_bus_axi4.foreach(axi => {
|
|
||||||
axi.tieoff()
|
|
||||||
experimental.DataMirror.directionOf(axi.ar.ready) match {
|
|
||||||
case core.ActualDirection.Input =>
|
|
||||||
axi.r.bits := DontCare
|
|
||||||
axi.b.bits := DontCare
|
|
||||||
case core.ActualDirection.Output =>
|
|
||||||
axi.aw.bits := DontCare
|
|
||||||
axi.ar.bits := DontCare
|
|
||||||
axi.w.bits := DontCare
|
|
||||||
}
|
|
||||||
})
|
|
||||||
dut.connectSimUARTs()
|
dut.connectSimUARTs()
|
||||||
|
|
||||||
io.success := dut.connectSimSerial()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test harness using the Debug Test Module (DTM) to bringup the system
|
|
||||||
*/
|
|
||||||
class TestHarnessWithDTM(implicit p: Parameters) extends Module
|
|
||||||
{
|
|
||||||
val io = IO(new Bundle {
|
|
||||||
val success = Output(Bool())
|
|
||||||
})
|
|
||||||
|
|
||||||
// force Chisel to rename module
|
|
||||||
override def desiredName = "TestHarness"
|
|
||||||
|
|
||||||
val dut = p(BuildTopWithDTM)(clock, reset.toBool, p)
|
|
||||||
|
|
||||||
dut.reset := reset.asBool | dut.debug.get.ndreset
|
|
||||||
dut.connectSimAXIMem()
|
dut.connectSimAXIMem()
|
||||||
dut.connectSimAXIMMIO()
|
dut.connectSimAXIMMIO()
|
||||||
dut.dontTouchPorts()
|
dut.dontTouchPorts()
|
||||||
@@ -84,5 +54,4 @@ class TestHarnessWithDTM(implicit p: Parameters) extends Module
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
Debug.connectDebug(dut.debug, dut.psd, clock, reset.asBool, io.success)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,103 +15,33 @@ import utilities.{System, SystemModule}
|
|||||||
import sifive.blocks.devices.gpio._
|
import sifive.blocks.devices.gpio._
|
||||||
import sifive.blocks.devices.uart._
|
import sifive.blocks.devices.uart._
|
||||||
|
|
||||||
import icenet.{HasPeripheryIceNIC, HasPeripheryIceNICModuleImp}
|
import icenet.{CanHavePeripheryIceNIC, CanHavePeripheryIceNICModuleImp}
|
||||||
|
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
// BOOM and/or Rocket Top Level Systems
|
// BOOM and/or Rocket Top Level Systems
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
|
|
||||||
|
// DOC include start: Top
|
||||||
class Top(implicit p: Parameters) extends System
|
class Top(implicit p: Parameters) extends System
|
||||||
with HasNoDebug
|
with CanHavePeripheryUARTAdapter // Enables optionally adding the UART print adapter
|
||||||
with HasPeripherySerial
|
with HasPeripheryUART // Enables optionally adding the sifive UART
|
||||||
with CanHavePeripheryUARTWithAdapter {
|
with HasPeripheryGPIO // Enables optionally adding the sifive GPIOs
|
||||||
|
with CanHavePeripheryBlockDevice // Enables optionally adding the block device
|
||||||
|
with CanHavePeripheryInitZero // Enables optionally adding the initzero example widget
|
||||||
|
with CanHavePeripheryGCD // Enables optionally adding the GCD example widget
|
||||||
|
with CanHavePeripherySerial // Enables optionally adding the TSI serial-adapter and port
|
||||||
|
with CanHavePeripheryIceNIC // Enables optionally adding the IceNIC for firesim
|
||||||
|
{
|
||||||
override lazy val module = new TopModule(this)
|
override lazy val module = new TopModule(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
class TopModule[+L <: Top](l: L) extends SystemModule(l)
|
class TopModule[+L <: Top](l: L) extends SystemModule(l)
|
||||||
with HasNoDebugModuleImp
|
|
||||||
with HasPeripherySerialModuleImp
|
|
||||||
with CanHavePeripheryUARTWithAdapterImp
|
|
||||||
with DontTouch
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------
|
|
||||||
// DOC include start: TopWithPWMTL
|
|
||||||
|
|
||||||
class TopWithPWMTL(implicit p: Parameters) extends Top
|
|
||||||
with HasPeripheryPWMTL {
|
|
||||||
override lazy val module = new TopWithPWMTLModule(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
class TopWithPWMTLModule(l: TopWithPWMTL) extends TopModule(l)
|
|
||||||
with HasPeripheryPWMTLModuleImp
|
|
||||||
|
|
||||||
// DOC include end: TopWithPWMTL
|
|
||||||
//---------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class TopWithPWMAXI4(implicit p: Parameters) extends Top
|
|
||||||
with HasPeripheryPWMAXI4 {
|
|
||||||
override lazy val module = new TopWithPWMAXI4Module(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
class TopWithPWMAXI4Module(l: TopWithPWMAXI4) extends TopModule(l)
|
|
||||||
with HasPeripheryPWMAXI4ModuleImp
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class TopWithGCD(implicit p: Parameters) extends Top
|
|
||||||
with HasPeripheryGCD {
|
|
||||||
override lazy val module = new TopWithGCDModule(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
class TopWithGCDModule(l: TopWithGCD) extends TopModule(l)
|
|
||||||
with HasPeripheryGCDModuleImp
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class TopWithBlockDevice(implicit p: Parameters) extends Top
|
|
||||||
with HasPeripheryBlockDevice {
|
|
||||||
override lazy val module = new TopWithBlockDeviceModule(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
class TopWithBlockDeviceModule(l: TopWithBlockDevice) extends TopModule(l)
|
|
||||||
with HasPeripheryBlockDeviceModuleImp
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class TopWithGPIO(implicit p: Parameters) extends Top
|
|
||||||
with HasPeripheryGPIO {
|
|
||||||
override lazy val module = new TopWithGPIOModule(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
class TopWithGPIOModule(l: TopWithGPIO)
|
|
||||||
extends TopModule(l)
|
|
||||||
with HasPeripheryGPIOModuleImp
|
with HasPeripheryGPIOModuleImp
|
||||||
|
with HasPeripheryUARTModuleImp
|
||||||
//---------------------------------------------------------------------------------------------------------
|
with CanHavePeripheryBlockDeviceModuleImp
|
||||||
|
with CanHavePeripheryGCDModuleImp
|
||||||
class TopWithDTM(implicit p: Parameters) extends System
|
with CanHavePeripherySerialModuleImp
|
||||||
{
|
with CanHavePeripheryIceNICModuleImp
|
||||||
override lazy val module = new TopWithDTMModule(this)
|
with CanHavePeripheryUARTAdapterModuleImp
|
||||||
}
|
with DontTouch
|
||||||
|
// DOC include end: Top
|
||||||
class TopWithDTMModule[+L <: TopWithDTM](l: L) extends SystemModule(l)
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------
|
|
||||||
// DOC include start: TopWithInitZero
|
|
||||||
class TopWithInitZero(implicit p: Parameters) extends Top
|
|
||||||
with HasPeripheryInitZero {
|
|
||||||
override lazy val module = new TopWithInitZeroModuleImp(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
class TopWithInitZeroModuleImp(l: TopWithInitZero) extends TopModule(l)
|
|
||||||
with HasPeripheryInitZeroModuleImp
|
|
||||||
// DOC include end: TopWithInitZero
|
|
||||||
|
|
||||||
class TopWithIceNIC(implicit p: Parameters) extends Top
|
|
||||||
with HasPeripheryIceNIC {
|
|
||||||
override lazy val module = new TopWithIceNICModule(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
class TopWithIceNICModule(outer: TopWithIceNIC)
|
|
||||||
extends TopModule(outer)
|
|
||||||
with HasPeripheryIceNICModuleImp
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import freechips.rocketchip.devices.debug.HasPeripheryDebugModuleImp
|
|||||||
import freechips.rocketchip.subsystem.{CanHaveMasterAXI4MemPortModuleImp}
|
import freechips.rocketchip.subsystem.{CanHaveMasterAXI4MemPortModuleImp}
|
||||||
import sifive.blocks.devices.uart.HasPeripheryUARTModuleImp
|
import sifive.blocks.devices.uart.HasPeripheryUARTModuleImp
|
||||||
|
|
||||||
import testchipip.{HasPeripherySerialModuleImp, HasPeripheryBlockDeviceModuleImp}
|
import testchipip.{CanHavePeripherySerialModuleImp, CanHavePeripheryBlockDeviceModuleImp}
|
||||||
import icenet.HasPeripheryIceNICModuleImpValidOnly
|
import icenet.HasPeripheryIceNICModuleImpValidOnly
|
||||||
|
|
||||||
import junctions.{NastiKey, NastiParameters}
|
import junctions.{NastiKey, NastiParameters}
|
||||||
@@ -32,19 +32,19 @@ class WithTiedOffDebug extends RegisterBridgeBinder({ case target: HasPeripheryD
|
|||||||
})
|
})
|
||||||
|
|
||||||
class WithSerialBridge extends RegisterBridgeBinder({
|
class WithSerialBridge extends RegisterBridgeBinder({
|
||||||
case target: HasPeripherySerialModuleImp => Seq(SerialBridge(target.serial)(target.p))
|
case target: CanHavePeripherySerialModuleImp => Seq(SerialBridge(target.serial.get)(target.p))
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithNICBridge extends RegisterBridgeBinder({
|
class WithNICBridge extends RegisterBridgeBinder({
|
||||||
case target: HasPeripheryIceNICModuleImpValidOnly => Seq(NICBridge(target.net)(target.p))
|
case target: HasPeripheryIceNICModuleImpValidOnly => Seq(NICBridge(target.net)(target.p))
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithUARTBridge extends RegisterBridgeBinder({
|
class WithUARTBridge extends RegisterBridgeBinder({
|
||||||
case target: HasPeripheryUARTModuleImp => target.uart.map(u => UARTBridge(u)(target.p))
|
case target: HasPeripheryUARTModuleImp => target.uart.map(u => UARTBridge(u)(target.p))
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithBlockDeviceBridge extends RegisterBridgeBinder({
|
class WithBlockDeviceBridge extends RegisterBridgeBinder({
|
||||||
case target: HasPeripheryBlockDeviceModuleImp => Seq(BlockDevBridge(target.bdev, target.reset.toBool)(target.p))
|
case target: CanHavePeripheryBlockDeviceModuleImp => Seq(BlockDevBridge(target.bdev.get, target.reset.toBool)(target.p))
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithFASEDBridge extends RegisterBridgeBinder({
|
class WithFASEDBridge extends RegisterBridgeBinder({
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import freechips.rocketchip.subsystem._
|
|||||||
import freechips.rocketchip.devices.tilelink.BootROMParams
|
import freechips.rocketchip.devices.tilelink.BootROMParams
|
||||||
import freechips.rocketchip.devices.debug.{DebugModuleParams, DebugModuleKey}
|
import freechips.rocketchip.devices.debug.{DebugModuleParams, DebugModuleKey}
|
||||||
import boom.common.BoomTilesKey
|
import boom.common.BoomTilesKey
|
||||||
import testchipip.{BlockDeviceKey, BlockDeviceConfig}
|
import testchipip.{BlockDeviceKey, BlockDeviceConfig, SerialKey}
|
||||||
import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTParams}
|
import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTParams}
|
||||||
import scala.math.{min, max}
|
import scala.math.{min, max}
|
||||||
import tracegen.TraceGenKey
|
import tracegen.TraceGenKey
|
||||||
@@ -47,13 +47,17 @@ class WithUARTKey extends Config((site, here, up) => {
|
|||||||
nRxEntries = 256))
|
nRxEntries = 256))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
class WithSerial extends Config((site, here, up) => {
|
||||||
|
case SerialKey => true
|
||||||
|
})
|
||||||
|
|
||||||
class WithBlockDevice extends Config(new testchipip.WithBlockDevice)
|
class WithBlockDevice extends Config(new testchipip.WithBlockDevice)
|
||||||
|
|
||||||
class WithNICKey extends Config((site, here, up) => {
|
class WithNICKey extends Config((site, here, up) => {
|
||||||
case NICKey => NICConfig(
|
case NICKey => Some(NICConfig(
|
||||||
inBufFlits = 8192,
|
inBufFlits = 8192,
|
||||||
ctrlQueueDepth = 64,
|
ctrlQueueDepth = 64,
|
||||||
checksumOffload = true)
|
checksumOffload = true))
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithRocketL2TLBs(entries: Int) extends Config((site, here, up) => {
|
class WithRocketL2TLBs(entries: Int) extends Config((site, here, up) => {
|
||||||
@@ -112,6 +116,7 @@ class FireSimRocketChipConfig extends Config(
|
|||||||
new WithoutTLMonitors ++
|
new WithoutTLMonitors ++
|
||||||
new WithUARTKey ++
|
new WithUARTKey ++
|
||||||
new WithNICKey ++
|
new WithNICKey ++
|
||||||
|
new WithSerial ++
|
||||||
new WithBlockDevice ++
|
new WithBlockDevice ++
|
||||||
new WithRocketL2TLBs(1024) ++
|
new WithRocketL2TLBs(1024) ++
|
||||||
new WithPerfCounters ++
|
new WithPerfCounters ++
|
||||||
@@ -169,6 +174,7 @@ class FireSimBoomConfig extends Config(
|
|||||||
new WithoutTLMonitors ++
|
new WithoutTLMonitors ++
|
||||||
new WithUARTKey ++
|
new WithUARTKey ++
|
||||||
new WithNICKey ++
|
new WithNICKey ++
|
||||||
|
new WithSerial ++
|
||||||
new WithBlockDevice ++
|
new WithBlockDevice ++
|
||||||
new WithBoomL2TLBs(1024) ++
|
new WithBoomL2TLBs(1024) ++
|
||||||
new WithoutClockGating ++
|
new WithoutClockGating ++
|
||||||
|
|||||||
@@ -42,10 +42,10 @@ class FireSimDUT(implicit p: Parameters) extends Subsystem
|
|||||||
with HasHierarchicalBusTopology
|
with HasHierarchicalBusTopology
|
||||||
with CanHaveMasterAXI4MemPort
|
with CanHaveMasterAXI4MemPort
|
||||||
with HasPeripheryBootROM
|
with HasPeripheryBootROM
|
||||||
with HasPeripherySerial
|
with CanHavePeripherySerial
|
||||||
with HasPeripheryUART
|
with HasPeripheryUART
|
||||||
with HasPeripheryIceNIC
|
with CanHavePeripheryIceNIC
|
||||||
with HasPeripheryBlockDevice
|
with CanHavePeripheryBlockDevice
|
||||||
with HasTraceIO
|
with HasTraceIO
|
||||||
{
|
{
|
||||||
override lazy val module = new FireSimModuleImp(this)
|
override lazy val module = new FireSimModuleImp(this)
|
||||||
@@ -55,10 +55,10 @@ class FireSimModuleImp[+L <: FireSimDUT](l: L) extends SubsystemModuleImp(l)
|
|||||||
with HasRTCModuleImp
|
with HasRTCModuleImp
|
||||||
with CanHaveMasterAXI4MemPortModuleImp
|
with CanHaveMasterAXI4MemPortModuleImp
|
||||||
with HasPeripheryBootROMModuleImp
|
with HasPeripheryBootROMModuleImp
|
||||||
with HasPeripherySerialModuleImp
|
with CanHavePeripherySerialModuleImp
|
||||||
with HasPeripheryUARTModuleImp
|
with HasPeripheryUARTModuleImp
|
||||||
with HasPeripheryIceNICModuleImpValidOnly
|
with HasPeripheryIceNICModuleImpValidOnly
|
||||||
with HasPeripheryBlockDeviceModuleImp
|
with CanHavePeripheryBlockDeviceModuleImp
|
||||||
with HasTraceIOImp
|
with HasTraceIOImp
|
||||||
with CanHaveMultiCycleRegfileImp
|
with CanHaveMultiCycleRegfileImp
|
||||||
|
|
||||||
@@ -68,9 +68,9 @@ class FireSimNoNICDUT(implicit p: Parameters) extends Subsystem
|
|||||||
with HasHierarchicalBusTopology
|
with HasHierarchicalBusTopology
|
||||||
with CanHaveMasterAXI4MemPort
|
with CanHaveMasterAXI4MemPort
|
||||||
with HasPeripheryBootROM
|
with HasPeripheryBootROM
|
||||||
with HasPeripherySerial
|
with CanHavePeripherySerial
|
||||||
with HasPeripheryUART
|
with HasPeripheryUART
|
||||||
with HasPeripheryBlockDevice
|
with CanHavePeripheryBlockDevice
|
||||||
with HasTraceIO
|
with HasTraceIO
|
||||||
{
|
{
|
||||||
override lazy val module = new FireSimNoNICModuleImp(this)
|
override lazy val module = new FireSimNoNICModuleImp(this)
|
||||||
@@ -80,9 +80,9 @@ class FireSimNoNICModuleImp[+L <: FireSimNoNICDUT](l: L) extends SubsystemModule
|
|||||||
with HasRTCModuleImp
|
with HasRTCModuleImp
|
||||||
with CanHaveMasterAXI4MemPortModuleImp
|
with CanHaveMasterAXI4MemPortModuleImp
|
||||||
with HasPeripheryBootROMModuleImp
|
with HasPeripheryBootROMModuleImp
|
||||||
with HasPeripherySerialModuleImp
|
with CanHavePeripherySerialModuleImp
|
||||||
with HasPeripheryUARTModuleImp
|
with HasPeripheryUARTModuleImp
|
||||||
with HasPeripheryBlockDeviceModuleImp
|
with CanHavePeripheryBlockDeviceModuleImp
|
||||||
with HasTraceIOImp
|
with HasTraceIOImp
|
||||||
with CanHaveMultiCycleRegfileImp
|
with CanHaveMultiCycleRegfileImp
|
||||||
|
|
||||||
@@ -107,12 +107,11 @@ class FireSimSupernode(implicit p: Parameters) extends DefaultFireSimHarness(()
|
|||||||
|
|
||||||
// Verilog blackbox integration demo
|
// Verilog blackbox integration demo
|
||||||
class FireSimVerilogGCDDUT(implicit p: Parameters) extends FireSimDUT
|
class FireSimVerilogGCDDUT(implicit p: Parameters) extends FireSimDUT
|
||||||
with example.HasPeripheryGCD
|
with example.CanHavePeripheryGCD
|
||||||
{
|
{
|
||||||
override lazy val module = new FireSimVerilogGCDModuleImp(this)
|
override lazy val module = new FireSimVerilogGCDModuleImp(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
class FireSimVerilogGCDModuleImp[+L <: FireSimVerilogGCDDUT](l: L) extends FireSimModuleImp(l)
|
class FireSimVerilogGCDModuleImp[+L <: FireSimVerilogGCDDUT](l: L) extends FireSimModuleImp(l)
|
||||||
with example.HasPeripheryGCDModuleImp
|
|
||||||
|
|
||||||
class FireSimVerilogGCD(implicit p: Parameters) extends DefaultFireSimHarness(() => new FireSimVerilogGCDDUT)
|
class FireSimVerilogGCD(implicit p: Parameters) extends DefaultFireSimHarness(() => new FireSimVerilogGCDDUT)
|
||||||
|
|||||||
Submodule generators/icenet updated: 87b3bf5e46...2874db7fdc
Submodule generators/sha3 updated: 6814c99913...faf08c0f39
Submodule generators/testchipip updated: db01ac1514...62cf2629a7
Submodule sims/firesim updated: d799550b42...5f6bd4fa16
Reference in New Issue
Block a user