Merge pull request #599 from ucb-bar/dev

Chipyard 1.4.0 Release
This commit is contained in:
Jerry Zhao
2021-01-20 15:26:47 -08:00
committed by GitHub
196 changed files with 7922 additions and 3008 deletions

View File

@@ -54,7 +54,7 @@ sends the TSI command recieved by the simulation stub into the DUT which then co
command into a TileLink request. This conversion is done by the ``SerialAdapter`` module
(located in the ``generators/testchipip`` project). In simulation, FESVR
resets the DUT, writes into memory the test program, and indicates to the DUT to start the program
through an interrupt (see :ref:`Chipyard Boot Process`). Using TSI is currently the fastest
through an interrupt (see :ref:`customization/Boot-Process:Chipyard Boot Process`). Using TSI is currently the fastest
mechanism to communicate with the DUT in simulation.
In the case of a chip tapeout bringup, TSI commands can be sent over a custom communication
@@ -96,7 +96,7 @@ Starting the TSI or DMI Simulation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
All default Chipyard configurations use TSI to communicate between the simulation and the simulated SoC/DUT. Hence, when running a
software RTL simulation, as is indicated in the :ref:`Software RTL Simulation` section, you are in-fact using TSI to communicate with the DUT. As a
software RTL simulation, as is indicated in the :ref:`simulation/Software-RTL-Simulation:Software RTL Simulation` section, you are in-fact using TSI to communicate with the DUT. As a
reminder, to run a software RTL simulation, run:
.. code-block:: bash
@@ -130,38 +130,8 @@ Using the JTAG Interface
------------------------
The main way to use JTAG with a Rocket Chip based system is to instantiate the Debug Transfer Module (DTM)
and configure it to use a JTAG interface (by default the DTM is setup to use the DMI interface mentioned above).
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`` config fragment that configures the instantiated DTM to use the JTAG protocol as the
bringup method.
.. literalinclude:: ../../generators/chipyard/src/main/scala/config/RocketConfigs.scala
:language: scala
:start-after: DOC include start: JtagRocket
:end-before: DOC include end: JtagRocket
Building a DTM+JTAG Simulator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
After creating the config, call the ``make`` command like the following to build a simulator for your RTL:
.. code-block:: bash
cd sims/verilator
# or
cd sims/vcs
make CONFIG=jtagRocketConfig
In this example, the simulation will use the config that you previously specified, as well as set
the other parameters that are needed to satisfy the build system. After that point, you
should have a JTAG enabled simulator that you can attach to using OpenOCD and GDB!
and configure it to use a JTAG interface. The default Chipyard designs instantiate the DTM and configure it
to use JTAG. You may attach OpenOCD and GDB to any of the default JTAG-enabled designs.
Debugging with JTAG
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -1,8 +1,8 @@
Debugging BOOM
======================
In addition to the default debugging techniques specified in :ref:`Debugging RTL`,
single-core BOOM designs can utilize the Dromajo co-simulator (see :ref:`Dromajo`)
In addition to the default debugging techniques specified in :ref:`Advanced-Concepts/Debugging-RTL:Debugging RTL`,
single-core BOOM designs can utilize the Dromajo co-simulator (see :ref:`Tools/Dromajo:Dromajo`)
to verify functionality.
.. warning:: Dromajo currently only works in single-core BOOM systems without accelerators.
@@ -12,11 +12,14 @@ to verify functionality.
Setting up Dromajo Co-simulation
--------------------------------------
Dromajo co-simulation is setup to work when two config fragments are added to a BOOM config.
First, a ``chipyard.config.WithTraceIO`` config fragment must be added so that BOOM's traceport is enabled.
Second, a ``chipyard.iobinders.WithSimDromajoBridge`` config fragment must be added to
connect the Dromajo co-simulator to the traceport.
Once both config fragments are added Dromajo should be enabled.
Dromajo co-simulation is setup to work when three config fragments are added to a BOOM config.
* A ``chipyard.config.WithTraceIO`` config fragment must be added so that BOOM's traceport is enabled.
* A ``chipyard.iobinders.WithTraceIOPunchthrough`` config fragment must be added to add the ``TraceIO`` to the ``ChipTop``
* A ``chipyard.harness.WithSimDromajoBridge`` config fragment must be added to instantiate a Dromajo cosimulator in the ``TestHarness`` and connect it to the ``ChipTop``'s ``TraceIO``
Once all config fragments are added Dromajo should be enabled.
To build/run Dromajo with a BOOM design, run your configuration the following make commands:

View File

@@ -14,9 +14,9 @@ ChipTop/DUT
``ChipTop`` is the top-level module that instantiates the ``System`` submodule, usually an instance of the concrete class ``DigitalTop``.
The vast majority of the design resides in the ``System``.
Other components that exist inside the ``ChipTop`` layer are generally IO cells, clock receivers and multiplexers, reset synchronizers, and other analog IP that needs to exist outside of the ``System``.
The ``IOBinders`` are responsible for instantiating the IO cells and defining the test harness collateral that connects to the top-level ports.
Most of these types of devices can be instantiated using custom ``IOBinders``, so the provided ``ChipTop`` and ``ChipTopCaughtReset`` classes are sufficient.
However, if needed, the ``BaseChipTop`` abstract class can be extended for building more custom ``ChipTop`` designs.
The ``IOBinders`` are responsible for instantiating the IO cells for ``ChipTop`` IO that correspond to IO of the ``System``.
The ``HarnessBinders`` are responsible for instantiating test harness collateral that connects to the ``ChipTop`` ports.
Most types of devices and testing collateral can be instantiated using custom ``IOBinders`` and ``HarnessBinders``.
System/DigitalTop
@@ -58,7 +58,7 @@ Tops
A SoC Top then extends the ``System`` class with traits for custom components.
In Chipyard, this includes things like adding a NIC, UART, and GPIO as well as setting up the hardware for the bringup method.
Please refer to :ref:`Communicating with the DUT` for more information on these bringup methods.
Please refer to :ref:`Advanced-Concepts/Chip-Communication:Communicating with the DUT` for more information on these bringup methods.
TestHarness
-------------------------

View File

@@ -14,15 +14,15 @@ Processor Cores
**Rocket Core**
An in-order RISC-V core.
See :ref:`Rocket Core` for more information.
See :ref:`Generators/Rocket:Rocket Core` for more information.
**BOOM (Berkeley Out-of-Order Machine)**
An out-of-order RISC-V core.
See :ref:`Berkeley Out-of-Order Machine (BOOM)` for more information.
See :ref:`Generators/BOOM:Berkeley Out-of-Order Machine (BOOM)` for more information.
**Ariane Core**
An in-order RISC-V core written in System Verilog.
See :ref:`Ariane Core` for more information.
**CVA6 Core**
An in-order RISC-V core written in System Verilog. Previously called Ariane.
See :ref:`Generators/CVA6:CVA6 Core` for more information.
Accelerators
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -31,7 +31,7 @@ Accelerators
A decoupled vector architecture co-processor.
Hwacha currently implements a non-standard RISC-V extension, using a vector architecture programming model.
Hwacha integrates with a Rocket or BOOM core using the RoCC (Rocket Custom Co-processor) interface.
See :ref:`Hwacha` for more information.
See :ref:`Generators/Hwacha:Hwacha` for more information.
**Gemmini**
A matrix-multiply accelerator targeting neural-networks
@@ -64,24 +64,24 @@ Tools
A hardware description library embedded in Scala.
Chisel is used to write RTL generators using meta-programming, by embedding hardware generation primitives in the Scala programming language.
The Chisel compiler elaborates the generator into a FIRRTL output.
See :ref:`Chisel` for more information.
See :ref:`Tools/Chisel:Chisel` for more information.
**FIRRTL**
An intermediate representation library for RTL description of digital designs.
FIRRTL is used as a formalized digital circuit representation between Chisel and Verilog.
FIRRTL enables digital circuits manipulation between Chisel elaboration and Verilog generation.
See :ref:`FIRRTL` for more information.
See :ref:`Tools/FIRRTL:FIRRTL` for more information.
**Barstools**
A collection of common FIRRTL transformations used to manipulate a digital circuit without changing the generator source RTL.
See :ref:`Barstools` for more information.
See :ref:`Tools/Barstools:Barstools` for more information.
**Dsptools**
A Chisel library for writing custom signal processing hardware, as well as integrating custom signal processing hardware into an SoC (especially a Rocket-based SoC).
**Dromajo**
A RV64GC emulator primarily used for co-simulation and was originally developed by Esperanto Technologies.
See :ref:`Dromajo` for more information.
See :ref:`Tools/Dromajo:Dromajo` for more information.
Toolchains
-------------------------------------------
@@ -106,15 +106,15 @@ Software
Sims
-------------------------------------------
**verilator (Verilator wrapper)**
**Verilator**
Verilator is an open source Verilog simulator.
The ``verilator`` directory provides wrappers which construct Verilator-based simulators from relevant generated RTL, allowing for execution of test RISC-V programs on the simulator (including vcd waveform files).
See :ref:`Verilator (Open-Source)` for more information.
See :ref:`Simulation/Software-RTL-Simulation:Verilator (Open-Source)` for more information.
**vcs (VCS wrapper)**
**VCS**
VCS is a proprietary Verilog simulator.
Assuming the user has valid VCS licenses and installations, the ``vcs`` directory provides wrappers which construct VCS-based simulators from relevant generated RTL, allowing for execution of test RISC-V programs on the simulator (including vcd/vpd waveform files).
See :ref:`Synopsys VCS (License Required)` for more information.
See :ref:`Simulation/Software-RTL-Simulation:Synopsys VCS (License Required)` for more information.
**FireSim**
FireSim is an open-source FPGA-accelerated simulation platform, using Amazon Web Services (AWS) EC2 F1 instances on the public cloud.
@@ -122,7 +122,16 @@ Sims
To model I/O, FireSim includes synthesizeable and timing-accurate models for standard interfaces like DRAM, Ethernet, UART, and others.
The use of the elastic public cloud enable FireSim to scale simulations up to thousands of nodes.
In order to use FireSim, the repository must be cloned and executed on AWS instances.
See :ref:`FireSim` for more information.
See :ref:`Simulation/FPGA-Accelerated-Simulation:FireSim` for more information.
Prototyping
-------------------------------------------
**FPGA Prototyping**
FPGA prototyping is supported in Chipyard using SiFive's ``fpga-shells``.
Some examples of FPGAs supported are the Xilinx Arty 35T and VCU118 boards.
For a fast and deterministic simulation with plenty of debugging tools, please consider using the :ref:`Simulation/FPGA-Accelerated-Simulation:FireSim` platform.
See :ref:`Prototyping/index:Prototyping Flow` for more information on FPGA prototypes.
VLSI
-------------------------------------------
@@ -132,4 +141,4 @@ VLSI
The HAMMER flow provide automated scripts which generate relevant tool commands based on a higher level description of physical design constraints.
The Hammer flow also allows for re-use of process technology knowledge by enabling the construction of process-technology-specific plug-ins, which describe particular constraints relating to that process technology (obsolete standard cells, metal layer routing constraints, etc.).
The Hammer flow requires access to proprietary EDA tools and process technology libraries.
See :ref:`Core HAMMER` for more information.
See :ref:`VLSI/Hammer:Core HAMMER` for more information.

View File

