more docs
This commit is contained in:
362
docs/Getting-Started/Adding-An-Accelerator-Tutorial.rst
Normal file
362
docs/Getting-Started/Adding-An-Accelerator-Tutorial.rst
Normal file
@@ -0,0 +1,362 @@
|
||||
|
||||
|
||||
Adding An Accelerator/Device
|
||||
===============================
|
||||
|
||||
Accelerators or custom IO devices can be added to your SoC in several ways:
|
||||
+ MMIO Peripheral (a.k.a TileLink-Attached Accelerator)
|
||||
+ Tightly-Coupled RoCC Accelerator
|
||||
|
||||
These approaches differ in the method of the communication between the processor and the custom block.
|
||||
|
||||
With the TileLink-Attached approach, the processor communicates with MMIO peripherals through memory-mapped registers.
|
||||
|
||||
In contrast, the processor communicates with a RoCC accelerators through a custom protocol and custom non-standard ISA instructions reserved in the RISC-V ISA encoding space. Each core can have up to four accelerators that are controlled by custom instructions and share resources with the CPU.
|
||||
RoCC coprocessor instructions have the following form.
|
||||
|
||||
::
|
||||
customX rd, rs1, rs2, funct
|
||||
|
||||
The X will be a number 0-3, and determines the opcode of the instruction,
|
||||
which controls which accelerator an instruction will be routed to.
|
||||
The ``rd``, ``rs1``, and ``rs2`` fields are the register numbers of the destination
|
||||
register and two source registers. The ``funct`` field is a 7-bit integer that
|
||||
the accelerator can use to distinguish different instructions from each other.
|
||||
|
||||
Note that communication through a RoCC interfaces requires a custom software toolchain, whereas MMIO peripherals can use that standard toolchain with approriate driver support.
|
||||
|
||||
|
||||
Integrating into the Generator Build System
|
||||
-------------------------------------------
|
||||
|
||||
While developing, you want to include Chisel code in a submodule so that it
|
||||
can be shared by different projects. To add a submodule to the project
|
||||
template, make sure that your project is organized as follows.
|
||||
|
||||
yourproject/
|
||||
build.sbt
|
||||
src/main/scala/
|
||||
YourFile.scala
|
||||
|
||||
Put this in a git repository and make it accessible. Then add it as a submodule
|
||||
to under the following directory hierarchy: ``rebar/generators/yourproject``.
|
||||
|
||||
::
|
||||
git submodule add https://git-repository.com/yourproject.git
|
||||
|
||||
Then add `yourproject` to the ReBAR top-level build.sbt file.
|
||||
|
||||
::
|
||||
lazy val yourproject = project.settings(commonSettings).dependsOn(rocketchip)
|
||||
|
||||
|
||||
You can then import the classes defined in the submodule in a new project if
|
||||
you add it as a dependency. For instance, if you want to use this code in
|
||||
the `example` project, change the final line in build.sbt to the following.
|
||||
|
||||
::
|
||||
lazy val example = (project in file(".")).settings(commonSettings).dependsOn(testchipip, yourproject)
|
||||
|
||||
|
||||
Finally, add `yourproject` to the `PACKAGES` variable in the `Makefrag`. This will allow make to detect
|
||||
that your source files have changed when building the verilog/firrtl files.
|
||||
|
||||
|
||||
|
||||
MMIO Peripheral
|
||||
------------------
|
||||
|
||||
The easiest way to create a TileLink peripheral is to use the
|
||||
TLRegisterRouter, which abstracts away the details of handling the TileLink
|
||||
protocol and provides a convenient interface for specifying memory-mapped
|
||||
registers. To create a RegisterRouter-based peripheral, you will need to
|
||||
specify a parameter case class for the configuration settings, a bundle trait
|
||||
with the extra top-level ports, and a module implementation containing the
|
||||
actual RTL.
|
||||
|
||||
::
|
||||
case class PWMParams(address: BigInt, beatBytes: Int)
|
||||
|
||||
trait PWMTLBundle extends Bundle {
|
||||
val pwmout = Output(Bool())
|
||||
}
|
||||
|
||||
trait PWMTLModule {
|
||||
val io: PWMTLBundle
|
||||
implicit val p: Parameters
|
||||
def params: PWMParams
|
||||
|
||||
val w = params.beatBytes * 8
|
||||
val period = Reg(UInt(w.W))
|
||||
val duty = Reg(UInt(w.W))
|
||||
val enable = RegInit(false.B)
|
||||
|
||||
// ... Use the registers to drive io.pwmout ...
|
||||
|
||||
regmap(
|
||||
0x00 -> Seq(
|
||||
RegField(w, period)),
|
||||
0x04 -> Seq(
|
||||
RegField(w, duty)),
|
||||
0x08 -> Seq(
|
||||
RegField(1, enable)))
|
||||
}
|
||||
|
||||
|
||||
Once you have these classes, you can construct the final peripheral by
|
||||
extending the TLRegisterRouter and passing the proper arguments. The first
|
||||
set of arguments determines where the register router will be placed in the
|
||||
global address map and what information will be put in its device tree entry.
|
||||
The second set of arguments is the IO bundle constructor, which we create
|
||||
by extending TLRegBundle with our bundle trait. The final set of arguments
|
||||
is the module constructor, which we create by extends TLRegModule with our
|
||||
module trait.
|
||||
|
||||
::
|
||||
class PWMTL(c: PWMParams)(implicit p: Parameters)
|
||||
extends TLRegisterRouter(
|
||||
c.address, "pwm", Seq("ucbbar,pwm"),
|
||||
beatBytes = c.beatBytes)(
|
||||
new TLRegBundle(c, _) with PWMTLBundle)(
|
||||
new TLRegModule(c, _, _) with PWMTLModule)
|
||||
|
||||
|
||||
The full module code with comments can be found in src/main/scala/example/PWM.scala.
|
||||
|
||||
After creating the module, we need to hook it up to our SoC. Rocketchip
|
||||
accomplishes this using the [cake pattern](http://www.cakesolutions.net/teamblogs/2011/12/19/cake-pattern-in-depth).
|
||||
This basically involves placing code inside traits. In the RocketChip cake,
|
||||
there are two kinds of traits: a LazyModule trait and a module implementation
|
||||
trait.
|
||||
|
||||
The LazyModule trait runs setup code that must execute before all the hardware
|
||||
gets elaborated. For a simple memory-mapped peripheral, this just involves
|
||||
connecting the peripheral's TileLink node to the MMIO crossbar.
|
||||
|
||||
::
|
||||
trait HasPeripheryPWM extends HasSystemNetworks {
|
||||
implicit val p: Parameters
|
||||
|
||||
private val address = 0x2000
|
||||
|
||||
val pwm = LazyModule(new PWMTL(
|
||||
PWMParams(address, peripheryBusConfig.beatBytes))(p))
|
||||
|
||||
pwm.node := TLFragmenter(
|
||||
peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node)
|
||||
}
|
||||
|
||||
|
||||
Note that the PWMTL class we created from the register router is itself a
|
||||
LazyModule. Register routers have a TileLike node simply named "node", which
|
||||
we can hook up to the RocketChip peripheryBus. This will automatically add
|
||||
address map and device tree entries for the peripheral.
|
||||
|
||||
The module implementation trait is where we instantiate our PWM module and
|
||||
connect it to the rest of the SoC. Since this module has an extra `pwmout`
|
||||
output, we declare that in this trait, using Chisel's multi-IO
|
||||
functionality. We then connect the PWMTL's pwmout to the pwmout we declared.
|
||||
|
||||
::
|
||||
trait HasPeripheryPWMModuleImp extends LazyMultiIOModuleImp {
|
||||
implicit val p: Parameters
|
||||
val outer: HasPeripheryPWM
|
||||
|
||||
val pwmout = IO(Output(Bool()))
|
||||
|
||||
pwmout := outer.pwm.module.io.pwmout
|
||||
}
|
||||
|
||||
|
||||
Now we want to mix our traits into the system as a whole. This code is from
|
||||
src/main/scala/example/Top.scala.
|
||||
|
||||
::
|
||||
class ExampleTopWithPWM(q: Parameters) extends ExampleTop(q)
|
||||
with PeripheryPWM {
|
||||
override lazy val module = Module(
|
||||
new ExampleTopWithPWMModule(p, this))
|
||||
}
|
||||
|
||||
class ExampleTopWithPWMModule(l: ExampleTopWithPWM)
|
||||
extends ExampleTopModule(l) with HasPeripheryPWMModuleImp
|
||||
|
||||
|
||||
Just as we need separate traits for LazyModule and module implementation, we
|
||||
need two classes to build the system. The ExampleTop classes already have the
|
||||
basic peripherals included for us, so we will just extend those.
|
||||
|
||||
The ExampleTop class includes the pre-elaboration code and also a lazy val to
|
||||
produce the module implementation (hence LazyModule). The ExampleTopModule
|
||||
class is the actual RTL that gets synthesized.
|
||||
|
||||
Finally, we need to add a configuration class in
|
||||
src/main/scala/example/Configs.scala that tells the TestHarness to instantiate
|
||||
ExampleTopWithPWM instead of the default ExampleTop.
|
||||
|
||||
::
|
||||
class WithPWM extends Config((site, here, up) => {
|
||||
case BuildTop => (p: Parameters) =>
|
||||
Module(LazyModule(new ExampleTopWithPWM()(p)).module)
|
||||
})
|
||||
|
||||
class PWMConfig extends Config(new WithPWM ++ new BaseExampleConfig)
|
||||
|
||||
|
||||
Now we can test that the PWM is working. The test program is in tests/pwm.c
|
||||
|
||||
::
|
||||
#define PWM_PERIOD 0x2000
|
||||
#define PWM_DUTY 0x2008
|
||||
#define PWM_ENABLE 0x2010
|
||||
|
||||
static inline void write_reg(unsigned long addr, unsigned long data)
|
||||
{
|
||||
volatile unsigned long *ptr = (volatile unsigned long *) addr;
|
||||
*ptr = data;
|
||||
}
|
||||
|
||||
static inline unsigned long read_reg(unsigned long addr)
|
||||
{
|
||||
volatile unsigned long *ptr = (volatile unsigned long *) addr;
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
write_reg(PWM_PERIOD, 20);
|
||||
write_reg(PWM_DUTY, 5);
|
||||
write_reg(PWM_ENABLE, 1);
|
||||
}
|
||||
|
||||
|
||||
This just writes out to the registers we defined earlier. The base of the
|
||||
module's MMIO region is at 0x2000. This will be printed out in the address
|
||||
map portion when you generated the verilog code.
|
||||
|
||||
Compiling this program with make produces a `pwm.riscv` executable.
|
||||
|
||||
Now with all of that done, we can go ahead and run our simulation.
|
||||
|
||||
::
|
||||
cd verisim
|
||||
make CONFIG=PWMConfig
|
||||
./simulator-example-PWMConfig ../tests/pwm.riscv
|
||||
|
||||
|
||||
|
||||
|
||||
Adding a RoCC Accelerator
|
||||
----------------------------
|
||||
|
||||
RoCC accelerators are lazy modules that extend the LazyRoCC class.
|
||||
Their implementation should extends the LazyRoCCModule class.
|
||||
|
||||
::
|
||||
class CustomAccelerator(opcodes: OpcodeSet)
|
||||
(implicit p: Parameters) extends LazyRoCC(opcodes) {
|
||||
override lazy val module = new CustomAcceleratorModule(this)
|
||||
}
|
||||
|
||||
class CustomAcceleratorModule(outer: CustomAccelerator)
|
||||
extends LazyRoCCModuleImp(outer) {
|
||||
val cmd = Queue(io.cmd)
|
||||
// The parts of the command are as follows
|
||||
// inst - the parts of the instruction itself
|
||||
// opcode
|
||||
// rd - destination register number
|
||||
// rs1 - first source register number
|
||||
// rs2 - second source register number
|
||||
// funct
|
||||
// xd - is the destination register being used?
|
||||
// xs1 - is the first source register being used?
|
||||
// xs2 - is the second source register being used?
|
||||
// rs1 - the value of source register 1
|
||||
// rs2 - the value of source register 2
|
||||
...
|
||||
}
|
||||
|
||||
|
||||
The ``opcodes`` parameter for ``LazyRoCC`` is
|
||||
the set of custom opcodes that will map to this accelerator. More on this
|
||||
in the next subsection.
|
||||
|
||||
The ``LazyRoCC`` class contains two TLOutputNode instances, ``atlNode`` and ``tlNode``.
|
||||
The former connects into a tile-local arbiter along with the backside of the
|
||||
L1 instruction cache. The latter connects directly to the L1-L2 crossbar.
|
||||
The corresponding Tilelink ports in the module implementation's IO bundle
|
||||
are ``atl`` and ``tl``, respectively.
|
||||
|
||||
The other interfaces available to the accelerator are ``mem``, which provides
|
||||
access to the L1 cache; ``ptw`` which provides access to the page-table walker;
|
||||
the ``busy`` signal, which indicates when the accelerator is still handling an
|
||||
instruction; and the ``interrupt`` signal, which can be used to interrupt the CPU.
|
||||
|
||||
Look at the examples in rocket-chip/src/main/scala/tile/LazyRocc.scala for
|
||||
detailed information on the different IOs.
|
||||
|
||||
### Adding RoCC accelerator to Config
|
||||
|
||||
RoCC accelerators can be added to a core by overriding the ``BuildRoCC`` parameter
|
||||
in the configuration. This takes a sequence of functions producing ``LazyRoCC``
|
||||
objects, one for each accelerator you wish to add.
|
||||
|
||||
For instance, if we wanted to add the previously defined accelerator and
|
||||
route custom0 and custom1 instructions to it, we could do the following.
|
||||
|
||||
::
|
||||
class WithCustomAccelerator extends Config((site, here, up) => {
|
||||
case BuildRoCC => Seq((p: Parameters) => LazyModule(
|
||||
new CustomAccelerator(OpcodeSet.custom0 | OpcodeSet.custom1)(p)))
|
||||
})
|
||||
|
||||
class CustomAcceleratorConfig extends Config(
|
||||
new WithCustomAccelerator ++ new DefaultExampleConfig)
|
||||
|
||||
|
||||
|
||||
|
||||
Adding a DMA port
|
||||
-------------------
|
||||
|
||||
IO devices or accelerators (like a disk or network
|
||||
driver), we may want to have the device write directly to the coherent
|
||||
memory system instead. To add a device like that, you would do the following.
|
||||
|
||||
::
|
||||
class DMADevice(implicit p: Parameters) extends LazyModule {
|
||||
val node = TLClientNode(TLClientParameters(
|
||||
name = "dma-device", sourceId = IdRange(0, 1)))
|
||||
|
||||
lazy val module = new DMADeviceModule(this)
|
||||
}
|
||||
|
||||
class DMADeviceModule(outer: DMADevice) extends LazyModuleImp(outer) {
|
||||
val io = IO(new Bundle {
|
||||
val mem = outer.node.bundleOut
|
||||
val ext = new ExtBundle
|
||||
})
|
||||
|
||||
// ... rest of the code ...
|
||||
}
|
||||
|
||||
trait HasPeripheryDMA extends HasSystemNetworks {
|
||||
implicit val p: Parameters
|
||||
|
||||
val dma = LazyModule(new DMADevice)
|
||||
|
||||
fsb.node := dma.node
|
||||
}
|
||||
|
||||
trait HasPeripheryDMAModuleImp extends LazyMultiIOModuleImp {
|
||||
val ext = IO(new ExtBundle)
|
||||
ext <> outer.dma.module.io.ext
|
||||
}
|
||||
|
||||
|
||||
The ``ExtBundle`` contains the signals we connect off-chip that we get data from.
|
||||
The DMADevice also has a Tilelink client port that we connect into the L1-L2
|
||||
crossbar through the front-side buffer (fsb). The sourceId variable given in
|
||||
the TLClientNode instantiation determines the range of ids that can be used
|
||||
in acquire messages from this device. Since we specified [0, 1) as our range,
|
||||
only the ID 0 can be used.
|
||||
79
docs/Getting-Started/Configs-Parameters-Mixins.rst
Normal file
79
docs/Getting-Started/Configs-Parameters-Mixins.rst
Normal file
@@ -0,0 +1,79 @@
|
||||
Configs, Parameters, Mix-ins, and Everything In Between
|
||||
========================================================
|
||||
|
||||
A significant portion of generators in the ReBAR framework use the Rocket chip parameter system.
|
||||
This parameter system enables for the flexible configuration of the SoC without invasive RTL changes.
|
||||
In order to use the parameter system correctly, we will use several terms and conventions:
|
||||
|
||||
**Parameter**
|
||||
|
||||
TODO: Need to explain up, site, field, and other stuff from Henry's thesis.
|
||||
|
||||
It is important to note that a significant challenge with the Rocket parameter system is being able to identify the correct parameter to use, and the impact that parameter has on the overall system. We are still investigating methods to facilitate parameter exploration and discovery.
|
||||
|
||||
|
||||
**Config**
|
||||
A *Config* is a collection of multiple parameters being set to specific values.
|
||||
Configs are additive, and can override each other.
|
||||
A Config can be composed of other configs.
|
||||
The naming convetion for an additive config is `With<YourConfig>`, while the naming convention for a non-additive config will be `<YourConfig>`.
|
||||
Configs can take arguments which will in-turn set parameters in the specific configs.
|
||||
|
||||
Example config:
|
||||
|
||||
..
|
||||
class WithMyAcceleratorParams extends Config((site, here, up) => {
|
||||
case MyAcceleratorKey =>
|
||||
MyAcceleratorConfig(
|
||||
Rows = 2,
|
||||
rowBits = 64,
|
||||
Columns = 16,
|
||||
hartId = 1,
|
||||
some_length = 256,
|
||||
)
|
||||
})
|
||||
|
||||
Example config which uses a higher level config:
|
||||
|
||||
..
|
||||
class WithMyMoreComplexAcceleratorConfig extends Config((site, here, up) => {
|
||||
case MyAcceleratorKey =>
|
||||
MyAcceleratorConfig(
|
||||
Rows = 2,
|
||||
rowBits = site(SystemBusKey).beatBits,
|
||||
hartId = up(RocketTilesKey, site).length,
|
||||
)
|
||||
})
|
||||
|
||||
Example of additive configs:
|
||||
|
||||
..
|
||||
class SomeAdditiveConfig extends Config(
|
||||
new WithMyMoreComplexAcceleratorConfig ++
|
||||
new WithMyAcceleratorParams ++
|
||||
new DefaultExampleConfig
|
||||
)
|
||||
|
||||
|
||||
**Cake Pattern**
|
||||
The cake pattern is a scala programming pattern, which enable "mixing" of multiple traits or interface definitions (sometimes refered to as dependancy injection). It is used in the Rocket chip SoC library and ReBAR framework in merging multiple system components and IO interfaces into a large system component.
|
||||
|
||||
Example of using the cake pattern to merge multiple system components into a single top-level design, extending a basic Rocket SoC:
|
||||
|
||||
..
|
||||
class MySoC(implicit p: Parameters) extends RocketSubsystem
|
||||
with CanHaveMisalignedMasterAXI4MemPort
|
||||
with HasPeripheryBootROM
|
||||
with HasNoDebug
|
||||
with HasPeripherySerial
|
||||
with HasPeripheryUART
|
||||
with HasPeripheryIceNIC
|
||||
{
|
||||
//Additional top-level specific instantiations or wiring
|
||||
}
|
||||
|
||||
|
||||
**Mix-in**
|
||||
A mix-in is a scala trait, which sets parameters for specific system components, as well as enabling instantiation and wiring of the relevant system components to system buses.
|
||||
The naming convetion for an additive mix-in is `Has<YourMixin>`.
|
||||
|
||||
86
docs/Getting-Started/ReBAR-Basics.rst
Normal file
86
docs/Getting-Started/ReBAR-Basics.rst
Normal file
@@ -0,0 +1,86 @@
|
||||
|
||||
|
||||
ReBAR Basics
|
||||
===============================
|
||||
|
||||
|
||||
Generators
|
||||
-------------------------------------------
|
||||
Generators are parametrized programs written as RTL code, designed to generate verilog code based on configuration specifications.
|
||||
Generators can be used to generate Systems-on-Chip (SoCs) using a collection of system components organized in unique generator projects.
|
||||
The ReBAR Framework currently consists of the following generators:
|
||||
|
||||
Processor Cores
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
**Rocket**
|
||||
An in-order RISC-V core.
|
||||
|
||||
**BOOM (Berkeley Out-of-Order Machine)**
|
||||
An out-of-order RISC-V core.
|
||||
|
||||
Data-Parallel Accelerators
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
**Hwacha**
|
||||
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
|
||||
|
||||
|
||||
System Components:
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
**icenet**
|
||||
A Network Interface Controller (NIC) designed to achieve up to 200 Gbps.
|
||||
|
||||
**sifive-blocks**
|
||||
System components implemented by SiFive and used by SiFive projects, designed to be integrated with the Rocket chip generator. These system and peripheral components include UART, SPI, JTAG, I2C, PWM, and other peripheral and interface devices.
|
||||
|
||||
**AWL (Analog Widget Library)**
|
||||
Digital components required for integration with high speed serial links.
|
||||
|
||||
**testchipip**
|
||||
A collection of utilites used for testing chips and interfacing them with larger test environments.
|
||||
|
||||
|
||||
Fixed Function Accelerators:
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
TBD
|
||||
|
||||
|
||||
|
||||
Tools
|
||||
-------------------------------------------
|
||||
**Chisel**
|
||||
A hardware description library embedded in Scala. Chisel is used to write RTL generators using meta-programming, by emdedding hardware generation primitives in the Scala programming language. The Chisel compilter elaborate the generator into a FIRRTL output.
|
||||
|
||||
**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.
|
||||
|
||||
**BARSTOOLS**
|
||||
A collection of common FIRRTL transformations used to manipulate a digital circuit without changing the generator source RTL.
|
||||
|
||||
|
||||
Toolchains
|
||||
-------------------------------------------
|
||||
**riscv-tools**
|
||||
A collection of software toolchains used to develope and execute software on the RISC-V ISA. The include compiler and assembler toolchains, functional ISA simulator (spike), the Berkeley Boot Loader (BBL) and proxy kernel. The riscv-tools repository was previously required to run any RISC-V software, however, many of the riscv-tools components have since been upstreamed to their respective open-source projects (Linux, GNU, etc.). Nevertheless, for consistent versioning, as well as software design flexibility for custom hardware, we include the riscv-tools repository and installation in the ReBAR framework.
|
||||
|
||||
|
||||
**esp-tools**
|
||||
A fork of riscv-tools, designed to work with the Hwacha non-standard RISC-V extension. This fork can also be used as an example demonstrating how to add additional RoCC accelerators to the ISA-level simulation (Spike) and the higher-level software toolchain (GNU binutils, riscv-opcodes, etc.)
|
||||
|
||||
|
||||
Sims
|
||||
-------------------------------------------
|
||||
**verisim (Verilator wrapper)**
|
||||
Verilator is an open source Verilog simulator. The verisim 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).
|
||||
|
||||
**vsim (VCS wrapper)**
|
||||
VCS is a proprietary Verilog simulator. Assuming the user has valid VCS licenses and installations, the vsim 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).
|
||||
|
||||
**FireSim**
|
||||
FireSim is an open-source FPGA-accelerated simulation platform, using Amazon Web Services (AWS) EC2 F1 instances on the public cloud. FireSim automatically transforms and instruments open-hardware designs into fast (10s-100s MHz), deterministic, FPGA-based simulators that enable productive pre-silicon verification and performance validation. 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 clound 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.
|
||||
|
||||
|
||||
VLSI
|
||||
-------------------------------------------
|
||||
**HAMMER**
|
||||
HAMMER is a VLSI flow designed to provide a layer of abstraction between general physical design concepts to vendor-specific EDA tool commands. The HAMMER flow provide automated scripts which generate relevant tool commands based on a higher level description of physical desing contraints. 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 contraints relating to that process technology (obsolete standard cells, metal layer routing contraints, etc.). The HAMMER flow requires access to proprietry EDA tools and process technology libraries.
|
||||
100
docs/Getting-Started/Running-A-Simulation.rst
Normal file
100
docs/Getting-Started/Running-A-Simulation.rst
Normal file
@@ -0,0 +1,100 @@
|
||||
Running A Simulation
|
||||
========================================================
|
||||
|
||||
ReBAR provides support and intergration for multiple simulation flows, for various user levels and requirments.
|
||||
In the majority of cases during a digital design development process, simple software RTL. When more advanced full-system evaluation is required, with long running workloads, FPGA-accelerated simulation will then become a preferable solution.
|
||||
|
||||
|
||||
Software RTL Simulation
|
||||
------------------------
|
||||
The ReBAR framework provides wrappers for two common software RTL simulators: the open-source Verilator simulator. and the proprietry VCS simulator.The following instructions assume at least one of these simulators is installed.
|
||||
|
||||
Verilator
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Verilator is an open-source RTL simulator. We run Verilator simulations from within the `sims/verisim` directory.
|
||||
In order to construct the simulator with our custom design, we run the following command within the `sims/verisim` directory:
|
||||
|
||||
..
|
||||
make TOP=<my_top_level_name> CONFIG=<my_config_name> SBT_PROJECT=<my_sbt_package_name> MODEL=<my_test_environment>
|
||||
|
||||
Where `<my_top_level_name>` is the class name of the top level design, `<my
|
||||
The `make` command my have additional parameters (such as `CONFIG_PACKAGE` or `MODEL_PACKAGE`) depending on the complexity of the design and integration with multiple sub-project repositories in the sbt-based build system.
|
||||
|
||||
Common configurations are package using a `SUB_PROJECT` make variable. There, in order to simulate a simple Rocket-based example system we can use:
|
||||
|
||||
..
|
||||
make SUB_PROJECT=example
|
||||
|
||||
Alternatively, if we would like to simulate a simple BOOM-based example system we can use:
|
||||
|
||||
..
|
||||
make SUB_PROJECT=exampleboom
|
||||
|
||||
|
||||
Once the simulator has been constructed, we would like to run RISC-V programs on it. In the `sims/verisim` directory, we will find an executable file called `TODO`. We run this executable with out target RISC-V program as a command line argument. For example:
|
||||
|
||||
..
|
||||
TODO
|
||||
|
||||
Alternatively, we can run a pre-packaged suite of RISC-V assembly tests, by adding the make target run-asm-tests. For example
|
||||
|
||||
..
|
||||
make run-asm-tests TOP=<my_top_level_name> CONFIG=<my_config_name> SBT_PROJECT=<my_sbt_package_name> MODEL=<my_test_environment>
|
||||
|
||||
or
|
||||
|
||||
..
|
||||
make run-asm-tests SUB_PROJECT=example
|
||||
|
||||
|
||||
|
||||
VCS
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
VCS is a proprietry RTL simulator. This guide assumes that the VCS installation is found on our PATH. We run VCS simulations from within the `sims/vsim` directory.
|
||||
In order to construct the simulator with our custom design, we run the following command within the `sims/vsim` directory:
|
||||
|
||||
..
|
||||
make TOP=<my_top_level_name> CONFIG=<my_config_name> SBT_PROJECT=<my_sbt_package_name> MODEL=<my_test_environment>
|
||||
|
||||
Where `<my_top_level_name>` is the class name of the top level design, `<my
|
||||
The `make` command my have additional parameters (such as `CONFIG_PACKAGE` or `MODEL_PACKAGE`) depending on the complexity of the design and integration with multiple sub-project repositories in the sbt-based build system.
|
||||
|
||||
Common configurations are package using a `SUB_PROJECT` make variable. There, in order to simulate a simple Rocket-based example system we can use:
|
||||
|
||||
..
|
||||
make SUB_PROJECT=example
|
||||
|
||||
Alternatively, if we would like to simulate a simple BOOM-based example system we can use:
|
||||
|
||||
..
|
||||
make SUB_PROJECT=exampleboom
|
||||
|
||||
|
||||
Once the simulator has been constructed, we would like to run RISC-V programs on it. In the `sims/vsim` directory, we will find an executable file called `TODO`. We run this executable with out target RISC-V program as a command line argument. For example:
|
||||
|
||||
..
|
||||
TODO
|
||||
|
||||
Alternatively, we can run a pre-packaged suite of RISC-V assembly tests, by adding the make target run-asm-tests. For example
|
||||
|
||||
..
|
||||
make run-asm-tests TOP=<my_top_level_name> CONFIG=<my_config_name> SBT_PROJECT=<my_sbt_package_name> MODEL=<my_test_environment>
|
||||
|
||||
or
|
||||
|
||||
..
|
||||
make run-asm-tests SUB_PROJECT=example
|
||||
|
||||
|
||||
|
||||
FPGA Accelerated Simulation
|
||||
---------------------------
|
||||
FireSim enables simulations at 1000x-100000x the speed of standard software simulation. This is enabled using FPGA-acceleration on F1 instances of the AWS (Amazon Web Services) public cloud. There FireSim simulation require to be set-up on the AWS public cloud rather than on our local development machine.
|
||||
|
||||
To run an FPGA-accelerated simulation using FireSim, a we need to clone the ReBAR repository (or our fork of the ReBAR repository) to an AWS EC2, and follow the setup instructions specificied in the FireSim Initial Setup documentation page.
|
||||
|
||||
After setting up the FireSim environment, we now need to generate a FireSim simulation around our selected digital design. We will work from within the `sims/firesim` directory.
|
||||
|
||||
TODO: Continue from here
|
||||
|
||||
22
docs/Getting-Started/index.rst
Normal file
22
docs/Getting-Started/index.rst
Normal file
@@ -0,0 +1,22 @@
|
||||
.. _ReBAR Basics:
|
||||
|
||||
ReBAR Basics
|
||||
================================
|
||||
|
||||
These guides will walk you through the basics of the ReBAR framework:
|
||||
|
||||
- First, we will go over the different configurations avaliable.
|
||||
|
||||
- Then, we will walk through adding a custom accelerator.
|
||||
|
||||
Hit next to get started!
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Getting Started:
|
||||
|
||||
ReBAR-Basics
|
||||
Configs-Parameters-Mixins
|
||||
Adding-An-Accelerator-Tutorial
|
||||
Running-A-Simulation
|
||||
rebar-generator-mixins
|
||||
135
docs/Getting-Started/rebar-generator-mixins.rst
Normal file
135
docs/Getting-Started/rebar-generator-mixins.rst
Normal file
@@ -0,0 +1,135 @@
|
||||
|
||||
|
||||
SoC Generator Config Mix-ins:
|
||||
==============================
|
||||
|
||||
Rocket Chip
|
||||
-----------------------
|
||||
|
||||
+ System-on-Chip
|
||||
- HasTiles
|
||||
- HasClockDomainCrossing
|
||||
- HasResetVectorWire
|
||||
- HasNoiseMakerIO
|
||||
|
||||
|
||||
+ Basic Core
|
||||
- HasRocketTiles
|
||||
- HasRocketCoreParameters
|
||||
- HasCoreIO
|
||||
|
||||
|
||||
+ Branch Prediction
|
||||
- HasBtbParameters
|
||||
|
||||
|
||||
+ Additional Compute
|
||||
- HasFPUCtrlSigs
|
||||
- HasFPUParameters
|
||||
- HasLazyRoCC
|
||||
- HasFpuOpt
|
||||
|
||||
|
||||
+ Memory System
|
||||
- HasRegMap
|
||||
- HasCoreMemOp
|
||||
- HasHellaCache
|
||||
- HasL1ICacheParameters
|
||||
- HasICacheFrontendModule
|
||||
- HasAXI4ControlRegMap
|
||||
- HasTLControlRegMap
|
||||
- HasTLBusParams
|
||||
- HasTLXbarPhy
|
||||
|
||||
|
||||
+ Interrupts
|
||||
- HasInterruptSources
|
||||
- HasExtInterrupts
|
||||
- HasAsyncExtInterrupts
|
||||
- HasSyncExtInterrupts
|
||||
|
||||
|
||||
+ Periphery
|
||||
- HasPeripheryDebug
|
||||
- HasPeripheryBootROM
|
||||
- HasBuiltInDeviceParams
|
||||
|
||||
|
||||
BOOM
|
||||
-----------------------
|
||||
+ Basic Core
|
||||
- HasBoomTiles
|
||||
- HasBoomCoreParameters
|
||||
- HasBoomCoreIO
|
||||
- HasBoomUOP
|
||||
- HasRegisterFileIO
|
||||
|
||||
|
||||
+ Branch Prediction
|
||||
- HasGShareParameters
|
||||
- HasBoomBTBParameters
|
||||
|
||||
|
||||
+ Memory System
|
||||
- HasL1ICacheBankedParameters
|
||||
- HasBoomICacheFrontend
|
||||
- HasBoomHellaCache
|
||||
|
||||
|
||||
SiFive Blocks
|
||||
-----------------------
|
||||
|
||||
+ Peripherals
|
||||
- HasPeripheryGPIO
|
||||
- HasPeripheryI2C
|
||||
- HasPeripheryMockAON
|
||||
- HasPeripheryPWM
|
||||
- HasPeripherySPI
|
||||
- HasSPIProtocol
|
||||
- HasSPIEndian
|
||||
- HasSPILength
|
||||
- HasSPICSMode
|
||||
- HasPeripherySPIFlash
|
||||
- HasPeripheryUART
|
||||
|
||||
|
||||
testchipip
|
||||
-----------------------
|
||||
|
||||
+ Peripherals
|
||||
- HasPeripheryBlockDevice
|
||||
- HasPeripherySerial
|
||||
- HasNoDebug
|
||||
|
||||
|
||||
Icenet
|
||||
-----------------------
|
||||
|
||||
+ Periphery Network Interface Controller
|
||||
- HasPeripheryIceNIC
|
||||
|
||||
|
||||
AWL
|
||||
-----------------------
|
||||
|
||||
+ IO
|
||||
- HasEncoding8b10b
|
||||
- HasTLBidirectionalPacketizer
|
||||
- HasTLController
|
||||
- HasGenericTransceiverSubsystem
|
||||
|
||||
+ Debug/Testing
|
||||
- HasBertDebug
|
||||
- HasPatternMemDebug
|
||||
- HasBitStufferDebug4Modes
|
||||
- HasBitReversalDebug
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user