Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename Config Mixins to Fragments #451

Merged
merged 8 commits into from
Feb 27, 2020
8 changes: 4 additions & 4 deletions docs/Advanced-Concepts/CDEs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ Consider the following example using CDEs.
}


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.
When forming a query based on a ``Parameters`` object, like ``p(SomeKeyX)``, the configuration system traverses the "chain" of config fragments 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
val params = Config(new WithX(true) ++ new WithY(true)) // "chain" together config fragments
params(SomeKeyX) // evaluates to true
params(SomeKeyY) // evaluates to true
params(SomeKeyZ) // evaluates to false
Expand Down Expand Up @@ -68,7 +68,7 @@ In this example, the partial function in ``WithXEqualsYSite`` will look up the v
Here
~~~~

``here`` provides a ``View`` of the locally defined Config, which typically just contains some partial function.
``here`` provides a ``View`` of the locally defined config, which typically just contains some partial function.

.. code:: scala

Expand Down Expand Up @@ -103,7 +103,7 @@ Up
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``.
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 config fragments were used*. Since the order of config fragments 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``.
Expand Down
4 changes: 2 additions & 2 deletions docs/Advanced-Concepts/Chip-Communication.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ Similar to TSI, the DMI protocol is an implementation of HTIF.
In order to communicate with the DUT with the DMI protocol, the DUT needs to contain a Debug Transfer Module (DTM).
The DTM is given in the `RISC-V Debug Specification <https://riscv.org/specifications/debug-specification/>`__
and is responsible for managing communication between the DUT and whatever lives on the other side of the DMI (in this case FESVR).
This is implemented in the Rocket Chip ``Subsystem`` by having the ``HasPeripheryDebug`` and ``HasPeripheryDebugModuleImp`` mixins.
This is implemented in the Rocket Chip ``Subsystem`` by having the ``HasPeripheryDebug`` and ``HasPeripheryDebugModuleImp`` traits.
During simulation, the host sends DMI commands to a
simulation stub called ``SimDTM`` (C++ class) that resides in a ``SimDTM`` Verilog module
(both are located in the ``generators/rocket-chip`` project). This ``SimDTM`` Verilog module then
Expand Down Expand Up @@ -138,7 +138,7 @@ Creating a DTM+JTAG Config
First, a DTM config must be created for the system that you want to create.
This step is similar to the DMI simulation section within the :ref:`Starting the TSI or DMI Simulation` section.
The configuration is very similar to a DMI-based configuration. The main difference
is the addition of the ``WithJtagDTM`` mixin that configures the instantiated DTM to use the JTAG protocol as the
is the addition of the ``WithJtagDTM`` config fragment that configures the instantiated DTM to use the JTAG protocol as the
bringup method.

.. literalinclude:: ../../generators/chipyard/src/main/scala/RocketConfigs.scala
Expand Down
2 changes: 1 addition & 1 deletion docs/Advanced-Concepts/Top-Testharness.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Please refer to :ref:`Communicating with the DUT` for more information on these
TestHarness
-------------------------

The wiring between the ``TestHarness`` and the Top are performed in methods defined in mixins added to the Top.
The wiring between the ``TestHarness`` and the Top are performed in methods defined in traits added to the Top.
When these methods are called from the ``TestHarness``, they may instantiate modules within the scope of the harness,
and then connect them to the DUT. For example, the ``connectSimAXIMem`` method defined in the
``CanHaveMasterAXI4MemPortModuleImp`` trait, when called from the ``TestHarness``, will instantiate ``SimAXIMems``
Expand Down
2 changes: 1 addition & 1 deletion docs/Advanced-Concepts/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Advanced Concepts
================================

The following sections are advanced topics about how to Chipyard works, how to use Chipyard, and special features of the framework.
They expect you to know about Chisel, Parameters, Configs, etc.
They expect you to know about Chisel, Parameters, configs, etc.

.. toctree::
:maxdepth: 2
Expand Down
34 changes: 16 additions & 18 deletions docs/Chipyard-Basics/Configs-Parameters-Mixins.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Configs, Parameters, Mix-ins, and Everything In Between
Configs, Parameters, Mixins, and Everything In Between
========================================================