@@ -17,7 +17,7 @@ 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 (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`).
Configs can take arguments which will in-turn set parameters in the design or reference other parameters in the design (see :ref:`Chipyard-Basics/Configs-Parameters-Mixins: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.
@@ -121,7 +121,7 @@ This is shown in the ``Top`` class where things such as ``CanHavePeripherySerial
Additional References
---------------------------
Another description of traits/mixins and config fragments is given in :ref:`Keys, Traits, and Configs`.
Another description of traits/mixins and config fragments is given in :ref:`Customization/Keys-Traits-Configs: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).

View File

@@ -73,7 +73,7 @@ This depends on what you are planning to do with Chipyard.
* If you intend to run a simulation of one of the vanilla Chipyard examples, go to :ref:`sw-rtl-sim-intro` and follow the instructions.
* If you intend to run a simulation of a custom Chipyard SoC Configuration, go to :ref:`Simulating A Custom Project` and follow the instructions.
* If you intend to run a simulation of a custom Chipyard SoC Configuration, go to :ref:`Simulation/Software-RTL-Simulation:Simulating A Custom Project` and follow the instructions.
* If you intend to run a full-system FireSim simulation, go to :ref:`firesim-sim-intro` and follow the instructions.

View File

@@ -34,7 +34,7 @@ FESVR is a program that runs on the host CPU and can read/write arbitrary
parts of the target system memory using the Tethered Serial Interface (TSI).
FESVR uses TSI to load a baremetal executable or second-stage bootloader into
the SoC memory. In :ref:`Software RTL Simulation`, this will be the binary you
the SoC memory. In :ref:`Simulation/Software-RTL-Simulation:Software RTL Simulation`, this will be the binary you
pass to the simulator. Once it is finished loading the program, FESVR will
write to the software interrupt register for CPU 0, which will bring CPU 0
out of its WFI loop. Once it receives the interrupt, CPU 0 will write to

View File

@@ -0,0 +1,301 @@
.. _custom_core:
Adding a custom core
====================
You may want to integrate a custom RISC-V core into the Chipyard framework. This documentation page provides step-by-step
instructions on how to achieve this.
.. note::
RoCC is currently not supported by cores other than Rocket and BOOM. Please use Rocket or BOOM as the RoCC base core if you need to use RoCC.
.. note::
This page contains links to the files that contains important definitions in the Rocket chip repository, which is maintained separately
from Chipyard. If you find any discrepancy between the code on this page and the code in the source file, please report it through
GitHub issues!
Wrap Verilog Module with Blackbox (Optional)
--------------------------------------------
Since Chipyard uses Scala and Chisel, if the top module of your core is not in Chisel, you will first need to create a Verilog
blackbox for it so that it can be processed by Chipyard. See :ref:`incorporating-verilog-blocks` for instructions.
Create Parameter Case Classes
-----------------------------
Chipyard will generate a core for every ``InstantiableTileParams`` object it discovered in the ``TilesLocated(InSubsystem)`` key.
This object is derived from``TileParams``, a trait containing the information needed to create a tile. All cores must have
their own implementation of ``InstantiableTileParams``, as well as ``CoreParams`` which is passed as a field in ``TileParams``.
``TileParams`` holds the parameters for the tile, which include parameters for all components in the tile (e.g.
core, cache, MMU, etc.), while ``CoreParams`` contains parameters specific to the core on the tile.
They must be implemented as case classes with fields that can be overridden by
other config fragments as the constructor parameters. See the appendix at the bottom of the page for a list of
variable to be implemented. You can also add custom fields to them, but standard fields should always be preferred.
``InstantiableTileParams[TileType]`` holds the constructor of ``TileType`` on top of the fields of ``TileParams``,
where ``TileType`` is the tile class (see the next section).
All custom cores will also need to implement ``instantiate()`` in their tile parameter class to return a new instance
of the tile class ``TileType``.
``TileParams`` (in the file `BaseTile.scala <https://github.com/chipsalliance/rocket-chip/blob/master/src/main/scala/tile/BaseTile.scala>`_) ,
``InstantiableTileParams`` (in the file `BaseTile.scala <https://github.com/chipsalliance/rocket-chip/blob/master/src/main/scala/tile/BaseTile.scala>`_),
``CoreParams`` (in the file `Core.scala <https://github.com/chipsalliance/rocket-chip/blob/master/src/main/scala/tile/Core.scala>`_),
and ``FPUParams`` (in the file `FPU.scala <https://github.com/chipsalliance/rocket-chip/blob/master/src/main/scala/tile/FPU.scala>`_)
contains the following fields:
.. code-block:: scala
trait TileParams {
val core: CoreParams // Core parameters (see below)
val icache: Option[ICacheParams] // Rocket specific: I1 cache option
val dcache: Option[DCacheParams] // Rocket specific: D1 cache option
val btb: Option[BTBParams] // Rocket specific: BTB / branch predictor option
val hartId: Int // Hart ID: Must be unique within a design config (This MUST be a case class parameter)
val beuAddr: Option[BigInt] // Rocket specific: Bus Error Unit for Rocket Core
val blockerCtrlAddr: Option[BigInt] // Rocket specific: Bus Blocker for Rocket Core
val name: Option[String] // Name of the core
}
abstract class InstantiableTileParams[TileType <: BaseTile] extends TileParams {
def instantiate(crossing: TileCrossingParamsLike, lookup: LookupByHartIdImpl)
(implicit p: Parameters): TileType
}
trait CoreParams {
val bootFreqHz: BigInt // Frequency
val useVM: Boolean // Support virtual memory
val useUser: Boolean // Support user mode
val useSupervisor: Boolean // Support supervisor mode
val useDebug: Boolean // Support RISC-V debug specs
val useAtomics: Boolean // Support A extension
val useAtomicsOnlyForIO: Boolean // Support A extension for memory-mapped IO (may be true even if useAtomics is false)
val useCompressed: Boolean // Support C extension
val useVector: Boolean = false // Support V extension
val useSCIE: Boolean // Support custom instructions (in custom-0 and custom-1)
val useRVE: Boolean // Use E base ISA
val mulDiv: Option[MulDivParams] // *Rocket specific: M extension related setting (Use Some(MulDivParams()) to indicate M extension supported)
val fpu: Option[FPUParams] // F and D extensions and related setting (see below)
val fetchWidth: Int // Max # of insts fetched every cycle
val decodeWidth: Int // Max # of insts decoded every cycle
val retireWidth: Int // Max # of insts retired every cycle
val instBits: Int // Instruction bits (if 32 bit and 64 bit are both supported, use 64)
val nLocalInterrupts: Int // # of local interrupts (see SiFive interrupt cookbook)
val nPMPs: Int // # of Physical Memory Protection units
val pmpGranularity: Int // Size of the smallest unit of region for PMP unit (must be power of 2)
val nBreakpoints: Int // # of hardware breakpoints supported (in RISC-V debug specs)
val useBPWatch: Boolean // Support hardware breakpoints
val nPerfCounters: Int // # of supported performance counters
val haveBasicCounters: Boolean // Support basic counters defined in the RISC-V counter extension
val haveFSDirty: Boolean // If true, the core will set FS field in mstatus CSR to dirty when appropriate
val misaWritable: Boolean // Support writable misa CSR (like variable instruction bits)
val haveCFlush: Boolean // Rocket specific: enables Rocket's custom instruction extension to flush the cache
val nL2TLBEntries: Int // # of L2 TLB entries
val mtvecInit: Option[BigInt] // mtvec CSR (of V extension) initial value
val mtvecWritable: Boolean // If mtvec CSR is writable
// Normally, you don't need to change these values (except lrscCycles)
def customCSRs(implicit p: Parameters): CustomCSRs = new CustomCSRs
def hasSupervisorMode: Boolean = useSupervisor || useVM
def instBytes: Int = instBits / 8
def fetchBytes: Int = fetchWidth * instBytes
// Rocket specific: Longest possible latency of Rocket core D1 cache. Simply set it to the default value 80 if you don't use it.
def lrscCycles: Int
def dcacheReqTagBits: Int = 6
def minFLen: Int = 32
def vLen: Int = 0
def sLen: Int = 0
def eLen(xLen: Int, fLen: Int): Int = xLen max fLen
def vMemDataBits: Int = 0
}
case class FPUParams(
minFLen: Int = 32, // Minimum floating point length (no need to change)
fLen: Int = 64, // Maximum floating point length, use 32 if only single precision is supported
divSqrt: Boolean = true, // Div/Sqrt operation supported
sfmaLatency: Int = 3, // Rocket specific: Fused multiply-add pipeline latency (single precision)
dfmaLatency: Int = 4 // Rocket specific: Fused multiply-add pipeline latency (double precision)
)
Most of the fields here (marked "Rocket spcific") are originally designed for the Rocket core and thus contain some
implementation-specific details, but many of them are general enough to be useful for other cores. You may ignore
any fields marked "Rocket specific" and use their default values; however, if you need to store additional information
with meaning or usage similar to these "Rocket specific" fields, it is recommended to use these fields instead of
creating your own custom fields.
You will also need a ``CanAttachTile`` class to add the tile config into the config system, with the following format:
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/TutorialTile.scala
:language: scala
:start-after: DOC include start: CanAttachTile
:end-before: DOC include end: CanAttachTile
During elaboration, Chipyard will look for subclasses of ``CanAttachTile`` in the config system and instantiate a tile
from the parameters in this class for every such class it found.
.. note::
Implementations may choose to ignore some fields here or use them in a non-standard way, but using an inaccurate
value may break Chipyard components that rely on them (e.g. an inaccurate indication of supported ISA extension will
result in an incorrect test suite being generated) as well as any custom modules that use them. ALWAYS document any
fields you ignore or with altered usage in your core implementation, and if you are implementing other devices that
would look up these config values, also document them. "Rocket specific" values are generally safe to ignore, but
you should document them if you use them.
Create Tile Class
-----------------
In Chipyard, all Tiles are diplomatically instantiated. In the first phase, diplomatic nodes which specify Tile-to-System
interconnects are evaluated, while in the second "Module Implementation" phase, hardware is elaborated.
See :ref:`tilelink_and_diplomacy` for more details. In this step, you will need to implement a tile class for your core,
which specifies the constraints on the core's parameters and the connections with other diplomatic nodes. This class
usually contains Diplomacy/TileLink code only, and Chisel RTL code should not go here.
All tile classes implement ``BaseTile`` and will normally implement ``SinksExternalInterrupts`` and ``SourcesExternalNotifications``,
which allow the tile to accept external interrupt. A typical tile has the following form:
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/TutorialTile.scala
:language: scala
:start-after: DOC include start: Tile class
:end-before: DOC include end: Tile class
Connect TileLink Buses
----------------------
Chipyard uses TileLink as its onboard bus protocol. If your core doesn't use TileLink, you will need to insert converters
between the core's memory protocol and TileLink within the Tile module.
in the tile class. Below is an example of how to connect a core using AXI4 to the TileLink bus with converters provided by
Rocket chip:
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/TutorialTile.scala
:language: scala
:start-after: DOC include start: AXI4 convert
:end-before: DOC include end: AXI4 convert
Remember, you may not need all of these intermediate widgets. See :ref:`diplomatic_widgets` for the meaning of each intermediate
widget. If you are using TileLink, then you only need the tap node and the TileLink node used by your components. Chipyard also
provides converters for AHB, APB and AXIS, and most of the AXI4 widgets has equivalent widget for these bus protocol; see the
source files in ``generators/rocket-chip/src/main/scala/amba`` for more info.
If you are using some other bus protocol, you may implement your own converters, using the files in ``generators/rocket-chip/src/main/scala/amba``
as the template, but it is not recommended unless you are familiar with TileLink.
``memAXI4Node`` is an AXI4 master node and is defined as following in our example:
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/TutorialTile.scala
:language: scala
:start-after: DOC include start: AXI4 node
:end-before: DOC include end: AXI4 node
where ``portName`` and ``idBits`` (number of bits to represent a port ID) are the parameter provides by the tile.
Make sure to read :ref:`node_types` to check out what type of nodes Chipyard supports and their parameters!
Also, by default, there are boundary buffers for both master and slave connections to the bus when they are leaving the tile, and you
can override the following two functions to control how to buffer the bus requests/responses:
(You can find the definition of these two functions in the class ``BaseTile`` in the file
`BaseTile.scala <https://github.com/chipsalliance/rocket-chip/blob/master/src/main/scala/tile/BaseTile.scala>`_)
.. code-block:: scala
// By default, their value is "TLBuffer(BufferParams.none)".
protected def makeMasterBoundaryBuffers(implicit p: Parameters): TLBuffer
protected def makeSlaveBoundaryBuffers(implicit p: Parameters): TLBuffer
You can find more information on ``TLBuffer`` in :ref:`diplomatic_widgets`.
Create Implementation Class
---------------------------
The implementation class contains the parameterized, actual hardware that depends on the values resolved by the Diplomacy
framework according to the info provided in the Tile class. This class will normally contains Chisel RTL code. If your
core is in Verilog, you will need to instantiate the black box class that wraps your Verilog implementation and connect it with the buses
and other components. No Diplomacy/TileLink code should be in this class; you should only connect the IO signals in TileLink
interfaces or other diplomatically defined components, which are located in the tile class.
The implementation class for your core is of the following form:
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/TutorialTile.scala
:language: scala
:start-after: DOC include start: Implementation class
:end-before: DOC include end: Implementation class
If you create an AXI4 node (or equivalents), you will need to connect them to your core. You can connect a port like this:
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/TutorialTile.scala
:language: scala
:start-after: DOC include start: AXI4 connect
:end-before: DOC include end: AXI4 connect
Connect Interrupt
-----------------
Chipyard allows a tile to either receive interrupts from other devices or initiate interrupts to notify other cores/devices.
In the tile that inherited ``SinksExternalInterrupts``, one can create a ``TileInterrupts`` object (a Chisel bundle) and
call ``decodeCoreInterrupts()`` with the object as the argument. Note that you should call this function in the implementation
class since it returns a Chisel bundle used by RTL code. You can then read the interrupt bits from the ``TileInterrupts`` bundle
we create above. The definition of ``TileInterrupts``
(in the file `Interrupts.scala <https://github.com/chipsalliance/rocket-chip/blob/master/src/main/scala/tile/Interrupts.scala>`_) is
.. code-block:: scala
class TileInterrupts(implicit p: Parameters) extends CoreBundle()(p) {
val debug = Bool() // debug interrupt
val mtip = Bool() // Machine level timer interrupt
val msip = Bool() // Machine level software interrupt
val meip = Bool() // Machine level external interrupt
val seip = usingSupervisor.option(Bool()) // Valid only if supervisor mode is supported
val lip = Vec(coreParams.nLocalInterrupts, Bool()) // Local interrupts
}
Here is an example on how to connect these signals in the implementation class:
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/TutorialTile.scala
:language: scala
:start-after: DOC include start: connect interrupt
:end-before: DOC include end: connect interrupt
Also, the tile can also notify other cores or devices for some events by calling following functions in ``SourcesExternalNotifications``
from the implementation class:
(These functions can be found in in the trait ``SourcesExternalNotifications`` in the file
`Interrupts.scala <https://github.com/chipsalliance/rocket-chip/blob/master/src/main/scala/tile/Interrupts.scala>`_)
.. code-block:: scala
def reportHalt(could_halt: Option[Bool]) // Triggered when there is an unrecoverable hardware error (halt the machine)
def reportHalt(errors: Seq[CanHaveErrors]) // Varient for standard error bundle (Rocket specific: used only by cache when there's an ECC error)
def reportCease(could_cease: Option[Bool], quiescenceCycles: Int = 8) // Triggered when the core stop retiring instructions (like clock gating)
def reportWFI(could_wfi: Option[Bool]) // Triggered when a WFI instruction is executed
Here is an example on how to use these functions to raise interrupt.
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/TutorialTile.scala
:language: scala
:start-after: DOC include start: raise interrupt
:end-before: DOC include end: raise interrupt
Create Config Fragments to Integrate the Core
---------------------------------------------
To use your core in a Chipyard config, you will need a config fragment that will create a ``TileParams`` object of your core in
the current config. An example of such config will be like this:
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/TutorialTile.scala
:language: scala
:start-after: DOC include start: Config fragment
:end-before: DOC include end: Config fragment
Chipyard looks up the tile parameters in the field ``TilesLocated(InSubsystem)``, whose type is a list of ``InstantiableTileParams``.
This config fragment simply appends new tile parameters to the end of this list.
Now you have finished all the steps to prepare your cores for Chipyard! To generate the custom core, simply follow the instructions
in :ref:`custom_chisel` to add your project to the build system, then create a config by following the steps in :ref:`hetero_socs_`.
You can now run most desired workflows for the new config just as you would for the built-in cores (depending on the functionality your core supports).
If you would like to see an example of a complete third-party Verilog core integrated into Chipyard, ``generators/ariane/src/main/scala/CVA6Tile.scala``
provides a concrete example of the CVA6 core. Note that this particular example includes additional nuances with respect to the interaction of the AXI
interface with the memory coherency system.

View File

@@ -22,7 +22,7 @@ that writes zeros to the memory at a configured address.
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`.
For more info on creating TileLink client nodes, take a look at :ref:`TileLink-Diplomacy-Reference/NodeTypes: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.

View File

@@ -5,7 +5,7 @@ Adding a Firrtl Transform
Similar to how LLVM IR passes can perform transformations and optimizations on software, FIRRTL transforms can
modify Chisel-elaborated RTL.
As mentioned in Section :ref:`firrtl`, transforms are modifications that happen on the FIRRTL IR that can modify a circuit.
As mentioned in Section :ref:`Tools/FIRRTL:firrtl`, transforms are modifications that happen on the FIRRTL IR that can modify a circuit.
Transforms are a powerful tool to take in the FIRRTL IR that is emitted from Chisel and run analysis or convert the circuit into a new form.
Where to add transforms
@@ -24,7 +24,7 @@ If you look inside of the `tools/barstools/tapeout/src/main/scala/transforms/Gen
you can see that FIRRTL is invoked twice, once for the "Top" and once for the "Harness". If you want to add transforms to just modify the DUT, you can add them to ``topTransforms``.
Otherwise, if you want to add transforms to just modify the test harness, you can add them to ``harnessTransforms``.
For more information on Barstools, please visit the :ref:`Barstools` section.
For more information on Barstools, please visit the :ref:`Tools/Barstools:Barstools` section.
Examples of transforms
----------------------

View File

@@ -1,3 +1,5 @@
.. _hetero_socs_:
Heterogeneous SoCs
===============================
@@ -8,7 +10,7 @@ Creating a Rocket and BOOM System
-------------------------------------------
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]_.
Both BOOM and Rocket have config fragments labelled ``WithN{Small|Medium|Large|etc.}BoomCores(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.
@@ -18,52 +20,6 @@ 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`` 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`` 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 config fragment to add to your system would look something like the following.
.. code-block:: scala
// create 6 cores (4 boom and 2 rocket)
class WithHeterCoresSetup extends Config((site, here, up) => {
case BoomTilesKey => {
val boomTile0 = BoomTileParams(...) // params for boom core 0
val boomTile1 = BoomTileParams(...) // params for boom core 1
val boomTile2 = BoomTileParams(...) // params for boom core 2
val boomTile3 = BoomTileParams(...) // params for boom core 3
Seq(boomTile0, boomTile1, boomTile2, boomTile3)
}
case RocketTilesKey => {
val rocketTile0 = RocketTileParams(...) // params for rocket core 0
val rocketTile1 = RocketTileParams(...) // params for rocket core 1
Seq(rocketTile0, rocketTile1)
}
})
Then you could use this new config fragment like the following.
.. code-block:: scala
class SixCoreConfig extends Config(
new WithTSI ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new WithHeterCoresSetup ++
new freechips.rocketchip.system.BaseConfig)
Note, in this setup you need to specify the ``hartId`` of each core in the "TileParams", where each ``hartId`` is unique.
Adding Hwachas
-------------------------------------------
@@ -92,8 +48,7 @@ An example is shown below with two BOOM cores, and one Rocket tile with a RoCC a
:start-after: DOC include start: DualBoomAndRocketOneHwacha
: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`` config fragment assigns a Hwacha accelerator to a particular ``hartId`` (in this case, the ``hartId`` of ``2`` corresponds to the Rocket core).
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.

View File

@@ -1,41 +1,43 @@
IOBinders and HarnessBinders
============================
In Chipyard we use special ``Parameters`` keys, ``IOBinders`` and ``HarnessBinders`` to bridge the gap between digital system IOs and TestHarness collateral.
IOBinders
=========
---------
The ``IOBinder`` functions are responsible for instantiating IO cells and IOPorts in the ``ChipTop`` layer.
``IOBinders`` are typically defined using the ``OverrideIOBinder`` or ``ComposeIOBinder`` macros. An ``IOBinder`` consists of a function matching ``Systems`` with a given trait that generates IO ports and IOCells, and returns a list of generated ports and cells.
For example, the ``WithUARTIOCells`` IOBinder will, for any ``System`` that might have UART ports (``HasPeripheryUARTModuleImp``, generate ports within the ``ChipTop`` (``ports``) as well as IOCells with the appropriate type and direction (``cells2d``). This function returns a the list of generated ports, and the list of generated IOCells. The list of generated ports is passed to the ``HarnessBinders`` such that they can be connected to ``TestHarness`` devices.
In Chipyard we use a special ``Parameters`` key, ``IOBinders`` to instantiate IO cells in the ``ChipTop`` layer and determine what modules to bind to the IOs of a ``ChipTop`` in the ``TestHarness``.
.. literalinclude:: ../../generators/chipyard/src/main/scala/IOBinders.scala
:language: scala
:start-after: DOC include start: IOBinders
:end-before: DOC include end: IOBinders
:start-after: DOC include start: WithUARTIOCells
:end-before: DOC include end: WithUARTIOCells
HarnessBinders
--------------
This special key solves the problem of duplicating test-harnesses for each different ``System`` type.
You could just as well create a custom harness module that attaches IOs explicitly.
Instead, the ``IOBinders`` key provides a map from Scala traits to attachment behaviors.
Each ``IOBinder`` returns a tuple of three values: the list of ``ChipTop`` ports created by the ``IOBinder``, the list of all IO cell modules instantiated by the ``IOBinder``, and an optional function to be called inside the test harness.
This function is responsible for instantiating logic inside the ``TestHarness`` to appropriately drive the ``ChipTop`` IO ports created by the ``IOBinder``.
Conveniently, because the ``IOBinder`` is generating the port, it may also use the port inside this function, which prevents the ``BaseChipTop`` code from ever needing to access the port ``val``, thus having the ``IOBinder`` house all port specific code.
This scheme prevents the need to have two separate binder functions for each ``System`` trait.
When creating custom ``IOBinders`` it is important to use ``suggestName`` to name ports; otherwise Chisel will raise an exception trying to name the IOs.
The example ``IOBinders`` demonstrate this.
The ``HarnessBinder`` functions determine what modules to bind to the IOs of a ``ChipTop`` in the ``TestHarness``. The ``HarnessBinder`` interface is designed to be reused across various simulation/implementation modes, enabling decoupling of the target design from simulation and testing concerns.
As an example, the ``WithGPIOTiedOff`` IOBinder creates IO cells for the GPIO module(s) instantiated in the ``System``, then punches out new ``Analog`` ports for each one.
The test harness simply ties these off, but additional logic could be inserted to perform some kind of test in the ``TestHarness``.
* For SW RTL or GL simulations, the default set of ``HarnessBinders`` instantiate software-simulated models of various devices, for example external memory or UART, and connect those models to the IOs of the ``ChipTop``.
* For FireSim simulations, FireSim-specific ``HarnessBinders`` instantiate ``Bridges``, which faciliate cycle-accurate simulation across the simulated chip's IOs. See the FireSim documentation for more details.
* In the future, a Chipyard FPGA prototyping flow may use ``HarnessBinders`` to connect ``ChipTop`` IOs to other devices or IOs in the FPGA harness.
.. literalinclude:: ../../generators/chipyard/src/main/scala/IOBinders.scala
Like ``IOBinders``, ``HarnessBinders`` are defined using macros (``OverrideHarnessBinder, ComposeHarnessBinder``), and match ``Systems`` with a given trait. However, ``HarnessBinders`` are also passed a reference to the ``TestHarness`` (``th: HasHarnessSignalReferences``) and the list of ports generated by the corresponding ``IOBinder`` (``ports: Seq[Data]``).
For exmaple, the ``WithUARTAdapter`` will connect the UART SW display adapter to the ports generated by the ``WithUARTIOCells`` described earlier, if those ports are present.
.. literalinclude:: ../../generators/chipyard/src/main/scala/HarnessBinders.scala
:language: scala
:start-after: DOC include start: WithGPIOTiedOff
:end-before: DOC include end: WithGPIOTiedOff
:start-after: DOC include start: WithUARTAdapter
:end-before: DOC include end: WithUARTAdapter
The ``IOBinder`` and ``HarnessBinder`` system is designed to enable decoupling of concerns between the target design and the simulation system.
``IOBinders`` also do not need to create ports. Some ``IOBinders`` can simply insert circuitry inside the ``ChipTop`` layer.
For example, the ``WithSimAXIMemTiedOff`` IOBinder specifies that any ``System`` which matches ``CanHaveMasterAXI4MemPortModuleImp`` will have a ``SimAXIMem`` connected inside ``ChipTop``.
For a given set of chip IOs, there may be not only multiple simulation platforms ("harnesses", so-to-speak), but also multiple simulation strategies. For example, the choice of whether to connect the backing AXI4 memory port to an accurate DRAM model (``SimDRAM``) or a simple simulated memory model (``SimAXIMem``) is isolated in ``HarnessBinders``, and does not affect target RTL generation.
.. literalinclude:: ../../generators/chipyard/src/main/scala/IOBinders.scala
:language: scala
:start-after: DOC include start: WithSimAXIMem
:end-before: DOC include end: WithSimAXIMem
These classes are all ``Config`` objects, which can be mixed into the configs to specify IO connection behaviors.
There are two macros for generating these ``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.
Similarly, for a given simulation platform and strategy, there may be multiple strategies for generating the chip IOs. This target-design configuration is isolated in the ``IOBinders``.

View File

@@ -13,7 +13,7 @@ if you use the ``WithNMedCores`` or ``WithNSmallCores`` configurations, you can
configure 4 KiB direct-mapped caches for L1I and L1D.
If you only want to change the size or associativity, there are config
fragments for those too. See :ref:`Config Fragments` for how to add these to a custom ``Config``.
fragments for those too. See :ref:`Customization/Keys-Traits-Configs:Config Fragments` for how to add these to a custom ``Config``.
.. code-block:: scala

View File

@@ -7,6 +7,8 @@ These guides will walk you through customization of your system-on-chip:
- How to include your custom Chisel sources in the Chipyard build system
- Adding custom core
- 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
@@ -35,6 +37,7 @@ We recommend reading all these pages in order. Hit next to get started!
Heterogeneous-SoCs
Custom-Chisel
Custom-Core
RoCC-or-MMIO
RoCC-Accelerators
MMIO-Peripherals

View File

@@ -1,14 +1,14 @@
Ariane Core
CVA6 Core
====================================
`Ariane <https://github.com/pulp-platform/ariane>`__ is a 6-stage in-order scalar processor core, originally developed at ETH-Zurich by F. Zaruba and L. Benini.
The `Ariane core` is wrapped in an `Ariane tile` so it can be used as a component within the `Rocket Chip SoC generator`.
`CVA6 <https://github.com/openhwgroup/cva6>`__ (previously called Ariane) is a 6-stage in-order scalar processor core, originally developed at ETH-Zurich by F. Zaruba and L. Benini.
The `CVA6 core` is wrapped in an `CVA6 tile` so it can be used as a component within the `Rocket Chip SoC generator`.
The core by itself exposes an AXI interface, interrupt ports, and other misc. ports that are connected from within the tile to TileLink buses and other parameterization signals.
.. Warning:: Since the core uses an AXI interface to connect to memory, it is highly recommended to use the core in a single-core setup (since AXI is a non-coherent memory interface).
While the core itself is not a generator, we expose the same parameterization that the Ariane core provides (i.e. change branch prediction parameters).
While the core itself is not a generator, we expose the same parameterization that the CVA6 core provides (i.e. change branch prediction parameters).
.. Warning:: This target does not support Verilator simulation at this time. Please use VCS.
For more information, please refer to the `GitHub repository <https://github.com/pulp-platform/ariane>`__.
For more information, please refer to the `GitHub repository <https://github.com/openhwgroup/cva6>`__.

View File

@@ -8,11 +8,11 @@ A diagram of IceNet's microarchitecture is shown below.
.. image:: ../_static/images/nic-design.png
There are four basic parts of the NIC: the :ref:`Controller`, which takes requests
from and sends responses to the CPU; the :ref:`Send Path`, which reads data from
memory and sends it out to the network; the :ref:`Receive Path`, which receives
There are four basic parts of the NIC: the :ref:`Generators/IceNet:Controller`, which takes requests
from and sends responses to the CPU; the :ref:`Generators/IceNet:Send Path`, which reads data from
memory and sends it out to the network; the :ref:`Generators/IceNet:Receive Path`, which receives
data from the network and writes it to memory; and, optionally,
the :ref:`Pause Handler`, which generates Ethernet pause frames for the purpose
the :ref:`Generators/IceNet:Pause Handler`, which generates Ethernet pause frames for the purpose
of flow control.
Controller
@@ -78,7 +78,7 @@ Configuration
To add IceNIC to your design, add ``HasPeripheryIceNIC`` to your lazy module
and ``HasPeripheryIceNICModuleImp`` to the module implementation. If you
are confused about the distinction between lazy module and module
implementation, refer to :ref:`Cake Pattern / Mixin`.
implementation, refer to :ref:`Chipyard-Basics/Configs-Parameters-Mixins:Cake Pattern / Mixin`.
Then add the ``WithIceNIC`` config fragment to your configuration. This will
define ``NICKey``, which IceNIC uses to determine its parameters. The config fragment

View File

@@ -30,7 +30,7 @@ The tiles connect to the ``SystemBus``, which connect it to the L2 cache banks.
The L2 cache banks then connect to the ``MemoryBus``, which connects to the
DRAM controller through a TileLink to AXI converter.
To learn more about the memory hierarchy, see :ref:`Memory Hierarchy`.
To learn more about the memory hierarchy, see :ref:`Customization/Memory-Hierarchy:Memory Hierarchy`.
MMIO
----

17
docs/Generators/Sodor.rst Normal file
View File

@@ -0,0 +1,17 @@
Sodor Core
====================================
`Sodor <https://github.com/ucb-bar/riscv-sodor>`__ is a collection of 5 simple RV32MI cores designed for educational purpose.
The `Sodor core` is wrapped in an tile during generation so it can be used as a component within the `Rocket Chip SoC generator`.
The cores contain a small scratchpad memory to which the program are loaded through a TileLink slave port, and the cores **DO NOT**
support external memory.
The five available cores and their corresponding generator configuration are:
* 1-stage (essentially an ISA simulator) - ``Sodor1StageConfig``
* 2-stage (demonstrates pipelining in Chisel) - ``Sodor2StageConfig``
* 3-stage (uses sequential memory; supports both Harvard (``Sodor3StageConfig``) and Princeton (``Sodor3StageSinglePortConfig``) versions)
* 5-stage (can toggle between fully bypassed or fully interlocked) - ``Sodor5StageConfig``
* "bus"-based micro-coded implementation - ``SodorUCodeConfig``
For more information, please refer to the `GitHub repository <https://github.com/ucb-bar/riscv-sodor>`__.

View File

@@ -2,9 +2,9 @@ Test Chip IP
============
Chipyard includes a Test Chip IP library which provides various hardware
widgets that may be useful when designing SoCs. This includes a :ref:`Serial Adapter`,
:ref:`Block Device Controller`, :ref:`TileLink SERDES`, :ref:`TileLink Switcher`,
:ref:`TileLink Ring Network`, and :ref:`UART Adapter`.
widgets that may be useful when designing SoCs. This includes a :ref:`Generators/TestChipIP:Serial Adapter`,
:ref:`Generators/TestChipIP:Block Device Controller`, :ref:`Generators/TestChipIP:TileLink SERDES`, :ref:`Generators/TestChipIP:TileLink Switcher`,
:ref:`Generators/TestChipIP:TileLink Ring Network`, and :ref:`Generators/TestChipIP:UART Adapter`.
Serial Adapter
--------------
@@ -14,7 +14,7 @@ processor. An instance of RISC-V frontend server running on the host CPU
can send commands to the serial adapter to read and write data from the memory
system. The frontend server uses this functionality to load the test program
into memory and to poll for completion of the program. More information on
this can be found in :ref:`Chipyard Boot Process`.
this can be found in :ref:`Customization/Boot-Process:Chipyard Boot Process`.
Block Device Controller
-----------------------
@@ -69,7 +69,7 @@ to the TLXbar provided by RocketChip, but uses ring networks internally rather
than crossbars. This can be useful for chips with very wide TileLink networks
(many cores and L2 banks) that can sacrifice cross-section bandwidth to relieve
wire routing congestion. Documentation on how to use the ring network can be
found in :ref:`The System Bus`. The implementation itself can be found
found in :ref:`Customization/Memory-Hierarchy:The System Bus`. The implementation itself can be found
`here <https://github.com/ucb-bar/testchipip/blob/master/src/main/scala/Ring.scala>`_,
and may serve as an example of how to implement your own TileLink network with
a different topology.

View File

@@ -4,7 +4,7 @@ Included RTL Generators
============================
A Generator can be thought of as a generalized RTL design, written using a mix of meta-programming and standard RTL.
This type of meta-programming is enabled by the Chisel hardware description language (see :ref:`Chisel`).
This type of meta-programming is enabled by the Chisel hardware description language (see :ref:`Tools/Chisel:Chisel`).
A standard RTL design is essentially just a single instance of a design coming from a generator.
However, by using meta-programming and parameter systems, generators can allow for integration of complex hardware designs in automated ways.
The following pages introduce the generators integrated with the Chipyard framework.
@@ -27,6 +27,7 @@ so changes to the generators themselves will automatically be used when building
TestChipIP
SiFive-Generators
SHA3
Ariane
CVA6
NVDLA
Sodor

26
docs/Prototyping/Arty.rst Normal file
View File

@@ -0,0 +1,26 @@
Running a Design on Arty
========================
Basic Arty Design
-----------------
The default Xilinx Arty 35T harness is setup to have JTAG available over the board's PMOD pins, and UART available over its FTDI serial USB adapter. The pin mappings for JTAG signals are identical to those described in the `SiFive Freedom E310 Arty 35T Getting Started Guide <https://static.dev.sifive.com/SiFive-E310-arty-gettingstarted-v1.0.6.pdf>`__.
The JTAG interface allows a user to connect to the core via OpenOCD, run bare-metal applications, and debug these applications with gdb. UART allows a user to communicate with the core over a USB connection and serial console running on a PC.
To extend this design, a user may create their own Chipyard configuration and add the ``WithArtyTweaks`` located in ``fpga/src/main/scala/arty/Configs.scala``.
Adding this config. fragment will enable and connect the JTAG and UART interfaces to your Chipyard design.
.. literalinclude:: ../../fpga/src/main/scala/arty/Configs.scala
:language: scala
:start-after: DOC include start: AbstractArty and Rocket
:end-before: DOC include end: AbstractArty and Rocket
Future peripherals to be supported include the Arty 35T SPI Flash EEPROM, and I2C/PWM/SPI over the Arty 35T GPIO pins. These peripherals are available as part of sifive-blocks.
Brief Implementation Description and Guidance for Adding/Changing Xilinx Collateral
-----------------------------------------------------------------------------------
Like the VCU118, the basis for the Arty 35T design is the creation of a special test harness that connects the external IO (which exist as Xilinx IP blackboxes) to the Chipyard design.
This is done with the ``ArtyTestHarness`` in the basic default Arty 35T target. However, unlike the ``VCU118TestHarness``, the ``ArtyTestHarness`` uses no ``Overlays``, and instead directly connects chip top IO to the ports of the external IO blackboxes, using functions such as ``IOBUF`` provided by ``fpga-shells``.
Unlike the VCU118 and other more complicated test harnesses, the Arty 35T Vivado collateral is not generated by ``Overlays``, but rather are a static collection of ``create_ip`` and ``set_properties`` statements located in the files within ``fpga/fpga-shells/xilinx/arty/tcl`` and ``fpga/fpga-shells/xilinx/arty/constraints``.
If the user wishes to re-map FPGA package pins to different harness-level IO, this may be changed within ``fpga/fpga-shells/xilinx/arty/constraints/arty-master.xdc``. The addition of new Xilinx IP blocks may be done in ``fpga-shells/xilinx/arty/tcl/ip.tcl``, mapped to harness-level IOs in ``arty-master.xdc``, and wired through from the test harness to the chip top using ``HarnessBinders`` and ``IOBinders``.
Examples of a simple ``IOBinder`` and ``HarnessBinder`` for routing signals (in this case the debug and JTAG resets) from the core to the test harness are the ``WithResetPassthrough`` and ``WithArtyResetHarnessBinder``.

View File

@@ -0,0 +1,70 @@
General Setup and Usage
==============================
Sources and Submodule Setup
---------------------------
All FPGA prototyping-related collateral and sources are located in the ``fpga`` top-level Chipyard directory.
This includes the ``fpga-shells`` submodule and the ``src`` directory that hold both Scala, TCL and other collateral.
However, the ``fpga-shells`` submodule repository is not initialized by default.
To initialize the ``fpga-shells`` submodule repository, run the included initialization script from the Chipyard top-level directory:
.. code-block:: shell
# in the chipyard top level folder
./scripts/init-fpga.sh
Generating a Bitstream
----------------------
Generating a bitstream for any FPGA target using Vivado is similar to building RTL for a software RTL simulation.
Similar to a software RTL simulation (:ref:`Simulation/Software-RTL-Simulation:Simulating A Custom Project`), you can run the following command in the ``fpga`` directory to build a bitstream using Vivado:
.. code-block:: shell
make SBT_PROJECT=... MODEL=... VLOG_MODEL=... MODEL_PACKAGE=... CONFIG=... CONFIG_PACKAGE=... GENERATOR_PACKAGE=... TB=... TOP=... BOARD=... FPGA_BRAND=... bitstream
# or
make SUB_PROJECT=<sub_project> bitstream
The ``SUB_PROJECT`` make variable is a way to meta make variable that sets all of the other make variables to a specific default.
For example:
.. code-block:: shell
make SUB_PROJECT=vcu118 bitstream
# converts to
make SBT_PROJECT=fpga_platforms MODEL=VCU118FPGATestHarness VLOG_MODEL=VCU118FPGATestHarness MODEL_PACKAGE=chipyard.fpga.vcu118 CONFIG=RocketVCU118Config CONFIG_PACKAGE=chipyard.fpga.vcu118 GENERATOR_PACKAGE=chipyard TB=none TOP=ChipTop BOARD=vcu118 FPGA_BRAND=... bitstream
Some ``SUB_PROJECT`` defaults are already defined for use, including ``vcu118`` and ``arty``.
These default ``SUB_PROJECT``'s setup the necessary test harnesses, packages, and more for the Chipyard make system.
Like a software RTL simulation make invocation, all of the make variables can be overridden with user specific values (ex. include the ``SUB_PROJECT`` with a ``CONFIG`` and ``CONFIG_PACKAGE`` override).
In most cases, you will just need to run a command with a ``SUB_PROJECT`` and an overridden ``CONFIG`` to point to.
For example, building the BOOM configuration on the VCU118:
.. code-block:: shell
make SUB_PROJECT=vcu118 CONFIG=BoomVCU118Config bitstream
That command will build the RTL and generate a bitstream using Vivado.
The generated bitstream will be located in your designs specific build folder (``generated-src/<LONG_NAME>/obj``).
However, like a software RTL simulation, you can also run the intermediate make steps to just generate Verilog or FIRRTL.
Debugging with ILAs on Supported FPGAs
--------------------------------------
ILA (integrated logic analyzers) can be added to certain designs for debugging relevant signals.
First, open up the post synthesis checkpoint located in the build directory for your design in Vivado (it should be labeled ``post_synth.dcp``).
Then using Vivado, add ILAs (and other debugging tools) for your design (search online for more information on how to add an ILA).
This can be done by modifying the post synthesis checkpoint, saving it, and running ``make ... debug-bitstream``.
This will create a new bitstream called ``top.bit`` in a folder named ``generated-src/<LONG_NAME>/debug_obj/``.
For example, running the bitstream build for an added ILA for a BOOM config.:
.. code-block:: shell
make SUB_PROJECT=vcu118 CONFIG=BoomVCU118Config debug-bitstream
.. IMPORTANT:: For more extensive debugging tools for FPGA simulations including printf synthesis, assert synthesis, instruction traces, ILAs, out-of-band profiling, co-simulation, and more, please refer to the :ref:`Simulation/FPGA-Accelerated-Simulation:FireSim` platform.

View File

@@ -0,0 +1,60 @@
Running a Design on VCU118
==========================
Basic VCU118 Design
-------------------
The default Xilinx VCU118 harness is setup to have UART, a SPI SDCard, and DDR backing memory.
This allows it to run RISC-V Linux from an SDCard while piping the terminal over UART to the host machine (the machine connected to the VCU118).
To extend this design, you can create your own Chipyard configuration and add the ``WithVCU118Tweaks`` located in ``fpga/src/main/scala/vcu118/Configs.scala``.
Adding this config fragment will enable and connect the UART, SPI SDCard, and DDR backing memory to your Chipyard design/config.
.. literalinclude:: ../../fpga/src/main/scala/vcu118/Configs.scala
:language: scala
:start-after: DOC include start: AbstractVCU118 and Rocket
:end-before: DOC include end: AbstractVCU118 and Rocket
Brief Implementation Description + More Complicated Designs
-----------------------------------------------------------
The basis for a VCU118 design revolves around creating a special test harness to connect the external IOs to your Chipyard design.
This is done with the ``VCU118TestHarness`` in the basic default VCU118 FPGA target.
The ``VCU118TestHarness`` (located in ``fpga/src/main/scala/vcu118/TestHarness.scala``) uses ``Overlays`` that connect to the VCU118 external IOs.
Generally, the ``Overlays`` take an IO from the ``ChipTop`` (labeled as ``topDesign`` in the file) when "placed" and connect it to the external IO and generate necessary Vivado collateral.
For example, the following shows a UART ``Overlay`` being "placed" into the design with a IO input called ``io_uart_bb``.
.. literalinclude:: ../../fpga/src/main/scala/vcu118/TestHarness.scala
:language: scala
:start-after: DOC include start: UartOverlay
:end-before: DOC include end: UartOverlay
Here the ``UARTOverlayKey`` is referenced and used to "place" the necessary connections (and collateral) to connect to the UART.
The ``UARTDesignInput`` is used to pass in the UART IO from the ``ChipTop``/``topDesign`` to the ``Overlay``.
Note that the ``BundleBridgeSource`` can be viewed as a glorified wire (that is defined in the ``LazyModule`` scope).
This pattern is similar for all other ``Overlays`` in the test harness.
They must be "placed" and given a set of inputs (IOs, parameters).
The main exception to this pattern is the ``Overlay`` used to generate the clock(s) for the FPGA.
.. literalinclude:: ../../fpga/src/main/scala/vcu118/TestHarness.scala
:language: scala
:start-after: DOC include start: ClockOverlay
:end-before: DOC include end: ClockOverlay
Without going into too much detail, the clocks overlay is placed in the harness and a PLL node (``harnessSysPLL``) generates the necessary clocks specified by ``ClockSinkNodes``.
For ease of use, you can change the ``FPGAFrequencyKey`` to change the default clock frequency of the FPGA design.
After the harness is created, the ``BundleBridgeSource``'s must be connected to the ``ChipTop`` IOs.
This is done with harness binders and io binders (see ``fpga/src/main/scala/vcu118/HarnessBinders.scala`` and ``fpga/src/main/scala/vcu118/IOBinders.scala``).
For more information on harness binders and io binders, refer to :ref:`Customization/IOBinders:IOBinders and HarnessBinders`.
Introduction to the Bringup Platform
------------------------------------
An example of a more complicated design used for Chipyard test chips can be viewed in ``fpga/src/main/scala/vcu118/bringup/``.
This example extends the default test harness and creates new ``Overlays`` to connect to a DUT (connected to the FMC port).
Extensions include another UART (connected over FMC), I2C (connected over FMC), miscellaneous GPIOS (can be connected to anything), and a TSI Host Widget.
The TSI Host Widget is used to interact with the DUT from the prototype over a SerDes link (sometimes called the Low BandWidth InterFace - LBWIF) and provide access to a channel of the FPGA's DRAM.
.. Note:: Remember that since whenever a new test harness is created (or the config changes, or the config packages changes, or...), you need to modify the make invocation.
For example, ``make SUB_PROJECT=vcu118 CONFIG=MyNewVCU118Config CONFIG_PACKAGE=this.is.my.scala.package bitstream``.
See :ref:`Prototyping/General:Generating a Bitstream` for information on the various make variables.

View File

@@ -0,0 +1,16 @@
Prototyping Flow
================
Chipyard supports FPGA prototyping for local FPGAs supported by `fpga-shells <https://github.com/sifive/fpga-shells>`__.
This includes popular FPGAs such as the Xilinx VCU118 and the Xilinx Arty 35T board.
.. Note:: While ``fpga-shells`` provides harnesses for other FPGA development boards such as the Xilinx VC707 and some MicroSemi PolarFire, only harnesses for the Xilinx VCU118 and Xilinx Arty 35T boards are currently supported in Chipyard.
However, the VCU118 and Arty 35T examples demonstrate how a user may implement support for other harnesses provided by fpga-shells.
.. toctree::
:maxdepth: 2
:caption: Prototyping Flow:
General
VCU118
Arty

View File

@@ -46,7 +46,20 @@ and proceed with the rest of the tutorial.
Running your Design in FireSim
------------------------------
Converting a Chipyard config (one in ``chipyard/src/main/scala`` to run in FireSim is simple. We are using the same target (top) RTL, and only need to specify a new set of connection behaviors for the IOs of that module. Simply create a matching config within ``generators/firechip/src/main/scala/TargetConfigs`` that inherits your config defined in ``chipyard``.
Converting a Chipyard config (one in ``chipyard/src/main/scala`` to run in FireSim is simple, and can be done either through the traditional configuration system or through FireSim's build-recipes scheme.
A FireSim simulation requires 3 additional config fragments:
* ``WithFireSimConfigTweaks`` modifies your design to better fit the FireSim usage model. This is composed of multiple smaller config fragments. For example, the removal of clock-gating (using the ``WithoutClockGating`` config fragment) which is required for correct functioning of the compiler. This config fragment also includes other config fragments such as the inclusion of UART in the design, which although may technically be optional,is *strongly* recommended.
* ``WithDefaultMemModel`` provides a default configuration for FASED memory models in the FireSim simulation. See the FireSim documentation for details. This config fragment is currently included by default within ``WithFireSimConfigTweaks``, so it isn't neccessary to add in separately, but it is required if you choose not to use ``WithFireSimConfigTweaks``.
* ``WithDefaultFireSimBridges`` sets the ``IOBinders`` key to use FireSim's Bridge system, which can drive target IOs with software bridge models running on the simulation host. See the FireSim documentation for details.
The simplest method to add this config fragments to your custom Chipyard config is through FireSim's build recipe scheme.
After your FireSim environment is setup, you will define your custom build recipe in ``sims/firesim/deploy/deploy/config_build_recipes.ini``. By prepending the FireSim config fragments (separated by ``_``) to your Chipyard configuration, these config fragments will be added to your custom configuration as if they were listed in a custom Chisel config class definition. For example, if you would like to convert the Chipyard ``LargeBoomConfig`` to a FireSim simulation with a DDR3 memory model, the appropriate FireSim ``TARGET_CONFIG`` would be ``DDR3FRFCFSLLC4MB_WithDefaultFireSimBridges_WithFireSimConfigTweaks_chipyard.LargeBoomConfig``. Note that the FireSim config fragments are part of the ``firesim.firesim`` scala package and therefore there do not need to be prefixed with the full package name as opposed to the Chipyard config fragments which need to be prefixed with the chipyard package name.
An alternative method to prepending the FireSim config fragments in the FireSim build recipe is to create a new "permanent" FireChip custom configuration, which includes the FireSim config fragments.
We are using the same target (top) RTL, and only need to specify a new set of connection behaviors for the IOs of that module. Simply create a matching config within ``generators/firechip/src/main/scala/TargetConfigs`` that inherits your config defined in ``chipyard``.
.. literalinclude:: ../../generators/firechip/src/main/scala/TargetConfigs.scala
@@ -54,9 +67,4 @@ Converting a Chipyard config (one in ``chipyard/src/main/scala`` to run in FireS
:start-after: DOC include start: firesimconfig
:end-before: DOC include end: firesimconfig
Only 3 additional config fragments are needed.
* ``WithFireSimConfigTweaks`` modifies your design to better fit the FireSim usage model. For example, FireSim designs typically include a UART. Technically, adding this in is optional, but *strongly* recommended.
* ``WithDefaultMemModel`` sets the external memory model in the FireSim simulation. See the FireSim documentation for details.
* ``WithDefaultFireSimBridges`` sets the ``IOBinders`` key to use FireSim's Bridge system, which can drive target IOs with software bridge models running on the simulation host. See the FireSim documentation for details.
While this option seems to require the maintenance of additional configuration code, it has the benefit of allowing for the inclusion of more complex config fragments which also accept custom arguments (for example, ``WithDefaultMemModel`` can take an optional argument``)

View File

@@ -40,8 +40,7 @@ For a proprietry VCS simulation, enter the ``sims/vcs`` directory
# Enter VCS directory
cd sims/vcs
.. _sim-default:
.. _sw-sim-help:
Simulating The Default Example
-------------------------------
@@ -62,6 +61,12 @@ For instance, to run one of the riscv-tools assembly tests.
.. Note:: In a VCS simulator, the simulator name will be ``simv-chipyard-RocketConfig`` instead of ``simulator-chipyard-RocketConfig``.
The makefiles have a ``run-binary`` rule that simplifies running the simulation executable. It adds many of the common command line options for you and redirects the output to a file.
.. code-block:: shell
make run-binary BINARY=$RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-simple
Alternatively, we can run a pre-packaged suite of RISC-V assembly or benchmark tests, by adding the make target ``run-asm-tests`` or ``run-bmark-tests``.
For example:
@@ -76,6 +81,22 @@ For example:
.. _sw-sim-custom:
Makefile Variables and Commands
-------------------------------
You can get a list of useful Makefile variables and commands available from the Verilator or VCS directories. simply run ``make help``:
.. code-block:: shell
# Enter Verilator directory
cd sims/verilator
make help
# Enter VCS directory
cd sims/vcs
make help
.. _sim-default:
Simulating A Custom Project
-------------------------------
@@ -126,6 +147,29 @@ All ``make`` targets that can be applied to the default example, can also be app
Finally, in the ``generated-src/<...>-<package>-<config>/`` directory resides all of the collateral and Verilog source files for the build/simulation.
Specifically, the SoC top-level (``TOP``) Verilog file is denoted with ``*.top.v`` while the ``TestHarness`` file is denoted with ``*.harness.v``.
Fast Memory Loading
-------------------
The simulator loads the program binary over a simulated serial line. This can be quite slow if there is a lot of static data, so the simulator also allows data to be loaded from a file directly into the DRAM model.
.. code-block:: shell
make run-binary BINARY=test.riscv LOADMEM=testdata.hex LOADMEM_ADDR=81000000
The ``.hex`` file should be a text file with a hexadecimal number on each line.
.. code-block:: text
deadbeef
0123
Each line uses little-endian order, so this file would produce the bytes "ef be ad de 01 23". ``LOADMEM_ADDR`` specifies which address in memory (in hexadecimal) to write the first byte to. The default is 0x81000000.
A special target that facilitates automatically generating a hex file for an entire elf RISC-V exectuable and then running the simulator with the appropriate flags is also available.
.. code-block:: shell
make run-binary-hex BINARY=test.riscv
Generating Waveforms
-----------------------
@@ -138,3 +182,18 @@ An open-source vcd-capable waveform viewer is `GTKWave <http://gtkwave.sourcefor
For a VCS simulation, this will generate a vpd file (this is a proprietary waveform representation format used by Synopsys) that can be loaded to vpd-supported waveform viewers.
If you have Synopsys licenses, we recommend using the DVE waveform viewer.
.. _sw-sim-verilator-opts:
Additional Verilator Options
-------------------------------
When building the verilator simulator there are some additional options:
.. code-block:: shell
make VERILATOR_THREADS=8 NUMACTL=1
The ``VERILATOR_THREADS=<num>`` option enables the compiled Verilator simulator to use ``<num>`` parallel threads.
On a multi-socket machine, you will want to make sure all threads are on the same socket by using ``NUMACTL=1`` to enable ``numactl``.
By enabling this, you will use Chipyard's ``numa_prefix`` wrapper, which is a simple wrapper around ``numactl`` that runs your verilated simulator like this: ``$(numa_prefix) ./simulator-<name> <simulator-args>``.
Note that both these flags are mutually exclusive, you can use either independently (though it makes sense to use ``NUMACTL`` just with ``VERILATOR_THREADS=8`` during a Verilator simulation).

View File

@@ -3,14 +3,14 @@ Simulation
Chipyard supports two classes of simulation:
#. Software RTL simulation using commercial or open-source (Verilator) RTL simulators
#. Software RTL simulation using commercial or open-source (Verilator) RTL simulators
#. FPGA-accelerated full-system simulation using FireSim
Software RTL simulators of Chipyard designs run at O(1 KHz), but compile
quickly and provide full waveforms. Conversly, FPGA-accelerated simulators run
quickly and provide full waveforms. Conversely, FPGA-accelerated simulators run
at O(100 MHz), making them appropriate for booting an operating system and
running a complete workload, but have multi-hour compile times and poorer debug
visability.
visibility.
Click next to see how to run a simulation.
@@ -20,4 +20,3 @@ Click next to see how to run a simulation.
Software-RTL-Simulation
FPGA-Accelerated-Simulation

View File

@@ -1,3 +1,5 @@
.. _node_types:
TileLink Node Types
===================
@@ -57,7 +59,7 @@ TileLink messages.
The ``edge`` object represents the edge of the Diplomacy graph. It contains
some useful helper functions which will be documented in
:ref:`TileLink Edge Object Methods`.
:ref:`TileLink-Diplomacy-Reference/EdgeFunctions:TileLink Edge Object Methods`.
Manager Node
------------
@@ -114,7 +116,7 @@ most MMIO peripherals should set it to.
The next six arguments start with ``support`` and determine the different
A channel message types that the manager can accept. The definitions of the
message types are explained in :ref:`TileLink Edge Object Methods`.
message types are explained in :ref:`TileLink-Diplomacy-Reference/EdgeFunctions:TileLink Edge Object Methods`.
The ``TransferSizes`` case class specifies the range of logical sizes (in bytes)
that the manager can accept for the particular message type. This is an inclusive
range and all logical sizes must be powers of two. So in this case, the manager
@@ -135,7 +137,7 @@ to handle TileLink requests, it is usually much easier to use a register node.
This type of node provides a ``regmap`` method that allows you to specify
control/status registers and automatically generates the logic to handle the
TileLink protocol. More information about how to use register nodes can be
found in :ref:`Register Router`.
found in :ref:`TileLink-Diplomacy-Reference/Register-Router:Register Router`.
Identity Node
-------------
@@ -174,7 +176,7 @@ If we want to connect the client and manager groups together, we can now do this
:end-before: DOC include end: MyClientManagerComplex
The meaning of the ``:=*`` operator is explained in more detail in the
:ref:`Diplomacy Connectors` section. In summary, it connects two nodes together
:ref:`TileLink-Diplomacy-Reference/Diplomacy-Connectors:Diplomacy Connectors` section. In summary, it connects two nodes together
using multiple edges. The edges in the identity node are assigned in order,
so in this case ``client1.node`` will eventually connect to ``manager1.node``
and ``client2.node`` will connect to ``manager2.node``.
@@ -190,7 +192,7 @@ produces the same number of outputs. However, unlike the identity node, the
adapter node does not simply pass the connections through unchanged.
It can change the logical and physical interfaces between input and output and
rewrite messages going through. RocketChip provides a library of adapters,
which are catalogued in :ref:`Diplomatic Widgets`.
which are catalogued in :ref:`TileLink-Diplomacy-Reference/Widgets:Diplomatic Widgets`.
You will rarely need to create an adapter node yourself, but the invocation is
as follows.

View File

@@ -32,7 +32,7 @@ The default value is 4 bytes. The ``concurrency`` argument is the size of the
internal queue for TileLink requests. By default, this value is 0, which means
there will be no queue. This value must be greater than 0 if you wish to
decoupled requests and responses for register accesses. This is discussed
in :ref:`Using Functions`.
in :ref:`TileLink-Diplomacy-Reference/Register-Router:Using Functions`.
The main way to interact with the node is to call the ``regmap`` method, which
takes a sequence of pairs. The first element of the pair is an offset from the
@@ -128,7 +128,7 @@ Register Routers for Other Protocols
One useful feature of the register router interface is that you can easily
change the protocol being used. For instance, in the first example in
:ref:`Basic Usage`, you could simply change the ``TLRegisterNode`` to
:ref:`TileLink-Diplomacy-Reference/Register-Router:Basic Usage`, you could simply change the ``TLRegisterNode`` to
and ``AXI4RegisterNode``.
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/RegisterNodeExample.scala

View File

@@ -1,3 +1,5 @@
.. _diplomatic_widgets:
Diplomatic Widgets
==================
@@ -79,7 +81,7 @@ The arguments for the five-argument constructor are
AXI4Buffer
----------
Similar to the :ref:`TLBuffer`, but for AXI4. It also takes ``BufferParams`` objects
Similar to the :ref:`TileLink-Diplomacy-Reference/Widgets:TLBuffer`, but for AXI4. It also takes ``BufferParams`` objects
as arguments.
**Arguments:**
@@ -198,10 +200,11 @@ transactions.
AXI4Fragmenter
--------------
The AXI4Fragmenter is similar to the :ref:`TLFragmenter`, except it can only
break multi-beat AXI4 transactions into single-beat transactions. This
effectively serves as an AXI4 to AXI4-Lite converter. The constructor for this
widget does not take any arguments.
The AXI4Fragmenter is similar to the :ref:`TileLink-Diplomacy-Reference/Widgets:TLFragmenter`.
The AXI4Fragmenter slices all AXI accesses into simple power-of-two sized and aligned transfers
of the largest size supported by the manager. This makes it suitable as a first stage transformation
to apply before an AXI4=>TL bridge. It also makes it suitable for placing after TL=>AXI4 bridge
driving an AXI-lite slave.
**Example Usage:**
@@ -235,7 +238,7 @@ you will want to use a TLSourceShrinker.
AXI4IdIndexer
-------------
The AXI4 equivalent of :ref:`TLSourceShrinker`. This limits the number of
The AXI4 equivalent of :ref:`TileLink-Diplomacy-Reference/Widgets:TLSourceShrinker`. This limits the number of
AWID/ARID bits in the slave AXI4 interface. Useful for connecting to external
or black box AXI4 ports.
@@ -255,7 +258,7 @@ or black box AXI4 ports.
The AXI4IdIndexer will create a ``user`` field on the slave interface, as it
stores the ID of the master requests in this field. If connecting to an AXI4
interface that doesn't have a ``user`` field, you'll need to use the :ref:`AXI4UserYanker`.
interface that doesn't have a ``user`` field, you'll need to use the :ref:`TileLink-Diplomacy-Reference/Widgets:AXI4UserYanker`.
TLWidthWidget
-------------
@@ -299,7 +302,7 @@ The possible values of ``policy`` are:
ordering guaranteed
- ``TLFIFOFixer.allVolatile`` - All managers that have a RegionType of
``VOLATILE``, ``PUT_EFFECTS``, or ``GET_EFFECTS`` will have ordering
guaranteed (see :ref:`Manager Node` for explanation of region types).
guaranteed (see :ref:`TileLink-Diplomacy-Reference/NodeTypes:Manager Node` for explanation of region types).
TLXbar and AXI4Xbar
-------------------
@@ -375,14 +378,14 @@ override the default arguments of the constructors for these widgets.
AXI4Fragmenter() :=
axi4master.node
You will need to add an :ref:`AXI4Deinterleaver` after the TLToAXI4 converter
You will need to add an :ref:`TileLink-Diplomacy-Reference/Widgets:AXI4Deinterleaver` after the TLToAXI4 converter
because it cannot deal with interleaved read responses. The TLToAXI4 converter
also uses the AXI4 user field to store some information, so you will need an
:ref:`AXI4UserYanker` if you want to connect to an AXI4 port without user
:ref:`TileLink-Diplomacy-Reference/Widgets:AXI4UserYanker` if you want to connect to an AXI4 port without user
fields.
Before you connect an AXI4 port to the AXI4ToTL widget, you will need to
add an :ref:`AXI4Fragmenter` and :ref:`AXI4UserYanker` because the converter cannot
add an :ref:`TileLink-Diplomacy-Reference/Widgets:AXI4Fragmenter` and :ref:`TileLink-Diplomacy-Reference/Widgets:AXI4UserYanker` because the converter cannot
deal with multi-beat transactions or user fields.
TLROM

View File

@@ -1,3 +1,5 @@
.. _tilelink_and_diplomacy:
TileLink and Diplomacy Reference
================================

View File

@@ -23,15 +23,15 @@ An external module reference is a FIRRTL construct that enables a design to refe
A list of unique SRAM configurations is output to a ``.conf`` file by FIRRTL, which is used to map technology SRAMs.
Without this transform, FIRRTL will map all ``SeqMem`` s to flip-flop arrays with equivalent behavior, which may lead to a design that is difficult to route.
The ``.conf`` file is consumed by a tool called MacroCompiler, which is part of the :ref:`Barstools` scala package.
The ``.conf`` file is consumed by a tool called MacroCompiler, which is part of the :ref:`Tools/Barstools:Barstools` scala package.
MacroCompiler is also passed an ``.mdf`` file that describes the available list of technology SRAMs or the capabilities of the SRAM compiler, if one is provided by the foundry.
Typically a foundry SRAM compiler will be able to generate a set of different SRAMs collateral based on some requirements on size, aspect ratio, etc. (see :ref:`SRAM MDF Fields`).
Typically a foundry SRAM compiler will be able to generate a set of different SRAMs collateral based on some requirements on size, aspect ratio, etc. (see :ref:`Tools/Barstools:SRAM MDF Fields`).
Using a user-customizable cost function, MacroCompiler will select the SRAMs that are the best fit for each dimensionality in the ``.conf`` file.
This may include over provisioning (e.g. using a 64x1024 SRAM for a requested 60x1024, if the latter is not available) or arraying.
Arraying can be done in both width and depth, as well as to solve masking constraints.
For example, a 128x2048 array could be composed of four 64x1024 arrays, with two macros in parallel to create two 128x1024 virtual SRAMs which are combinationally muxed to add depth.
If this macro requires byte-granularity write masking, but no technology SRAMs support masking, then the tool may choose to use thirty-two 8x1024 arrays in a similar configuration.
For information on writing ``.mdf`` files, look at `MDF on github <https://github.com/ucb-bar/plsi-mdf>`__ and a brief description in :ref:`SRAM MDF Fields` section.
For information on writing ``.mdf`` files, look at `MDF on github <https://github.com/ucb-bar/plsi-mdf>`__ and a brief description in :ref:`Tools/Barstools:SRAM MDF Fields` section.
The output of MacroCompiler is a Verilog file containing modules that wrap the technology SRAMs into the specified interface names from the ``.conf``.
If the technology supports an SRAM compiler, then MacroCompiler will also emit HammerIR that can be passed to Hammer to run the compiler itself and generate design collateral.
@@ -103,7 +103,7 @@ This is necessary to facilitate post-synthesis and post-place-and-route simulati
Simulations after you the design goes through a VLSI flow will use the verilog netlist generated from the flow and will need an untouched test harness to drive it.
Separating these components into separate files makes this straightforward.
Without the separation the file that included the test harness would also redefine the DUT which is often disallowed in simulation tools.
To do this, there is a FIRRTL ``App`` in :ref:`Barstools` called ``GenerateTopAndHarness``, which runs the appropriate transforms to elaborate the modules separately.
To do this, there is a FIRRTL ``App`` in :ref:`Tools/Barstools:Barstools` called ``GenerateTopAndHarness``, which runs the appropriate transforms to elaborate the modules separately.
This also renames modules in the test harness so that any modules that are instantiated in both the test harness and the chip are uniquified.
.. Note:: For VLSI projects, this ``App`` is run instead of the normal FIRRTL ``App`` to elaborate Verilog.
@@ -131,5 +131,5 @@ This, unfortunately, breaks the process-agnostic RTL abstraction, so it is recom
The simplest way to do this is to have a config fragment that when included updates instantiates the IO cells and connects them in the test harness.
When simulating chip-specific designs, it is important to include the IO cells.
The IO cell behavioral models will often assert if they are connected incorrectly, which is a useful runtime check.
They also keep the IO interface at the chip and test harness boundary (see :ref:`Separating the Top module from the TestHarness module`) consistent after synthesis and place-and-route,
They also keep the IO interface at the chip and test harness boundary (see :ref:`Tools/Barstools:Separating the Top module from the TestHarness module`) consistent after synthesis and place-and-route,
which allows the RTL simulation test harness to be reused.

View File

@@ -4,4 +4,4 @@ Chisel Testers
`Chisel Testers <https://github.com/freechipsproject/chisel-testers>`__ is a library for writing tests for Chisel designs.
It provides a Scala API for interacting with a DUT.
It can use multiple backends, including things such as Treadle and Verilator.
See :ref:`Treadle and FIRRTL Interpreter` and :ref:`sw-rtl-sim-intro` for more information on these simulation methods.
See :ref:`Tools/Treadle:Treadle and FIRRTL Interpreter` and :ref:`sw-rtl-sim-intro` for more information on these simulation methods.

View File

@@ -13,7 +13,7 @@ The Chisel generator starts elaboration using the module and configuration class
This is where the Chisel "library functions" are called with the parameters given and Chisel tries to construct a circuit based on the Chisel code.
If a runtime error happens here, Chisel is stating that it cannot "build" your circuit due to "violations" between your code and the Chisel "library".
However, if that passes, the output of the generator gives you an FIRRTL file and other misc collateral!
See :ref:`FIRRTL` for more information on how to get a FIRRTL file to Verilog.
See :ref:`Tools/FIRRTL:FIRRTL` for more information on how to get a FIRRTL file to Verilog.
For an interactive tutorial on how to use Chisel and get started please visit the `Chisel Bootcamp <https://github.com/freechipsproject/chisel-bootcamp>`__.
Otherwise, for all things Chisel related including API documentation, news, etc, visit their `website <https://chisel-lang.org/>`__.

View File

@@ -19,4 +19,4 @@ An example of a divergence and Dromajo's printout is shown below.
Dromajo shows the divergence compared to simulation (PC, inst, inst-bits, write data, etc) and also provides the register state on failure.
It is useful to catch bugs that affect architectural state before a simulation hangs or crashes.
To use Dromajo with BOOM, refer to :ref:`Debugging RTL` section on Dromajo.
To use Dromajo with BOOM, refer to :ref:`Advanced-Concepts/Debugging-RTL:Debugging RTL` section on Dromajo.

308
docs/VLSI/Basic-Flow.rst Normal file
View File

@@ -0,0 +1,308 @@
.. _hammer_basic_flow:
Using Hammer To Place and Route a Custom Block
=================================================
.. IMPORTANT:: In order to use the Hammer VLSI flow, you need access to Hammer tools and technology plugins. You can obtain these by emailing hammer-plugins-access@lists.berkeley.edu with a request for which plugin(s) you would like access to. Make sure your email includes your github ID and proof (through affiliation or otherwise) that you have licensed access to relevant tools.
Initialize the Hammer Plug-ins
----------------------------------
In the Chipyard root, run:
.. code-block:: shell
./scripts/init-vlsi.sh <tech-plugin-name>
This will pull the Hammer & CAD tool plugin submodules, assuming the technology plugins are available on github.
Currently only the asap7 technology plugin is available on github.
If you have additional private technology plugins (this is a typical use-case for proprietry process technologies with require NDAs and secure servers), you can clone them directly
into VLSI directory with the name ``hammer-<tech-plugin-name>-plugin``.
For example, for an imaginary process technology called tsmintel3:
.. code-block:: shell
cd vlsi
git clone git@my-secure-server.berkeley.edu:tsmintel3/hammer-tsmintel3-plugin.git
Next, we define the Hammer environment into the shell:
.. code-block:: shell
cd vlsi # (if you haven't done so yet)
export HAMMER_HOME=$PWD/hammer
source $HAMMER_HOME/sourceme.sh
.. Note:: Some VLSI EDA tools are supported only on RHEL-based operating systems. We recommend using Chipyard on RHEL7 and above. However, many VLSI server still have old operating systems such as RHEL6, which have software packages older than the basic chipyard requirements. In order to build Chipyard on RHEL6, you will likely need to use tool packages such as devtoolset (for example, devtoolset-8) and/or build from source gcc, git, gmake, make, dtc, cc, bison, libexpat and liby.
Setting up the Hammer Configuration Files
--------------------------------------------
The first configuration file that needs to be set up is the Hammer environment configuration file ``env.yml``. In this file you need to set the paths to the EDA tools and license servers you will be using. You do not have to fill all the fields in this configuration file, you only need to fill in the paths for the tools that you will be using.
If you are working within a shared server farm environment with an LSF cluster setup (for example, the Berkeley Wireless Research Center), please note the additional possible environment configuration listed in the :ref:`VLSI/Basic-Flow:Advanced Environment Setup` segment of this documentation page.
Hammer relies on YAML-based configuration files. While these configuration can be consolidated within a single files (as is the case in the ASAP7 tutorial :ref:`tutorial` and the ``nangate45``
OpenRoad example), the generally suggested way to work with an arbitrary process technology or tools plugins would be to use three configuration files, matching the three Hammer concerns - tools, tech, and design.
The ``vlsi`` directory includes three such example configuration files matching the three concerns: ``example-tools.yml``, ``example-tech.yml``, and ``example-design.yml``.
The ``example-tools.yml`` file configures which EDA tools hammer will use. This example file uses Cadence Innovus, Genus and Voltus, Synopsys VCS, and Mentor Calibre (which are likely the tools you will use if you're working in the Berkeley Wireless Research Center). Note that tool versions are highly sensitive to the process-technology in-use. Hence, tool versions that work with one process technology may not work with another (for example, ASAP7 will not work with an Innovus version newer than 18.1, while other proprietary process technologies will likely require newer versions such as 19.1).
The ``example-design.yml`` file contains basic build system information (how many cores/threads to use, etc.), as well as configurations that are specific to the design we are working on such as clock signal name and frequency, power modes, floorplan, and additional constraints that we will add later on.
Finally, the ``example-tech`` file is a template file for a process technology plugin configuration. We will copy this file, and replace its fields with the appropriate process technology details for the tech plugin that we have access to. For example, for the ``asap7`` tech plugin we will replace the <tech_name> field with "asap7", the Node size "N" with "7", and the path to the process technology files installation directory.
We recommend copying these example configuration files and customizing them with a different name, so you can have different configuration files for different process technologies and designs (e.g. create tech-tsmintel3.yml from example-tech.yml)
Building the Design
---------------------
After we have set the configuration files, we will now elaborate our Chipyard Chisel design into Verilog, while also performing the required transformations in order to make the Verilog VLSI-friendly.
Additionally, we will automatically generate another set of Hammer configuration files matching to this design, which will be used in order to configure the physical design tools.
We will do so by calling ``make buildfile`` with appropriate Chipyard configuration variables and Hammer configuration files.
As in the rest of the Chipyard flows, we specify our SoC configuration using the ``CONFIG`` make variable.
However, unlike the rest of the Chipyard flows, in the case of physical design we might be interested in working in a hierarchical fashion and therefore we would like to work on a single module.
Therefore, we can also specify a ``VLSI_TOP`` make variable with the same of a specific Verilog module (which should also match the name of the equivalent Chisel module) which we would like to work on.
The makefile will automatically call tools such as Barstools and the MacroCopmiler (:ref:`Tools/Barstools:barstools`) in order to make the generated Verilog more VLSI friendly.
By default, the MacroCopmiler will attempt to map memories into the SRAM options within the Hammer technology plugin. However, if you are wokring with a new process technology are prefer to work with flipflop arrays, you can configure the MacroCompiler using the ``MACROCOMPILER_MODE`` make variable. For example, the ASAP7 process technology does not have associated SRAMs, and therefore the ASAP7 Hammer tutorial (:ref:`tutorial`) uses the ``MACROCOMPILER_MODE='--mode synflops'`` option (Note that synthesizing a design with only flipflops is very slow and will often may not meet constraints).
We call the ``make buildfile`` command while also specifying the name of the process technology we are working with (same ``tech_name`` for the configuration files and plugin name) and the configuration files we created. Note, in the ASAP7 tutorial ((:ref:`tutorial`)) these configuration files are merged into a single file called ``example-asap7.yml``.
Hence, if we want to monolithically place and route the entire SoC, the relevant command would be
.. code-block:: shell
make buildfile CONFIG=<chipyard_config_name> tech_name=<tech_name> INPUT_CONFS="example-design.yml example-tools.yml example-tech.yml"
In a more typical scenario of working on a single module, for example the Gemmini accelerator within the GemminiRocketConfig Chipyard SoC configuration, the relevant command would be
.. code-block:: shell
make buildfile CONFIG=GemminiRocketConfig VLSI_TOP=Gemmini tech_name=tsmintel3 INPUT_CONFS="example-design.yml example-tools.yml example-tech.yml"
Running the VLSI Flow
---------------------
Running a basic VLSI flow using the Hammer default configurations is fairly simple, and consists of simple ``make`` command with the previously mentioned Make variables.
Synthesis
^^^^^^^^^
In order to run synthesis, we run ``make syn`` with the matching Make variables.
Post-synthesis logs and collateral will be saved in ``build/<config-name>/syn-rundir``. The raw QoR data (area, timing, gate counts, etc.) will be found in ``build/<config-name>/syn-rundir/reports``.
Hence, if we want to monolithically synthesize the entire SoC, the relevant command would be
.. code-block:: shell
make syn CONFIG=<chipyard_config_name> tech_name=<tech_name> INPUT_CONFS="example-design.yml example-tools.yml example-tech.yml"
In a more typical scenario of working on a single module, for example the Gemmini accelerator within the GemminiRocketConfig Chipyard SoC configuration, the relevant command would be
.. code-block:: shell
make syn CONFIG=GemminiRocketConfig VLSI_TOP=Gemmini tech_name=tsmintel3 INPUT_CONFS="example-design.yml example-tools.yml example-tech.yml"
It is worth checking the final-qor.rpt report to make sure that the synthesized design meets timing before moving to the place-and-route step.
Place-and-Route
^^^^^^^^^^^^^^^
In order to run place-and-route, we run ``make par`` with the matching Make variables.
Post-PnR logs and collateral will be saved in ``build/<config-name>/par-rundir``. Specifically, the resulting GDSII file will be in that directory with the suffix ``*.gds``. and timing reports can be found in ``build/<config-name>/par-rundir/timingReports``.
Place-and-route is requires more design details in contrast to synthesis. For example, place-and-route requires some basic floorplanning constraints. The default ``example-design.yml`` configuration file template allows the tool (specifically, the Cadence Innovus tool) to use it's automatic floorplanning capability within the top level of the design (``ChipTop``). However, if we choose to place-and-route a specific block which is not the SoC top level, we need to change the top-level path name to match the ``VLSI_TOP`` make parameter we are using.
Hence, if we want to monolitically place-and-route the entire SoC with the default tech plug-in parameters for power-straps and corners, the relevant command would be
.. code-block:: shell
make par CONFIG=<chipyard_config_name> tech_name=<tech_name> INPUT_CONFS="example-design.yml example-tools.yml example-tech.yml"
In a more typical scenario of working on a single module, for example the Gemmini accelerator within the GemminiRocketConfig Chipyard SoC configuration,
.. code-block:: shell
vlsi.inputs.placement_constraints:
- path: "Gemmini"
type: toplevel
x: 0
y: 0
width: 300
height: 300
margins:
left: 0
right: 0
top: 0
bottom: 0
The relevant ``make`` command would then be
.. code-block:: shell
make par CONFIG=GemminiRocketConfig VLSI_TOP=Gemmini tech_name=tsmintel3 INPUT_CONFS="example-design.yml example-tools.yml example-tech.yml"
Note that the width and height specification can vary widely between different modulesi and level of the module hierarchy. Make sure to set sane width and height values.
Place-and-route generally requires more fine-grained input specifications regarding power nets, clock nets, pin assignments and floorplanning. While the template configuration files provide defaults for automatic tool defaults, these will usually result in very bad QoR, and therefore it is recommended to specify better-informed floorplans, pin assignments and power nets. For more information about cutomizing theses parameters, please refer to the :ref:`VLSI/Basic-Flow:Customizing Your VLSI Flow in Hammer` sections or to the Hammer documentation.
Additionally, some Hammer process technology plugins do not provide sufficient default values for requires settings such as power nets and pin assignments (for example, ASAP7). In those cases, these constraints will need to be specified manually in the top-level configuration yml files, as is the case in the ``example-asap7.yml`` configuration file.
Place-and-route tools are very sensitive to process technologes (significantly more sensitive than synthesis tools), and different process technologies may work only on specific tool versions. It is recommended to check what is the appropriate tool version for the specific process technology you are working with.
.. Note:: If you edit the yml configuration files in between synthesis and place-and-route, the `make par` command will automatically re-run synthesis. If you would like to avoid that and are confident that your configuration file changes do not affect synthesis results, you may use the `make redo-par` instead.
Power Estimation
^^^^^^^^^^^^^^^^^^^^
Power estimation in Hammer can be performed in one of two stages: post-synthesis (post-syn) or post-place-and-route (post-par). The most accurate power estimation is post-par, and it includes finer grained details of the places instances and wire lengths.
Post-par power estimation can be based on static average signal toggles rates (also known as "static power estimation"), or based on simulation-extracted signal toggle data (also known as "dynamic power estimation").
.. Warning:: In order to run post-par power estimation, make sure that a power estimation tool (such as Cadence Voltus) has been defined in your ``example-tools.yml`` file. Make sure that the power estimation tool (for example, Cadence Voltus) version matches the physical design tool (for example, Cadence Innovus) version, otherwise you will encounter a database mismatch error.
Simulation-exacted power estimation often requires a dedicated testharness for the block under evalution (DUT). While the Hammer flow supports such configurations (further details can be found in the Hammer documentation), Chipyard's integrated flows support an automated full digital SoC simulation-extracted post-par power estimation through the integration of software RTL simulation flows with the Hammer VLSI flow. As such, full digital SoC simulation-extracted power estimation can be performed by specifying a simple binary executable with the associated ``make`` command.
.. code-block:: shell
make power-par BINARY=/path/to/baremetal/binary/rv64ui-p-addi.riscv CONFIG=<chipyard_config_name> tech_name=tsmintel3 INPUT_CONFS="example-design.yml example-tools.yml example-tech.yml"
The simulation-extracted power estimation flow implicitly uses Hammer's gate-level simulation flow (in order to generate the ``saif`` activity data file). This gate-level simulation flow can also be run independantly from the power estimation flow using the ``make sim-par`` command.
.. Note:: The gate-level simulation flow (and there the simulation-extracted power-estimation) is currently integrated only with the Synopsys VCS simulation (Verilator does not support gate-level simulation. Support for Cadence Incisive is work-in-progress)
Signoff
^^^^^^^^^
During chip tapeout, you will need to perform sign-off check to make sure the generated GDSII can be fabricated as intended. This is done using dedicated signoff tools that perform design rule checking (DRC) and layout versus schematic (LVS) verification.
In most cases, placed-and-routed designs will not pass DRC and LVS on first attempts due to nuanced design rules and subtle/silent failures of the place-and-route tools. Passing DRC and LVS will often requires adding manual placement constraints to "force" the EDA tools into certain patterns.
If you have placed-and-routed a design with the goal of getting area and power estimates, DRC and LVS are not strictly neccessary and the results will likely be quite similar. If you are intending to tapeout and fabricate a chip, DRC and LVS are mandatory and will likely requires multiple-iterations of refining manual placement constraints.
Having a large number of DRC/LVS violations can have a significant impact on the runtime of the place-and-route procedure (since the tools will try to fix each of them several times). A large number of DRC/LVS violations may also be an indication that the design is not necessarily realistic for this particular process technology, which may have power/area implications.
Since signoff checks are required only for a complete chip tapeout, they are currently not fully automated in Hammer, and often require some additional manual inclusion of custom Makefiles associated with specific process technologies. However, the general steps from running signoff within Hammer (under the assumption of a fully automated tech plug-in) are Make commands similar to the previous steps.
In order to run DRC, the relevant ``make`` command is ``make drc``. As in the previous stages, the make command should be accompanied by the relevant configuration Make variables:
.. code-block:: shell
make drc CONFIG=GemminiRocketConfig VLSI_TOP=Gemmini tech_name=tsmintel3 INPUT_CONFS="example-design.yml example-tools.yml example-tech.yml"
DRC does not emit easily audited reports, as the rule names violated can be quite esoteric. It is often more productive to rather use the scripts generated by Hammer to open the DRC error database within the appropriate tool. These generated scripts can be called from ``./build/<config-name>/drc-rundir/generated-scripts/view_drc``.
In order to run LVS, the relevant ``make`` command is ``make lvs``. As in the previous stages, the make command should be accompanied by the relevant configuration Make variables:
.. code-block:: shell
make lvs CONFIG=GemminiRocketConfig VLSI_TOP=Gemmini tech_name=tsmintel3 INPUT_CONFS="example-design.yml example-tools.yml example-tech.yml"
LVS does not emit easily audited reports, as the violations are often cryptic when seen textually. As a result it is often more productive to visually see the LVS issues using the generated scripts that enable opening the LVS error database within the appropriate tool. These generated scripts can be called from ``./build/<config-name>/lvs-rundir/generated-scripts/view_lvs``.
Customizing Your VLSI Flow in Hammer
----------------------------------------
Advanced Environment Setup
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you have access to a shared LSF cluster and you would like Hammer to submit it's compute-intensive jobs to the LSF cluster rather than your login machine, you can add the following code segment to your ``env.yml`` file (completing the relevant values for the bsub binary path, the number of CPUs requested, and the requested LSF queue):
.. code-block:: shell
#submit command (use LSF)
vlsi.submit:
command: "lsf"
settings: [{"lsf": {
"bsub_binary": "</path/to/bsub/binary/bsub>",
"num_cpus": <N>,
"queue": "<lsf_queu>",
"extra_args": ["-R", "span[hosts=1]"]
}
}]
settings_meta: "append"
Composing a Hierarchical Design
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For large designs, a monolithic VLSI flow may take the EDA tools a very long time to process and optimize, to the extent that it may not be feasable sometimes.
Hammer supports a hierarchical physical design flow, which decomposes the design into several specified sub-components and runs the flow on each sub-components separetly. Hammer is then able to assemble these blocks together into a top-level design. This hierarchical approach speeds up the VLSI flow for large designs, especially designs in which there may me multiple instantiations of the same sub-components(since the sub-component can simply be replicated in the layout).
While hierarchical physical design can be performed in multiple ways (top-down, bottom-up, abutment etc.), Hammer currently supports only the bottom-up approach.
The bottom-up approach traverses a tree representing the hierarchy starting from the leaves and towards the direction of the root (the "top level"), and runs the physical design flow on each node of the hierarchy tree using the previously layed-out children nodes.
As nodes get closer to the root (or "top level") of the hierarchy, largers sections of the design get layed-out.
The Hammer hierarchical flow relies on a manually-specified descrition of the desired heirarchy tree. The specification of the heirarchy tree is defined based on the instance names in the generated Verilog, which sometime make this specification challenging due to inconsisent instance names. Additionally, the specification of the heirarchy tree is intertwined with the manual specification of a floorplan for the design.
For example, if we choose to specifiy the previously mentioned ``GemminiRocketConfig`` configuration in a hierarchical fashion in which the Gemmini accelerator and the last-level cache are run separetly from the top-level SoC, we would replace the floorplan example in ``example-design.yml`` from the :ref:`VLSI/Basic-Flow:Place-and-Route` section with the following specification:
.. code-block:: shell
vlsi.inputs.hiearchical.top_module: "ChipTop"
vlsi.inputs.hierarchical.mode: manual"
vlsi.inputs.manual_modules:
- ChipTop:
- RocketTile
- InclusiveCache
- RocketTile:
- Gemmini
vlsi.manual_placement_constraints:
- ChipTop
- path: "ChipTop"
type: toplevel
x: 0
y: 0
width: 500
height: 500
margins:
left: 0
right: 0
top: 0
bottom: 0
- RocketTile
- path: "chiptop.system.tile_prci_domain.tile"
type: hierarchical
master: ChipTop
x: 0
y: 0
width: 250
height: 250
margins:
left: 0
right: 0
top: 0
bottom: 0
- Gemmini
- path: "chiptop.system.tile_prci_domain.tile.gemmini"
type: hierarchical
master: RocketTile
x: 0
y: 0
width: 200
height: 200
margins:
left: 0
right: 0
top: 0
bottom: 0
- InclusiveCache
- path: "chiptop.system.subsystem_l2_wrapper.l2"
type: hierarchical
master: ChipTop
x: 0
y: 0
width: 100
height: 100
margins:
left: 0
right: 0
top: 0
bottom: 0
In this specification, ``vlsi.inputs.hierarchical.mode`` indicates the manual specification of the heirarchy tree (which is the only mode currently supported by Hammer), ``vlsi.inputs.hiearchical.top_module`` sets the root of the hierarchical tree, ``vlsi.inputs.hierarchical.manual_modules`` enumerates the tree of hierarchical modules, and ``vlsi.inputs.hierarchical.manual_placement_constraints`` enumerates the floorplan for each module.
.. Specifying a Custom Floorplan
.. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Customizing Generated Tcl Scripts
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The ``example-vlsi`` python script is the Hammer entry script with placeholders for hooks. Hooks are additional snippets of python and TCL (via ``x.append()``) to extend the Hammer APIs. Hooks can be inserted using the ``make_pre/post/replacement_hook`` methods as shown in the ``example-vlsi`` entry script example. In this particular example, a list of hooks is paased in the ``get_extra_par_hooks`` function in the ``ExampleDriver`` class. Refer to the `Hammer documentation on hooks <https://hammer-vlsi.readthedocs.io/en/latest/Hammer-Use/Hooks.html>`__ for a detailed description of how these are injected into the VLSI flow.

View File

@@ -10,7 +10,7 @@ Transforming the RTL
--------------------
Building a chip requires specializing the generic verilog emitted by FIRRTL to adhere to the constraints imposed by the technology used for fabrication.
This includes mapping Chisel memories to available technology macros such as SRAMs, mapping the input and output of your chip to connect to technology IO cells, see :ref:`Barstools`.
This includes mapping Chisel memories to available technology macros such as SRAMs, mapping the input and output of your chip to connect to technology IO cells, see :ref:`Tools/Barstools:Barstools`.
In addition to these required transformations, it may also be beneficial to transform the RTL to make it more amenable to hierarchical physical design easier.
This often includes modifying the logical hierarchy to match the physical hierarchy through grouping components together or flattening components into a single larger module.
@@ -49,6 +49,6 @@ Running the VLSI tool flow
--------------------------
For the full documentation on how to use the VLSI tool flow, see the `Hammer Documentation <https://hammer-vlsi.readthedocs.io/>`__.
For an example of how to use the VLSI in the context of Chipyard, see :ref:`ASAP7 Tutorial`.
For an example of how to use the VLSI in the context of Chipyard, see :ref:`VLSI/Tutorial:ASAP7 Tutorial`.

View File

@@ -30,7 +30,7 @@ This example gives a suggested file structure and build system. The ``vlsi/`` fo
* Verilog wrapper around the accelerator and dummy hard macro.
* example.yml
* example-asap7.yml
* Hammer IR for this tutorial.
@@ -77,7 +77,7 @@ Pull the Hammer environment into the shell:
source $HAMMER_HOME/sourceme.sh
Building the Design
-------------------
--------------------
To elaborate the ``Sha3RocketConfig`` (Rocket Chip w/ the accelerator) and set up all prerequisites for the build system to push just the accelerator + hard macro through the flow:
.. code-block:: shell

View File

@@ -10,5 +10,6 @@ In particular, we aim to support the Hammer physical design generator flow.
Building-A-Chip
Hammer
Basic-Flow
Tutorial
Advanced-Usage

View File

@@ -190,3 +190,6 @@ texinfo_documents = [
intersphinx_mapping = {'python' : ('https://docs.python.org/', None),
'boom' : ('https://docs.boom-core.org/en/latest/', None),
'firesim' : ('http://docs.fires.im/en/latest/', None) }
# resolve label conflict between documents
autosectionlabel_prefix_document = True

View File

@@ -11,7 +11,7 @@ Welcome to Chipyard's documentation!
Chipyard is a framework for designing and evaluating full-system hardware using agile teams.
It is composed of a collection of tools and libraries designed to provide an integration between open-source and commercial tools for the development of systems-on-chip.
.. IMPORTANT:: **New to Chipyard?** Jump to the :ref:`Initial Repository Setup` page for setup instructions.
.. IMPORTANT:: **New to Chipyard?** Jump to the :ref:`Chipyard-Basics/Initial-Repo-Setup:Initial Repository Setup` page for setup instructions.
Getting Help
------------
@@ -45,6 +45,8 @@ Table of Contents
TileLink-Diplomacy-Reference/index
Prototyping/index
Indices and tables
==================