Merge branch 'dev' of https://github.com/ucb-bar/chipyard into ariane-decouple
This commit is contained in:
@@ -14,5 +14,5 @@ if [ ! -d "$HOME/$1-install" ]; then
|
||||
cd $HOME
|
||||
|
||||
# init all submodules including the tools
|
||||
CHIPYARD_DIR="$LOCAL_CHIPYARD_DIR" NPROC=2 $LOCAL_CHIPYARD_DIR/scripts/build-toolchains.sh $1
|
||||
CHIPYARD_DIR="$LOCAL_CHIPYARD_DIR" NPROC=$CI_MAKE_NPROC $LOCAL_CHIPYARD_DIR/scripts/build-toolchains.sh $1
|
||||
fi
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
# clean directories that are older than 30 days
|
||||
# clean directories that are older than 14 days
|
||||
# argument is used as the directory to look in
|
||||
|
||||
age () {
|
||||
@@ -20,7 +20,7 @@ age () {
|
||||
|
||||
for d in $1/*/ ; do
|
||||
DIR_AGE="$(age $d)"
|
||||
if [ $DIR_AGE -ge 30 ]; then
|
||||
if [ $DIR_AGE -ge 14 ]; then
|
||||
echo "Deleting $d since is it $DIR_AGE old"
|
||||
rm -rf $d
|
||||
else
|
||||
|
||||
@@ -6,7 +6,7 @@ version: 2.1
|
||||
parameters:
|
||||
tools-cache-version:
|
||||
type: string
|
||||
default: "v4"
|
||||
default: "v5"
|
||||
|
||||
# default execution env.s
|
||||
executors:
|
||||
@@ -204,6 +204,16 @@ jobs:
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
project-key: "chipyard-sha3"
|
||||
prepare-chipyard-streaming-fir:
|
||||
executor: main-env
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
project-key: "chipyard-streaming-fir"
|
||||
prepare-chipyard-streaming-passthrough:
|
||||
executor: main-env
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
project-key: "chipyard-streaming-passthrough"
|
||||
prepare-chipyard-hetero:
|
||||
executor: main-env
|
||||
steps:
|
||||
@@ -287,6 +297,16 @@ jobs:
|
||||
steps:
|
||||
- run-tests:
|
||||
project-key: "chipyard-sha3"
|
||||
chipyard-streaming-fir-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
project-key: "chipyard-streaming-fir"
|
||||
chipyard-streaming-passthrough-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
project-key: "chipyard-streaming-passthrough"
|
||||
chipyard-hetero-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
@@ -439,6 +459,16 @@ workflows:
|
||||
- install-riscv-toolchain
|
||||
- install-verilator
|
||||
|
||||
- prepare-chipyard-streaming-fir:
|
||||
requires:
|
||||
- install-riscv-toolchain
|
||||
- install-verilator
|
||||
|
||||
- prepare-chipyard-streaming-passthrough:
|
||||
requires:
|
||||
- install-riscv-toolchain
|
||||
- install-verilator
|
||||
|
||||
- prepare-chipyard-hetero:
|
||||
requires:
|
||||
- install-riscv-toolchain
|
||||
@@ -525,6 +555,14 @@ workflows:
|
||||
requires:
|
||||
- prepare-chipyard-sha3
|
||||
|
||||
- chipyard-streaming-fir-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-streaming-fir
|
||||
|
||||
- chipyard-streaming-passthrough-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-streaming-passthrough
|
||||
|
||||
- chipyard-hetero-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-hetero
|
||||
|
||||
@@ -18,13 +18,16 @@ clean () {
|
||||
}
|
||||
|
||||
# make parallelism
|
||||
NPROC=8
|
||||
CI_MAKE_NPROC=8
|
||||
# chosen based on a 24c system shared with 1 other project
|
||||
REMOTE_MAKE_NPROC=4
|
||||
|
||||
# verilator version
|
||||
VERILATOR_VERSION=v4.034
|
||||
|
||||
# remote variables
|
||||
REMOTE_WORK_DIR=$CI_DIR/$CIRCLE_PROJECT_REPONAME-$CIRCLE_BRANCH-$CIRCLE_SHA1-$CIRCLE_JOB
|
||||
REMOTE_PREFIX=$CI_DIR/$CIRCLE_PROJECT_REPONAME-$CIRCLE_BRANCH
|
||||
REMOTE_WORK_DIR=$REMOTE_PREFIX-$CIRCLE_SHA1-$CIRCLE_JOB
|
||||
REMOTE_RISCV_DIR=$REMOTE_WORK_DIR/riscv-tools-install
|
||||
REMOTE_ESP_DIR=$REMOTE_WORK_DIR/esp-tools-install
|
||||
REMOTE_CHIPYARD_DIR=$REMOTE_WORK_DIR/chipyard
|
||||
@@ -32,7 +35,7 @@ REMOTE_SIM_DIR=$REMOTE_CHIPYARD_DIR/sims/verilator
|
||||
REMOTE_FIRESIM_DIR=$REMOTE_CHIPYARD_DIR/sims/firesim/sim
|
||||
# Disable the supershell to greatly improve the readability of SBT output when captured by Circle CI
|
||||
REMOTE_JAVA_ARGS="-Xmx9G -Xss8M -Dsbt.ivy.home=$REMOTE_WORK_DIR/.ivy2 -Dsbt.supershell=false -Dsbt.global.base=$REMOTE_WORK_DIR/.sbt -Dsbt.boot.directory=$REMOTE_WORK_DIR/.sbt/boot"
|
||||
REMOTE_VERILATOR_DIR=$CI_DIR/$CIRCLE_PROJECT_REPONAME-$CIRCLE_BRANCH-$CIRCLE_SHA1-verilator-install
|
||||
REMOTE_VERILATOR_DIR=$REMOTE_PREFIX-$CIRCLE_SHA1-verilator-install
|
||||
|
||||
# local variables (aka within the docker container)
|
||||
LOCAL_CHECKOUT_DIR=$HOME/project
|
||||
@@ -46,6 +49,8 @@ LOCAL_FIRESIM_DIR=$LOCAL_CHIPYARD_DIR/sims/firesim/sim
|
||||
declare -A mapping
|
||||
mapping["chipyard-rocket"]="SUB_PROJECT=chipyard"
|
||||
mapping["chipyard-sha3"]="SUB_PROJECT=chipyard CONFIG=Sha3RocketConfig"
|
||||
mapping["chipyard-streaming-fir"]="SUB_PROJECT=chipyard CONFIG=StreamingFIRRocketConfig"
|
||||
mapping["chipyard-streaming-passthrough"]="SUB_PROJECT=chipyard CONFIG=StreamingPassthroughRocketConfig"
|
||||
mapping["chipyard-hetero"]="SUB_PROJECT=chipyard CONFIG=LargeBoomAndRocketConfig"
|
||||
mapping["chipyard-boom"]="SUB_PROJECT=chipyard CONFIG=SmallBoomConfig"
|
||||
mapping["chipyard-blkdev"]="SUB_PROJECT=chipyard CONFIG=SimBlockDeviceRocketConfig"
|
||||
|
||||
@@ -58,7 +58,8 @@ run "export RISCV=\"$TOOLS_DIR\"; \
|
||||
export LD_LIBRARY_PATH=\"$LD_LIB_DIR\"; \
|
||||
export PATH=\"$REMOTE_VERILATOR_DIR/bin:\$PATH\"; \
|
||||
export VERILATOR_ROOT=\"$REMOTE_VERILATOR_DIR\"; \
|
||||
make -j$NPROC -C $REMOTE_SIM_DIR JAVA_ARGS=\"$REMOTE_JAVA_ARGS\" ${mapping[$1]}"
|
||||
export COURSIER_CACHE=\"$REMOTE_WORK_DIR/.coursier-cache\"; \
|
||||
make -j$REMOTE_MAKE_NPROC -C $REMOTE_SIM_DIR JAVA_ARGS=\"$REMOTE_JAVA_ARGS\" ${mapping[$1]}"
|
||||
run "rm -rf $REMOTE_CHIPYARD_DIR/project"
|
||||
|
||||
# copy back the final build
|
||||
|
||||
@@ -9,7 +9,9 @@ set -ex
|
||||
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
|
||||
source $SCRIPT_DIR/defaults.sh
|
||||
|
||||
# clean older directories (delete prior directories related to this branch also)
|
||||
run_script $LOCAL_CHIPYARD_DIR/.circleci/clean-old-files.sh $CI_DIR
|
||||
run "rm -rf $REMOTE_PREFIX*"
|
||||
|
||||
# set stricthostkeychecking to no (must happen before rsync)
|
||||
run "echo \"Ping $SERVER\""
|
||||
@@ -20,4 +22,4 @@ run "git clone http://git.veripool.org/git/verilator $REMOTE_VERILATOR_DIR; \
|
||||
autoconf; \
|
||||
export VERILATOR_ROOT=$REMOTE_VERILATOR_DIR; \
|
||||
./configure; \
|
||||
make -j$NPROC;"
|
||||
make -j$REMOTE_MAKE_NPROC;"
|
||||
|
||||
@@ -48,4 +48,5 @@ run "export RISCV=\"$TOOLS_DIR\"; \
|
||||
export FIRESIM_ENV_SOURCED=1; \
|
||||
export PATH=\"$REMOTE_VERILATOR_DIR/bin:\$PATH\"; \
|
||||
export VERILATOR_ROOT=\"$REMOTE_VERILATOR_DIR\"; \
|
||||
export COURSIER_CACHE=\"$REMOTE_WORK_DIR/.coursier-cache\"; \
|
||||
make -C $REMOTE_FIRESIM_DIR JAVA_ARGS=\"$REMOTE_JAVA_ARGS\" testOnly ${mapping[$1]}"
|
||||
|
||||
@@ -46,4 +46,5 @@ run "export RISCV=\"$TOOLS_DIR\"; \
|
||||
export FIRESIM_ENV_SOURCED=1; \
|
||||
export PATH=\"$REMOTE_VERILATOR_DIR/bin:\$PATH\"; \
|
||||
export VERILATOR_ROOT=\"$REMOTE_VERILATOR_DIR\"; \
|
||||
export COURSIER_CACHE=\"$REMOTE_WORK_DIR/.coursier-cache\"; \
|
||||
make -C $REMOTE_FIRESIM_DIR JAVA_ARGS=\"$REMOTE_JAVA_ARGS\" TARGET_PROJECT=midasexamples test"
|
||||
|
||||
@@ -10,11 +10,11 @@ SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
|
||||
source $SCRIPT_DIR/defaults.sh
|
||||
|
||||
run_bmark () {
|
||||
make run-bmark-tests-fast -j$NPROC -C $LOCAL_SIM_DIR $@
|
||||
make run-bmark-tests-fast -j$CI_MAKE_NPROC -C $LOCAL_SIM_DIR $@
|
||||
}
|
||||
|
||||
run_asm () {
|
||||
make run-asm-tests-fast -j$NPROC -C $LOCAL_SIM_DIR $@
|
||||
make run-asm-tests-fast -j$CI_MAKE_NPROC -C $LOCAL_SIM_DIR $@
|
||||
}
|
||||
|
||||
run_both () {
|
||||
@@ -45,7 +45,7 @@ case $1 in
|
||||
export RISCV=$LOCAL_ESP_DIR
|
||||
export LD_LIBRARY_PATH=$LOCAL_ESP_DIR/lib
|
||||
export PATH=$RISCV/bin:$PATH
|
||||
make run-rv64uv-p-asm-tests -j$NPROC -C $LOCAL_SIM_DIR ${mapping[$1]}
|
||||
make run-rv64uv-p-asm-tests -j$CI_MAKE_NPROC -C $LOCAL_SIM_DIR ${mapping[$1]}
|
||||
;;
|
||||
chipyard-gemmini)
|
||||
export RISCV=$LOCAL_ESP_DIR
|
||||
@@ -62,6 +62,14 @@ case $1 in
|
||||
(cd $LOCAL_CHIPYARD_DIR/generators/sha3/software && ./build.sh)
|
||||
$LOCAL_SIM_DIR/simulator-chipyard-Sha3RocketConfig $LOCAL_CHIPYARD_DIR/generators/sha3/software/benchmarks/bare/sha3-rocc.riscv
|
||||
;;
|
||||
chipyard-streaming-passthrough)
|
||||
make -C $LOCAL_CHIPYARD_DIR/tests
|
||||
$LOCAL_SIM_DIR/simulator-chipyard-StreamingPassthroughRocketConfig $LOCAL_CHIPYARD_DIR/tests/streaming-passthrough.riscv
|
||||
;;
|
||||
chipyard-streaming-fir)
|
||||
make -C $LOCAL_CHIPYARD_DIR/tests
|
||||
$LOCAL_SIM_DIR/simulator-chipyard-StreamingFIRRocketConfig $LOCAL_CHIPYARD_DIR/tests/streaming-fir.riscv
|
||||
;;
|
||||
chipyard-spiflashread)
|
||||
make -C $LOCAL_CHIPYARD_DIR/tests
|
||||
make -C $LOCAL_SIM_DIR ${mapping[$1]} BINARY=$LOCAL_CHIPYARD_DIR/tests/spiflashread.riscv SIM_FLAGS="+spiflash0=${LOCAL_CHIPYARD_DIR}/tests/spiflash.img" run-binary
|
||||
|
||||
12
.github/ISSUE_TEMPLATE/bug-report.md
vendored
12
.github/ISSUE_TEMPLATE/bug-report.md
vendored
@@ -8,16 +8,14 @@ labels: bug
|
||||
<!-- choose one -->
|
||||
**Impact**: rtl | software | unknown | other
|
||||
|
||||
**Tell us about your environment:**
|
||||
*Chipyard Version:* <!-- 1.2.0, Hash: 2c0928 -->
|
||||
*OS:* <!-- `Linux knight 4.4.0-92-generic #115-Ubuntu SMP Thu Aug 10 09:04:33 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux` -->
|
||||
*Other:* <!-- `prior steps taken/documentation followed/...` -->
|
||||
|
||||
**What is the current behavior?**
|
||||
|
||||
**What is the expected behavior?**
|
||||
|
||||
**Please tell us about your environment:**
|
||||
<!-- (examples)
|
||||
- version: `chipyard git commit hash`
|
||||
- os: `Linux knight 4.4.0-92-generic #115-Ubuntu SMP Thu Aug 10 09:04:33 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux`
|
||||
- other: `prior steps taken/documentation followed/...`
|
||||
-->
|
||||
|
||||
**Other information**
|
||||
<!-- include detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, ... -->
|
||||
|
||||
5
.github/ISSUE_TEMPLATE/question.md
vendored
5
.github/ISSUE_TEMPLATE/question.md
vendored
@@ -5,6 +5,11 @@ labels: question
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
this type of issue is more for "how-tos", understanding chipyard, etc.
|
||||
if you find an error or issue with chipyard, please use the "Bug Report Issue".
|
||||
-->
|
||||
|
||||
<!-- have you looked at the Chipyard documentation? -->
|
||||
<!-- have you looked at the subproject documentation/githubs? -->
|
||||
<!-- for example: -->
|
||||
|
||||
19
README.md
19
README.md
@@ -29,13 +29,28 @@ Chipyard is actively developed in the [Berkeley Architecture Research Group][ucb
|
||||
|
||||
* See [CONTRIBUTING.md](/CONTRIBUTING.md)
|
||||
|
||||
## Chipyard-related Publications
|
||||
## Attribution and Chipyard-related Publications
|
||||
|
||||
These publications cover many of the internal components used in Chipyard. However, for the most up-to-date details, users should refer to the Chipyard docs.
|
||||
If used for research, please cite Chipyard by the following publication:
|
||||
|
||||
```
|
||||
@article{chipyard,
|
||||
author={Amid, Alon and Biancolin, David and Gonzalez, Abraham and Grubb, Daniel and Karandikar, Sagar and Liew, Harrison and Magyar, Albert and Mao, Howard and Ou, Albert and Pemberton, Nathan and Rigge, Paul and Schmidt, Colin and Wright, John and Zhao, Jerry and Shao, Yakun Sophia and Asanovi\'{c}, Krste and Nikoli\'{c}, Borivoje},
|
||||
journal={IEEE Micro},
|
||||
title={Chipyard: Integrated Design, Simulation, and Implementation Framework for Custom SoCs},
|
||||
year={2020},
|
||||
pages={},
|
||||
doi={10.1109/MM.2020.2996616},
|
||||
ISSN={1937-4143},
|
||||
}
|
||||
```
|
||||
|
||||
These additional publications cover many of the internal components used in Chipyard. However, for the most up-to-date details, users should refer to the Chipyard docs.
|
||||
|
||||
* **Generators**
|
||||
* **Rocket Chip**: K. Asanovic, et al., *UCB EECS TR*. [PDF](http://www2.eecs.berkeley.edu/Pubs/TechRpts/2016/EECS-2016-17.pdf).
|
||||
* **BOOM**: C. Celio, et al., *Hot Chips 30*. [PDF](https://www.hotchips.org/hc30/1conf/1.03_Berkeley_BROOM_HC30.Berkeley.Celio.v02.pdf).
|
||||
* **SonicBOOM (BOOMv3): J. Zhao, et al., *CARRV'20*. [PDF](https://carrv.github.io/2020/papers/CARRV2020_paper_15_Zhao.pdf).
|
||||
* **Hwacha**: Y. Lee, et al., *ESSCIRC'14*. [PDF](http://hwacha.org/papers/riscv-esscirc2014.pdf).
|
||||
* **Gemmini**: H. Genc, et al., *arXiv*. [PDF](https://arxiv.org/pdf/1911.09925).
|
||||
* **Sims**
|
||||
|
||||
15
build.sbt
15
build.sbt
@@ -20,6 +20,8 @@ lazy val commonSettings = Seq(
|
||||
libraryDependencies += "com.github.scopt" %% "scopt" % "3.7.0",
|
||||
libraryDependencies += "org.scala-lang.modules" % "scala-jline" % "2.12.1",
|
||||
libraryDependencies += "com.typesafe.play" %% "play-json" % "2.6.10",
|
||||
libraryDependencies += "org.typelevel" %% "spire" % "0.16.2",
|
||||
libraryDependencies += "org.scalanlp" %% "breeze" % "1.0",
|
||||
addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full),
|
||||
unmanagedBase := (chipyardRoot / unmanagedBase).value,
|
||||
allDependencies := allDependencies.value.filterNot(_.organization == "edu.berkeley.cs"),
|
||||
@@ -129,6 +131,7 @@ lazy val iocell = (project in file("./tools/barstools/iocell/"))
|
||||
lazy val chipyard = conditionalDependsOn(project in file("generators/chipyard"))
|
||||
.dependsOn(boom, hwacha, sifive_blocks, sifive_cache, utilities, iocell,
|
||||
sha3, // On separate line to allow for cleaner tutorial-setup patches
|
||||
dsptools, `rocket-dsptools`,
|
||||
gemmini, icenet, tracegen, ariane, nvdla)
|
||||
.settings(commonSettings)
|
||||
|
||||
@@ -180,19 +183,17 @@ lazy val barstoolsMacros = (project in file("./tools/barstools/macros/"))
|
||||
.enablePlugins(sbtassembly.AssemblyPlugin)
|
||||
.settings(commonSettings)
|
||||
|
||||
lazy val dsptools = (project in file("./tools/dsptools"))
|
||||
lazy val dsptools = freshProject("dsptools", file("./tools/dsptools"))
|
||||
.dependsOn(chisel, chisel_testers)
|
||||
.settings(
|
||||
commonSettings,
|
||||
libraryDependencies ++= Seq(
|
||||
"org.typelevel" %% "spire" % "0.14.1",
|
||||
"org.scalanlp" %% "breeze" % "0.13.2",
|
||||
"junit" % "junit" % "4.12" % "test",
|
||||
"org.scalatest" %% "scalatest" % "3.0.5" % "test",
|
||||
"org.scalacheck" %% "scalacheck" % "1.14.0" % "test"
|
||||
"junit" % "junit" % "4.13" % "test",
|
||||
"org.scalatest" %% "scalatest" % "3.0.8",
|
||||
"org.scalacheck" %% "scalacheck" % "1.14.3" % "test"
|
||||
))
|
||||
|
||||
lazy val `rocket-dsptools` = (project in file("./tools/dsptools/rocket"))
|
||||
lazy val `rocket-dsptools` = freshProject("rocket-dsptools", file("./tools/dsptools/rocket"))
|
||||
.dependsOn(rocketchip, dsptools)
|
||||
.settings(commonSettings)
|
||||
|
||||
|
||||
@@ -86,3 +86,28 @@ This depends on what you are planning to do with Chipyard.
|
||||
* If you intend to run a tutorial VLSI flow using one of the Chipyard examples, go to :ref:`tutorial` and follow the instructions.
|
||||
|
||||
* If you intend to build a chip using one of the vanilla Chipyard examples, go to :ref:`build-a-chip` and follow the instructions.
|
||||
|
||||
Upgrading Chipyard Release Versions
|
||||
-------------------------------------------
|
||||
|
||||
In order to upgrade between Chipyard versions, we recommend using a fresh clone of the repository (or your fork, with the new release merged into it).
|
||||
|
||||
|
||||
Chipyard is a complex framework that depends on a mix of build systems and scripts. Specifically, it relies on git submodules, on sbt build files, and on custom written bash scripts and generated files.
|
||||
For this reason, upgrading between Chipyard versions is **not** as trivial as just running ``git submodule update -recursive``. This will result in recursive cloning of large submodules that are not necessarily used within your specific Chipyard environments. Furthermore, it will not resolve the status of stale state generated files which may not be compatible between release versions.
|
||||
|
||||
|
||||
If you are an advanced git user, an alternative approach to a fresh repository clone may be to run ``git clean -dfx``, and then run the standard Chipyard setup sequence. This approach is dangerous, and **not-recommended** for users who are not deeply familiar with git, since it "blows up" the repository state and removes all untracked and modified files without warning. Hence, if you were working on custom un-committed changes, you would lose them.
|
||||
|
||||
If you would still like to try to perform an in-place manual version upgrade (**not-recommended**), we recommend at least trying to resolve stale state in the following areas:
|
||||
|
||||
* Delete stale ``target`` directories generated by sbt.
|
||||
|
||||
* Delete jar collateral generated by FIRRTL (``lib/firrtl.jar``)
|
||||
|
||||
* Re-generate generated scripts and source files (for example, ``env.sh``)
|
||||
|
||||
* Re-generating/deleting target software state (Linux kernel binaries, Linux images) within FireMarshal
|
||||
|
||||
|
||||
This is by no means a comprehensive list of potential stale state within Chipyard. Hence, as mentioned earlier, the recommended method for a Chipyard version upgrade is a fresh clone (or a merge, and then a fresh clone).
|
||||
|
||||
125
docs/Customization/Dsptools-Blocks.rst
Normal file
125
docs/Customization/Dsptools-Blocks.rst
Normal file
@@ -0,0 +1,125 @@
|
||||
.. _dsptools-blocks:
|
||||
|
||||
Dsptools is a Chisel library that aids in writing custom signal processing accelerators. It does this by:
|
||||
* Giving types and helpers that allow you to express mathematical operations more directly.
|
||||
* Typeclasses that let you write polymorphic generators, for example an FIR filter generator that works for both real- and complex-valued filters.
|
||||
* Structures for packaging DSP blocks and integrating them into a rocketchip-based SoC.
|
||||
* Test harnesses for testing DSP circuits, as well as VIP-style drivers and monitors for DSP blocks.
|
||||
|
||||
The `Dsptools repository <https://github.com/ucb-bar/dsptools/>`_ has more documentation.
|
||||
|
||||
|
||||
Dsptools Blocks
|
||||
===============
|
||||
A ``DspBlock`` is the basic unit of signal processing functionality that can be integrated into an SoC.
|
||||
It has a AXI4-stream interface and an optional memory interface.
|
||||
The idea is that these ``DspBlocks`` can be easily designed, unit tested, and assembled lego-style to build complex functionality.
|
||||
A ``DspChain`` is one example of how to assemble ``DspBlocks``, in which case the streaming interfaces are connected serially into a pipeline, and a bus is instatiated and connected to every block with a memory interface.
|
||||
|
||||
Chipyard has example designs that integrate a ``DspBlock`` to a rocketchip-based SoC as an MMIO peripheral. The custom ``DspBlock`` has a ``ReadQueue`` before it and a ``WriteQueue`` after it, which allow memory mapped access to the streaming interfaces so the rocket core can interact with the ``DspBlock`` [#]_. This section will primarily focus on designing Tilelink-based peripherals. However, through the resources provided in Dsptools, one could also define an AXI4-based peripheral by following similar steps. Furthermore, the examples here are simple, but can be extended to implement more complex accelerators, for example an `OFDM baseband <https://github.com/grebe/ofdm>`_ or a `spectrometer <https://github.com/ucb-art/craft2-chip>`_.
|
||||
|
||||
.. figure:: ../_static/images/fir-block-diagram.svg
|
||||
:align: center
|
||||
:alt: Block diagram showing how FIR is integrated with rocket.
|
||||
:width: 400px
|
||||
|
||||
For this example, we will show you how to connect a simple FIR filter created using Dsptools as an MMIO peripheral as shown in the figure above. The full code can be found in ``generators/chipyard/src/main/scala/example/dsptools/GenericFIR.scala``. That being said, one could substitute any module with a ready valid interface in the place of the FIR and achieve the same results. As long as the read and valid signals of the module are attached to those of a corresponding ``DSPBlock`` wrapper, and that wrapper is placed in a chain with a ``ReadQueue`` and a ``WriteQueue``, following the general outline establised by these steps will allow you to interact with that block as a memory mapped IO.
|
||||
|
||||
The module ``GenericFIR`` is the overall wrapper of our FIR module. This module links together a variable number of ``GenericFIRDirectCell`` submodules, each of which performs the computations for one coefficient in a FIR direct form architecture. It is important to note that both modules are type-generic, which means that they can be instantiated for any datatype ``T`` that implements ``Ring`` operations (e.g. addition, multiplication, identities).
|
||||
|
||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/dsptools/GenericFIR.scala
|
||||
:language: scala
|
||||
:start-after: DOC include start: GenericFIR chisel
|
||||
:end-before: DOC include end: GenericFIR chisel
|
||||
|
||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/dsptools/GenericFIR.scala
|
||||
:language: scala
|
||||
:start-after: DOC include start: GenericFIRDirectCell chisel
|
||||
:end-before: DOC include end: GenericFIRDirectCell chisel
|
||||
|
||||
Creating a DspBlock
|
||||
-------------------
|
||||
|
||||
The first step in attaching the FIR filter as a MMIO peripheral is to create an abstract subclass of ``DspBlock`` the wraps around the ``GenericFIR`` module. Streaming outputs and inputs are packed and unpacked into ``UInt`` s. If there were control signals, this is where they'd go from raw IOs to memory mapped. The main steps of this process are as follows.
|
||||
|
||||
1. Instantiate a ``GenericFIR`` within ``GenericFIRBlock``.
|
||||
2. Attach the ready and valid signals from the in and out connections.
|
||||
3. Cast the module input data to the input type of ``GenericFIR`` (``GenericFIRBundle``) and attach.
|
||||
4. Cast the output of ``GenericFIR`` to ``UInt`` and attach to the module output.
|
||||
|
||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/dsptools/GenericFIR.scala
|
||||
:language: scala
|
||||
:start-after: DOC include start: GenericFIRBlock chisel
|
||||
:end-before: DOC include end: GenericFIRBlock chisel
|
||||
|
||||
Note that at this point the ``GenericFIRBlock`` does not have a type of memory interface specified. This abstract class can be used to create different flavors that use AXI-4, TileLink, AHB, or whatever other memory interface you like like.
|
||||
|
||||
Connecting DspBlock by TileLink
|
||||
-------------------------------
|
||||
With these classes implemented, you can begin to construct the chain by extending ``GenericFIRBlock`` while using the ``TLDspBlock`` trait via mixin.
|
||||
|
||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/dsptools/GenericFIR.scala
|
||||
:language: scala
|
||||
:start-after: DOC include start: TLGenericFIRBlock chisel
|
||||
:end-before: DOC include end: TLGenericFIRBlock chisel
|
||||
|
||||
We can then construct the final chain by utilizing the ``TLWriteQueue`` and ``TLReadeQueue`` modules found in ``generators/chipyard/src/main/scala/example/dsptools/DspBlocks.scala``. The chain is created by passing a list of factory functions to the constructor of ``TLChain``. The constructor then automatically instantiates these ``DspBlocks``, connects their stream nodes in order, creates a bus, and connects any ``DspBlocks`` that have memory interfaces to the bus.
|
||||
|
||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/dsptools/GenericFIR.scala
|
||||
:language: scala
|
||||
:start-after: DOC include start: TLGenericFIRChain chisel
|
||||
:end-before: DOC include end: TLGenericFIRChain chisel
|
||||
|
||||
Top Level Traits
|
||||
----------------
|
||||
As in the previous MMIO example, we use a cake pattern to hook up our module to our SoC.
|
||||
|
||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/dsptools/GenericFIR.scala
|
||||
:language: scala
|
||||
:start-after: DOC include start: CanHavePeripheryStreamingFIR chisel
|
||||
:end-before: DOC include end: CanHavePeripheryStreamingFIR chisel
|
||||
|
||||
Note that this is the point at which we decide the datatype for our FIR. You could create different configs that use different types for the FIR, for example a config that instantiates a complex-valued FIR filter.
|
||||
|
||||
Constructing the Top and Config
|
||||
-------------------------------
|
||||
|
||||
Once again following the path of the previous MMIO example, we now want to mix our traits into the system as a whole. The code is from ``generators/chipyard/src/main/scala/DigitalTop.scala``
|
||||
|
||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/DigitalTop.scala
|
||||
:language: scala
|
||||
:start-after: DOC include start: DigitalTop
|
||||
:end-before: DOC include end: DigitalTop
|
||||
|
||||
Finally, we create the configuration class in ``generators/chipyard/src/main/scala/config/RocketConfigs.scala`` that uses the ``WithFIR`` mixin defined in ``generators/chipyard/src/main/scala/example/dsptools/GenericFIR.scala``.
|
||||
|
||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/dsptools/GenericFIR.scala
|
||||
:language: scala
|
||||
:start-after: DOC include start: WithStreamingFIR
|
||||
:end-before: DOC include end: WithStreamingFIR
|
||||
|
||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/config/RocketConfigs.scala
|
||||
:language: scala
|
||||
:start-after: DOC include start: StreamingFIRRocketConfig
|
||||
:end-before: DOC include end: StreamingFIRRocketConfig
|
||||
|
||||
FIR Testing
|
||||
-----------
|
||||
|
||||
We can now test that the FIR is working. The test program is found in ``tests/streaming-fir.c``.
|
||||
|
||||
.. literalinclude:: ../../tests/streaming-fir.c
|
||||
:language: c
|
||||
|
||||
The test feed a series of values into the fir and compares the output to a golden model of computation. The base of the module's MMIO write region is at 0x2000 and the base of the read region is at 0x2100 by default.
|
||||
|
||||
Compiling this program with ``make`` produces a ``streaming-fir.riscv`` executable.
|
||||
|
||||
Now we can run our simulation.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
cd sims/verilator
|
||||
make CONFIG=StreamingFIRRocketConfig BINARY=../../tests/streaming-fir.riscv run-binary
|
||||
|
||||
.. [#] ``ReadQueue`` and ``WriteQueue`` are good illustrations of how to write a ``DspBlock`` and how they can be integrated into rocket, but in a real design a DMA engine would be preferred. ``ReadQueue`` will stall the processor if you try to read an empty queue, and ``WriteQueue`` will stall if you try to write to a full queue, which a DMA engine can more elegantly avoid. Furthermore, a DMA engine can do the work of moving data, freeing the processor to do other useful work (or sleep).
|
||||
@@ -31,8 +31,8 @@ Note that these configurations fully remove the L2 cache and mbus.
|
||||
|
||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/config/RocketConfigs.scala
|
||||
:language: scala
|
||||
:start-after: DOC include start: scratchpadrocket
|
||||
:end-before: DOC include end: scratchpadrocket
|
||||
:start-after: DOC include start: l1scratchpadrocket
|
||||
:end-before: DOC include end: l1scratchpadrocket
|
||||
|
||||
|
||||
This configuration fully removes the L2 cache and memory bus by setting the
|
||||
@@ -94,11 +94,20 @@ number of DRAM channels is restricted to powers of two.
|
||||
|
||||
new freechips.rocketchip.subsystem.WithNMemoryChannels(2)
|
||||
|
||||
|
||||
In VCS and Verilator simulation, the DRAM is simulated using the
|
||||
``SimAXIMem`` module, which simply attaches a single-cycle SRAM to each
|
||||
memory channel.
|
||||
|
||||
Instead of connecting to off-chip DRAM, you can instead connect a scratchpad
|
||||
and remove the off-chip link. This is done by adding a fragment like
|
||||
``testchipip.WithBackingScratchpad`` to your configuration and removing the
|
||||
memory port with ``freechips.rocketchip.subsystem.WithNoMemPort``.
|
||||
|
||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/config/RocketConfigs.scala
|
||||
:language: scala
|
||||
:start-after: DOC include start: mbusscratchpadrocket
|
||||
:end-before: DOC include end: mbusscratchpadrocket
|
||||
|
||||
If you want a more realistic memory simulation, you can use FireSim, which
|
||||
can simulate the timing of DDR3 controllers. More documentation on FireSim
|
||||
memory models is available in the `FireSim docs <https://docs.fires.im/en/latest/>`_.
|
||||
|
||||
@@ -11,7 +11,9 @@ These guides will walk you through customization of your system-on-chip:
|
||||
|
||||
- Adding custom MMIO widgets to the Chipyard memory system by Tilelink or AXI4, with custom Top-level IOs
|
||||
|
||||
- Standard practices for using keys, traits, and configs to parameterize your design
|
||||
- Adding custom Dsptools based blocks as MMIO widgets.
|
||||
|
||||
- Standard practices for using Keys, Traits, and Configs to parameterize your design
|
||||
|
||||
- Customizing the memory hierarchy
|
||||
|
||||
@@ -36,6 +38,7 @@ We recommend reading all these pages in order. Hit next to get started!
|
||||
RoCC-or-MMIO
|
||||
RoCC-Accelerators
|
||||
MMIO-Peripherals
|
||||
Dsptools-Blocks
|
||||
Keys-Traits-Configs
|
||||
DMA-Devices
|
||||
Incorporating-Verilog-Blocks
|
||||
|
||||
@@ -36,12 +36,18 @@ Major parameters of interest include:
|
||||
|
||||
* Scratchpad and accumulator memory parameters (``sp_banks``, ``sp_capacity``, ``acc_capacity``): Determine the properties of the Gemmini scratchpad memory: overall capacity of the scratchpad or accumulators (in KiB), and the number of banks the scratchpad is divided into.
|
||||
|
||||
* Type parameters (``inputType``, ``outputType``, ``accType``): Determine the data-types flowing through different parts of a Gemmini accelerator. For example, ``inputType`` may be an 8-bit fixed-point number, while ``accType``, which determines the type of partial accumulations in a matrix multiplication, may be a 32-bit integer. ``outputType`` only determines the type of the data passed between two processing elements (PEs); for example, an 8-bit multiplication may produce a 16-bit result which must be shared between PEs in a systolic array.
|
||||
* Type parameters (``inputType``, ``outputType``, ``accType``): Determine the data-types flowing through different parts of a Gemmini accelerator. For example, ``inputType`` may be an 8-bit fixed-point number, while ``accType``, which determines the type of partial accumulations in a matrix multiplication, may be a 32-bit integer. ``outputType`` only determines the type of the data passed between two processing elements (PEs); for example, an 8-bit multiplication may produce a 16-bit result which must be shared between PEs in a systolic array. If your datatype is a floating-point number, then you might also want to change the ``pe_latency`` parameter, which specifies how many shift registers to add inside the PEs. This might be necessary if your datatype cannot complete a multiply-accumulate operation within a single cycle.
|
||||
|
||||
* Access-execute queue parameters (``ld_queue_length``, ``st_queue_length``, ``ex_queue_length``, ``rob_entries``): To implement access-execute decoupling, a Gemmini accelerator has a load instruction queue, a store instruction queue, and an execute instruction queue. The relative sizes of these queue determine the level of access-execute decoupling. Gemmini also implements a reorder buffer (ROB) - the number of entries in the ROB determines possible dependency management limitations.
|
||||
|
||||
* DMA parameters (``dma_maxbytes``, ``dma_buswidth``, ``mem_pipeline``): Gemmini implements a DMA to move data from main memory to the Gemmini scratchpad, and from the Gemmini accumulators to main memory. The size of these DMA transactions is determined by the DMA parameters. These DMA parameters are tightly coupled with Rocket Chip SoC system parameters: in particular ``dma_buswidth`` is associated with the ``SystemBusKey`` ``beatBytes`` parameter, and ``dma_maxbytes`` is associated with ``cacheblockbytes`` Rocket Chip parameters.
|
||||
|
||||
There are also optional features, which can be either enabled or left out of Gemmini at elaboration-time. For example:
|
||||
|
||||
Scaling during "move-in" operations (``mvin_scale_args``, ``mvin_scale_acc_args``): When data is being moved in from DRAM or main memory into Gemmini's local scratchpad memory, it can optionally be multiplied by a scaling factor. These parameters specify what the datatype of the scaling factor is, and how the scaling is actually done. If these are set to ``None``, then this optional feature will be disabled at elaboration time. If both the scratchpad inputs are accumulator inputs are to be scaled in the same say, then the ``mvin_scale_shared`` parameter can be set to ``true`` so that the multipliers and functional units are shared.
|
||||
|
||||
|
||||
|
||||
Gemmini Software
|
||||
------------------
|
||||
|
||||
@@ -51,9 +57,11 @@ The ISA includes configuration instructions, data movement instructions (from ma
|
||||
Since Gemmini instructions are not exposed through the GNU binutils assembler, several C macros are provided in order to construct the instruction encodings to call these instructions.
|
||||
|
||||
The Gemmini generator includes a C matrix multiplication library which wraps the calls to the custom Gemmini instructions.
|
||||
The ``software`` directory of the generator includes the aforementioned library and macros, as well as bare-metal tests, and some FireMarshal workloads to run the tests in a Linux environment. In particular, the matrix multiplication C library can be found in the ``software/gemmini-rocc-tests/include/gemmini.h`` file.
|
||||
The ``software`` directory of the generator (within the generator repository in ``generators/gemmini/software``) includes the aforementioned library and macros, as well as bare-metal tests, and some FireMarshal workloads to run the tests in a Linux environment. In particular, the matrix multiplication C library can be found in the ``generators/gemmini/software/gemmini-rocc-tests/include/gemmini.h`` file.
|
||||
|
||||
The Gemmini generator generates a C header file based on the generator parameters. This header files gets compiled together with the matrix multiplication library to tune library performance. The generated header file can be found under ``software/gemmini-rocc-tests/include/gemmini_params.h``
|
||||
The Gemmini generator generates a C header file based on the generator parameters. This header files gets compiled together with the matrix multiplication library to tune library performance. The generated header file can be found under ``generators/gemmini/software/gemmini-rocc-tests/include/gemmini_params.h``
|
||||
|
||||
Gemmini can also be used to run ONNX-specified neural-networks through a port of Microsoft's ONNX-Runtime framework. The port is included as the `onnxruntime-riscv <https://github.com/pranav-prakash/onnxruntime-riscv>`__ repository submoduled in the `software` directory. The port is under development, and usage documentation can be found `within its repository <https://github.com/pranav-prakash/onnxruntime-riscv/blob/systolic/systolic_runner/docs>`__.
|
||||
|
||||
Build and Run Gemmini Tests
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
1
docs/_static/images/fir-block-diagram.svg
vendored
Normal file
1
docs/_static/images/fir-block-diagram.svg
vendored
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 32 KiB |
Submodule generators/boom updated: f0caca8d6b...f1a20b1b3e
@@ -23,6 +23,8 @@ class DigitalTop(implicit p: Parameters) extends System
|
||||
with icenet.CanHavePeripheryIceNIC // Enables optionally adding the IceNIC for FireSim
|
||||
with chipyard.example.CanHavePeripheryInitZero // Enables optionally adding the initzero example widget
|
||||
with chipyard.example.CanHavePeripheryGCD // Enables optionally adding the GCD example widget
|
||||
with chipyard.example.CanHavePeripheryStreamingFIR // Enables optionally adding the DSPTools FIR example widget
|
||||
with chipyard.example.CanHavePeripheryStreamingPassthrough // Enables optionally adding the DSPTools streaming-passthrough example widget
|
||||
with nvidia.blocks.dla.CanHavePeripheryNVDLA // Enables optionally having an NVDLA
|
||||
{
|
||||
override lazy val module = new DigitalTopModule(this)
|
||||
|
||||
@@ -9,6 +9,7 @@ import freechips.rocketchip.diplomacy.{LazyModule}
|
||||
import freechips.rocketchip.devices.debug._
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.system.{SimAXIMem}
|
||||
import freechips.rocketchip.amba.axi4.{AXI4Bundle, AXI4SlaveNode, AXI4EdgeParameters}
|
||||
import freechips.rocketchip.util._
|
||||
|
||||
import sifive.blocks.devices.gpio._
|
||||
@@ -182,6 +183,20 @@ object AddIOCells {
|
||||
port.suggestName("serial")
|
||||
(port, ios)
|
||||
}
|
||||
|
||||
def axi4(io: Seq[AXI4Bundle], node: AXI4SlaveNode): Seq[(AXI4Bundle, AXI4EdgeParameters, Seq[IOCell])] = {
|
||||
io.zip(node.in).map{ case (mem_axi4, (_, edge)) => {
|
||||
val (port, ios) = IOCell.generateIOFromSignal(mem_axi4, Some("iocell_mem_axi4"))
|
||||
port.suggestName("mem_axi4")
|
||||
(port, edge, ios)
|
||||
}}
|
||||
}
|
||||
|
||||
def blockDev(bdev: BlockDeviceIO): (BlockDeviceIO, Seq[IOCell]) = {
|
||||
val (port, ios) = IOCell.generateIOFromSignal(bdev, Some("iocell_bdev"))
|
||||
port.suggestName("bdev")
|
||||
(port, ios)
|
||||
}
|
||||
}
|
||||
|
||||
// DOC include start: WithGPIOTiedOff
|
||||
@@ -211,11 +226,25 @@ class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideIOBinder({
|
||||
})
|
||||
|
||||
class WithSimBlockDevice extends OverrideIOBinder({
|
||||
(system: CanHavePeripheryBlockDeviceModuleImp) => system.connectSimBlockDevice(system.clock, system.reset.asBool); Nil
|
||||
(system: CanHavePeripheryBlockDeviceModuleImp) => system.bdev.map { bdev =>
|
||||
val (port, ios) = AddIOCells.blockDev(bdev)
|
||||
val harnessFn = (th: chipyard.TestHarness) => {
|
||||
SimBlockDevice.connect(th.clock, th.reset.asBool, Some(port))(system.p)
|
||||
Nil
|
||||
}
|
||||
Seq((Seq(port), ios, Some(harnessFn)))
|
||||
}.getOrElse(Nil)
|
||||
})
|
||||
|
||||
class WithBlockDeviceModel extends OverrideIOBinder({
|
||||
(system: CanHavePeripheryBlockDeviceModuleImp) => system.connectBlockDeviceModel(); Nil
|
||||
(system: CanHavePeripheryBlockDeviceModuleImp) => system.bdev.map { bdev =>
|
||||
val (port, ios) = AddIOCells.blockDev(bdev)
|
||||
val harnessFn = (th: chipyard.TestHarness) => {
|
||||
BlockDeviceModel.connect(Some(port))(system.p)
|
||||
Nil
|
||||
}
|
||||
Seq((Seq(port), ios, Some(harnessFn)))
|
||||
}.getOrElse(Nil)
|
||||
})
|
||||
|
||||
class WithLoopbackNIC extends OverrideIOBinder({
|
||||
@@ -232,21 +261,38 @@ class WithSimNIC extends OverrideIOBinder({
|
||||
// accessible to the IOBinder
|
||||
// DOC include start: WithSimAXIMem
|
||||
class WithSimAXIMem extends OverrideIOBinder({
|
||||
(system: CanHaveMasterAXI4MemPort with BaseSubsystem) => SimAXIMem.connectMem(system)(system.p); Nil
|
||||
(system: CanHaveMasterAXI4MemPort with BaseSubsystem) => {
|
||||
val peiTuples = AddIOCells.axi4(system.mem_axi4, system.memAXI4Node)
|
||||
// TODO: we are inlining the connectMem method of SimAXIMem because
|
||||
// it takes in a dut rather than seq of axi4 ports
|
||||
val harnessFn = (th: chipyard.TestHarness) => {
|
||||
peiTuples.map { case (port, edge, ios) =>
|
||||
val mem = LazyModule(new SimAXIMem(edge, size = system.p(ExtMem).get.master.size)(system.p))
|
||||
Module(mem.module).suggestName("mem")
|
||||
mem.io_axi4.head <> port
|
||||
}
|
||||
Nil
|
||||
}
|
||||
Seq((peiTuples.map(_._1), peiTuples.flatMap(_._3), Some(harnessFn)))
|
||||
}
|
||||
})
|
||||
// DOC include end: WithSimAXIMem
|
||||
|
||||
class WithBlackBoxSimMem extends OverrideIOBinder({
|
||||
(system: CanHaveMasterAXI4MemPort with BaseSubsystem) => {
|
||||
(system.mem_axi4 zip system.memAXI4Node.in).foreach { case (io, (_, edge)) =>
|
||||
val memSize = system.p(ExtMem).get.master.size
|
||||
val lineSize = system.p(CacheBlockBytes)
|
||||
val mem = Module(new SimDRAM(memSize, lineSize, edge.bundle))
|
||||
mem.io.axi <> io
|
||||
mem.io.clock := system.module.clock
|
||||
mem.io.reset := system.module.reset
|
||||
val peiTuples = AddIOCells.axi4(system.mem_axi4, system.memAXI4Node)
|
||||
val harnessFn = (th: chipyard.TestHarness) => {
|
||||
peiTuples.map { case (port, edge, ios) =>
|
||||
val memSize = system.p(ExtMem).get.master.size
|
||||
val lineSize = system.p(CacheBlockBytes)
|
||||
val mem = Module(new SimDRAM(memSize, lineSize, edge.bundle))
|
||||
mem.io.axi <> port
|
||||
mem.io.clock := th.clock
|
||||
mem.io.reset := th.reset
|
||||
}
|
||||
Nil
|
||||
}
|
||||
Nil
|
||||
Seq((peiTuples.map(_._1), peiTuples.flatMap(_._3), Some(harnessFn)))
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import freechips.rocketchip.config.{Config}
|
||||
class RocketConfig extends Config(
|
||||
new chipyard.iobinders.WithUARTAdapter ++ // display UART with a SimUARTAdapter
|
||||
new chipyard.iobinders.WithTieOffInterrupts ++ // tie off top-level interrupts
|
||||
new chipyard.iobinders.WithBlackBoxSimMem ++ // drive the master AXI4 memory with a SimAXIMem
|
||||
new chipyard.iobinders.WithBlackBoxSimMem ++ // drive the master AXI4 memory with a blackbox DRAMSim model
|
||||
new chipyard.iobinders.WithTiedOffDebug ++ // tie off debug (since we are using SimSerial for testing)
|
||||
new chipyard.iobinders.WithSimSerial ++ // drive TSI with SimSerial for testing
|
||||
new testchipip.WithTSI ++ // use testchipip serial offchip link
|
||||
@@ -205,6 +205,24 @@ class SmallSPIFlashRocketConfig extends Config(
|
||||
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++
|
||||
new freechips.rocketchip.system.BaseConfig)
|
||||
|
||||
class SimAXIRocketConfig extends Config(
|
||||
new chipyard.iobinders.WithUARTAdapter ++
|
||||
new chipyard.iobinders.WithTieOffInterrupts ++
|
||||
new chipyard.iobinders.WithSimAXIMem ++ // drive the master AXI4 memory with a SimAXIMem, a 1-cycle magic memory
|
||||
new chipyard.iobinders.WithTiedOffDebug ++
|
||||
new chipyard.iobinders.WithSimSerial ++
|
||||
new testchipip.WithTSI ++
|
||||
new chipyard.config.WithBootROM ++
|
||||
new chipyard.config.WithUART ++
|
||||
new chipyard.config.WithL2TLBs(1024) ++
|
||||
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++
|
||||
new freechips.rocketchip.system.BaseConfig)
|
||||
|
||||
class SimBlockDeviceRocketConfig extends Config(
|
||||
new chipyard.iobinders.WithUARTAdapter ++
|
||||
new chipyard.iobinders.WithTieOffInterrupts ++
|
||||
@@ -384,14 +402,35 @@ class LoopbackNICRocketConfig extends Config(
|
||||
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++
|
||||
new freechips.rocketchip.system.BaseConfig)
|
||||
|
||||
// DOC include start: scratchpadrocket
|
||||
class ScratchpadRocketConfig extends Config(
|
||||
// DOC include start: l1scratchpadrocket
|
||||
class L1ScratchpadSmallRocketConfig extends Config(
|
||||
new chipyard.iobinders.WithUARTAdapter ++
|
||||
new chipyard.iobinders.WithTieOffInterrupts ++
|
||||
new chipyard.iobinders.WithTiedOffDebug ++
|
||||
new chipyard.iobinders.WithSimSerial ++
|
||||
new testchipip.WithTSI ++
|
||||
new testchipip.WithBackingScratchpad ++ // add backing scratchpad
|
||||
new chipyard.config.WithBootROM ++
|
||||
new chipyard.config.WithUART ++
|
||||
new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // remove offchip mem port
|
||||
new freechips.rocketchip.subsystem.WithNBanks(0) ++
|
||||
new freechips.rocketchip.subsystem.WithNoMemPort ++
|
||||
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||
new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 scratchpad
|
||||
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++
|
||||
new freechips.rocketchip.subsystem.WithNSmallCores(1) ++
|
||||
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++
|
||||
new freechips.rocketchip.system.BaseConfig)
|
||||
// DOC include end: l1scratchpadrocket
|
||||
|
||||
// DOC include start: mbusscratchpadrocket
|
||||
class MbusScratchpadRocketConfig extends Config(
|
||||
new chipyard.iobinders.WithUARTAdapter ++
|
||||
new chipyard.iobinders.WithTieOffInterrupts ++
|
||||
new chipyard.iobinders.WithTiedOffDebug ++
|
||||
new chipyard.iobinders.WithSimSerial ++
|
||||
new testchipip.WithTSI ++
|
||||
new testchipip.WithBackingScratchpad ++ // add mbus backing scratchpad
|
||||
new chipyard.config.WithBootROM ++
|
||||
new chipyard.config.WithUART ++
|
||||
new chipyard.config.WithL2TLBs(1024) ++
|
||||
@@ -403,7 +442,7 @@ class ScratchpadRocketConfig extends Config(
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++
|
||||
new freechips.rocketchip.system.BaseConfig)
|
||||
// DOC include end: scratchpadrocket
|
||||
// DOC include end: mbusscratchpadrocket
|
||||
|
||||
// DOC include start: RingSystemBusRocket
|
||||
class RingSystemBusRocketConfig extends Config(
|
||||
@@ -426,6 +465,46 @@ class RingSystemBusRocketConfig extends Config(
|
||||
new freechips.rocketchip.system.BaseConfig)
|
||||
// DOC include end: RingSystemBusRocket
|
||||
|
||||
class StreamingPassthroughRocketConfig extends Config(
|
||||
new chipyard.example.WithStreamingPassthrough ++ // use top with tilelink-controlled streaming passthrough
|
||||
new chipyard.iobinders.WithUARTAdapter ++
|
||||
new chipyard.iobinders.WithTieOffInterrupts ++
|
||||
new chipyard.iobinders.WithBlackBoxSimMem ++
|
||||
new chipyard.iobinders.WithTiedOffDebug ++
|
||||
new chipyard.iobinders.WithSimSerial ++
|
||||
new testchipip.WithTSI ++
|
||||
new chipyard.config.WithBootROM ++
|
||||
new chipyard.config.WithUART ++
|
||||
new chipyard.config.WithL2TLBs(1024) ++
|
||||
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++
|
||||
new freechips.rocketchip.system.BaseConfig)
|
||||
|
||||
// DOC include start: StreamingFIRRocketConfig
|
||||
class StreamingFIRRocketConfig extends Config (
|
||||
new chipyard.example.WithStreamingFIR ++ // use top with tilelink-controlled streaming FIR
|
||||
new chipyard.iobinders.WithUARTAdapter ++
|
||||
new chipyard.iobinders.WithTieOffInterrupts ++
|
||||
new chipyard.iobinders.WithBlackBoxSimMem ++
|
||||
new chipyard.iobinders.WithTiedOffDebug ++
|
||||
new chipyard.iobinders.WithSimSerial ++
|
||||
new testchipip.WithTSI ++
|
||||
new chipyard.config.WithBootROM ++
|
||||
new chipyard.config.WithUART ++
|
||||
new chipyard.config.WithL2TLBs(1024) ++
|
||||
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++
|
||||
new freechips.rocketchip.system.BaseConfig)
|
||||
// DOC include end: StreamingFIRRocketConfig
|
||||
|
||||
class SmallNVDLARocketConfig extends Config(
|
||||
new chipyard.iobinders.WithUARTAdapter ++
|
||||
new chipyard.iobinders.WithTieOffInterrupts ++
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
package chipyard.example
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import dspblocks._
|
||||
import dsptools.numbers._
|
||||
import freechips.rocketchip.amba.axi4stream._
|
||||
import freechips.rocketchip.config.Parameters
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.regmapper._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.subsystem._
|
||||
|
||||
/**
|
||||
* The memory interface writes entries into the queue.
|
||||
* They stream out the streaming interface
|
||||
* @param depth number of entries in the queue
|
||||
* @param streamParameters parameters for the stream node
|
||||
* @param p
|
||||
*/
|
||||
abstract class WriteQueue[D, U, E, O, B <: Data]
|
||||
(
|
||||
val depth: Int,
|
||||
val streamParameters: AXI4StreamMasterParameters = AXI4StreamMasterParameters()
|
||||
)(implicit p: Parameters) extends DspBlock[D, U, E, O, B] with HasCSR {
|
||||
// stream node, output only
|
||||
val streamNode = AXI4StreamMasterNode(streamParameters)
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
require(streamNode.out.length == 1)
|
||||
|
||||
// get the output bundle associated with the AXI4Stream node
|
||||
val out = streamNode.out.head._1
|
||||
// width (in bits) of the output interface
|
||||
val width = out.params.n * 8
|
||||
// instantiate a queue
|
||||
val queue = Module(new Queue(UInt(out.params.dataBits.W), depth))
|
||||
// connect queue output to streaming output
|
||||
out.valid := queue.io.deq.valid
|
||||
out.bits.data := queue.io.deq.bits
|
||||
// don't use last
|
||||
out.bits.last := false.B
|
||||
queue.io.deq.ready := out.ready
|
||||
|
||||
regmap(
|
||||
// each write adds an entry to the queue
|
||||
0x0 -> Seq(RegField.w(width, queue.io.enq)),
|
||||
// read the number of entries in the queue
|
||||
(width+7)/8 -> Seq(RegField.r(width, queue.io.count)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TLDspBlock specialization of WriteQueue
|
||||
* @param depth number of entries in the queue
|
||||
* @param csrAddress address range for peripheral
|
||||
* @param beatBytes beatBytes of TL interface
|
||||
* @param p
|
||||
*/
|
||||
class TLWriteQueue (depth: Int, csrAddress: AddressSet, beatBytes: Int)
|
||||
(implicit p: Parameters) extends WriteQueue[
|
||||
TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLEdgeIn, TLBundle
|
||||
](depth) with TLHasCSR {
|
||||
val devname = "tlQueueIn"
|
||||
val devcompat = Seq("ucb-art", "dsptools")
|
||||
val device = new SimpleDevice(devname, devcompat) {
|
||||
override def describe(resources: ResourceBindings): Description = {
|
||||
val Description(name, mapping) = super.describe(resources)
|
||||
Description(name, mapping)
|
||||
}
|
||||
}
|
||||
// make diplomatic TL node for regmap
|
||||
override val mem = Some(TLRegisterNode(address = Seq(csrAddress), device = device, beatBytes = beatBytes))
|
||||
}
|
||||
|
||||
object TLWriteQueue {
|
||||
def apply(
|
||||
depth: Int = 8,
|
||||
csrAddress: AddressSet = AddressSet(0x2000, 0xff),
|
||||
beatBytes: Int = 8,
|
||||
)(implicit p: Parameters) = {
|
||||
val writeQueue = LazyModule(new TLWriteQueue(depth = depth, csrAddress = csrAddress, beatBytes = beatBytes))
|
||||
writeQueue
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The streaming interface adds elements into the queue.
|
||||
* The memory interface can read elements out of the queue.
|
||||
* @param depth number of entries in the queue
|
||||
* @param streamParameters parameters for the stream node
|
||||
* @param p
|
||||
*/
|
||||
abstract class ReadQueue[D, U, E, O, B <: Data]
|
||||
(
|
||||
val depth: Int,
|
||||
val streamParameters: AXI4StreamSlaveParameters = AXI4StreamSlaveParameters()
|
||||
)(implicit p: Parameters) extends DspBlock[D, U, E, O, B] with HasCSR {
|
||||
val streamNode = AXI4StreamSlaveNode(streamParameters)
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
require(streamNode.in.length == 1)
|
||||
|
||||
// get the input associated with the stream node
|
||||
val in = streamNode.in.head._1
|
||||
// make a Decoupled[UInt] that RegReadFn can do something with
|
||||
val out = Wire(Decoupled(UInt()))
|
||||
// get width of streaming input interface
|
||||
val width = in.params.n * 8
|
||||
// instantiate a queue
|
||||
val queue = Module(new Queue(UInt(in.params.dataBits.W), depth))
|
||||
// connect input to the streaming interface
|
||||
queue.io.enq.valid := in.valid
|
||||
queue.io.enq.bits := in.bits.data
|
||||
in.ready := queue.io.enq.ready
|
||||
// connect output to wire
|
||||
out.valid := queue.io.deq.valid
|
||||
out.bits := queue.io.deq.bits
|
||||
queue.io.deq.ready := out.ready
|
||||
|
||||
regmap(
|
||||
// map the output of the queue
|
||||
0x0 -> Seq(RegField.r(width, RegReadFn(out))),
|
||||
// read the number of elements in the queue
|
||||
(width+7)/8 -> Seq(RegField.r(width, queue.io.count)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TLDspBlock specialization of ReadQueue
|
||||
* @param depth number of entries in the queue
|
||||
* @param csrAddress address range
|
||||
* @param beatBytes beatBytes of TL interface
|
||||
* @param p
|
||||
*/
|
||||
class TLReadQueue( depth: Int, csrAddress: AddressSet, beatBytes: Int)
|
||||
(implicit p: Parameters) extends ReadQueue[
|
||||
TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLEdgeIn, TLBundle
|
||||
](depth) with TLHasCSR {
|
||||
val devname = "tlQueueOut"
|
||||
val devcompat = Seq("ucb-art", "dsptools")
|
||||
val device = new SimpleDevice(devname, devcompat) {
|
||||
override def describe(resources: ResourceBindings): Description = {
|
||||
val Description(name, mapping) = super.describe(resources)
|
||||
Description(name, mapping)
|
||||
}
|
||||
}
|
||||
// make diplomatic TL node for regmap
|
||||
override val mem = Some(TLRegisterNode(address = Seq(csrAddress), device = device, beatBytes = beatBytes))
|
||||
}
|
||||
|
||||
object TLReadQueue {
|
||||
def apply(
|
||||
depth: Int = 8,
|
||||
csrAddress: AddressSet = AddressSet(0x2100, 0xff),
|
||||
beatBytes: Int = 8)(implicit p: Parameters) = {
|
||||
val readQueue = LazyModule(new TLReadQueue(depth = depth, csrAddress = csrAddress, beatBytes = beatBytes))
|
||||
readQueue
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
//// See LICENSE for license details.
|
||||
//
|
||||
package chipyard.example
|
||||
|
||||
import chisel3._
|
||||
import chisel3.experimental.FixedPoint
|
||||
import chisel3.util._
|
||||
import dspblocks._
|
||||
import dsptools.numbers._
|
||||
import freechips.rocketchip.amba.axi4stream._
|
||||
import freechips.rocketchip.config.{Parameters, Field, Config}
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.subsystem._
|
||||
|
||||
// FIR params
|
||||
case class GenericFIRParams(
|
||||
writeAddress: BigInt = 0x2000,
|
||||
readAddress: BigInt = 0x2100,
|
||||
depth: Int
|
||||
)
|
||||
|
||||
case object GenericFIRKey extends Field[Option[GenericFIRParams]](None)
|
||||
|
||||
class GenericFIRCellBundle[T<:Data:Ring](genIn:T, genOut:T) extends Bundle {
|
||||
val data: T = genIn.cloneType
|
||||
val carry: T = genOut.cloneType
|
||||
|
||||
override def cloneType: this.type = GenericFIRCellBundle(genIn, genOut).asInstanceOf[this.type]
|
||||
}
|
||||
object GenericFIRCellBundle {
|
||||
def apply[T<:Data:Ring](genIn:T, genOut:T): GenericFIRCellBundle[T] = new GenericFIRCellBundle(genIn, genOut)
|
||||
}
|
||||
|
||||
class GenericFIRCellIO[T<:Data:Ring](genIn:T, genOut:T) extends Bundle {
|
||||
val coeff = Input(genIn.cloneType)
|
||||
val in = Flipped(Decoupled(GenericFIRCellBundle(genIn, genOut)))
|
||||
val out = Decoupled(GenericFIRCellBundle(genIn, genOut))
|
||||
}
|
||||
object GenericFIRCellIO {
|
||||
def apply[T<:Data:Ring](genIn:T, genOut:T): GenericFIRCellIO[T] = new GenericFIRCellIO(genIn, genOut)
|
||||
}
|
||||
|
||||
class GenericFIRBundle[T<:Data:Ring](proto: T) extends Bundle {
|
||||
val data: T = proto.cloneType
|
||||
|
||||
override def cloneType: this.type = GenericFIRBundle(proto).asInstanceOf[this.type]
|
||||
}
|
||||
object GenericFIRBundle {
|
||||
def apply[T<:Data:Ring](proto: T): GenericFIRBundle[T] = new GenericFIRBundle(proto)
|
||||
}
|
||||
|
||||
class GenericFIRIO[T<:Data:Ring](genIn:T, genOut:T) extends Bundle {
|
||||
val in = Flipped(Decoupled(GenericFIRBundle(genIn)))
|
||||
val out = Decoupled(GenericFIRBundle(genOut))
|
||||
}
|
||||
object GenericFIRIO {
|
||||
def apply[T<:Data:Ring](genIn:T, genOut:T): GenericFIRIO[T] = new GenericFIRIO(genIn, genOut)
|
||||
}
|
||||
|
||||
// A generic FIR filter
|
||||
// DOC include start: GenericFIR chisel
|
||||
class GenericFIR[T<:Data:Ring](genIn:T, genOut:T, coeffs: Seq[T]) extends Module {
|
||||
val io = IO(GenericFIRIO(genIn, genOut))
|
||||
|
||||
// Construct a vector of genericFIRDirectCells
|
||||
val directCells = Seq.fill(coeffs.length){ Module(new GenericFIRDirectCell(genIn, genOut)).io }
|
||||
|
||||
// Construct the direct FIR chain
|
||||
for ((cell, coeff) <- directCells.zip(coeffs)) {
|
||||
cell.coeff := coeff
|
||||
}
|
||||
|
||||
// Connect input to first cell
|
||||
directCells.head.in.bits.data := io.in.bits.data
|
||||
directCells.head.in.bits.carry := Ring[T].zero
|
||||
directCells.head.in.valid := io.in.valid
|
||||
io.in.ready := directCells.head.in.ready
|
||||
|
||||
// Connect adjacent cells
|
||||
// Note that .tail() returns a collection that consists of all
|
||||
// elements in the inital collection minus the first one.
|
||||
// This means that we zip together directCells[0, n] and
|
||||
// directCells[1, n]. However, since zip ignores unmatched elements,
|
||||
// the resulting zip is (directCells[0], directCells[1]) ...
|
||||
// (directCells[n-1], directCells[n])
|
||||
for ((current, next) <- directCells.zip(directCells.tail)) {
|
||||
next.in.bits := current.out.bits
|
||||
next.in.valid := current.out.valid
|
||||
current.out.ready := next.in.ready
|
||||
}
|
||||
|
||||
// Connect output to last cell
|
||||
io.out.bits.data := directCells.last.out.bits.carry
|
||||
directCells.last.out.ready := io.out.ready
|
||||
io.out.valid := directCells.last.out.valid
|
||||
|
||||
}
|
||||
// DOC include end: GenericFIR chisel
|
||||
|
||||
// A generic FIR direct cell used to construct a larger direct FIR chain
|
||||
//
|
||||
// in ----- [z^-1]-- out
|
||||
// |
|
||||
// coeff ----[*]
|
||||
// |
|
||||
// carryIn --[+]-- carryOut
|
||||
//
|
||||
// DOC include start: GenericFIRDirectCell chisel
|
||||
class GenericFIRDirectCell[T<:Data:Ring](genIn: T, genOut: T) extends Module {
|
||||
val io = IO(GenericFIRCellIO(genIn, genOut))
|
||||
|
||||
// Registers to delay the input and the valid to propagate with calculations
|
||||
val hasNewData = RegInit(0.U)
|
||||
val inputReg = Reg(genIn.cloneType)
|
||||
|
||||
// Passthrough ready
|
||||
io.in.ready := io.out.ready
|
||||
|
||||
// When a new transaction is ready on the input, we will have new data to output
|
||||
// next cycle. Take this data in
|
||||
when (io.in.fire()) {
|
||||
hasNewData := 1.U
|
||||
inputReg := io.in.bits.data
|
||||
}
|
||||
|
||||
// We should output data when our cell has new data to output and is ready to
|
||||
// recieve new data. This insures that every cell in the chain passes its data
|
||||
// on at the same time
|
||||
io.out.valid := hasNewData & io.in.fire()
|
||||
io.out.bits.data := inputReg
|
||||
|
||||
// Compute carry
|
||||
// This uses the ring implementation for + and *, i.e.
|
||||
// (a * b) maps to (Ring[T].prod(a, b)) for whicever T you use
|
||||
io.out.bits.carry := inputReg * io.coeff + io.in.bits.carry
|
||||
}
|
||||
// DOC include end: GenericFIRDirectCell chisel
|
||||
|
||||
|
||||
// DOC include start: GenericFIRBlock chisel
|
||||
abstract class GenericFIRBlock[D, U, EO, EI, B<:Data, T<:Data:Ring]
|
||||
(
|
||||
genIn: T,
|
||||
genOut: T,
|
||||
coeffs: Seq[T]
|
||||
)(implicit p: Parameters) extends DspBlock[D, U, EO, EI, B] {
|
||||
val streamNode = AXI4StreamIdentityNode()
|
||||
val mem = None
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
require(streamNode.in.length == 1)
|
||||
require(streamNode.out.length == 1)
|
||||
|
||||
val in = streamNode.in.head._1
|
||||
val out = streamNode.out.head._1
|
||||
|
||||
// instantiate generic fir
|
||||
val fir = Module(new GenericFIR(genIn, genOut, coeffs))
|
||||
|
||||
// Attach ready and valid to outside interface
|
||||
in.ready := fir.io.in.ready
|
||||
fir.io.in.valid := in.valid
|
||||
|
||||
fir.io.out.ready := out.ready
|
||||
out.valid := fir.io.out.valid
|
||||
|
||||
// cast UInt to T
|
||||
fir.io.in.bits := in.bits.data.asTypeOf(GenericFIRBundle(genIn))
|
||||
|
||||
// cast T to UInt
|
||||
out.bits.data := fir.io.out.bits.asUInt
|
||||
}
|
||||
}
|
||||
// DOC include end: GenericFIRBlock chisel
|
||||
|
||||
// DOC include start: TLGenericFIRBlock chisel
|
||||
class TLGenericFIRBlock[T<:Data:Ring]
|
||||
(
|
||||
val genIn: T,
|
||||
val genOut: T,
|
||||
coeffs: Seq[T]
|
||||
)(implicit p: Parameters) extends
|
||||
GenericFIRBlock[TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLEdgeIn, TLBundle, T](
|
||||
genIn, genOut, coeffs
|
||||
) with TLDspBlock
|
||||
// DOC include end: TLGenericFIRBlock chisel
|
||||
|
||||
// DOC include start: TLGenericFIRChain chisel
|
||||
class TLGenericFIRChain[T<:Data:Ring] (genIn: T, genOut: T, coeffs: Seq[T], params: GenericFIRParams)(implicit p: Parameters)
|
||||
extends TLChain(Seq(
|
||||
TLWriteQueue(params.depth, AddressSet(params.writeAddress, 0xff))(_),
|
||||
{ implicit p: Parameters =>
|
||||
val fir = LazyModule(new TLGenericFIRBlock(genIn, genOut, coeffs))
|
||||
fir
|
||||
},
|
||||
TLReadQueue(params.depth, AddressSet(params.readAddress, 0xff))(_)
|
||||
))
|
||||
// DOC include end: TLGenericFIRChain chisel
|
||||
|
||||
// DOC include start: CanHavePeripheryStreamingFIR chisel
|
||||
trait CanHavePeripheryStreamingFIR extends BaseSubsystem {
|
||||
val streamingFIR = p(GenericFIRKey) match {
|
||||
case Some(params) => {
|
||||
val streamingFIR = LazyModule(new TLGenericFIRChain(
|
||||
genIn = FixedPoint(8.W, 3.BP),
|
||||
genOut = FixedPoint(8.W, 3.BP),
|
||||
coeffs = Seq(1.F(0.BP), 2.F(0.BP), 3.F(0.BP)),
|
||||
params = params))
|
||||
pbus.toVariableWidthSlave(Some("streamingFIR")) { streamingFIR.mem.get := TLFIFOFixer() }
|
||||
Some(streamingFIR)
|
||||
}
|
||||
case None => None
|
||||
}
|
||||
}
|
||||
// DOC include end: CanHavePeripheryStreamingFIR chisel
|
||||
|
||||
/**
|
||||
* Mixin to add FIR to rocket config
|
||||
*/
|
||||
// DOC include start: WithStreamingFIR
|
||||
class WithStreamingFIR extends Config((site, here, up) => {
|
||||
case GenericFIRKey => Some(GenericFIRParams(depth = 8))
|
||||
})
|
||||
// DOC include end: WithStreamingFIR
|
||||
@@ -0,0 +1,150 @@
|
||||
//// See LICENSE for license details.
|
||||
//
|
||||
package chipyard.example
|
||||
|
||||
import chisel3._
|
||||
import chisel3.{Bundle, Module}
|
||||
import chisel3.util._
|
||||
import dspblocks._
|
||||
import dsptools.numbers._
|
||||
import freechips.rocketchip.amba.axi4stream._
|
||||
import freechips.rocketchip.config.{Parameters, Field, Config}
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.subsystem._
|
||||
|
||||
// Simple passthrough to use as testbed sanity check
|
||||
// StreamingPassthrough params
|
||||
case class StreamingPassthroughParams(
|
||||
writeAddress: BigInt = 0x2000,
|
||||
readAddress: BigInt = 0x2100,
|
||||
depth: Int
|
||||
)
|
||||
|
||||
// StreamingPassthrough key
|
||||
case object StreamingPassthroughKey extends Field[Option[StreamingPassthroughParams]](None)
|
||||
|
||||
class StreamingPassthroughBundle[T<:Data:Ring](proto: T) extends Bundle {
|
||||
val data: T = proto.cloneType
|
||||
|
||||
override def cloneType: this.type = StreamingPassthroughBundle(proto).asInstanceOf[this.type]
|
||||
}
|
||||
object StreamingPassthroughBundle {
|
||||
def apply[T<:Data:Ring](proto: T): StreamingPassthroughBundle[T] = new StreamingPassthroughBundle(proto)
|
||||
}
|
||||
|
||||
class StreamingPassthroughIO[T<:Data:Ring](proto: T) extends Bundle {
|
||||
val in = Flipped(Decoupled(StreamingPassthroughBundle(proto)))
|
||||
val out = Decoupled(StreamingPassthroughBundle(proto))
|
||||
}
|
||||
object StreamingPassthroughIO {
|
||||
def apply[T<:Data:Ring](proto: T): StreamingPassthroughIO[T] = new StreamingPassthroughIO(proto)
|
||||
}
|
||||
|
||||
class StreamingPassthrough[T<:Data:Ring](proto: T) extends Module {
|
||||
val io = IO(StreamingPassthroughIO(proto))
|
||||
|
||||
io.in.ready := io.out.ready
|
||||
io.out.bits.data := io.in.bits.data
|
||||
io.out.valid := io.in.valid
|
||||
}
|
||||
|
||||
/**
|
||||
* Make DspBlock wrapper for StreamingPassthrough
|
||||
* @param cordicParams parameters for cordic
|
||||
* @param ev$1
|
||||
* @param ev$2
|
||||
* @param ev$3
|
||||
* @param p
|
||||
* @tparam D
|
||||
* @tparam U
|
||||
* @tparam EO
|
||||
* @tparam EI
|
||||
* @tparam B
|
||||
* @tparam T Type parameter for passthrough, i.e. FixedPoint or DspReal
|
||||
*/
|
||||
abstract class StreamingPassthroughBlock[D, U, EO, EI, B<:Data, T<:Data:Ring]
|
||||
(
|
||||
proto: T
|
||||
)(implicit p: Parameters) extends DspBlock[D, U, EO, EI, B] {
|
||||
val streamNode = AXI4StreamIdentityNode()
|
||||
val mem = None
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
require(streamNode.in.length == 1)
|
||||
require(streamNode.out.length == 1)
|
||||
|
||||
val in = streamNode.in.head._1
|
||||
val out = streamNode.out.head._1
|
||||
|
||||
// instantiate passthrough
|
||||
val passthrough = Module(new StreamingPassthrough(proto))
|
||||
|
||||
// Pass ready and valid from read queue to write queue
|
||||
in.ready := passthrough.io.in.ready
|
||||
passthrough.io.in.valid := in.valid
|
||||
|
||||
// cast UInt to T
|
||||
passthrough.io.in.bits := in.bits.data.asTypeOf(StreamingPassthroughBundle(proto))
|
||||
|
||||
passthrough.io.out.ready := out.ready
|
||||
out.valid := passthrough.io.out.valid
|
||||
|
||||
// cast T to UInt
|
||||
out.bits.data := passthrough.io.out.bits.asUInt
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TLDspBlock specialization of StreamingPassthrough
|
||||
* @param cordicParams parameters for passthrough
|
||||
* @param ev$1
|
||||
* @param ev$2
|
||||
* @param ev$3
|
||||
* @param p
|
||||
* @tparam T Type parameter for passthrough data type
|
||||
*/
|
||||
class TLStreamingPassthroughBlock[T<:Data:Ring]
|
||||
(
|
||||
val proto: T
|
||||
)(implicit p: Parameters) extends
|
||||
StreamingPassthroughBlock[TLClientPortParameters, TLManagerPortParameters, TLEdgeOut, TLEdgeIn, TLBundle, T](proto)
|
||||
with TLDspBlock
|
||||
|
||||
/**
|
||||
* A chain of queues acting as our MMIOs with the passthrough module in between them.
|
||||
* @param depth depth of queues
|
||||
* @param ev$1
|
||||
* @param ev$2
|
||||
* @param ev$3
|
||||
* @param p
|
||||
* @tparam T Type parameter for passthrough, i.e. FixedPoint or DspReal
|
||||
*/
|
||||
class TLStreamingPassthroughChain[T<:Data:Ring](params: StreamingPassthroughParams, proto: T)(implicit p: Parameters)
|
||||
extends TLChain(Seq(
|
||||
TLWriteQueue(params.depth, AddressSet(params.writeAddress, 0xff))(_),
|
||||
{ implicit p: Parameters => {
|
||||
val streamingPassthrough = LazyModule(new TLStreamingPassthroughBlock(proto))
|
||||
streamingPassthrough
|
||||
}},
|
||||
TLReadQueue(params.depth, AddressSet(params.readAddress, 0xff))(_)
|
||||
))
|
||||
|
||||
trait CanHavePeripheryStreamingPassthrough { this: BaseSubsystem =>
|
||||
val passthrough = p(StreamingPassthroughKey) match {
|
||||
case Some(params) => {
|
||||
val streamingPassthroughChain = LazyModule(new TLStreamingPassthroughChain(params, UInt(32.W)))
|
||||
pbus.toVariableWidthSlave(Some("streamingPassthrough")) { streamingPassthroughChain.mem.get := TLFIFOFixer() }
|
||||
Some(streamingPassthroughChain)
|
||||
}
|
||||
case None => None
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mixin to add passthrough to rocket config
|
||||
*/
|
||||
class WithStreamingPassthrough extends Config((site, here, up) => {
|
||||
case StreamingPassthroughKey => Some(StreamingPassthroughParams(depth = 8))
|
||||
})
|
||||
|
||||
@@ -11,7 +11,12 @@ private[stage] object UnderscoreDelimitedConfigsAnnotation extends HasShellOptio
|
||||
override val options = Seq(
|
||||
new ShellOption[String](
|
||||
longOption = "legacy-configs",
|
||||
toAnnotationSeq = a => Seq(new ConfigsAnnotation(a.split("_"))),
|
||||
toAnnotationSeq = a => {
|
||||
val split = a.split('.')
|
||||
val packageName = split.init.mkString(".")
|
||||
val configs = split.last.split("_")
|
||||
Seq(new ConfigsAnnotation(configs map { config => s"${packageName}.${config}" } ))
|
||||
},
|
||||
helpText = "A string of underscore-delimited configs (configs have decreasing precendence from left to right).",
|
||||
shortOption = Some("LC")
|
||||
)
|
||||
|
||||
@@ -16,6 +16,7 @@ import freechips.rocketchip.stage.RocketChipOptions
|
||||
import freechips.rocketchip.stage.phases.{RocketTestSuiteAnnotation}
|
||||
import freechips.rocketchip.system.{RocketTestSuite, TestGeneration}
|
||||
import freechips.rocketchip.util.HasRocketChipStageUtils
|
||||
import freechips.rocketchip.tile.XLen
|
||||
|
||||
import chipyard.{TestSuiteHelper, CoreManager}
|
||||
|
||||
@@ -30,9 +31,13 @@ class AddDefaultTests extends Phase with PreservesAll[Phase] with HasRocketChipS
|
||||
private def addTestSuiteAnnotations(implicit p: Parameters): Seq[Annotation] = {
|
||||
val annotations = mutable.ArrayBuffer[Annotation]()
|
||||
val suiteHelper = new TestSuiteHelper
|
||||
suiteHelper.addRocketTestSuites
|
||||
suiteHelper.addBoomTestSuites
|
||||
CoreManager.cores map (core => suiteHelper.addThirdPartyTestSuites(core.tileParamsLookup))
|
||||
// Use Xlen as a proxy for detecting if we are a processor-like target
|
||||
// The underlying test suites expect this field to be defined
|
||||
if (p.lift(XLen).nonEmpty) {
|
||||
suiteHelper.addRocketTestSuites
|
||||
suiteHelper.addBoomTestSuites
|
||||
CoreManager.cores map (core => suiteHelper.addThirdPartyTestSuites(core.tileParamsLookup))
|
||||
}
|
||||
|
||||
// if hwacha parameter exists then generate its tests
|
||||
// TODO: find a more elegant way to do this. either through
|
||||
|
||||
@@ -29,6 +29,7 @@ object NodeIdx {
|
||||
}
|
||||
|
||||
class FireSim(implicit val p: Parameters) extends RawModule {
|
||||
freechips.rocketchip.util.property.cover.setPropLib(new midas.passes.FireSimPropertyLibrary())
|
||||
val clockBridge = Module(new RationalClockBridge)
|
||||
val clock = clockBridge.io.clocks.head
|
||||
val reset = WireInit(false.B)
|
||||
|
||||
@@ -84,6 +84,7 @@ class FiresimMulticlockTopModule[+L <: DigitalTop](l: L) extends chipyard.Digita
|
||||
|
||||
// Harness Definition
|
||||
class FireSimMulticlockPOC(implicit val p: Parameters) extends RawModule {
|
||||
freechips.rocketchip.util.property.cover.setPropLib(new midas.passes.FireSimPropertyLibrary())
|
||||
val clockBridge = Module(new RationalClockBridge(p(FireSimClockKey).additionalClocks:_*))
|
||||
val refClock = clockBridge.io.clocks.head
|
||||
val reset = WireInit(false.B)
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
//See LICENSE for license details.
|
||||
|
||||
package firesim.firesim
|
||||
|
||||
import java.io.{File, FileWriter}
|
||||
|
||||
import chisel3.RawModule
|
||||
import chisel3.internal.firrtl.{Circuit, Port}
|
||||
|
||||
import freechips.rocketchip.diplomacy.{ValName, AutoBundle}
|
||||
import freechips.rocketchip.devices.debug.DebugIO
|
||||
import freechips.rocketchip.util.{ElaborationArtefacts}
|
||||
import freechips.rocketchip.system.DefaultTestSuites._
|
||||
import freechips.rocketchip.system.{TestGeneration, RegressionTestSuite}
|
||||
import freechips.rocketchip.config.Parameters
|
||||
import freechips.rocketchip.subsystem.RocketTilesKey
|
||||
import freechips.rocketchip.tile.XLen
|
||||
|
||||
import firesim.util.{GeneratorArgs, HasTargetAgnosticUtilites, HasFireSimGeneratorUtilities}
|
||||
|
||||
import scala.util.Try
|
||||
|
||||
import chipyard.TestSuiteHelper
|
||||
|
||||
trait HasTestSuites {
|
||||
def addTestSuites(targetName: String, params: Parameters) {
|
||||
val suiteHelper = new TestSuiteHelper
|
||||
suiteHelper.addRocketTestSuites(params)
|
||||
suiteHelper.addBoomTestSuites(params)
|
||||
suiteHelper.addArianeTestSuites(params)
|
||||
TestGeneration.addSuites(suiteHelper.suites.values.toSeq)
|
||||
TestGeneration.addSuite(FastBlockdevTests)
|
||||
TestGeneration.addSuite(SlowBlockdevTests)
|
||||
if (!targetName.contains("NoNIC"))
|
||||
TestGeneration.addSuite(NICLoopbackTests)
|
||||
|
||||
import hwacha.HwachaTestSuites._
|
||||
if (Try(params(hwacha.HwachaNLanes)).getOrElse(0) > 0) {
|
||||
TestGeneration.addSuites(rv64uv.map(_("p")))
|
||||
TestGeneration.addSuites(rv64uv.map(_("vp")))
|
||||
TestGeneration.addSuite(rv64sv("p"))
|
||||
TestGeneration.addSuite(hwachaBmarks)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mixed into an App or into a TestSuite
|
||||
trait IsFireSimGeneratorLike extends HasFireSimGeneratorUtilities with HasTestSuites {
|
||||
/** Output software test Makefrags, which provide targets for integration testing. */
|
||||
def generateTestSuiteMakefrags {
|
||||
addTestSuites(names.topModuleClass, targetParams)
|
||||
writeOutputFile(s"$longName.d", TestGeneration.generateMakeFrag) // Subsystem-specific test suites
|
||||
}
|
||||
|
||||
// Output miscellaneous files produced as a side-effect of elaboration
|
||||
def generateArtefacts {
|
||||
// generate RC's artefacts
|
||||
ElaborationArtefacts.files.foreach { case (extension, contents) =>
|
||||
writeOutputFile(s"${longName}.${extension}", contents ())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object FireSimGenerator extends App with IsFireSimGeneratorLike {
|
||||
override lazy val longName = names.topModuleProject + "." + names.topModuleClass + "." + names.configs
|
||||
lazy val generatorArgs = GeneratorArgs(args)
|
||||
lazy val genDir = new File(names.targetDir)
|
||||
// The only reason this is not generateFirrtl; generateAnno is that we need to use a different
|
||||
// JsonProtocol to properly write out the annotations. Fix once the generated are unified
|
||||
elaborate
|
||||
generateTestSuiteMakefrags
|
||||
generateArtefacts
|
||||
}
|
||||
@@ -6,44 +6,34 @@ import java.io.File
|
||||
import scala.concurrent.{Future, Await, ExecutionContext}
|
||||
import scala.sys.process.{stringSeqToProcess, ProcessLogger}
|
||||
import scala.io.Source
|
||||
import org.scalatest.Suites
|
||||
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.system.{RocketTestSuite, BenchmarkTestSuite}
|
||||
import freechips.rocketchip.system.TestGeneration._
|
||||
import freechips.rocketchip.system.DefaultTestSuites._
|
||||
|
||||
import firesim.util.GeneratorArgs
|
||||
|
||||
abstract class FireSimTestSuite(
|
||||
topModuleClass: String,
|
||||
targetConfigs: String,
|
||||
platformConfigs: String,
|
||||
N: Int = 8
|
||||
) extends firesim.TestSuiteCommon with IsFireSimGeneratorLike {
|
||||
) extends firesim.TestSuiteCommon {
|
||||
import scala.concurrent.duration._
|
||||
import ExecutionContext.Implicits.global
|
||||
|
||||
val longName = names.topModuleProject + "." + names.topModuleClass + "." + names.configs
|
||||
val topModuleProject = "firesim.firesim"
|
||||
|
||||
lazy val generatorArgs = GeneratorArgs(
|
||||
midasFlowKind = "midas",
|
||||
targetDir = "generated-src",
|
||||
topModuleProject = "firesim.firesim",
|
||||
topModuleClass = topModuleClass,
|
||||
targetConfigProject = "firesim.firesim",
|
||||
targetConfigs = targetConfigs ++ "_WithScalaTestFeatures",
|
||||
platformConfigProject = "firesim.firesim",
|
||||
platformConfigs = platformConfigs)
|
||||
|
||||
// From HasFireSimGeneratorUtilities
|
||||
// For the firesim utilities to use the same directory as the test suite
|
||||
override lazy val testDir = genDir
|
||||
val chipyardLongName = topModuleProject + "." + topModuleClass + "." + targetConfigs
|
||||
|
||||
// From TestSuiteCommon
|
||||
val targetTuple = generatorArgs.tupleName
|
||||
val commonMakeArgs = Seq(s"DESIGN=${generatorArgs.topModuleClass}",
|
||||
s"TARGET_CONFIG=${generatorArgs.targetConfigs}",
|
||||
s"PLATFORM_CONFIG=${generatorArgs.platformConfigs}")
|
||||
val targetTuple = s"$topModuleClass-$targetConfigs-$platformConfigs"
|
||||
val commonMakeArgs = Seq(s"DESIGN=${topModuleClass}",
|
||||
s"TARGET_CONFIG=${targetConfigs}",
|
||||
s"PLATFORM_CONFIG=${platformConfigs}")
|
||||
|
||||
override lazy val genDir = new File(firesimDir, s"generated-src/${chipyardLongName}")
|
||||
|
||||
|
||||
def invokeMlSimulator(backend: String, name: String, debug: Boolean, additionalArgs: Seq[String] = Nil) = {
|
||||
make((Seq(s"${outDir.getAbsolutePath}/${name}.%s".format(if (debug) "vpd" else "out"),
|
||||
@@ -61,12 +51,6 @@ abstract class FireSimTestSuite(
|
||||
}
|
||||
}
|
||||
|
||||
//def runReplay(backend: String, replayBackend: String, name: String) = {
|
||||
// val dir = (new File(outDir, backend)).getAbsolutePath
|
||||
// (Seq("make", s"replay-$replayBackend",
|
||||
// s"SAMPLE=${dir}/${name}.sample", s"output_dir=$dir") ++ makeArgs).!
|
||||
//}
|
||||
|
||||
def runSuite(backend: String, debug: Boolean = false)(suite: RocketTestSuite) {
|
||||
// compile emulators
|
||||
behavior of s"${suite.makeTargetName} running on $backend"
|
||||
@@ -83,20 +67,6 @@ abstract class FireSimTestSuite(
|
||||
results.flatten foreach { case (name, exitcode) =>
|
||||
it should s"pass $name" in { assert(exitcode == 0) }
|
||||
}
|
||||
//replayBackends foreach { replayBackend =>
|
||||
// if (platformParams(midas.EnableSnapshot) && isCmdAvailable("vcs")) {
|
||||
// assert((Seq("make", s"vcs-$replayBackend") ++ makeArgs).! == 0) // compile vcs
|
||||
// suite.names foreach { name =>
|
||||
// it should s"replay $name in $replayBackend" in {
|
||||
// assert(runReplay(backend, replayBackend, s"$name$postfix") == 0)
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// suite.names foreach { name =>
|
||||
// ignore should s"replay $name in $backend"
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
} else {
|
||||
ignore should s"pass $backend"
|
||||
}
|
||||
@@ -127,66 +97,24 @@ abstract class FireSimTestSuite(
|
||||
}
|
||||
|
||||
clean
|
||||
mkdirs
|
||||
elaborate
|
||||
generateTestSuiteMakefrags
|
||||
generateArtefacts
|
||||
runTest("verilator", "rv64ui-p-simple", false, Seq(s"""EXTRA_SIM_ARGS=+trace-humanreadable0"""))
|
||||
//diffTracelog("rv64ui-p-simple.out")
|
||||
runSuite("verilator")(benchmarks)
|
||||
runSuite("verilator")(FastBlockdevTests)
|
||||
}
|
||||
|
||||
class RocketF1Tests extends FireSimTestSuite("FireSim", "DDR3FRFCFSLLC4MB_FireSimQuadRocketConfig", "WithSynthAsserts_BaseF1Config")
|
||||
class BoomF1Tests extends FireSimTestSuite("FireSim", "DDR3FRFCFSLLC4MB_FireSimLargeBoomConfig", "BaseF1Config")
|
||||
class RocketNICF1Tests extends FireSimTestSuite("FireSim", "WithNIC_DDR3FRFCFSLLC4MB_FireSimRocketConfig", "BaseF1Config") {
|
||||
runSuite("verilator")(NICLoopbackTests)
|
||||
}
|
||||
//class ArianeF1Tests extends FireSimTestSuite("FireSim", "WithNIC_DDR3FRFCFSLLC4MB_FireSimArianeConfig", "BaseF1Config") {
|
||||
// runSuite("verilator")(NICLoopbackTests)
|
||||
//}
|
||||
// Disabled until RAM optimizations re-enabled in multiclock
|
||||
//class RamModelRocketF1Tests extends FireSimTestSuite("FireSim", "FireSimDualRocketConfig", "BaseF1Config_MCRams")
|
||||
//class RamModelBoomF1Tests extends FireSimTestSuite("FireSim", "FireSimBoomConfig", "BaseF1Config_MCRams")
|
||||
|
||||
class RocketNICF1Tests extends FireSimTestSuite("FireSim", "WithNIC_DDR3FRFCFSLLC4MB_FireSimRocketConfig", "BaseF1Config")
|
||||
// Multiclock tests
|
||||
class RocketMulticlockF1Tests extends FireSimTestSuite(
|
||||
"FireSimMulticlockPOC",
|
||||
"FireSimQuadRocketMulticlockConfig",
|
||||
"WithSynthAsserts_BaseF1Config")
|
||||
|
||||
// Jerry broke these -- damn it Jerry.
|
||||
//abstract class FireSimTraceGenTest(targetConfig: String, platformConfig: String)
|
||||
// extends firesim.TestSuiteCommon with IsFireSimGeneratorLike {
|
||||
// val longName = names.topModuleProject + "." + names.topModuleClass + "." + names.configs
|
||||
//
|
||||
// lazy val generatorArgs = GeneratorArgs(
|
||||
// midasFlowKind = "midas",
|
||||
// targetDir = "generated-src",
|
||||
// topModuleProject = "firesim.firesim",
|
||||
// topModuleClass = "FireSimTraceGen",
|
||||
// targetConfigProject = "firesim.firesim",
|
||||
// targetConfigs = targetConfig ++ "_WithScalaTestFeatures",
|
||||
// platformConfigProject = "firesim.firesim",
|
||||
// platformConfigs = platformConfig)
|
||||
//
|
||||
// // From HasFireSimGeneratorUtilities
|
||||
// // For the firesim utilities to use the same directory as the test suite
|
||||
// override lazy val testDir = genDir
|
||||
//
|
||||
// // From TestSuiteCommon
|
||||
// val targetTuple = generatorArgs.tupleName
|
||||
// val commonMakeArgs = Seq(s"DESIGN=${generatorArgs.topModuleClass}",
|
||||
// s"TARGET_CONFIG=${generatorArgs.targetConfigs}",
|
||||
// s"PLATFORM_CONFIG=${generatorArgs.platformConfigs}")
|
||||
//
|
||||
// it should "pass" in {
|
||||
// assert(make("fsim-tracegen") == 0)
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//class FireSimLLCTraceGenTest extends FireSimTraceGenTest(
|
||||
// "DDR3FRFCFSLLC4MB_FireSimTraceGenConfig", "BaseF1Config")
|
||||
//
|
||||
//class FireSimL2TraceGenTest extends FireSimTraceGenTest(
|
||||
// "DDR3FRFCFS_FireSimTraceGenL2Config", "BaseF1Config")
|
||||
class ArianeF1Tests extends FireSimTestSuite("FireSim", "WithNIC_DDR3FRFCFSLLC4MB_FireSimArianeConfig", "BaseF1Config")
|
||||
|
||||
// This test suite only mirrors what is run in CI. CI invokes each test individually, using a testOnly call.
|
||||
class CITests extends Suites(
|
||||
new RocketF1Tests,
|
||||
new BoomF1Tests,
|
||||
new RocketNICF1Tests,
|
||||
new RocketMulticlockF1Tests)
|
||||
|
||||
Submodule generators/gemmini updated: d6f36d37d1...caaf781ec9
@@ -126,27 +126,30 @@ int main(int argc, char** argv)
|
||||
int verilog_plusargs_legal = 1;
|
||||
|
||||
dramsim = 0;
|
||||
opterr = 1;
|
||||
|
||||
while (1) {
|
||||
static struct option long_options[] = {
|
||||
{"cycle-count", no_argument, 0, 'c' },
|
||||
{"help", no_argument, 0, 'h' },
|
||||
{"max-cycles", required_argument, 0, 'm' },
|
||||
{"seed", required_argument, 0, 's' },
|
||||
{"rbb-port", required_argument, 0, 'r' },
|
||||
{"verbose", no_argument, 0, 'V' },
|
||||
{"dramsim", no_argument, 0, 'D' },
|
||||
{"cycle-count", no_argument, 0, 'c' },
|
||||
{"help", no_argument, 0, 'h' },
|
||||
{"max-cycles", required_argument, 0, 'm' },
|
||||
{"seed", required_argument, 0, 's' },
|
||||
{"rbb-port", required_argument, 0, 'r' },
|
||||
{"verbose", no_argument, 0, 'V' },
|
||||
{"dramsim", no_argument, 0, 'D' },
|
||||
{"permissive", no_argument, 0, 'p' },
|
||||
{"permissive-off", no_argument, 0, 'o' },
|
||||
#if VM_TRACE
|
||||
{"vcd", required_argument, 0, 'v' },
|
||||
{"dump-start", required_argument, 0, 'x' },
|
||||
{"vcd", required_argument, 0, 'v' },
|
||||
{"dump-start", required_argument, 0, 'x' },
|
||||
#endif
|
||||
HTIF_LONG_OPTIONS
|
||||
};
|
||||
int option_index = 0;
|
||||
#if VM_TRACE
|
||||
int c = getopt_long(argc, argv, "-chm:s:r:v:Vx:D", long_options, &option_index);
|
||||
int c = getopt_long(argc, argv, "-chm:s:r:v:Vx:Dpo", long_options, &option_index);
|
||||
#else
|
||||
int c = getopt_long(argc, argv, "-chm:s:r:VD", long_options, &option_index);
|
||||
int c = getopt_long(argc, argv, "-chm:s:r:VDpo", long_options, &option_index);
|
||||
#endif
|
||||
if (c == -1) break;
|
||||
retry:
|
||||
@@ -160,6 +163,8 @@ int main(int argc, char** argv)
|
||||
case 'r': rbb_port = atoi(optarg); break;
|
||||
case 'V': verbose = true; break;
|
||||
case 'D': dramsim = 1; break;
|
||||
case 'p': opterr = 0; break;
|
||||
case 'o': opterr = 1; break;
|
||||
#if VM_TRACE
|
||||
case 'v': {
|
||||
vcdfile = strcmp(optarg, "-") == 0 ? stdout : fopen(optarg, "w");
|
||||
@@ -195,6 +200,10 @@ int main(int argc, char** argv)
|
||||
c = 'c';
|
||||
else if (arg == "+dramsim")
|
||||
c = 'D';
|
||||
else if (arg == "+permissive")
|
||||
c = 'p';
|
||||
else if (arg == "+permissive-off")
|
||||
c = 'o';
|
||||
// If we don't find a legacy '+' EMULATOR argument, it still could be
|
||||
// a VERILOG_PLUSARG and not an error.
|
||||
else if (verilog_plusargs_legal) {
|
||||
@@ -226,9 +235,13 @@ int main(int argc, char** argv)
|
||||
}
|
||||
htif_option++;
|
||||
}
|
||||
std::cerr << argv[0] << ": invalid plus-arg (Verilog or HTIF) \""
|
||||
<< arg << "\"\n";
|
||||
c = '?';
|
||||
if(opterr) {
|
||||
std::cerr << argv[0] << ": invalid plus-arg (Verilog or HTIF) \""
|
||||
<< arg << "\"\n";
|
||||
c = '?';
|
||||
} else {
|
||||
c = 'p';
|
||||
}
|
||||
}
|
||||
goto retry;
|
||||
}
|
||||
|
||||
@@ -131,12 +131,14 @@ SRCDIR="$(pwd)/toolchains" module_all libgloss --prefix="${RISCV}/riscv64-unknow
|
||||
SRCDIR="$(pwd)/toolchains" module_all qemu --prefix="${RISCV}" --target-list=riscv64-softmmu
|
||||
|
||||
# make Dromajo
|
||||
git submodule update --init $CHIPYARD_DIR/tools/dromajo/dromajo-src
|
||||
make -C $CHIPYARD_DIR/tools/dromajo/dromajo-src/src
|
||||
|
||||
cd "$RDIR"
|
||||
|
||||
# create specific env.sh
|
||||
{
|
||||
echo "# auto-generated by build-toolchains.sh"
|
||||
echo "export CHIPYARD_TOOLCHAIN_SOURCED=1"
|
||||
echo "export RISCV=$(printf '%q' "$RISCV")"
|
||||
echo "export PATH=\${RISCV}/bin:\${PATH}"
|
||||
@@ -144,5 +146,6 @@ cd "$RDIR"
|
||||
} > env-$TOOLCHAIN.sh
|
||||
|
||||
# create general env.sh
|
||||
echo "# line auto-generated by build-toolchains.sh" >> env.sh
|
||||
echo "source \$( realpath \$(dirname "\${BASH_SOURCE[0]:-\${\(%\):-%x}}") )/env-$TOOLCHAIN.sh" >> env.sh
|
||||
echo "Toolchain Build Complete!"
|
||||
|
||||
@@ -29,6 +29,7 @@ git config submodule.toolchains/qemu.update none
|
||||
|
||||
# Don't automatically initialize generators with big submodules (e.g. linux source)
|
||||
git config submodule.generators/sha3.update none
|
||||
git config submodule.generators/gemmini.update none
|
||||
|
||||
# Disable updates to the FireSim submodule until explicitly requested
|
||||
git config submodule.sims/firesim.update none
|
||||
@@ -51,19 +52,19 @@ git config --unset submodule.vlsi/hammer-synopsys-plugins.update
|
||||
git config --unset submodule.vlsi/hammer-mentor-plugins.update
|
||||
|
||||
git config --unset submodule.generators/sha3.update
|
||||
git config --unset submodule.generators/gemmini.update
|
||||
git config --unset submodule.software/firemarshal.update
|
||||
|
||||
# Non-recursive clone to exclude riscv-linux
|
||||
git submodule update --init generators/sha3
|
||||
|
||||
# Non-recursive clone to exclude gemmini-software
|
||||
git submodule update --init generators/gemmini
|
||||
git -C generators/gemmini/ submodule update --init --recursive software/gemmini-rocc-tests
|
||||
|
||||
git config --unset submodule.sims/firesim.update
|
||||
# Minimal non-recursive clone to initialize sbt dependencies
|
||||
git submodule update --init sims/firesim
|
||||
(
|
||||
cd sims/firesim
|
||||
# Initialize dependencies for MIDAS-level RTL simulation
|
||||
git submodule update --init sim/midas
|
||||
)
|
||||
git config submodule.sims/firesim.update none
|
||||
|
||||
# Only shallow clone needed for basic SW tests
|
||||
@@ -73,4 +74,5 @@ git submodule update --init software/firemarshal
|
||||
if [ ! -f $RDIR/software/firemarshal/marshal-config.yaml ]; then
|
||||
echo "firesim-dir: '../../sims/firesim/'" > $RDIR/software/firemarshal/marshal-config.yaml
|
||||
fi
|
||||
echo "# line auto-generated by init-submodules-no-riscv-tools.sh" >> $RDIR/env.sh
|
||||
echo "PATH=\$( realpath \$(dirname "\${BASH_SOURCE[0]:-\${\(%\):-%x}}") )/software/firemarshal:\$PATH" >> $RDIR/env.sh
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
diff --git a/build.sbt b/build.sbt
|
||||
index 0c4581f..ff0597c 100644
|
||||
index 5d642c1..56f6fda 100644
|
||||
--- a/build.sbt
|
||||
+++ b/build.sbt
|
||||
@@ -128,7 +128,7 @@ lazy val iocell = (project in file("./tools/barstools/iocell/"))
|
||||
@@ -130,7 +130,7 @@ lazy val iocell = (project in file("./tools/barstools/iocell/"))
|
||||
|
||||
lazy val chipyard = conditionalDependsOn(project in file("generators/chipyard"))
|
||||
.dependsOn(boom, hwacha, sifive_blocks, sifive_cache, utilities, iocell,
|
||||
- sha3, // On separate line to allow for cleaner tutorial-setup patches
|
||||
+// sha3, // On separate line to allow for cleaner tutorial-setup patches
|
||||
dsptools, `rocket-dsptools`,
|
||||
gemmini, icenet, tracegen, ariane, nvdla)
|
||||
.settings(commonSettings)
|
||||
|
||||
@@ -155,9 +155,9 @@ lazy val ariane = (project in file("generators/ariane"))
|
||||
@@ -158,9 +158,9 @@ lazy val ariane = (project in file("generators/ariane"))
|
||||
.dependsOn(rocketchip)
|
||||
.settings(commonSettings)
|
||||
|
||||
|
||||
Submodule sims/firesim updated: 724a66b0f4...3143253dda
@@ -25,10 +25,7 @@ sim_prefix = simv
|
||||
sim = $(sim_dir)/$(sim_prefix)-$(MODEL_PACKAGE)-$(CONFIG)
|
||||
sim_debug = $(sim_dir)/$(sim_prefix)-$(MODEL_PACKAGE)-$(CONFIG)-debug
|
||||
|
||||
PERMISSIVE_ON=+permissive
|
||||
PERMISSIVE_OFF=+permissive-off
|
||||
|
||||
WAVEFORM_FLAG=+vcdplusfile=$(sim_out_name).vpd
|
||||
include $(base_dir)/vcs.mk
|
||||
|
||||
.PHONY: default debug
|
||||
default: $(sim)
|
||||
@@ -44,42 +41,7 @@ include $(base_dir)/common.mk
|
||||
#########################################################################################
|
||||
VCS = vcs -full64
|
||||
|
||||
VCS_CC_OPTS = \
|
||||
-CC "-I$(VCS_HOME)/include" \
|
||||
-CC "-I$(RISCV)/include" \
|
||||
-CC "-I$(dramsim_dir)" \
|
||||
-CC "-std=c++11" \
|
||||
$(dramsim_lib) \
|
||||
$(RISCV)/lib/libfesvr.a \
|
||||
-CC "$(EXTRA_SIM_CC_FLAGS)"
|
||||
|
||||
VCS_NONCC_OPTS = \
|
||||
+lint=all,noVCDE,noONGS,noUI \
|
||||
-timescale=1ns/1ps \
|
||||
-quiet \
|
||||
-q \
|
||||
+rad \
|
||||
+vcs+lic+wait \
|
||||
+vc+list \
|
||||
-error=noZMMCM \
|
||||
-error=PCWM-L \
|
||||
-sverilog +systemverilogext+.sv+.svi+.svh+.svt -assert svaext +libext+.sv \
|
||||
+v2k +verilog2001ext+.v95+.vt+.vp +libext+.v \
|
||||
+incdir+$(build_dir) \
|
||||
-f $(sim_common_files) \
|
||||
$(sim_vsrcs)
|
||||
|
||||
VCS_DEFINES = \
|
||||
+define+VCS \
|
||||
+define+CLOCK_PERIOD=1.0 \
|
||||
+define+PRINTF_COND=$(TB).printf_cond \
|
||||
+define+STOP_COND=!$(TB).reset \
|
||||
+define+RANDOMIZE_MEM_INIT \
|
||||
+define+RANDOMIZE_REG_INIT \
|
||||
+define+RANDOMIZE_GARBAGE_ASSIGN \
|
||||
+define+RANDOMIZE_INVALID_ASSIGN
|
||||
|
||||
VCS_OPTS = -notice -line $(VCS_CC_OPTS) $(VCS_NONCC_OPTS) $(VCS_DEFINES) $(EXTRA_SIM_SOURCES)
|
||||
VCS_OPTS = -notice -line $(VCS_CC_OPTS) $(VCS_NONCC_OPTS) $(VCS_DEFINE_OPTS) $(EXTRA_SIM_SOURCES)
|
||||
|
||||
#########################################################################################
|
||||
# vcs simulator rules
|
||||
|
||||
@@ -28,9 +28,6 @@ sim_prefix = simulator
|
||||
sim = $(sim_dir)/$(sim_prefix)-$(MODEL_PACKAGE)-$(CONFIG)
|
||||
sim_debug = $(sim_dir)/$(sim_prefix)-$(MODEL_PACKAGE)-$(CONFIG)-debug
|
||||
|
||||
PERMISSIVE_ON=
|
||||
PERMISSIVE_OFF=
|
||||
|
||||
WAVEFORM_FLAG=-v$(sim_out_name).vcd
|
||||
|
||||
.PHONY: default debug
|
||||
|
||||
Submodule software/firemarshal updated: a40f0252c4...141a3d366f
Submodule software/nvdla-workload updated: 02faf59692...88b09e0171
Submodule software/spec2017 updated: a4333f243c...8f2812bebc
@@ -5,7 +5,8 @@ LDFLAGS= -static
|
||||
|
||||
include libgloss.mk
|
||||
|
||||
PROGRAMS = pwm blkdev accum charcount nic-loopback big-blkdev pingd nvdla spiflashread spiflashwrite
|
||||
PROGRAMS = pwm blkdev accum charcount nic-loopback big-blkdev pingd \
|
||||
streaming-passthrough streaming-fir nvdla spiflashread spiflashwrite
|
||||
|
||||
spiflash.img: spiflash.py
|
||||
python3 $<
|
||||
|
||||
65
tests/streaming-fir.c
Normal file
65
tests/streaming-fir.c
Normal file
@@ -0,0 +1,65 @@
|
||||
#define PASSTHROUGH_WRITE 0x2000
|
||||
#define PASSTHROUGH_WRITE_COUNT 0x2008
|
||||
#define PASSTHROUGH_READ 0x2100
|
||||
#define PASSTHROUGH_READ_COUNT 0x2108
|
||||
|
||||
#define BP 3
|
||||
#define BP_SCALE ((double)(1 << BP))
|
||||
|
||||
#include "mmio.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
uint64_t roundi(double x)
|
||||
{
|
||||
if (x < 0.0) {
|
||||
return (uint64_t)(x - 0.5);
|
||||
} else {
|
||||
return (uint64_t)(x + 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
double test_vector[15] = {1.0, 2.0, 3.0, 4.0, 5.0, 4.0, 3.0, 2.0, 1.0, 0.5, 0.25, 0.125, 0.125};
|
||||
uint32_t num_tests = sizeof(test_vector) / sizeof(double);
|
||||
printf("Starting writing %d inputs\n", num_tests);
|
||||
|
||||
for (int i = 0; i < num_tests; i++) {
|
||||
reg_write64(PASSTHROUGH_WRITE, roundi(test_vector[i] * BP_SCALE));
|
||||
}
|
||||
|
||||
printf("Done writing\n");
|
||||
uint32_t rcnt = reg_read32(PASSTHROUGH_READ_COUNT);
|
||||
printf("Write count: %d\n", reg_read32(PASSTHROUGH_WRITE_COUNT));
|
||||
printf("Read count: %d\n", rcnt);
|
||||
|
||||
int failed = 0;
|
||||
if (rcnt != 0) {
|
||||
for (int i = 0; i < num_tests - 3; i++) {
|
||||
uint32_t res = reg_read32(PASSTHROUGH_READ);
|
||||
// double res = ((double)reg_read32(PASSTHROUGH_READ)) / BP_SCALE;
|
||||
double expected_double = 3*test_vector[i] + 2*test_vector[i+1] + test_vector[i+2];
|
||||
uint32_t expected = ((uint32_t)(expected_double * BP_SCALE + 0.5)) & 0xFF;
|
||||
if (res == expected) {
|
||||
printf("\n\nPass: Got %u Expected %u\n\n", res, expected);
|
||||
} else {
|
||||
failed = 1;
|
||||
printf("\n\nFail: Got %u Expected %u\n\n", res, expected);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
failed = 1;
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
printf("\n\nSome tests failed\n\n");
|
||||
} else {
|
||||
printf("\n\nAll tests passed\n\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
49
tests/streaming-passthrough.c
Normal file
49
tests/streaming-passthrough.c
Normal file
@@ -0,0 +1,49 @@
|
||||
#define PASSTHROUGH_WRITE 0x2000
|
||||
#define PASSTHROUGH_WRITE_COUNT 0x2008
|
||||
#define PASSTHROUGH_READ 0x2100
|
||||
#define PASSTHROUGH_READ_COUNT 0x2108
|
||||
|
||||
#include "mmio.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("Starting writing\n");
|
||||
uint32_t test_vector[7] = {3, 2, 1, 0, -1, -2, -3} ;
|
||||
for (int i = 0; i < 7; i++) {
|
||||
reg_write64(PASSTHROUGH_WRITE, test_vector[i]);
|
||||
}
|
||||
|
||||
printf("Done writing\n");
|
||||
uint32_t rcnt = reg_read32(PASSTHROUGH_READ_COUNT);
|
||||
printf("Write count: %d\n", reg_read32(PASSTHROUGH_WRITE_COUNT));
|
||||
printf("Read count: %d\n", rcnt);
|
||||
|
||||
int failed = 0;
|
||||
if (rcnt != 0) {
|
||||
for (int i = 0; i < 7; i++) {
|
||||
uint32_t res = reg_read32(PASSTHROUGH_READ);
|
||||
uint32_t expected = test_vector[i];
|
||||
if (res == expected) {
|
||||
printf("\n\nPass: Got %d Expected %d\n\n", res, test_vector[i]);
|
||||
} else {
|
||||
failed = 1;
|
||||
printf("\n\nFail: Got %d Expected %d\n\n", res, test_vector[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
failed = 1;
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
printf("\n\nSome tests failed\n\n");
|
||||
} else {
|
||||
printf("\n\nAll tests passed\n\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Submodule toolchains/esp-tools/riscv-isa-sim updated: 3c930b4031...13384cac1e
Submodule tools/chisel-testers updated: f410c59316...1aa906fe16
Submodule tools/dsptools updated: 15145ab623...211166e635
@@ -136,6 +136,8 @@ output_dir=$(sim_dir)/output/$(long_name)
|
||||
#########################################################################################
|
||||
# helper variables to run binaries
|
||||
#########################################################################################
|
||||
PERMISSIVE_ON=+permissive
|
||||
PERMISSIVE_OFF=+permissive-off
|
||||
BINARY ?=
|
||||
override SIM_FLAGS += +dramsim +max-cycles=$(timeout_cycles)
|
||||
VERBOSE_FLAGS ?= +verbose
|
||||
|
||||
42
vcs.mk
Normal file
42
vcs.mk
Normal file
@@ -0,0 +1,42 @@
|
||||
WAVEFORM_FLAG=+vcdplusfile=$(sim_out_name).vpd
|
||||
|
||||
CLOCK_PERIOD ?= 1.0
|
||||
RESET_DELAY ?= 777.7
|
||||
|
||||
VCS_CC_OPTS = \
|
||||
-CC "-I$(RISCV)/include" \
|
||||
-CC "-I$(dramsim_dir)" \
|
||||
-CC "-std=c++11" \
|
||||
-CC "$(EXTRA_SIM_CC_FLAGS)"
|
||||
|
||||
VCS_NONCC_OPTS = \
|
||||
$(dramsim_lib) \
|
||||
$(RISCV)/lib/libfesvr.a \
|
||||
+lint=all,noVCDE,noONGS,noUI \
|
||||
-error=PCWM-L \
|
||||
-error=noZMMCM \
|
||||
-timescale=1ns/10ps \
|
||||
-quiet \
|
||||
-q \
|
||||
+rad \
|
||||
+v2k \
|
||||
+vcs+lic+wait \
|
||||
+vc+list \
|
||||
-f $(sim_common_files) \
|
||||
-sverilog +systemverilogext+.sv+.svi+.svh+.svt -assert svaext +libext+.sv \
|
||||
+v2k +verilog2001ext+.v95+.vt+.vp +libext+.v \
|
||||
-debug_pp \
|
||||
+incdir+$(build_dir) \
|
||||
$(sim_vsrcs) \
|
||||
+libext+.v
|
||||
|
||||
VCS_DEFINE_OPTS = \
|
||||
+define+VCS \
|
||||
+define+CLOCK_PERIOD=$(CLOCK_PERIOD) \
|
||||
+define+RESET_DELAY=$(RESET_DELAY) \
|
||||
+define+PRINTF_COND=$(TB).printf_cond \
|
||||
+define+STOP_COND=!$(TB).reset \
|
||||
+define+RANDOMIZE_MEM_INIT \
|
||||
+define+RANDOMIZE_REG_INIT \
|
||||
+define+RANDOMIZE_GARBAGE_ASSIGN \
|
||||
+define+RANDOMIZE_INVALID_ASSIGN
|
||||
@@ -67,8 +67,8 @@ include $(base_dir)/common.mk
|
||||
#########################################################################################
|
||||
# srams
|
||||
#########################################################################################
|
||||
SRAM_GENERATOR_CONF = $(build_dir)/sram_generator-input.yml
|
||||
SRAM_CONF=$(build_dir)/sram_generator-output.json
|
||||
SRAM_GENERATOR_CONF = $(OBJ_DIR)/sram_generator-input.yml
|
||||
SRAM_CONF=$(OBJ_DIR)/sram_generator-output.json
|
||||
|
||||
## SRAM Generator
|
||||
.PHONY: sram_generator srams
|
||||
@@ -87,6 +87,88 @@ $(SRAM_CONF): $(SRAM_GENERATOR_CONF)
|
||||
cd $(vlsi_dir) && $(HAMMER_EXEC) -e $(ENV_YML) $(foreach x,$(INPUT_CONFS) $(SRAM_GENERATOR_CONF), -p $(x)) --obj_dir $(build_dir) sram_generator
|
||||
cd $(vlsi_dir) && cp output.json $@
|
||||
|
||||
#########################################################################################
|
||||
# simulation input configuration
|
||||
#########################################################################################
|
||||
include $(base_dir)/vcs.mk
|
||||
SIM_CONF = $(OBJ_DIR)/sim-inputs.yml
|
||||
SIM_DEBUG_CONF = $(OBJ_DIR)/sim-debug-inputs.yml
|
||||
SIM_TIMING_CONF = $(OBJ_DIR)/sim-timing-inputs.yml
|
||||
|
||||
include $(vlsi_dir)/sim.mk
|
||||
$(SIM_CONF): $(VLSI_RTL) $(HARNESS_FILE) $(HARNESS_SMEMS_FILE) $(sim_common_files)
|
||||
mkdir -p $(dir $@)
|
||||
echo "sim.inputs:" > $@
|
||||
echo " top_module: $(VLSI_TOP)" >> $@
|
||||
echo " input_files:" >> $@
|
||||
for x in $(HARNESS_FILE) $(HARNESS_SMEMS_FILE); do \
|
||||
echo ' - "'$$x'"' >> $@; \
|
||||
done
|
||||
echo " input_files_meta: 'append'" >> $@
|
||||
echo " timescale: '1ns/10ps'" >> $@
|
||||
echo " options:" >> $@
|
||||
for x in $(VCS_NONCC_OPTS); do \
|
||||
echo ' - "'$$x'"' >> $@; \
|
||||
done
|
||||
echo " options_meta: 'append'" >> $@
|
||||
echo " defines:" >> $@
|
||||
for x in $(subst +define+,,$(VCS_DEFINE_OPTS)); do \
|
||||
echo ' - "'$$x'"' >> $@; \
|
||||
done
|
||||
echo " defines_meta: 'append'" >> $@
|
||||
echo " compiler_opts:" >> $@
|
||||
for x in $(filter-out -CC,$(VCS_CC_OPTS)); do \
|
||||
echo ' - "'$$x'"' >> $@; \
|
||||
done
|
||||
echo " compiler_opts_meta: 'append'" >> $@
|
||||
echo " execution_flags_prepend: ['$(PERMISSIVE_ON)']" >> $@
|
||||
echo " execution_flags_append: ['$(PERMISSIVE_OFF)']" >> $@
|
||||
echo " execution_flags:" >> $@
|
||||
for x in $(SIM_FLAGS); do \
|
||||
echo ' - "'$$x'"' >> $@; \
|
||||
done
|
||||
echo " execution_flags_meta: 'append'" >> $@
|
||||
echo " benchmarks: ['$(BINARY)']" >> $@
|
||||
echo " tb_dut: 'testHarness.top'" >> $@
|
||||
|
||||
$(SIM_DEBUG_CONF): $(VLSI_RTL) $(HARNESS_FILE) $(HARNESS_SMEMS_FILE) $(sim_common_files)
|
||||
mkdir -p $(dir $@)
|
||||
echo "sim.inputs:" > $@
|
||||
echo " defines: ['DEBUG']" >> $@
|
||||
echo " defines_meta: 'append'" >> $@
|
||||
echo " execution_flags:" >> $@
|
||||
for x in $(VERBOSE_FLAGS) $(WAVEFORM_FLAG); do \
|
||||
echo ' - "'$$x'"' >> $@; \
|
||||
done
|
||||
echo " execution_flags_meta: 'append'" >> $@
|
||||
echo "sim.outputs.waveforms: ['$(sim_out_name).vpd']" >> $@
|
||||
|
||||
$(SIM_TIMING_CONF): $(VLSI_RTL) $(HARNESS_FILE) $(HARNESS_SMEMS_FILE) $(sim_common_files)
|
||||
mkdir -p $(dir $@)
|
||||
echo "sim.inputs:" > $@
|
||||
echo " defines: ['NTC']" >> $@
|
||||
echo " defines_meta: 'append'" >> $@
|
||||
echo " timing_annotated: 'true'" >> $@
|
||||
|
||||
POWER_CONF = $(OBJ_DIR)/power-inputs.yml
|
||||
include $(vlsi_dir)/power.mk
|
||||
LOWER_VLSI_TOP = $(shell echo $(VLSI_TOP) | tr A-Z a-z)
|
||||
$(POWER_CONF): $(VLSI_RTL) $(HARNESS_FILE) $(HARNESS_SMEMS_FILE) $(sim_common_files)
|
||||
mkdir -p $(dir $@)
|
||||
echo "power.inputs:" > $@
|
||||
echo " tb_dut: 'testHarness/$(LOWER_VLSI_TOP)'" >> $@
|
||||
echo " database: '$(OBJ_DIR)/par-rundir/$(VLSI_TOP)_FINAL'" >> $@
|
||||
echo " saifs: [" >> $@
|
||||
echo " '$(OBJ_DIR)/sim-par-rundir/$(notdir $(BINARY))/ucli.saif'" >> $@
|
||||
echo " ]" >> $@
|
||||
echo " waveforms: [" >> $@
|
||||
#echo " '$(OBJ_DIR)/sim-par-rundir/$(notdir $(BINARY))/$(sim_out_name).vcd'" >> $@
|
||||
echo " ]" >> $@
|
||||
echo " start_times: ['0ns']" >> $@
|
||||
echo " end_times: [" >> $@
|
||||
echo " '`bc <<< $(timeout_cycles)*$(CLOCK_PERIOD)`ns'" >> $@
|
||||
echo " ]" >> $@
|
||||
|
||||
#########################################################################################
|
||||
# synthesis input configuration
|
||||
#########################################################################################
|
||||
@@ -98,10 +180,16 @@ endif
|
||||
|
||||
$(SYN_CONF): $(VLSI_RTL) $(VLSI_BB)
|
||||
mkdir -p $(dir $@)
|
||||
echo "synthesis.inputs:" > $@
|
||||
echo "sim.inputs:" > $@
|
||||
echo " input_files:" >> $@
|
||||
for x in $(VLSI_RTL); do \
|
||||
echo ' - "'$$x'"' >> $@; \
|
||||
done
|
||||
echo " input_files_meta: 'append'" >> $@
|
||||
echo "synthesis.inputs:" >> $@
|
||||
echo " top_module: $(VLSI_TOP)" >> $@
|
||||
echo " input_files:" >> $@
|
||||
for x in $(VLSI_RTL) `cat $(VLSI_BB)`; do \
|
||||
for x in $(VLSI_RTL) $(shell cat $(VLSI_BB)); do \
|
||||
echo ' - "'$$x'"' >> $@; \
|
||||
done
|
||||
|
||||
@@ -124,4 +212,4 @@ $(OBJ_DIR)/hammer.d: $(HAMMER_D_DEPS)
|
||||
#########################################################################################
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf $(VLSI_OBJ_DIR) hammer-vlsi*.log __pycache__ output.json $(GENERATED_CONFS) $(gen_dir)
|
||||
rm -rf $(VLSI_OBJ_DIR) hammer-vlsi*.log __pycache__ output.json $(GENERATED_CONFS) $(gen_dir) $(SIM_CONF) $(SIM_DEBUG_CONF) $(SIM_TIMING_CONF) $(POWER_CONF)
|
||||
|
||||
Submodule vlsi/hammer updated: 2f37cd3121...9d83bbadc0
Submodule vlsi/hammer-cadence-plugins updated: 8f23bfa8c9...f644138bab
Submodule vlsi/hammer-synopsys-plugins updated: f812f8ce85...ef163445ee
6
vlsi/power.mk
Normal file
6
vlsi/power.mk
Normal file
@@ -0,0 +1,6 @@
|
||||
.PHONY: $(POWER_CONF)
|
||||
power-par: $(POWER_CONF) sim-par
|
||||
power-par: override HAMMER_POWER_EXTRA_ARGS += -p $(POWER_CONF)
|
||||
redo-power-par: $(POWER_CONF)
|
||||
redo-power-par: override HAMMER_EXTRA_ARGS += -p $(POWER_CONF)
|
||||
$(OBJ_DIR)/power-rundir/power-output-full.json: private override HAMMER_EXTRA_ARGS += $(HAMMER_POWER_EXTRA_ARGS)
|
||||
38
vlsi/sim.mk
Normal file
38
vlsi/sim.mk
Normal file
@@ -0,0 +1,38 @@
|
||||
.PHONY: $(SIM_CONF) $(SIM_DEBUG_CONF) $(SIM_TIMING_CONF)
|
||||
# Update hammer top-level sim targets to include our generated sim configs
|
||||
redo-sim-rtl: $(SIM_CONF)
|
||||
redo-sim-rtl: override HAMMER_EXTRA_ARGS += -p $(SIM_CONF)
|
||||
redo-sim-rtl-debug: $(SIM_DEBUG_CONF) redo-sim-rtl
|
||||
redo-sim-rtl-debug: override HAMMER_EXTRA_ARGS += -p $(SIM_DEBUG_CONF)
|
||||
|
||||
redo-sim-syn: $(SIM_CONF)
|
||||
redo-sim-syn: override HAMMER_EXTRA_ARGS += -p $(SIM_CONF)
|
||||
redo-sim-syn-debug: $(SIM_DEBUG_CONF) redo-sim-syn
|
||||
redo-sim-syn-debug: override HAMMER_EXTRA_ARGS += -p $(SIM_DEBUG_CONF)
|
||||
|
||||
redo-sim-par: $(SIM_CONF)
|
||||
redo-sim-par: override HAMMER_EXTRA_ARGS += -p $(SIM_CONF)
|
||||
redo-sim-par-debug: $(SIM_DEBUG_CONF) redo-sim-par
|
||||
redo-sim-par-debug: override HAMMER_EXTRA_ARGS += -p $(SIM_DEBUG_CONF)
|
||||
redo-sim-par-timing-debug: $(SIM_TIMING_CONF) redo-sim-par-debug
|
||||
redo-sim-par-timing-debug: override HAMMER_EXTRA_ARGS += -p $(SIM_TIMING_CONF)
|
||||
|
||||
sim-rtl: $(SIM_CONF)
|
||||
sim-rtl: override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_CONF)
|
||||
sim-rtl-debug: $(SIM_DEBUG_CONF) sim-rtl
|
||||
sim-rtl-debug: override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_DEBUG_CONF)
|
||||
$(OBJ_DIR)/sim-rundir/sim-output-full.json: private override HAMMER_EXTRA_ARGS += $(HAMMER_SIM_EXTRA_ARGS)
|
||||
|
||||
sim-syn: $(SIM_CONF)
|
||||
sim-syn: override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_CONF)
|
||||
sim-syn-debug: $(SIM_DEBUG_CONF) sim-syn
|
||||
sim-syn-debug: override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_DEBUG_CONF)
|
||||
$(OBJ_DIR)/sim-syn-rundir/sim-output-full.json: private override HAMMER_EXTRA_ARGS += $(HAMMER_SIM_EXTRA_ARGS)
|
||||
|
||||
sim-par: $(SIM_CONF)
|
||||
sim-par: override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_CONF)
|
||||
sim-par-debug: $(SIM_DEBUG_CONF) sim-par
|
||||
sim-par-debug: override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_DEBUG_CONF)
|
||||
sim-par-timing-debug: $(SIM_TIMING_CONF) sim-par-debug
|
||||
sim-par-timing-debug: override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_TIMING_CONF)
|
||||
$(OBJ_DIR)/sim-par-rundir/sim-output-full.json: private override HAMMER_EXTRA_ARGS += $(HAMMER_SIM_EXTRA_ARGS)
|
||||
Reference in New Issue
Block a user