A significant portion of generators in the Chipyard framework use the Rocket Chip parameter system.
Expand All @@ -14,12 +14,12 @@ We are still investigating methods to facilitate parameter exploration and disco
Configs
---------------------

A *Config* is a collection of multiple generator parameters being set to specific values.
Configs are additive, can override each other, and can be composed of other Configs.
The naming convention for an additive Config is ``With<YourConfigName>``, while the naming convention for a non-additive Config will be ``<YourConfig>``.
A *config* is a collection of multiple generator parameters being set to specific values.
Configs are additive, can override each other, and can be composed of other configs (sometimes referred to as config fragments).
The naming convention for an additive config or config fragment is ``With<YourConfigName>``, while the naming convention for a non-additive config will be ``<YourConfig>``.
Configs can take arguments which will in-turn set parameters in the design or reference other parameters in the design (see :ref:`Parameters`).

This example shows a basic additive Config class that takes in zero arguments and instead uses hardcoded values to set the RTL design parameters.
This example shows a basic config fragment class that takes in zero arguments and instead uses hardcoded values to set the RTL design parameters.
In this example, ``MyAcceleratorConfig`` is a Scala case class that defines a set of variables that the generator can use when referencing the ``MyAcceleratorKey`` in the design.

.. _basic-config-example:
Expand All @@ -36,7 +36,7 @@ In this example, ``MyAcceleratorConfig`` is a Scala case class that defines a se
someLength = 256)
})

This next example shows a "higher-level" additive Config that uses prior parameters that were set to derive other parameters.
This next example shows a "higher-level" additive config fragment that uses prior parameters that were set to derive other parameters.

.. _complex-config-example:
.. code-block:: scala
Expand All @@ -50,8 +50,8 @@ This next example shows a "higher-level" additive Config that uses prior paramet
hartId = up(RocketTilesKey, site).length)
})

The following example shows a non-additive Config that combines the prior two additive Configs using ``++``.
The additive Configs are applied from the right to left in the list (or bottom to top in the example).
The following example shows a non-additive config that combines or "assembles" the prior two config fragments using ``++``.
The additive config fragments are applied from the right to left in the list (or bottom to top in the example).
Thus, the order of the parameters being set will first start with the ``DefaultExampleConfig``, then ``WithMyAcceleratorParams``, then ``WithMyMoreComplexAcceleratorConfig``.

.. _top-level-config:
Expand All @@ -68,10 +68,10 @@ The ``site`` map gives you the definitions as seen from the root of the configur
The ``here`` map gives the definitions as seen at the current level of the hierarchy (i.e. in ``WithMyMoreComplexAcceleratorConfig`` itself).
The ``up`` map gives the definitions as seen from the next level up from the current (i.e. from ``WithMyAcceleratorParams``).

Cake Pattern
Cake Pattern / Mixin
-------------------------

A cake pattern is a Scala programming pattern, which enable "mixing" of multiple traits or interface definitions (sometimes referred to as dependency injection).
A cake pattern or mixin is a Scala programming pattern, which enable "mixing" of multiple traits or interface definitions (sometimes referred to as dependency injection).
It is used in the Rocket Chip SoC library and Chipyard framework in merging multiple system components and IO interfaces into a large system component.

This example shows the Chipyard default top that composes multiple traits together into a fully-featured SoC with many optional components.
Expand All @@ -83,7 +83,7 @@ This example shows the Chipyard default top that composes multiple traits togeth
:end-before: DOC include end: Top


There are two "cakes" here. One for the lazy module (ex. ``CanHavePeripherySerial``) and one for the lazy module
There are two "cakes" or mixins here. One for the lazy module (ex. ``CanHavePeripherySerial``) and one for the lazy module
implementation (ex. ``CanHavePeripherySerialModuleImp`` where ``Imp`` refers to implementation). The lazy module defines
all the logical connections between generators and exchanges configuration information among them, while the
lazy module implementation performs the actual Chisel RTL elaboration.
Expand Down Expand Up @@ -114,15 +114,13 @@ contain the implementation for the module, and may instantiate
other normal modules OR lazy modules (for nested Diplomacy
graphs, for example).


Mix-in
---------------------------

A mix-in is a Scala trait, which sets parameters for specific system components, as well as enabling instantiation and wiring of the relevant system components to system buses.
The naming convention for an additive mix-in is ``CanHave<YourMixin>``.
The naming convention for an additive mixin or trait is ``CanHave<YourMixin>``.
This is shown in the ``Top`` class where things such as ``CanHavePeripherySerial`` connect a RTL component to a bus and expose signals to the top-level.

Additional References
---------------------------

A brief explanation of some of these topics is given in the following video: https://www.youtube.com/watch?v=Eko86PGEoDY.
Another description of traits/mixins and config fragments is given in :ref:`Keys, Traits, and Configs`.
Additionally, a brief explanation of some of these topics (with slightly different naming) is given in the following video: https://www.youtube.com/watch?v=Eko86PGEoDY.

.. Note:: Chipyard uses the name "config fragments" over "config mixins" to avoid confusion between a mixin applying to a config or to the system ``Top`` (even though both are technically Scala mixins).
30 changes: 15 additions & 15 deletions docs/Customization/Heterogeneous-SoCs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ This discussion will focus on how you combine Rocket, BOOM and Hwacha in particu
Creating a Rocket and BOOM System
-------------------------------------------

Instantiating an SoC with Rocket and BOOM cores is all done with the configuration system and two specific mixins.
Both BOOM and Rocket have mixins labelled ``WithNBoomCores(X)`` and ``WithNBigCores(X)`` that automatically create ``X`` copies of the core/tile [1]_.
Instantiating an SoC with Rocket and BOOM cores is all done with the configuration system and two specific config fragments.
Both BOOM and Rocket have config fragments labelled ``WithNBoomCores(X)`` and ``WithNBigCores(X)`` that automatically create ``X`` copies of the core/tile [1]_.
When used together you can create a heterogeneous system.

The following example shows a dual core BOOM with a single core Rocket.
Expand All @@ -18,18 +18,18 @@ The following example shows a dual core BOOM with a single core Rocket.
:start-after: DOC include start: DualBoomAndRocket
:end-before: DOC include end: DualBoomAndRocket

In this example, the ``WithNBoomCores`` and ``WithNBigCores`` mixins set up the default parameters for the multiple BOOM and Rocket cores, respectively.
However, for BOOM, an extra mixin called ``WithLargeBooms`` is added to override the default parameters with a different set of more common default parameters.
This mixin applies to all BOOM cores in the system and changes the parameters for each.
In this example, the ``WithNBoomCores`` and ``WithNBigCores`` config fragments set up the default parameters for the multiple BOOM and Rocket cores, respectively.
However, for BOOM, an extra config fragment called ``WithLargeBooms`` is added to override the default parameters with a different set of more common default parameters.
This config fragment applies to all BOOM cores in the system and changes the parameters for each.

Great! Now you have a heterogeneous setup with BOOMs and Rockets.
The final thing you need to make this system work is to renumber the ``hartId``'s of the cores so that each core has a unique ``hartId`` (a ``hartId`` is the hardware thread id of the core).
The ``WithRenumberHarts`` mixin solves this by assigning a unique ``hartId`` to all cores in the system (it can label the Rocket cores first or the BOOM cores first).
The reason this is needed is because by default the ``WithN...Cores(X)`` mixin assumes that there are only BOOM or only Rocket cores in the system.
Thus, without the ``WithRenumberHarts`` mixin, each set of cores is labeled starting from zero causing multiple cores to be assigned the same ``hartId``.
The ``WithRenumberHarts`` config fragment solves this by assigning a unique ``hartId`` to all cores in the system (it can label the Rocket cores first or the BOOM cores first).
The reason this is needed is because by default the ``WithN...Cores(X)`` config fragment assumes that there are only BOOM or only Rocket cores in the system.
Thus, without the ``WithRenumberHarts`` config fragment, each set of cores is labeled starting from zero causing multiple cores to be assigned the same ``hartId``.

Another alternative option to create a multi heterogeneous core system is to override the parameters yourself so you can specify the core parameters per core.
The mixin to add to your system would look something like the following.
The config fragment to add to your system would look something like the following.

.. code-block:: scala

Expand All @@ -50,7 +50,7 @@ The mixin to add to your system would look something like the following.
}
})

Then you could use this new mixin like the following.
Then you could use this new config fragment like the following.

.. code-block:: scala

Expand Down Expand Up @@ -83,7 +83,7 @@ All with the same Hwacha parameters.
Assigning Accelerators to Specific Tiles with MultiRoCC
-------------------------------------------------------

Located in ``generators/chipyard/src/main/scala/ConfigMixins.scala`` is a mixin that provides support for adding RoCC accelerators to specific tiles in your SoC.
Located in ``generators/chipyard/src/main/scala/ConfigFragments.scala`` is a config fragment that provides support for adding RoCC accelerators to specific tiles in your SoC.
Named ``MultiRoCCKey``, this key allows you to attach RoCC accelerators based on the ``hartId`` of the tile.
For example, using this allows you to create a 8 tile system with a RoCC accelerator on only a subset of the tiles.
An example is shown below with two BOOM cores, and one Rocket tile with a RoCC accelerator (Hwacha) attached.
Expand All @@ -94,13 +94,13 @@ An example is shown below with two BOOM cores, and one Rocket tile with a RoCC a
:end-before: DOC include end: DualBoomAndRocketOneHwacha

In this example, the ``WithRenumberHarts`` relabels the ``hartId``'s of all the BOOM/Rocket cores.
Then after that is applied to the parameters, the ``WithMultiRoCCHwacha`` mixin assigns a Hwacha accelerator to a particular ``hartId`` (in this case, the ``hartId`` of ``2`` corresponds to the Rocket core).
Finally, the ``WithMultiRoCC`` mixin is called.
This mixin sets the ``BuildRoCC`` key to use the ``MultiRoCCKey`` instead of the default.
Then after that is applied to the parameters, the ``WithMultiRoCCHwacha`` config fragment assigns a Hwacha accelerator to a particular ``hartId`` (in this case, the ``hartId`` of ``2`` corresponds to the Rocket core).
Finally, the ``WithMultiRoCC`` config fragment is called.
This config fragment sets the ``BuildRoCC`` key to use the ``MultiRoCCKey`` instead of the default.
This must be used after all the RoCC parameters are set because it needs to override the ``BuildRoCC`` parameter.
If this is used earlier in the configuration sequence, then MultiRoCC does not work.

This mixin can be changed to put more accelerators on more cores by changing the arguments to cover more ``hartId``'s (i.e. ``WithMultiRoCCHwacha(0,1,3,6,...)``).
This config fragment can be changed to put more accelerators on more cores by changing the arguments to cover more ``hartId``'s (i.e. ``WithMultiRoCCHwacha(0,1,3,6,...)``).


.. [1] Note, in this section "core" and "tile" are used interchangeably but there is subtle distinction between a "core" and "tile" ("tile" contains a "core", L1D/I$, PTW).
Expand Down
2 changes: 1 addition & 1 deletion docs/Customization/IOBinders.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ For example, the ``WithSimAXIMemTiedOff`` IOBinder specifies that any ``Top`` wh

These classes are all ``Config`` objects, which can be mixed into the configs to specify IO connection behaviors.

There are two macros for generating these ``Configs``. ``OverrideIOBinder`` overrides any existing behaviors set for a particular IO in the ``Config`` object. This macro is frequently used because typically top-level IOs drive or are driven by only one source, so a composition of ``IOBinders`` does not make sense. The ``ComposeIOBinder`` macro provides the functionality of not overriding existing behaviors.
There are two macros for generating these ``Config``s. ``OverrideIOBinder`` overrides any existing behaviors set for a particular IO in the ``Config`` object. This macro is frequently used because typically top-level IOs drive or are driven by only one source, so a composition of ``IOBinders`` does not make sense. The ``ComposeIOBinder`` macro provides the functionality of not overriding existing behaviors.
Loading