Merge pull request #913 from ucb-bar/dev

Chipyard Release 1.6.0 (master merge from dev)
This commit is contained in:
Abraham Gonzalez
2022-02-15 22:47:12 -08:00
committed by GitHub
154 changed files with 3542 additions and 2036 deletions

View File

@@ -1,75 +0,0 @@
Chipyard CI
===========
Website: https://circleci.com/gh/ucb-bar/chipyard
CircleCI Brief Explanation
---------------------------
CircleCI is controlled by the `config.yml` script.
It consists of a *workflow* which has a series of *jobs* within it that do particular tasks.
All jobs in the workflow must pass for the CI run to be successful.
At the bottom of the `config.yml` there is a `workflows:` section that specifies the order in which the jobs of the workflow should run.
For example:
- prepare-rocketchip:
requires:
- install-riscv-toolchain
This specifies that the `prepare-rocketchip` job needs the `install-riscv-toolchain` steps to run before it can run.
All jobs in the CI workflow are specified at the top of `config.yml`
They specify a docker image to use (in this case a riscv-boom image since that is already available and works nicely) and an environment.
Finally, in the `steps:` section, the steps are run sequentially and state persists throughout a job.
So when you run something like `checkout` the next step has the checked out code.
Caching in the job is done by giving a file to cache on.
`restore_cache:` loads the cache into the environment if the key matches while `save_cache:` writes to the cache with the key IF IT IS NOT PRESENT.
Note, if the cache is already present for that key, the write to it is ignored.
Here the key is built from a string where the `checksum` portion converts the file given into a hash.
.circleci directory
-------------------
This directory contains all the collateral for the Chipyard CI to work.
The following is included:
`build-toolchains.sh` # build either riscv-tools or esp-tools
`create-hash.sh` # create hashes of riscv-tools/esp-tools so circleci caching can work
`do-rtl-build.sh` # use verilator to build a sim executable (remotely)
`config.yml` # main circleci config script to enumerate jobs/workflows
`defaults.sh` # default variables used
`check-commit.sh` # check that submodule commits are valid
`build-extra-tests.sh` # build default chipyard tests located in tests/
`clean-old-files.sh` # clean up build server files
`do-fpga-rtl-build.sh` # similar to `do-rtl-build` but using fpga/
`install-verilator.sh` # install verilator on build server
`run-firesim-scala-tests.sh` # run firesim scala tests
`run-tests.sh # run tests for a specific set of designs
`images/` # docker image used in CI
How things are setup for Chipyard
---------------------------------
The steps for CI to run are as follows.
1st, build the toolchains in parallel (note: `esp-tools` is currently not used in the run).
The docker image sets up the `PATH` and `RISCV` variable so that `riscv-tools` is the default (currently the `env.sh` script that is created at tool build is unused).
2nd, create the simulator binary.
This requires the `riscv-tools` for `fesvr` and `verilator` to be able to build the binary.
This stores all collateral for the tests (srcs, generated-srcs, sim binary, etc) to run "out of the gate" in the next job (make needs everything or else it will run again).
3rd, finally run the desired tests.
Other CI Setup
--------------
To get the CI to work correctly you need to setup CircleCI environment variables to point to the remote directory to build files and the server user/ip.
In the project settings, you can find this under "Build Settings" "Environment Variables".
You need to add two variables like the following:
CI\_DIR = /path/to/where/you/want/to/store/remote/files
SERVER = username@myserver.coolmachine.berkeley.edu
Additionally, you need to add under the "PERMISSIONS" "SSH Permissions" section a private key that is on the build server that you are using.
After adding a private key, it will show a fingerprint that should be added under the jobs that need to be run.
Note: On the remote server you need to have the `*.pub` key file added to the `authorized_keys` file.

View File

@@ -1,524 +0,0 @@
# CircleCI Configuration File
# version of circleci
version: 2.1
parameters:
tools-cache-version:
type: string
default: "v11"
# default execution env.s
executors:
main-env:
docker:
- image: ucbbar/chipyard-ci-image:1d51bb90
environment:
JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
# re-usable commands
commands:
toolchain-build:
description: "Build a toolchain"
parameters:
tools-version:
type: string
default: "riscv-tools"
steps:
- checkout
- run:
name: Create hash of toolchains
command: |
.circleci/create-hash.sh
- restore_cache:
keys:
- << parameters.tools-version >>-installed-<< pipeline.parameters.tools-cache-version >>-{{ checksum "../<< parameters.tools-version >>.hash" }}
- run:
name: Building << parameters.tools-version >>
command: |
.circleci/build-toolchains.sh << parameters.tools-version >>
no_output_timeout: 120m
- save_cache:
key: << parameters.tools-version >>-installed-<< pipeline.parameters.tools-cache-version >>-{{ checksum "../<< parameters.tools-version >>.hash" }}
paths:
- "/root/<< parameters.tools-version >>-install"
ssh-checkout:
description: "Add SSH key and checkout code"
steps:
- add_ssh_keys:
fingerprints:
- "3e:c3:02:5b:ed:64:8c:b7:b0:04:43:bc:83:43:73:1e"
- "32:d6:89:d2:97:fa:db:de:a8:2d:2a:f2:70:dd:80:89"
- checkout
setup-tools:
description: "Get toolchain"
parameters:
tools-version:
type: string
default: "riscv-tools"
steps:
- ssh-checkout
- run:
name: Create hash of toolchains
command: |
.circleci/create-hash.sh
- restore_cache:
keys:
- << parameters.tools-version >>-installed-<< pipeline.parameters.tools-cache-version >>-{{ checksum "../<< parameters.tools-version >>.hash" }}
prepare-rtl:
description: "Run the prepare step of RTL"
parameters:
tools-version:
type: string
default: "riscv-tools"
group-key:
type: string
timeout:
type: string
default: "120m"
build-script:
type: string
default: "do-rtl-build.sh"
build-type:
type: string
default: "sim"
steps:
- setup-tools:
tools-version: "<< parameters.tools-version >>"
- run:
name: Building << parameters.group-key >> subproject using Verilator
command: .circleci/<< parameters.build-script >> << parameters.group-key >> << parameters.build-type >>
no_output_timeout: << parameters.timeout >>
- save_cache:
key: << parameters.group-key >>-{{ .Branch }}-{{ .Revision }}
paths:
- "/root/project"
run-tests:
description: "Run a set of tests"
parameters:
tools-version:
type: string
default: "riscv-tools"
group-key:
type: string
project-key:
type: string
run-script:
type: string
default: "run-tests.sh"
timeout:
type: string
default: "25m"
steps:
- setup-tools:
tools-version: "<< parameters.tools-version >>"
- restore_cache:
keys:
- << parameters.group-key >>-{{ .Branch }}-{{ .Revision }}
- run:
name: Run << parameters.project-key >> subproject tests
command: .circleci/<< parameters.run-script >> << parameters.project-key >>
no_output_timeout: << parameters.timeout >>
# set of jobs to run
jobs:
commit-on-master-check:
executor: main-env
steps:
- checkout
- run:
name: Check commits of each submodule
command: |
.circleci/check-commit.sh
tutorial-setup-check:
executor: main-env
steps:
- checkout
- run:
name: Check that the tutorial-setup patches apply
command: |
scripts/tutorial-setup.sh
documentation-check:
executor: main-env
steps:
- checkout
- run:
name: Check that documentation builds with no warnings/errors
command: |
sudo apt-get update -y
sudo apt-get install -y python3-pip
sudo pip3 install -r docs/requirements.txt
make -C docs html
install-riscv-toolchain:
executor: main-env
steps:
- toolchain-build:
tools-version: "riscv-tools"
install-esp-toolchain:
executor: main-env
steps:
- toolchain-build:
tools-version: "esp-tools"
install-verilator:
executor: main-env
steps:
- ssh-checkout
- run:
name: Install Verilator to remote
command: |
.circleci/install-verilator.sh
build-extra-tests:
executor: main-env
steps:
- ssh-checkout
- run:
name: Create hash of toolchains
command: |
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-<< pipeline.parameters.tools-cache-version >>-{{ checksum "../riscv-tools.hash" }}
- run:
name: Build extra tests
command: .circleci/build-extra-tests.sh
no_output_timeout: 120m
- save_cache:
key: extra-tests-{{ .Branch }}-{{ .Revision }}
paths:
- "/root/project/tests"
prepare-chipyard-cores:
executor: main-env
steps:
- prepare-rtl:
group-key: "group-cores"
prepare-chipyard-peripherals:
executor: main-env
steps:
- prepare-rtl:
group-key: "group-peripherals"
prepare-chipyard-accels:
executor: main-env
steps:
- prepare-rtl:
tools-version: "esp-tools"
group-key: "group-accels"
prepare-chipyard-tracegen:
executor: main-env
steps:
- prepare-rtl:
group-key: "group-tracegen"
prepare-chipyard-other:
executor: main-env
steps:
- prepare-rtl:
group-key: "group-other"
chipyard-rocket-run-tests:
executor: main-env
steps:
- run-tests:
group-key: "group-cores"
project-key: "chipyard-rocket"
chipyard-hetero-run-tests:
executor: main-env
steps:
- run-tests:
group-key: "group-cores"
project-key: "chipyard-hetero"
timeout: "20m"
chipyard-boom-run-tests:
executor: main-env
steps:
- run-tests:
group-key: "group-cores"
project-key: "chipyard-boom"
chipyard-cva6-run-tests:
executor: main-env
steps:
- run-tests:
group-key: "group-cores"
project-key: "chipyard-cva6"
timeout: "30m"
chipyard-sodor-run-tests:
executor: main-env
steps:
- run-tests:
group-key: "group-cores"
project-key: "chipyard-sodor"
timeout: "30m"
chipyard-multiclock-rocket-run-tests:
executor: main-env
steps:
- run-tests:
group-key: "group-cores"
project-key: "chipyard-multiclock-rocket"
chipyard-dmirocket-run-tests:
executor: main-env
steps:
- run-tests:
group-key: "group-peripherals"
project-key: "chipyard-dmirocket"
chipyard-spiflashwrite-run-tests:
executor: main-env
steps:
- run-tests:
group-key: "group-peripherals"
project-key: "chipyard-spiflashwrite"
chipyard-spiflashread-run-tests:
executor: main-env
steps:
- run-tests:
group-key: "group-peripherals"
project-key: "chipyard-spiflashread"
chipyard-lbwif-run-tests:
executor: main-env
steps:
- run-tests:
group-key: "group-peripherals"
project-key: "chipyard-lbwif"
chipyard-sha3-run-tests:
executor: main-env
steps:
- run-tests:
tools-version: "esp-tools"
group-key: "group-accels"
project-key: "chipyard-sha3"
chipyard-streaming-fir-run-tests:
executor: main-env
steps:
- run-tests:
group-key: "group-accels"
project-key: "chipyard-streaming-fir"
chipyard-streaming-passthrough-run-tests:
executor: main-env
steps:
- run-tests:
group-key: "group-accels"
project-key: "chipyard-streaming-passthrough"
chipyard-hwacha-run-tests:
executor: main-env
steps:
- run-tests:
tools-version: "esp-tools"
group-key: "group-accels"
project-key: "chipyard-hwacha"
timeout: "30m"
chipyard-gemmini-run-tests:
executor: main-env
steps:
- run-tests:
tools-version: "esp-tools"
group-key: "group-accels"
project-key: "chipyard-gemmini"
chipyard-nvdla-run-tests:
executor: main-env
steps:
- run-tests:
group-key: "group-accels"
project-key: "chipyard-nvdla"
tracegen-run-tests:
executor: main-env
steps:
- run-tests:
group-key: "group-tracegen"
project-key: "tracegen"
tracegen-boom-run-tests:
executor: main-env
steps:
- run-tests:
group-key: "group-tracegen"
project-key: "tracegen-boom"
icenet-run-tests:
executor: main-env
steps:
- run-tests:
group-key: "group-other"
project-key: "icenet"
timeout: "30m"
testchipip-run-tests:
executor: main-env
steps:
- run-tests:
group-key: "group-other"
project-key: "testchipip"
timeout: "30m"
firesim-run-tests:
executor: main-env
steps:
- run-tests:
group-key: "extra-tests"
project-key: "firesim"
run-script: "run-firesim-scala-tests.sh"
timeout: "20m"
fireboom-run-tests:
executor: main-env
steps:
- run-tests:
group-key: "extra-tests"
project-key: "fireboom"
run-script: "run-firesim-scala-tests.sh"
timeout: "45m"
firesim-multiclock-run-tests:
executor: main-env
steps:
- run-tests:
group-key: "extra-tests"
project-key: "firesim-multiclock"
run-script: "run-firesim-scala-tests.sh"
timeout: "20m"
prepare-chipyard-fpga:
executor: main-env
steps:
- prepare-rtl:
group-key: "group-fpga"
build-type: "fpga"
# Order and dependencies of jobs to run
workflows:
version: 2
submodules-on-master:
jobs:
# Check to make sure submodule commits are on master branches
- commit-on-master-check
triggers:
- schedule:
cron: "0 0 * * *"
filters:
branches:
only:
- master
build-and-test-chipyard-integration:
jobs:
# Make the toolchains
- install-riscv-toolchain
- install-esp-toolchain
- install-verilator
- commit-on-master-check
# Attempt to apply the tutorial patches
- tutorial-setup-check
# Check that documentation builds
- documentation-check
# Build extra tests
- build-extra-tests:
requires:
- install-riscv-toolchain
# Prepare the verilator builds
- prepare-chipyard-cores:
requires:
- install-riscv-toolchain
- install-verilator
- prepare-chipyard-peripherals:
requires:
- install-riscv-toolchain
- install-verilator
- prepare-chipyard-accels:
requires:
- install-esp-toolchain
- install-verilator
- prepare-chipyard-tracegen:
requires:
- install-riscv-toolchain
- install-verilator
- prepare-chipyard-other:
requires:
- install-riscv-toolchain
- install-verilator
# Run the example tests
- chipyard-rocket-run-tests:
requires:
- prepare-chipyard-cores
- chipyard-hetero-run-tests:
requires:
- prepare-chipyard-cores
- chipyard-boom-run-tests:
requires:
- prepare-chipyard-cores
- chipyard-cva6-run-tests:
requires:
- prepare-chipyard-cores
- chipyard-sodor-run-tests:
requires:
- prepare-chipyard-cores
- chipyard-dmirocket-run-tests:
requires:
- prepare-chipyard-peripherals
- chipyard-spiflashwrite-run-tests:
requires:
- prepare-chipyard-peripherals
- chipyard-spiflashread-run-tests:
requires:
- prepare-chipyard-peripherals
- chipyard-lbwif-run-tests:
requires:
- prepare-chipyard-peripherals
- chipyard-sha3-run-tests:
requires:
- prepare-chipyard-accels
- chipyard-streaming-fir-run-tests:
requires:
- prepare-chipyard-accels
- chipyard-streaming-passthrough-run-tests:
requires:
- prepare-chipyard-accels
- chipyard-hwacha-run-tests:
requires:
- prepare-chipyard-accels
- chipyard-gemmini-run-tests:
requires:
- prepare-chipyard-accels
- chipyard-nvdla-run-tests:
requires:
- prepare-chipyard-accels
- tracegen-run-tests:
requires:
- prepare-chipyard-tracegen
- tracegen-boom-run-tests:
requires:
- prepare-chipyard-tracegen
- icenet-run-tests:
requires:
- prepare-chipyard-other
- testchipip-run-tests:
requires:
- prepare-chipyard-other
# Run the firesim tests
- firesim-run-tests:
requires:
- install-riscv-toolchain
- install-verilator
- build-extra-tests
- firesim-multiclock-run-tests:
requires:
- install-riscv-toolchain
- install-verilator
- build-extra-tests
- fireboom-run-tests:
requires:
- install-riscv-toolchain
- install-verilator
- build-extra-tests
# Prepare the fpga builds (just Verilog)
- prepare-chipyard-fpga:
requires:
- install-riscv-toolchain

View File

@@ -1,92 +0,0 @@
#!/bin/bash
# create the different verilator builds
# usage:
# do-rtl-build.sh <make command string> sim
# run rtl build for simulations and copy back results
# do-rtl-build.sh <make command string> fpga
# run rtl build for fpga and don't copy back results
# turn echo on and error on earliest command
set -ex
# get shared variables
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
source $SCRIPT_DIR/defaults.sh
# call clean on exit
trap clean EXIT
cd $LOCAL_CHIPYARD_DIR
./scripts/init-submodules-no-riscv-tools.sh
./scripts/init-fpga.sh
# set stricthostkeychecking to no (must happen before rsync)
run "echo \"Ping $SERVER\""
clean
# copy over riscv/esp-tools, and chipyard to remote
run "mkdir -p $REMOTE_CHIPYARD_DIR"
copy $LOCAL_CHIPYARD_DIR/ $SERVER:$REMOTE_CHIPYARD_DIR
run "cp -r ~/.ivy2 $REMOTE_WORK_DIR"
run "cp -r ~/.sbt $REMOTE_WORK_DIR"
TOOLS_DIR=$REMOTE_RISCV_DIR
LD_LIB_DIR=$REMOTE_RISCV_DIR/lib
if [ $1 = "group-accels" ]; then
export RISCV=$LOCAL_ESP_DIR
export LD_LIBRARY_PATH=$LOCAL_ESP_DIR/lib
export PATH=$RISCV/bin:$PATH
GEMMINI_SOFTWARE_DIR=$LOCAL_SIM_DIR/../../generators/gemmini/software/gemmini-rocc-tests
cd $LOCAL_SIM_DIR/../../generators/gemmini/software
git submodule update --init --recursive gemmini-rocc-tests
cd gemmini-rocc-tests
./build.sh
TOOLS_DIR=$REMOTE_ESP_DIR
LD_LIB_DIR=$REMOTE_ESP_DIR/lib
run "mkdir -p $REMOTE_ESP_DIR"
copy $LOCAL_ESP_DIR/ $SERVER:$REMOTE_ESP_DIR
else
run "mkdir -p $REMOTE_RISCV_DIR"
copy $LOCAL_RISCV_DIR/ $SERVER:$REMOTE_RISCV_DIR
fi
# choose what make dir to use
case $2 in
"sim")
REMOTE_MAKE_DIR=$REMOTE_SIM_DIR
;;
"fpga")
REMOTE_MAKE_DIR=$REMOTE_FPGA_DIR
;;
esac
# enter the verilator directory and build the specific config on remote server
run "export RISCV=\"$TOOLS_DIR\"; \
make -C $REMOTE_MAKE_DIR clean;"
read -a keys <<< ${grouping[$1]}
# need to set the PATH to use the new verilator (with the new verilator root)
for key in "${keys[@]}"
do
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\"; \
export COURSIER_CACHE=\"$REMOTE_WORK_DIR/.coursier-cache\"; \
make -j$REMOTE_MAKE_NPROC -C $REMOTE_MAKE_DIR FIRRTL_LOGLEVEL=info JAVA_OPTS=\"$REMOTE_JAVA_OPTS\" SBT_OPTS=\"$REMOTE_SBT_OPTS\" ${mapping[$key]}"
done
run "rm -rf $REMOTE_CHIPYARD_DIR/project"
# choose to copy back results
if [ $2 = "sim" ]; then
# copy back the final build
mkdir -p $LOCAL_CHIPYARD_DIR
copy $SERVER:$REMOTE_CHIPYARD_DIR/ $LOCAL_CHIPYARD_DIR
fi

View File

@@ -1,25 +0,0 @@
#!/bin/bash
# move verilator to the remote server
# turn echo on and error on earliest command
set -ex
# get shared variables
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\""
run "git clone http://git.veripool.org/git/verilator $REMOTE_VERILATOR_DIR; \
cd $REMOTE_VERILATOR_DIR; \
git checkout $VERILATOR_VERSION; \
autoconf; \
export VERILATOR_ROOT=$REMOTE_VERILATOR_DIR; \
./configure; \
make -j$REMOTE_MAKE_NPROC;"

View File

@@ -1,52 +0,0 @@
#!/bin/bash
# create the different verilator builds
# argument is the make command string
# turn echo on and error on earliest command
set -ex
# get shared variables
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
source $SCRIPT_DIR/defaults.sh
# call clean on exit
trap clean EXIT
cd $LOCAL_CHIPYARD_DIR
./scripts/init-submodules-no-riscv-tools.sh
cd $LOCAL_CHIPYARD_DIR/sims/firesim/sim/firesim-lib/src/main/cc/lib
git submodule update --init elfutils libdwarf
cd $LOCAL_CHIPYARD_DIR/sims/firesim
./scripts/build-libelf.sh
./scripts/build-libdwarf.sh
cd $LOCAL_CHIPYARD_DIR
make -C $LOCAL_CHIPYARD_DIR/tools/dromajo/dromajo-src/src
# set stricthostkeychecking to no (must happen before rsync)
run "echo \"Ping $SERVER\""
clean
# copy over riscv/esp-tools, and chipyard to remote
run "mkdir -p $REMOTE_CHIPYARD_DIR"
run "mkdir -p $REMOTE_RISCV_DIR"
copy $LOCAL_CHIPYARD_DIR/ $SERVER:$REMOTE_CHIPYARD_DIR
copy $LOCAL_RISCV_DIR/ $SERVER:$REMOTE_RISCV_DIR
run "cp -r ~/.ivy2 $REMOTE_WORK_DIR"
run "cp -r ~/.sbt $REMOTE_WORK_DIR"
TOOLS_DIR=$REMOTE_RISCV_DIR
LD_LIB_DIR=$REMOTE_RISCV_DIR/lib
# Run Firesim Scala Tests
run "export RISCV=\"$TOOLS_DIR\"; \
export LD_LIBRARY_PATH=\"$LD_LIB_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_OPTS=\"$REMOTE_JAVA_OPTS\" SBT_OPTS=\"$REMOTE_SBT_OPTS\" testOnly ${mapping[$1]}"

126
.github/CI_README.md vendored Normal file
View File

@@ -0,0 +1,126 @@
Chipyard Continuous Integration (CI)
===========
Website: https://gihub.com/gh/ucb-bar/chipyard/actions
GitHub Actions Brief Explanation
---------------------------
CI is executed by Github Actions (GA). GA is controlled by `.yml` files in the `.github/workflows/` directory.
In our case, we have just one workflow named `chipyard-run-tests.yml`.
It defines a number of `jobs` within it that do particular tasks.
All jobs in the workflow must pass for the CI run to be successful.
In general, a job is run in parallel with others unless it depends on some other job.
The dependency of one job on the completion of another is specified via the `needs` field.
For example:
```yaml
prepare-chipyard-cores:
name: prepare-chipyard-cores
needs: [make-keys, setup-complete]
```
This specifies that the `prepare-chipyard-cores` job needs the both the `make-keys` and the `setup-complete` steps to
be completed before it can run.
Chipyard runs its CI using a docker image created from `dockerfiles/Dockerfile`.
See its [README](../dockerfiles/README.md) for more details.
Finally, within each job's `steps:` section, the steps are run sequentially and state persists throughout a job.
So when you run something like `checkout` the next step has the checked out code.
[Composite Actions](https://docs.github.com/en/actions/creating-actions) (CA) allow for limited subroutine like code re-use within GA.
We use both community created and our own Composite Actions in our CI process. CA capabilities are changing rapidly.
Nesting of composite actions was only recently unveiled. There is a lot of room for more code reuse, in particular
we specify things over and over like docker image tag and checkout commands.
One use of CA: our process relies on caching to avoid running time-consuming and intensive tasks more often than necessary.
The following is an example of using the cache@v2 composite action. A step `uses: actions/cache@v2` which take as parameters the
path that contains the data to be cached and a key. Paths can have multiple targets.
The following step can look at the result of the cache operation, if there was cache miss, then we run the command that
will generate the data to be cached. The caching of the generated data is implicit.
>Note: GA cache documentation suggests using the yml level `if: steps.cache-primes.outputs.cache-hit != 'true'` to
> determine whether to run the data generation command.
> At the time of this writing the if construct has a bug and will not run correctly within a composite action. The use
> of a bash based if is a [hack found on stackoverflow](https://stackoverflow.com/questions/65473359/github-action-unable-to-add-if-condition-in-steps)
```yaml
- uses: actions/cache@v2
id: rtl-build-id
with:
path: |
sims/verilator
sims/firesim/sim
generators/gemmini/software/gemmini-rocc-tests
key: ${{ inputs.group-key }}-${{ github.ref }}-${{ github.sha }}
- name: run rtl build script if not cached
run: |
if [[ "${{ steps.rtl-build-id.outputs.cache-hit }}" != 'true' ]]; then
echo "Cache miss on ${{ inputs.group-key }}-${{ github.ref }}-${{ github.sha }}"
./.github/scripts/${{ inputs.build-script }} ${{ inputs.group-key }} ${{ inputs.build-type }}
else
echo "cache hit do not prepare rtl"
fi
shell: bash
```
Our own composite actions are defined in the `.github/actions/<ActionName>/action.yml`
.github/scripts directory
-------------------
This directory contains most the collateral for the Chipyard CI to work.
The following is included in `.github/scripts/: directory
`build-toolchains.sh` # build either riscv-tools or esp-tools
`create-hash.sh` # create hashes of riscv-tools/esp-tools to use as hash keys
`remote-do-rtl-build.sh` # use verilator to build a sim executable (remotely)
`defaults.sh` # default variables used
`check-commit.sh` # check that submodule commits are valid
`build-extra-tests.sh` # build default chipyard tests located in tests/
`clean-old-files.sh` # clean up build server files
`do-fpga-rtl-build.sh` # similar to `do-rtl-build` but using fpga/
`remote-install-verilator.sh` # install verilator on build server
`remote-run-firesim-scala-tests.sh` # run firesim scala tests
`run-tests.sh # run tests for a specific set of designs
How things are set up for Chipyard
---------------------------------
The steps for CI to run are as follows.
1. Build the toolchains in parallel (note: `esp-tools` is currently not used in the run).
The docker image sets up the `PATH` and `RISCV` variable so that `riscv-tools` is the default (currently the `env.sh` script that is created at tool build is unused).
2. Create the simulator binary.
This requires the `riscv-tools` for `fesvr` and `verilator` to be able to build the binary.
This stores all collateral for the tests (srcs, generated-srcs, sim binary, etc) to run "out of the gate" in the next job (make needs everything or else it will run again).
3. Finally, run the desired tests.
Other CI Setup
--------------
To get the CI to work correctly you need to create the following GH Repository Secrets
| Secret | Value |
| -------| ------------- |
| BUILDSERVER | the hostname of the remote build server (likely be a millennium machine) |
| BUILDUSER | the login to use on the build server |
| BUILDDIR | the directory to use on the build server |
| SERVERKEY | a private key to access the build server |
The main workflow also constructs and places in the environment a SERVER and a work directyory on that server env using the above secrets.
The SERVER is constructed like this:
```bash
SERVER = ${{ secrets.BUILDUSER }}@${{ secrets.BUILDSERVER }}
```
Additionally, you need to add under the "PERMISSIONS" "SSH Permissions" section a private key that is on the build server that you are using.
After adding a private key, it will show a fingerprint that should be added under the jobs that need to be run.
Note: On the remote server you need to have the `*.pub` key file added to the `authorized_keys` file.
Notes on CIRCLE CI
------------------
This code is heavily based on the origin [CircleCI]() work. There a quite a few differences
- CCI supports workflow level variables, in GA we must define things like `BUILDSERVER: ${{ secrets.BUILDSERVER }}` in every job
- CCI allows a much larger cache. The entire CY directory with toolchains and RTL could be cached, with GA there is a 5Gb total cache limit
- GA support more parallel jobs 20 vs 4
- GA seems to allow much longer run times

View File

@@ -1,21 +0,0 @@
---
name: Bug Report
about: Report a problem with Chipyard
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?**
**Other information**
<!-- include detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, ... -->

74
.github/ISSUE_TEMPLATE/bug-report.yml vendored Normal file
View File

@@ -0,0 +1,74 @@
name: Bug Report
description: File a bug report
labels: ["bug"]
body:
- type: checkboxes
attributes:
label: Background Work
description: Yes, I searched the following areas for a prior solution.
options:
- label: Yes, I searched the [mailing list](https://groups.google.com/forum/#!forum/chipyard)
required: true
- label: Yes, I searched [prior issues](https://github.com/ucb-bar/chipyard/issues)
required: true
- label: Yes, I searched the [documentation](https://chipyard.readthedocs.io/)
required: true
- type: textarea
attributes:
label: Chipyard Version and Hash
description: Repository version for reproducibility
placeholder: Version + Hash
value: |
Release: 1.5.0
Hash: a6a6a6
validations:
required: true
- type: textarea
attributes:
label: OS Setup
description: OS setup for reproducibility
placeholder: OS information
value: |
Ex: Output of `uname -a` and `lsb_release -a`
validations:
required: true
- type: textarea
attributes:
label: Other Setup
description: Any other setup relevant
placeholder: Other setup
value: |
Ex: Prior steps taken / Documentation Followed / etc...
validations:
required: false
- type: textarea
attributes:
label: Current Behavior
description: A concise description of what you're experiencing.
validations:
required: true
- type: textarea
attributes:
label: Expected Behavior
description: A concise description of what you expected to happen.
validations:
required: true
- type: textarea
attributes:
label: Other Information
description: Other information needed to reproduce the issue.
placeholder: |
Detailed explanations
Stack traces
Log files. Tip - You can add images / log files by clicking this area to highlight it and then dragging files in
Related issues
Suggestions on fixes
Other links
validations:
required: false

11
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: Chipyard Mailing List
url: https://groups.google.com/forum/#!forum/chipyard
about: Please ask and answer questions here.
- name: Rocket Chip Support
url: https://github.com/chipsalliance/rocket-chip/issues
about: Please ask and answer questions here.
- name: Chisel Support
url: https://www.chisel-lang.org/community.html
about: Please ask and answer questions here.

View File

@@ -1,13 +0,0 @@
---
name: Feature Request
about: Propose a change to Chipyard
---
<!-- choose one -->
**Impact**: rtl | software | unknown | other
**Description**
<!-- include detailed explanation, related issues, links for us to have context, ... -->
**What is a motivating example for changing the behavior?**

View File

@@ -0,0 +1,27 @@
name: Feature Request
description: File a feature request
labels: ["enhancement"]
body:
- type: checkboxes
attributes:
label: Background Work
description: Yes, I searched the following areas for a prior feature/solution to this problem.
options:
- label: Yes, I searched the [mailing list](https://groups.google.com/forum/#!forum/chipyard)
required: true
- label: Yes, I searched the [documentation](https://chipyard.readthedocs.io/)
required: true
- type: textarea
attributes:
label: Feature Description
description: Description of feature wanted
validations:
required: true
- type: textarea
attributes:
label: Motivating Example
description: A concise example demonstrating the feature.
validations:
required: true

View File

@@ -1,6 +0,0 @@
---
name: Other
about: Something else!
---

View File

@@ -1,18 +0,0 @@
---
name: Question
about: Ask a question
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: -->
<!-- rocketchip: https://github.com/chipsalliance/rocket-chip/issues -->
<!-- boom: https://github.com/riscv-boom/riscv-boom/issues -->
<!-- firesim: https://github.com/firesim/firesim/issues -->

View File

@@ -1,10 +1,27 @@
**Related issue**: <!-- if applicable -->
**Related PRs / Issues **:
<!-- List any related PRs/issues here, if applicable -->
<!-- choose one -->
**Type of change**: bug fix | new feature | other enhancement
**Type of change**:
- [ ] Bug fix
- [ ] New feature
- [ ] Other enhancement
<!-- choose one -->
**Impact**: rtl change | software change | unknown | other
**Impact**:
- [ ] RTL change
- [ ] Software change (RISC-V software)
- [ ] Build system change
- [ ] Other
<!-- must be filled out completely to be considered for merging -->
**Contributor Checklist**:
- [ ] Did you set `main` as the base branch?
- [ ] Did you delete any extraneous prints/debugging code?
- [ ] (If applicable) Did you add documentation for the feature?
- [ ] (If applicable) Did you add a test demonstrating the PR?
<!-- Do this if this PR is a bug fix that should be applied to master -->
- [ ] (If applicable) Did you mark the PR as "Please Backport"?
**Release Notes**
<!-- Text from here to the end of the body will be considered for inclusion in the release notes for the version containing this pull request. -->

8
.github/actions/job-end/action.yml vendored Normal file
View File

@@ -0,0 +1,8 @@
name: job-end
description: "Save a job status"
runs:
using: "composite"
steps:
- run: echo "success" > run_result
shell: bash

19
.github/actions/job-start/action.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
name: job-start
description: "Setup a job status"
outputs:
run_result:
value: ${{ steps.run_result.outputs.run_result }}
runs:
using: "composite"
steps:
- name: Restore the previous run result
uses: actions/cache@v2
with:
path: run_result
key: ${{ github.run_id }}-${{ github.job }}
restore-keys: ${{ github.run_id }}-${{ github.job }}
- name: Set run_result to default or use cached value
id: run_result
run: echo "::set-output name=run_result::$(cat run_result 2>/dev/null || echo 'default')"
shell: bash

40
.github/actions/prepare-rtl/action.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
name: prepare-rtl
description: 'Builds RTL based on parameters, caches the entire chipyard root dir when done'
inputs:
group-key:
description: group key
required: true
build-script:
description: rtl build script to use
required: false
default: "remote-do-rtl-build.sh"
build-type:
description: type of build
required: false
default: "sim"
runs:
using: "composite"
steps:
- name: Build RISC-V toolchains
uses: ./.github/actions/toolchain-build
- uses: actions/cache@v2
id: rtl-build-id
with:
path: |
sims/verilator
sims/firesim/sim
generators/gemmini/software/gemmini-rocc-tests
key: ${{ inputs.group-key }}-${{ github.ref }}-${{ github.sha }}
- name: Run RTL build if not cached
run: |
if [[ "${{ steps.rtl-build-id.outputs.cache-hit }}" != 'true' ]]; then
echo "Cache miss on ${{ inputs.group-key }}-${{ github.ref }}-${{ github.sha }}"
./.github/scripts/${{ inputs.build-script }} ${{ inputs.group-key }} ${{ inputs.build-type }}
else
echo "Cache hit do not rebuild RTL for ${{ inputs.group-key }}"
fi
shell: bash

31
.github/actions/run-tests/action.yml vendored Normal file
View File

@@ -0,0 +1,31 @@
name: run-tests
description: 'Runs tests according to input parameters'
inputs:
group-key:
description: group key
required: true
project-key:
description: project key
required: true
run-script:
description: rtl build script to use
required: false
default: "run-tests.sh"
runs:
using: "composite"
steps:
- name: Init submodules (since only the RTL is cached)
run: ./scripts/init-submodules-no-riscv-tools.sh --skip-validate
shell: bash
# Note: You shouldn't need the other inputs since it shouldn't build RTL from scratch
- name: Build RTL
uses: ./.github/actions/prepare-rtl
with:
group-key: ${{ inputs.group-key }}
- name: Run RTL tests
run: ./.github/scripts/${{ inputs.run-script }} ${{ inputs.project-key }}
shell: bash

View File

@@ -0,0 +1,51 @@
name: toolchain-build
description: 'Build/cache both toolchains'
runs:
using: "composite"
steps:
- name: Generate hashes
run: .github/scripts/create-hash.sh
shell: bash
# since "hashFiles" function differs on self-hosted vs GH-A machines
# make sure to cache the GH-A hashFiles result so that self-hosted can use it
- run: |
echo "${{ hashFiles('**/riscv-tools.hash') }}" > riscv-tools.hashFilesOutput
echo "${{ hashFiles('**/esp-tools.hash') }}" > esp-tools.hashFilesOutput
shell: bash
- name: Cache hashFiles outputs
uses: actions/cache@v2
with:
path: |
riscv-tools.hashFilesOutput
esp-tools.hashFilesOutput
key: hashFiles-${{ github.sha }}
- name: Generate cache keys based off hashFiles output
id: genkey
run: |
echo "::set-output name=riscv-tools-cache-key::$(cat riscv-tools.hashFilesOutput)"
echo "::set-output name=esp-tools-cache-key::$(cat esp-tools.hashFilesOutput)"
shell: bash
- name: Cache riscv-tools
uses: actions/cache@v2
with:
path: riscv-tools-install
key: riscv-tools-installed-${{ env.tools-cache-version }}-${{ steps.genkey.outputs.riscv-tools-cache-key }}
- name: Cache esp-tools
uses: actions/cache@v2
with:
path: esp-tools-install
key: esp-tools-installed-${{ env.tools-cache-version }}-${{ steps.genkey.outputs.esp-tools-cache-key }}
- name: Build RISC-V toolchain if not cached
run: ./.github/scripts/build-toolchains.sh riscv-tools
shell: bash
- name: Build ESP RISC-V toolchain if not cached
run: ./.github/scripts/build-toolchains.sh esp-tools
shell: bash

View File

@@ -7,5 +7,9 @@ set -ex
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
source $SCRIPT_DIR/defaults.sh
export RISCV="$GITHUB_WORKSPACE/riscv-tools-install"
export LD_LIBRARY_PATH="$RISCV/lib"
export PATH="$RISCV/bin:$PATH"
make -C $LOCAL_CHIPYARD_DIR/tests clean
make -C $LOCAL_CHIPYARD_DIR/tests

View File

@@ -15,4 +15,7 @@ if [ ! -d "$HOME/$1-install" ]; then
# init all submodules including the tools
CHIPYARD_DIR="$LOCAL_CHIPYARD_DIR" NPROC=$CI_MAKE_NPROC $LOCAL_CHIPYARD_DIR/scripts/build-toolchains.sh $1
# de-init the toolchain area to save on space (forced to ignore local changes)
git submodule deinit --force $LOCAL_CHIPYARD_DIR/toolchains/$1
fi

View File

@@ -17,15 +17,16 @@ git config submodule.vlsi/hammer-cadence-plugins.update none
git config submodule.vlsi/hammer-mentor-plugins.update none
git config submodule.vlsi/hammer-synopsys-plugins.update none
# initialize submodules and get the hashes
git submodule update --init
status=$(git submodule status)
all_names=()
search_submodule() {
echo "Running check on submodule $submodule in $dir"
# Initialize submodule and get the hashes
git submodule update --init $dir/$submodule
git -C $dir/$submodule fetch --unshallow
status=$(git submodule status)
hash=$(echo "$status" | grep "$dir.*$submodule " | awk '{print$1}' | grep -o "[[:alnum:]]*")
for branch in "${branches[@]}"
do
@@ -48,14 +49,9 @@ search () {
done
}
submodules=("cva6" "boom" "gemmini" "hwacha" "icenet" "nvdla" "rocket-chip" "sha3" "sifive-blocks" "sifive-cache" "testchipip" "riscv-sodor")
submodules=("cva6" "boom" "ibex" "gemmini" "hwacha" "icenet" "nvdla" "rocket-chip" "sha3" "sifive-blocks" "sifive-cache" "testchipip" "riscv-sodor")
dir="generators"
if [ "$CIRCLE_BRANCH" == "master" ] || [ "$CIRCLE_BRANCH" == "dev" ]
then
branches=("master")
else
branches=("master" "dev")
fi
branches=("master" "main" "dev")
search
submodules=("riscv-gnu-toolchain" "riscv-isa-sim" "riscv-pk" "riscv-tests")
@@ -82,22 +78,12 @@ search
submodules=("coremark" "firemarshal" "nvdla-workload" "spec2017")
dir="software"
if [ "$CIRCLE_BRANCH" == "master" ] || [ "$CIRCLE_BRANCH" == "dev" ]
then
branches=("master")
else
branches=("master" "dev")
fi
branches=("master" "dev")
search
submodules=("DRAMSim2" "axe" "barstools" "chisel-testers" "dsptools" "rocket-dsp-utils" "firrtl-interpreter" "torture" "treadle")
submodules=("DRAMSim2" "axe" "barstools" "chisel-testers" "dsptools" "rocket-dsp-utils" "torture")
dir="tools"
if [ "$CIRCLE_BRANCH" == "master" ] || [ "$CIRCLE_BRANCH" == "dev" ]
then
branches=("master")
else
branches=("master" "dev")
fi
branches=("master" "dev")
search
submodules=("dromajo-src")
@@ -107,12 +93,7 @@ search
submodules=("firesim")
dir="sims"
if [ "$CIRCLE_BRANCH" == "master" ] || [ "$CIRCLE_BRANCH" == "dev" ]
then
branches=("master")
else
branches=("master" "dev")
fi
branches=("master" "main" "dev")
search
submodules=("hammer")

View File

@@ -10,14 +10,11 @@ set -o pipefail
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
source $SCRIPT_DIR/defaults.sh
# enter bhd repo
cd $LOCAL_CHIPYARD_DIR
# Use normalized output of git-submodule status as hashfile
for tools in 'riscv-tools' 'esp-tools' ; do
git submodule status "toolchains/${tools}" 'toolchains/libgloss' 'toolchains/qemu' |
while read -r line ; do
echo "${line#[!0-9a-f]}"
done > "${HOME}/${tools}.hash"
done > "${tools}.hash"
done
echo "Hashfile for riscv-tools and esp-tools created in $HOME"
echo "Hashfile for riscv-tools and esp-tools created in $PWD"

View File

@@ -1,22 +1,5 @@
#!/bin/bash
copy () {
rsync -avzp -e 'ssh' --exclude '.git' $1 $2
}
run () {
ssh -o "StrictHostKeyChecking no" -t $SERVER $@
}
run_script () {
ssh -o "StrictHostKeyChecking no" -t $SERVER 'bash -s' < $1 "$2"
}
clean () {
# remove remote work dir
run "rm -rf $REMOTE_WORK_DIR"
}
# make parallelism
CI_MAKE_NPROC=8
# chosen based on a 24c system shared with 1 other project
@@ -25,33 +8,37 @@ REMOTE_MAKE_NPROC=4
# verilator version
VERILATOR_VERSION=v4.034
HOME=$GITHUB_WORKSPACE
# remote variables
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
# CI_DIR is defined externally based on the GH repository secret BUILDDIR
REMOTE_PREFIX=$CI_DIR/${GITHUB_REPOSITORY#*/}-${GITHUB_REF_NAME//\//-}
REMOTE_WORK_DIR=$GITHUB_WORKSPACE
REMOTE_RISCV_DIR=$GITHUB_WORKSPACE/riscv-tools-install
REMOTE_ESP_DIR=$GITHUB_WORKSPACE/esp-tools-install
REMOTE_CHIPYARD_DIR=$GITHUB_WORKSPACE
REMOTE_SIM_DIR=$REMOTE_CHIPYARD_DIR/sims/verilator
REMOTE_FIRESIM_DIR=$REMOTE_CHIPYARD_DIR/sims/firesim/sim
REMOTE_FPGA_DIR=$REMOTE_CHIPYARD_DIR/fpga
REMOTE_JAVA_OPTS="-Xmx10G -Xss8M"
# Disable the supershell to greatly improve the readability of SBT output when captured by Circle CI
REMOTE_SBT_OPTS="-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=$REMOTE_PREFIX-$CIRCLE_SHA1-verilator-install
REMOTE_VERILATOR_DIR=$REMOTE_PREFIX-$GITHUB_SHA-verilator-install
# local variables (aka within the docker container)
LOCAL_CHECKOUT_DIR=$HOME/project
LOCAL_RISCV_DIR=$HOME/riscv-tools-install
LOCAL_ESP_DIR=$HOME/esp-tools-install
LOCAL_CHIPYARD_DIR=$LOCAL_CHECKOUT_DIR
LOCAL_CHIPYARD_DIR=$HOME
LOCAL_SIM_DIR=$LOCAL_CHIPYARD_DIR/sims/verilator
LOCAL_FIRESIM_DIR=$LOCAL_CHIPYARD_DIR/sims/firesim/sim
# key value store to get the build groups
declare -A grouping
grouping["group-cores"]="chipyard-cva6 chipyard-rocket chipyard-hetero chipyard-boom chipyard-sodor chipyard-digitaltop chipyard-multiclock-rocket"
grouping["group-cores"]="chipyard-cva6 chipyard-ibex chipyard-rocket chipyard-hetero chipyard-boom chipyard-sodor chipyard-digitaltop chipyard-multiclock-rocket chipyard-nomem-scratchpad"
grouping["group-peripherals"]="chipyard-dmirocket chipyard-blkdev chipyard-spiflashread chipyard-spiflashwrite chipyard-mmios chipyard-lbwif"
grouping["group-accels"]="chipyard-nvdla chipyard-sha3 chipyard-hwacha chipyard-gemmini chipyard-streaming-fir chipyard-streaming-passthrough"
grouping["group-accels"]="chipyard-fftgenerator chipyard-nvdla chipyard-sha3 chipyard-hwacha chipyard-gemmini chipyard-streaming-fir chipyard-streaming-passthrough"
grouping["group-tracegen"]="tracegen tracegen-boom"
grouping["group-other"]="icenet testchipip"
grouping["group-fpga"]="arty vcu118"
@@ -71,6 +58,7 @@ mapping["chipyard-blkdev"]=" CONFIG=SimBlockDeviceRocketConfig"
mapping["chipyard-hwacha"]=" CONFIG=HwachaRocketConfig"
mapping["chipyard-gemmini"]=" CONFIG=GemminiRocketConfig"
mapping["chipyard-cva6"]=" CONFIG=CVA6Config"
mapping["chipyard-ibex"]=" CONFIG=IbexConfig"
mapping["chipyard-spiflashread"]=" CONFIG=LargeSPIFlashROMRocketConfig"
mapping["chipyard-spiflashwrite"]=" CONFIG=SmallSPIFlashRocketConfig"
mapping["chipyard-mmios"]=" CONFIG=MMIORocketConfig verilog"
@@ -79,6 +67,8 @@ mapping["tracegen-boom"]=" CONFIG=BoomTraceGenConfig"
mapping["chipyard-nvdla"]=" CONFIG=SmallNVDLARocketConfig"
mapping["chipyard-sodor"]=" CONFIG=Sodor5StageConfig"
mapping["chipyard-multiclock-rocket"]=" CONFIG=MulticlockRocketConfig"
mapping["chipyard-nomem-scratchpad"]=" CONFIG=MMIOScratchpadOnlyRocketConfig"
mapping["chipyard-fftgenerator"]=" CONFIG=FFTRocketConfig"
mapping["firesim"]="SCALA_TEST=firesim.firesim.RocketNICF1Tests"
mapping["firesim-multiclock"]="SCALA_TEST=firesim.firesim.RocketMulticlockF1Tests"

61
.github/scripts/remote-do-rtl-build.sh vendored Executable file
View File

@@ -0,0 +1,61 @@
#!/bin/bash
# create the different verilator builds
# usage:
# do-rtl-build.sh <make command string> sim
# run rtl build for simulations and copy back results
# do-rtl-build.sh <make command string> fpga
# run rtl build for fpga and don't copy back results
# turn echo on and error on earliest command
set -ex
# get shared variables
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
source $SCRIPT_DIR/defaults.sh
cd $REMOTE_CHIPYARD_DIR
./scripts/init-submodules-no-riscv-tools.sh --skip-validate
./scripts/init-fpga.sh
TOOLS_DIR=$REMOTE_RISCV_DIR
LD_LIB_DIR=$REMOTE_RISCV_DIR/lib
if [ $1 = "group-accels" ]; then
export RISCV=$REMOTE_ESP_DIR
export LD_LIBRARY_PATH=$REMOTE_ESP_DIR/lib
export PATH=$RISCV/bin:$PATH
pushd $REMOTE_CHIPYARD_DIR/generators/gemmini/software
git submodule update --init --recursive gemmini-rocc-tests
pushd gemmini-rocc-tests
./build.sh
popd
popd
fi
# choose what make dir to use
case $2 in
"sim")
REMOTE_MAKE_DIR=$REMOTE_SIM_DIR
;;
"fpga")
REMOTE_MAKE_DIR=$REMOTE_FPGA_DIR
;;
esac
# enter the verilator directory and build the specific config on remote server
export RISCV=$TOOLS_DIR
make -C $REMOTE_MAKE_DIR clean
read -a keys <<< ${grouping[$1]}
# need to set the PATH to use the new verilator (with the new verilator root)
for key in "${keys[@]}"
do
export RISCV=$TOOLS_DIR
export LD_LIBRARY_PATH=$LD_LIB_DIR
export PATH=$REMOTE_VERILATOR_DIR/bin:$PATH
export VERILATOR_ROOT=$REMOTE_VERILATOR_DIR
export COURSIER_CACHE=$REMOTE_WORK_DIR/.coursier-cache
make -j$REMOTE_MAKE_NPROC -C $REMOTE_MAKE_DIR FIRRTL_LOGLEVEL=info JAVA_OPTS="$REMOTE_JAVA_OPTS" SBT_OPTS="$REMOTE_SBT_OPTS" ${mapping[$key]}
done

22
.github/scripts/remote-install-verilator.sh vendored Executable file
View File

@@ -0,0 +1,22 @@
#!/bin/bash
# install verilator
# turn echo on and error on earliest command
set -ex
# get shared variables
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
source $SCRIPT_DIR/defaults.sh
# clean older directories (delete prior directories related to this branch also)
$SCRIPT_DIR/clean-old-files.sh $CI_DIR
rm -rf $REMOTE_PREFIX*
git clone http://git.veripool.org/git/verilator $REMOTE_VERILATOR_DIR
cd $REMOTE_VERILATOR_DIR
git checkout $VERILATOR_VERSION
autoconf
export VERILATOR_ROOT=$REMOTE_VERILATOR_DIR
./configure
make -j$REMOTE_MAKE_NPROC

View File

@@ -0,0 +1,43 @@
#!/bin/bash
# create the different verilator builds
# argument is the make command string
# turn echo on and error on earliest command
set -ex
# get shared variables
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
source $SCRIPT_DIR/defaults.sh
export RISCV="$REMOTE_RISCV_DIR"
export LD_LIBRARY_PATH="$RISCV/lib"
export PATH="$RISCV/bin:$PATH"
# Directory locations for handling firesim-local installations of libelf/libdwarf
# This would generally be handled by build-setup.sh/firesim-setup.sh
REMOTE_FIRESIM_SYSROOT=$REMOTE_FIRESIM_DIR/lib-install
./scripts/init-submodules-no-riscv-tools.sh --skip-validate
cd $REMOTE_CHIPYARD_DIR/sims/firesim/sim/firesim-lib/src/main/cc/lib
git submodule update --init elfutils libdwarf
cd $REMOTE_CHIPYARD_DIR/sims/firesim
mkdir -p $REMOTE_FIRESIM_SYSROOT
./scripts/build-libelf.sh $REMOTE_FIRESIM_SYSROOT
./scripts/build-libdwarf.sh $REMOTE_FIRESIM_SYSROOT
cd $REMOTE_CHIPYARD_DIR
make -C $REMOTE_CHIPYARD_DIR/tools/dromajo/dromajo-src/src
TOOLS_DIR=$REMOTE_RISCV_DIR
LD_LIB_DIR=$REMOTE_FIRESIM_SYSROOT/lib:$REMOTE_RISCV_DIR/lib
# Run Firesim Scala Tests
export RISCV=$TOOLS_DIR
export LD_LIBRARY_PATH=$LD_LIB_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_OPTS="$REMOTE_JAVA_OPTS" SBT_OPTS="$REMOTE_SBT_OPTS" testOnly ${mapping[$1]}

View File

@@ -9,12 +9,18 @@ set -ex
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
source $SCRIPT_DIR/defaults.sh
export RISCV="$GITHUB_WORKSPACE/riscv-tools-install"
export LD_LIBRARY_PATH="$RISCV/lib"
export PATH="$RISCV/bin:$PATH"
DISABLE_SIM_PREREQ="BREAK_SIM_PREREQ=1"
run_bmark () {
make run-bmark-tests-fast -j$CI_MAKE_NPROC -C $LOCAL_SIM_DIR $@
make run-bmark-tests-fast -j$CI_MAKE_NPROC -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ $@
}
run_asm () {
make run-asm-tests-fast -j$CI_MAKE_NPROC -C $LOCAL_SIM_DIR $@
make run-asm-tests-fast -j$CI_MAKE_NPROC -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ $@
}
run_both () {
@@ -23,11 +29,9 @@ run_both () {
}
run_tracegen () {
make tracegen -C $LOCAL_SIM_DIR $@
make tracegen -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ $@
}
# TODO BUG: the run-binary command forces a rebuild of the simulator in CI
# instead, directly run the simulator binary
case $1 in
chipyard-rocket)
run_bmark ${mapping[$1]}
@@ -51,7 +55,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$CI_MAKE_NPROC -C $LOCAL_SIM_DIR ${mapping[$1]}
make run-rv64uv-p-asm-tests -j$CI_MAKE_NPROC -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]}
;;
chipyard-gemmini)
export RISCV=$LOCAL_ESP_DIR
@@ -60,32 +64,32 @@ case $1 in
GEMMINI_SOFTWARE_DIR=$LOCAL_SIM_DIR/../../generators/gemmini/software/gemmini-rocc-tests
rm -rf $GEMMINI_SOFTWARE_DIR/riscv-tests
cd $LOCAL_SIM_DIR
$LOCAL_SIM_DIR/simulator-chipyard-GemminiRocketConfig $GEMMINI_SOFTWARE_DIR/build/bareMetalC/aligned-baremetal
$LOCAL_SIM_DIR/simulator-chipyard-GemminiRocketConfig $GEMMINI_SOFTWARE_DIR/build/bareMetalC/raw_hazard-baremetal
$LOCAL_SIM_DIR/simulator-chipyard-GemminiRocketConfig $GEMMINI_SOFTWARE_DIR/build/bareMetalC/mvin_mvout-baremetal
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} run-binary-fast BINARY=$GEMMINI_SOFTWARE_DIR/build/bareMetalC/aligned-baremetal
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} run-binary-fast BINARY=$GEMMINI_SOFTWARE_DIR/build/bareMetalC/raw_hazard-baremetal
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} run-binary-fast BINARY=$GEMMINI_SOFTWARE_DIR/build/bareMetalC/mvin_mvout-baremetal
;;
chipyard-sha3)
export RISCV=$LOCAL_ESP_DIR
export LD_LIBRARY_PATH=$LOCAL_ESP_DIR/lib
export PATH=$RISCV/bin:$PATH
(cd $LOCAL_CHIPYARD_DIR/generators/sha3/software && ./build.sh)
$LOCAL_SIM_DIR/simulator-chipyard-Sha3RocketConfig $LOCAL_CHIPYARD_DIR/generators/sha3/software/tests/bare/sha3-rocc.riscv
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} run-binary-fast BINARY=$LOCAL_CHIPYARD_DIR/generators/sha3/software/tests/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
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} run-binary-fast BINARY=$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
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} run-binary-fast BINARY=$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
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} BINARY=$LOCAL_CHIPYARD_DIR/tests/spiflashread.riscv SIM_FLAGS="+spiflash0=${LOCAL_CHIPYARD_DIR}/tests/spiflash.img" run-binary-fast
;;
chipyard-spiflashwrite)
make -C $LOCAL_CHIPYARD_DIR/tests
make -C $LOCAL_SIM_DIR ${mapping[$1]} BINARY=$LOCAL_CHIPYARD_DIR/tests/spiflashwrite.riscv SIM_FLAGS="+spiflash0=${LOCAL_CHIPYARD_DIR}/tests/spiflash.img" run-binary
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} BINARY=$LOCAL_CHIPYARD_DIR/tests/spiflashwrite.riscv SIM_FLAGS="+spiflash0=${LOCAL_CHIPYARD_DIR}/tests/spiflash.img" run-binary-fast
[[ "`xxd $LOCAL_CHIPYARD_DIR/tests/spiflash.img | grep 1337\ 00ff\ aa55\ face | wc -l`" == "6" ]] || false
;;
tracegen)
@@ -95,20 +99,27 @@ case $1 in
run_tracegen ${mapping[$1]}
;;
chipyard-cva6)
make run-binary-fast -C $LOCAL_SIM_DIR ${mapping[$1]} BINARY=$RISCV/riscv64-unknown-elf/share/riscv-tests/benchmarks/multiply.riscv
make run-binary-fast -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} BINARY=$RISCV/riscv64-unknown-elf/share/riscv-tests/benchmarks/multiply.riscv
;;
chipyard-ibex)
run_bmark ${mapping[$1]} #TODO: Find 32-bit test
;;
chipyard-sodor)
run_asm ${mapping[$1]}
;;
chipyard-nvdla)
make -C $LOCAL_CHIPYARD_DIR/tests
make -C $LOCAL_SIM_DIR ${mapping[$1]} BINARY=$LOCAL_CHIPYARD_DIR/tests/nvdla.riscv run-binary
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} BINARY=$LOCAL_CHIPYARD_DIR/tests/nvdla.riscv run-binary-fast
;;
chipyard-fftgenerator)
make -C $LOCAL_CHIPYARD_DIR/tests
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} BINARY=$LOCAL_CHIPYARD_DIR/tests/fft.riscv run-binary-fast
;;
icenet)
make run-binary-fast BINARY=none -C $LOCAL_SIM_DIR ${mapping[$1]}
make run-binary-fast BINARY=none -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]}
;;
testchipip)
make run-binary-fast BINARY=none -C $LOCAL_SIM_DIR ${mapping[$1]}
make run-binary-fast BINARY=none -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]}
;;
*)
echo "No set of tests for $1. Did you spell it right?"

748
.github/workflows/chipyard-run-tests.yml vendored Normal file
View File

@@ -0,0 +1,748 @@
name: chipyard-ci-process
on:
# run ci on pull requests targeting main only (since the ci runs on the merge commit)
pull_request:
branches:
- main
env:
tools-cache-version: v13
BUILDSERVER: ${{ secrets.BUILDSERVER }}
BUILDUSER: ${{ secrets.BUILDUSER }}
SERVER: ${{ secrets.BUILDUSER }}@${{ secrets.BUILDSERVER }}
CI_DIR: ${{ secrets.BUILDDIR }}
JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
jobs:
cancel-prior-workflows:
name: cancel-prior-workflows
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.9.1
with:
access_token: ${{ github.token }}
commit-on-master-check:
name: commit-on-master-check
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Check commits of each submodule
if: steps.job-start.outputs.run_result != 'success'
run: .github/scripts/check-commit.sh
- uses: ./.github/actions/job-end
tutorial-setup-check:
name: tutorial-setup-check
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Check that the tutorial-setup patches apply
if: steps.job-start.outputs.run_result != 'success'
run: scripts/tutorial-setup.sh
- uses: ./.github/actions/job-end
documentation-check:
name: documentation-check
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Check that documentation builds with no warnings/errors
if: steps.job-start.outputs.run_result != 'success'
run: |
sudo apt-get update -y
sudo apt-get install -y python3-pip
sudo pip3 install -r docs/requirements.txt
make -C docs html
- name: Show error log from sphinx if failed
if: ${{ steps.job-start.outputs.run_result != 'success' && failure() }}
run: cat /tmp/sphinx-err*.log
- uses: ./.github/actions/job-end
install-toolchains:
name: install-toolchains
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Build RISC-V toolchains
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/toolchain-build
- uses: ./.github/actions/job-end
build-extra-tests:
name: build-extra-tests
needs: install-toolchains
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Build RISC-V toolchains
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/toolchain-build
- name: Generate keys
if: steps.job-start.outputs.run_result != 'success'
id: genkey
run: |
echo "::set-output name=extra-tests-cache-key::extra-tests-${{ github.ref }}-${{ github.sha }}"
- uses: actions/cache@v2
if: steps.job-start.outputs.run_result != 'success'
id: build-extra-tools-cache
with:
path: extra-tests-install
key: ${{ steps.genkey.outputs.extra-tests-cache-key }}
restore-keys: ${{ steps.genkey.outputs.extra-tests-cache-key }}
- name: Build extra tests
if: steps.job-start.outputs.run_result != 'success'
run: .github/scripts/build-extra-tests.sh
- uses: ./.github/actions/job-end
install-verilator:
name: install-verilator
runs-on: self-hosted
needs: cancel-prior-workflows
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Build verilator on self-hosted
if: steps.job-start.outputs.run_result != 'success'
run: .github/scripts/remote-install-verilator.sh
- uses: ./.github/actions/job-end
# Sentinel job to simplify how we specify which that basic setup is complete
#
# When adding new prep jobs, please add them to `needs` below
setup-complete:
name: setup-complete
needs: [install-toolchains, install-verilator, build-extra-tests]
runs-on: ubuntu-latest
steps:
- name: Set up complete
run: echo Set up is complete!
##########################################################################
prepare-chipyard-cores:
name: prepare-chipyard-cores
needs: setup-complete
runs-on: self-hosted
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Build RTL on self-hosted
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/prepare-rtl
with:
group-key: "group-cores"
- uses: ./.github/actions/job-end
prepare-chipyard-peripherals:
name: prepare-chipyard-peripherals
needs: setup-complete
runs-on: self-hosted
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Build RTL on self-hosted
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/prepare-rtl
with:
group-key: "group-peripherals"
- uses: ./.github/actions/job-end
prepare-chipyard-accels:
name: prepare-chipyard-accels
needs: setup-complete
runs-on: self-hosted
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Build RTL on self-hosted
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/prepare-rtl
with:
group-key: "group-accels"
- uses: ./.github/actions/job-end
prepare-chipyard-tracegen:
name: prepare-chipyard-tracegen
needs: setup-complete
runs-on: self-hosted
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Build RTL on self-hosted
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/prepare-rtl
with:
group-key: "group-tracegen"
- uses: ./.github/actions/job-end
prepare-chipyard-other:
name: prepare-chipyard-other
needs: setup-complete
runs-on: self-hosted
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Build RTL on self-hosted
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/prepare-rtl
with:
group-key: "group-other"
- uses: ./.github/actions/job-end
prepare-chipyard-fpga:
name: prepare-chipyard-fpga
needs: setup-complete
runs-on: self-hosted
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Build RTL on self-hosted
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/prepare-rtl
with:
group-key: "group-fpga"
build-type: "fpga"
- uses: ./.github/actions/job-end
##########################################################################
chipyard-rocket-run-tests:
name: chipyard-rocket-run-tests
needs: prepare-chipyard-cores
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "group-cores"
project-key: "chipyard-rocket"
- uses: ./.github/actions/job-end
chipyard-hetero-run-tests:
name: chipyard-hetero-run-tests
needs: prepare-chipyard-cores
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "group-cores"
project-key: "chipyard-hetero"
- uses: ./.github/actions/job-end
chipyard-boom-run-tests:
name: chipyard-boom-run-tests
needs: prepare-chipyard-cores
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "group-cores"
project-key: "chipyard-boom"
- uses: ./.github/actions/job-end
chipyard-cva6-run-tests:
name: chipyard-cva6-run-tests
needs: prepare-chipyard-cores
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "group-cores"
project-key: "chipyard-cva6"
- uses: ./.github/actions/job-end
chipyard-ibex-run-tests:
name: chipyard-ibex-run-tests
needs: prepare-chipyard-cores
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "group-cores"
project-key: "chipyard-ibex"
- uses: ./.github/actions/job-end
chipyard-sodor-run-tests:
name: chipyard-sodor-run-tests
needs: prepare-chipyard-cores
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "group-cores"
project-key: "chipyard-sodor"
- uses: ./.github/actions/job-end
chipyard-fftgenerator-run-tests:
name: chipyard-fftgenerator-run-tests
needs: prepare-chipyard-accels
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "group-accels"
project-key: "chipyard-fftgenerator"
- uses: ./.github/actions/job-end
chipyard-dmirocket-run-tests:
name: chipyard-dmirocket-run-tests
needs: prepare-chipyard-peripherals
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "group-peripherals"
project-key: "chipyard-dmirocket"
- uses: ./.github/actions/job-end
chipyard-spiflashwrite-run-tests:
name: chipyard-spiflashwrite-run-tests
needs: prepare-chipyard-peripherals
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "group-peripherals"
project-key: "chipyard-spiflashwrite"
- uses: ./.github/actions/job-end
chipyard-spiflashread-run-tests:
name: chipyard-spiflashread-run-tests
needs: prepare-chipyard-peripherals
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "group-peripherals"
project-key: "chipyard-spiflashread"
- uses: ./.github/actions/job-end
chipyard-lbwif-run-tests:
name: chipyard-lbwif-run-tests
needs: prepare-chipyard-peripherals
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "group-peripherals"
project-key: "chipyard-lbwif"
- uses: ./.github/actions/job-end
chipyard-sha3-run-tests:
name: chipyard-sha3-run-tests
needs: prepare-chipyard-accels
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "group-accels"
project-key: "chipyard-sha3"
- uses: ./.github/actions/job-end
chipyard-streaming-fir-run-tests:
name: chipyard-streaming-fir-run-tests
needs: prepare-chipyard-accels
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "group-accels"
project-key: "chipyard-streaming-fir"
- uses: ./.github/actions/job-end
chipyard-streaming-passthrough-run-tests:
name: chipyard-streaming-passthrough-run-tests
needs: prepare-chipyard-accels
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "group-accels"
project-key: "chipyard-streaming-passthrough"
- uses: ./.github/actions/job-end
chipyard-hwacha-run-tests:
name: chipyard-hwacha-run-tests
needs: prepare-chipyard-accels
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "group-accels"
project-key: "chipyard-hwacha"
- uses: ./.github/actions/job-end
chipyard-gemmini-run-tests:
name: chipyard-gemmini-run-tests
needs: prepare-chipyard-accels
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "group-accels"
project-key: "chipyard-gemmini"
- uses: ./.github/actions/job-end
chipyard-nvdla-run-tests:
name: chipyard-nvdla-run-tests
needs: prepare-chipyard-accels
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "group-accels"
project-key: "chipyard-nvdla"
- uses: ./.github/actions/job-end
tracegen-boom-run-tests:
name: tracegen-boom-run-tests
needs: prepare-chipyard-tracegen
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "group-tracegen"
project-key: "tracegen-boom"
- uses: ./.github/actions/job-end
tracegen-run-tests:
name: tracegen-run-tests
needs: prepare-chipyard-tracegen
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "group-tracegen"
project-key: "tracegen"
- uses: ./.github/actions/job-end
icenet-run-tests:
name: icenet-run-tests
needs: prepare-chipyard-other
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "group-other"
project-key: "icenet"
- uses: ./.github/actions/job-end
testchipip-run-tests:
name: testchipip-run-tests
needs: prepare-chipyard-other
runs-on: ubuntu-latest
container:
image: ucbbar/chipyard-ci-image:554b436
options: --entrypoint /bin/bash
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "group-other"
project-key: "testchipip"
- uses: ./.github/actions/job-end
firesim-run-tests:
name: firesim-run-tests
needs: setup-complete
runs-on: self-hosted
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests on self-hosted
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "extra-tests"
project-key: "firesim"
run-script: "remote-run-firesim-scala-tests.sh"
- uses: ./.github/actions/job-end
fireboom-run-tests:
name: fireboom-run-tests
needs: setup-complete
runs-on: self-hosted
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests on self-hosted
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "extra-tests"
project-key: "fireboom"
run-script: "remote-run-firesim-scala-tests.sh"
- uses: ./.github/actions/job-end
firesim-multiclock-run-tests:
name: firesim-multiclock-run-tests
needs: setup-complete
runs-on: self-hosted
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: ./.github/actions/job-start
id: job-start
- name: Run tests on self-hosted
if: steps.job-start.outputs.run_result != 'success'
uses: ./.github/actions/run-tests
with:
group-key: "extra-tests"
project-key: "firesim-multiclock"
run-script: "remote-run-firesim-scala-tests.sh"
- uses: ./.github/actions/job-end
# Sentinel job to simplify how we specify which checks need to pass in branch
# protection and in Mergify
#
# When adding new top level jobs, please add them to `needs` below
all_tests_passed:
name: "all tests passed"
needs: [commit-on-master-check, tutorial-setup-check, documentation-check,
chipyard-rocket-run-tests, chipyard-hetero-run-tests, chipyard-boom-run-tests, chipyard-cva6-run-tests, chipyard-ibex-run-tests,
chipyard-sodor-run-tests, chipyard-dmirocket-run-tests, chipyard-spiflashwrite-run-tests, chipyard-fftgenerator-run-tests,
chipyard-spiflashread-run-tests, chipyard-lbwif-run-tests, chipyard-sha3-run-tests,
chipyard-streaming-fir-run-tests, chipyard-streaming-passthrough-run-tests, chipyard-hwacha-run-tests,
chipyard-gemmini-run-tests, chipyard-nvdla-run-tests,
tracegen-boom-run-tests, tracegen-run-tests,
icenet-run-tests, testchipip-run-tests,
prepare-chipyard-fpga,
firesim-run-tests, fireboom-run-tests, firesim-multiclock-run-tests]
runs-on: ubuntu-latest
steps:
- run: echo Success!

64
.gitmodules vendored
View File

@@ -1,42 +1,47 @@
[submodule "rocket-chip"]
path = generators/rocket-chip
url = https://github.com/ucb-bar/rocket-chip.git
url = https://github.com/chipsalliance/rocket-chip.git
shallow = true
[submodule "testchipip"]
path = generators/testchipip
url = https://github.com/ucb-bar/testchipip.git
shallow = true
[submodule "barstools"]
path = tools/barstools
url = https://github.com/ucb-bar/barstools.git
[submodule "tools/chisel3"]
path = tools/chisel3
url = https://github.com/freechipsproject/chisel3.git
[submodule "tools/firrtl"]
path = tools/firrtl
url = https://github.com/freechipsproject/firrtl
shallow = true
[submodule "tools/torture"]
path = tools/torture
url = https://github.com/ucb-bar/riscv-torture.git
shallow = true
[submodule "generators/boom"]
path = generators/boom
url = https://github.com/riscv-boom/riscv-boom.git
shallow = true
[submodule "generators/sifive-blocks"]
path = generators/sifive-blocks
url = https://github.com/sifive/sifive-blocks.git
shallow = true
[submodule "generators/hwacha"]
path = generators/hwacha
url = https://github.com/ucb-bar/hwacha.git
shallow = true
[submodule "sims/firesim"]
path = sims/firesim
url = https://github.com/firesim/firesim.git
shallow = true
[submodule "generators/icenet"]
path = generators/icenet
url = https://github.com/firesim/icenet.git
shallow = true
[submodule "generators/block-inclusivecache-sifive"]
path = generators/sifive-cache
url = https://github.com/sifive/block-inclusivecache-sifive.git
shallow = true
[submodule "toolchains/riscv-tools/riscv-gnu-toolchain"]
path = toolchains/riscv-tools/riscv-gnu-toolchain
url = https://github.com/riscv/riscv-gnu-toolchain.git
shallow = true
[submodule "toolchains/riscv-tools/riscv-gnu-toolchain-prebuilt"]
path = toolchains/riscv-tools/riscv-gnu-toolchain-prebuilt
url = https://github.com/ucb-bar/chipyard-toolchain-prebuilt.git
@@ -44,99 +49,132 @@
[submodule "toolchains/riscv-tools/riscv-isa-sim"]
path = toolchains/riscv-tools/riscv-isa-sim
url = https://github.com/riscv/riscv-isa-sim.git
shallow = true
[submodule "toolchains/riscv-tools/riscv-pk"]
path = toolchains/riscv-tools/riscv-pk
url = https://github.com/riscv/riscv-pk.git
shallow = true
[submodule "toolchains/riscv-tools/riscv-tests"]
path = toolchains/riscv-tools/riscv-tests
url = https://github.com/riscv/riscv-tests.git
shallow = true
[submodule "toolchains/riscv-tools/riscv-openocd"]
path = toolchains/riscv-tools/riscv-openocd
url = https://github.com/riscv/riscv-openocd.git
shallow = true
[submodule "toolchains/esp-tools/riscv-gnu-toolchain"]
path = toolchains/esp-tools/riscv-gnu-toolchain
url = https://github.com/ucb-bar/esp-gnu-toolchain.git
shallow = true
[submodule "toolchains/esp-tools/riscv-isa-sim"]
path = toolchains/esp-tools/riscv-isa-sim
url = https://github.com/ucb-bar/esp-isa-sim.git
shallow = true
[submodule "toolchains/esp-tools/riscv-pk"]
path = toolchains/esp-tools/riscv-pk
url = https://github.com/riscv/riscv-pk.git
shallow = true
[submodule "toolchains/esp-tools/riscv-tests"]
path = toolchains/esp-tools/riscv-tests
url = https://github.com/ucb-bar/esp-tests.git
shallow = true
[submodule "toolchains/libgloss"]
path = toolchains/libgloss
url = https://github.com/ucb-bar/libgloss-htif.git
shallow = true
[submodule "vlsi/hammer"]
path = vlsi/hammer
url = https://github.com/ucb-bar/hammer.git
shallow = true
[submodule "tools/dsptools"]
path = tools/dsptools
url = https://github.com/ucb-bar/dsptools.git
shallow = true
[submodule "tools/chisel-testers"]
path = tools/chisel-testers
url = https://github.com/freechipsproject/chisel-testers.git
[submodule "tools/treadle"]
path = tools/treadle
url = https://github.com/freechipsproject/treadle.git
shallow = true
[submodule "generators/sha3"]
path = generators/sha3
url = https://github.com/ucb-bar/sha3.git
[submodule "tools/firrtl-interpreter"]
path = tools/firrtl-interpreter
url = https://github.com/freechipsproject/firrtl-interpreter.git
shallow = true
[submodule "vlsi/hammer-cadence-plugins"]
path = vlsi/hammer-cadence-plugins
url = https://github.com/ucb-bar/hammer-cadence-plugins.git
shallow = true
[submodule "vlsi/hammer-synopsys-plugins"]
path = vlsi/hammer-synopsys-plugins
url = https://github.com/ucb-bar/hammer-synopsys-plugins.git
shallow = true
[submodule "vlsi/hammer-mentor-plugins"]
path = vlsi/hammer-mentor-plugins
url = https://github.com/ucb-bar/hammer-mentor-plugins.git
shallow = true
[submodule "toolchains/qemu"]
path = toolchains/qemu
url = https://github.com/qemu/qemu.git
shallow = true
[submodule "tools/axe"]
path = tools/axe
url = https://github.com/CTSRD-CHERI/axe.git
shallow = true
[submodule "software/spec2017"]
path = software/spec2017
url = https://github.com/ucb-bar/spec2017-workload.git
shallow = true
[submodule "software/coremark"]
path = software/coremark
url = https://github.com/ucb-bar/coremark-workload.git
shallow = true
[submodule "generators/gemmini"]
path = generators/gemmini
url = https://github.com/ucb-bar/gemmini
shallow = true
[submodule "software/firemarshal"]
path = software/firemarshal
url = https://github.com/firesim/FireMarshal.git
shallow = true
[submodule "generators/cva6"]
path = generators/cva6
url = https://github.com/ucb-bar/cva6-wrapper.git
shallow = true
[submodule "tools/DRAMSim2"]
path = tools/DRAMSim2
url = https://github.com/firesim/DRAMSim2.git
shallow = true
[submodule "generators/nvdla"]
path = generators/nvdla
url = https://github.com/ucb-bar/nvdla-wrapper.git
shallow = true
[submodule "software/nvdla-workload"]
path = software/nvdla-workload
url = https://github.com/ucb-bar/nvdla-workload.git
shallow = true
[submodule "tools/dromajo/dromajo-src"]
path = tools/dromajo/dromajo-src
url = https://github.com/riscv-boom/dromajo.git
shallow = true
[submodule "generators/riscv-sodor"]
path = generators/riscv-sodor
url = https://github.com/ucb-bar/riscv-sodor.git
shallow = true
[submodule "fpga/fpga-shells"]
path = fpga/fpga-shells
url = https://github.com/sifive/fpga-shells.git
shallow = true
[submodule "tools/api-config-chipsalliance"]
path = tools/api-config-chipsalliance
url = https://github.com/chipsalliance/api-config-chipsalliance.git
shallow = true
[submodule "tools/rocket-dsp-utils"]
path = tools/rocket-dsp-utils
url = https://github.com/ucb-bar/rocket-dsp-utils
shallow = true
[submodule "generators/ibex"]
path = generators/ibex
url = https://github.com/ucb-bar/ibex-wrapper
shallow = true
[submodule "generators/fft-generator"]
path = generators/fft-generator
url = https://github.com/ucb-bar/FFTGenerator.git
shallow = true

View File

@@ -1,7 +1,16 @@
version: 2
build:
os: ubuntu-20.04
tools:
python: "3.6"
formats: all
sphinx:
configuration: docs/conf.py
configuration: docs/conf.py
fail_on_warning: true
python:
install:
- requirements: docs/requirements.txt
install:
- requirements: docs/requirements.txt

View File

@@ -1,2 +0,0 @@
-Dsbt.sourcemode=true
-Dsbt.workspace=$PWD/tools

View File

@@ -2,6 +2,61 @@
This changelog follows the format defined here: https://keepachangelog.com/en/1.0.0/
## [1.6.0] - 2022-02-15
A more detailed account of everything included is included in the dev to master PR for this release: https://github.com/ucb-bar/chipyard/pull/913
### Added
* Diplomatic IOBinder-like approach to setting up PRCI across different deployment targets (#900)
* Default set of MMIO-controlled reset-setters and clock-gaters (#900)
* Added simulation makefile options `torture` and `torture-overnight` for running Torture (#992)
* FSDB waveform support (#1072, #1102)
* Use GitHub Actions for CI (#1004, #999, #1090, #1092)
* Add MAKE variable in `build-toolchains.sh` (#1021)
* Cleanup GH issue and PR templates (#1029, #1032)
* Add support for Ibex core (#979)
* Add system bus width fragment (#1071)
* Add support for FSDB waveform files (#1072, #1102)
* Document simulator timeout settings (#1094)
* Add FFT Generator (#1067)
* Add waveforms for post-PNR and power (#1108)
* Have PRCI control registers use clock of corresponding bus (#1109)
* Add check to verify that user is running on tagged release (#1114)
* Hammer tutorial in Sky130 (#1115)
### Changed
* Bump CVA6 (#909 )
* Bump Hammer tutorial for ASAP7 r1p7 (#934)
* Use Published Chisel, FIRRTL, Treadle, FIRRTLInterpreter packages instead of building from source. #1054
* Change serialTL width to 32. Speeds up simulations (#1040)
* Update how sbt flag is overridden (by using `SBT_BIN` variable) (#1041)
* Use published dependencies for Chisel, FIRRTL, Treadle, and FIRRTLInterpreter (#1054)
* Split `ConfigFragments.scala` into multiple files (with more organization) (#1061)
* Avoid initializing nvdla software by default (#1063)
* Update ASAP to 1.7 in Hammer (#934)
* Shorten Gemmini docs and point to repo (#1078)
* Bump Gemmini to 0.6.2 (#1083)
* Use python2 for tracegen script (#1107)
* Bump to Chisel/FIRRTL 3.5.1 (#1060, #1113)
* Bump to FireMarshal 1.12.1 (#1116)
* Bump to FireSim 1.13.0 (#1118 )
### Fixed
* Fix UART portmap for Arty (#968)
* Support changing make variable `MODEL` from the cmdline (#1030)
* Force FIRRTL to 1.4.1 (#1052)
* Fix MMIO IOBinder (#1045)
* Mask `fd` warning when running make (#1057)
* Fix Sodor 5-stage hazard check (#1086)
* Fix Sodor val io issue (#1089)
* Fix BOOM reference in Readme (#1104)
* Fix waveforms for post-P&R power analysis (#1108)
### Removed
* Remove duplicate `WithUARTIOCells` fragment (#1047)
* Remove MaxPermSize in java variables (#1082)
* Remove support for CircleCI (#1105)
## [1.5.0] - 2021-06-13
A more detailed account of everything included is included in the dev to master PR for this release: https://github.com/ucb-bar/chipyard/pull/773
@@ -9,7 +64,7 @@ A more detailed account of everything included is included in the dev to master
### Added
* FireMarshal support for FPGA prototypes (#849)
* Hammer update to include power estimation flows, rail analysis, hierarchical sim support, and improved ASAP7 plugin with dummy SRAMs (#886)
* Docker image
* Docker image
* Support specifying architecture when building tools. (#802)
* Add Config fragments: WithMultiRoCCFromBuildRoCC, PMP (#809, #821)
* Add support for simulating an AXI memory interface over the default TL serial link (#812)
@@ -22,7 +77,7 @@ A more detailed account of everything included is included in the dev to master
* FireSim bump to version 1.12
* FireMarshal bump to version 1.12
* Changes default FireSim frequency from 3.2 GHz (dual clock domains) to 1 GHz (single clock domain)
* Bump pygments from 2.2.0 to 2.7.4 in docs
* Bump pygments from 2.2.0 to 2.7.4 in docs
* Hammer tutorial example is now a TinyRocketConfig (#886)
* Sha3 Spike model moved from sha3 repo to esp-isa-sim

View File

@@ -3,6 +3,6 @@ Contributing to Chipyard
### Branch management:
1) github:com/ucb-bar/chipyard: master = stable release. All merges to master must go through PR.
2) github:com/ucb-bar/chipyard: dev = pre-release non-stable branch with latest features. All merges to dev must go through PR.
3) Other dependencies pointed at by Chipyard (e.g. firesim, boom): master should be the version submoduled in ucb-bar/chipyard master.
1) github:com/ucb-bar/chipyard: main = pre-release non-stable branch with latest features. All merges to main must go through PR.
2) github:com/ucb-bar/chipyard: specific tag = official chipyard release.
3) Other dependencies pointed at by Chipyard (e.g. firesim, boom): master/main should be the version submoduled in ucb-bar/chipyard main.

View File

@@ -1,10 +1,16 @@
![CHIPYARD](https://github.com/ucb-bar/chipyard/raw/master/docs/_static/images/chipyard-logo-full.png)
# Chipyard Framework [![CircleCI](https://circleci.com/gh/ucb-bar/chipyard/tree/master.svg?style=svg)](https://circleci.com/gh/ucb-bar/chipyard/tree/master)
# Chipyard Framework [![Test](https://github.com/ucb-bar/chipyard/workflows/chipyard-ci-process/badge.svg?style=svg)](https://github.com/ucb-bar/chipyard/actions)
## Quick Links
* **STABLE DOCUMENTATION**: https://chipyard.readthedocs.io/
* **USER QUESTION FORUM**: https://groups.google.com/forum/#!forum/chipyard
* **BUGS AND FEATURE-REQUESTS**: https://github.com/ucb-bar/chipyard/issues
## Using Chipyard
To get started using Chipyard, see the documentation on the Chipyard documentation site: https://chipyard.readthedocs.io/
To get started using Chipyard, see the stable documentation on the Chipyard documentation site: https://chipyard.readthedocs.io/
## What is Chipyard
@@ -16,14 +22,15 @@ Chipyard is actively developed in the [Berkeley Architecture Research Group][ucb
## Resources
* Chipyard Documentation: https://chipyard.readthedocs.io/
* Chipyard Basics slides: https://fires.im/micro19-slides-pdf/02_chipyard_basics.pdf
* Chipyard Tutorial Exercise slides: https://fires.im/micro19-slides-pdf/03_building_custom_socs.pdf
* Chipyard Stable Documentation: https://chipyard.readthedocs.io/
* Chipyard (x FireSim) Tutorial: https://fires.im/tutorial
* Chipyard Basics slides: https://fires.im/micro21-slides-pdf/02_chipyard_basics.pdf
* Chipyard Tutorial Exercise slides: https://fires.im/micro21-slides-pdf/03_building_custom_socs.pdf
## Need help?
* Join the Chipyard Mailing List: https://groups.google.com/forum/#!forum/chipyard
* If you find a bug, post an issue on this repo
* If you find a bug or would like propose a feature, post an issue on this repo: https://github.com/ucb-bar/chipyard/issues
## Contributing
@@ -56,7 +63,7 @@ These additional publications cover many of the internal components used in Chip
* **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).
* **BOOM**: C. Celio, et al., *Hot Chips 30*. [PDF](https://old.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).
* **COBRA (BOOM Branch Prediction)**: J. Zhao, et al., *ISPASS'21*. [PDF](https://ieeexplore.ieee.org/document/9408173).
* **Hwacha**: Y. Lee, et al., *ESSCIRC'14*. [PDF](http://hwacha.org/papers/riscv-esscirc2014.pdf).

163
build.sbt
View File

@@ -6,10 +6,10 @@ lazy val chipyardRoot = Project("chipyardRoot", file("."))
lazy val commonSettings = Seq(
organization := "edu.berkeley.cs",
version := "1.3",
version := "1.6",
scalaVersion := "2.12.10",
test in assembly := {},
assemblyMergeStrategy in assembly := { _ match {
assembly / test := {},
assembly / assemblyMergeStrategy := { _ match {
case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard
case _ => MergeStrategy.first}},
scalacOptions ++= Seq("-deprecation","-unchecked","-Xsource:2.11"),
@@ -17,14 +17,7 @@ lazy val commonSettings = Seq(
unmanagedBase := (chipyardRoot / unmanagedBase).value,
allDependencies := {
// drop specific maven dependencies in subprojects in favor of Chipyard's version
val dropDeps = Seq(
("edu.berkeley.cs", "firrtl"),
("edu.berkeley.cs", "chisel3"),
("edu.berkeley.cs", "rocketchip"),
("edu.berkeley.cs", "chisel-iotesters"),
("edu.berkeley.cs", "treadle"),
("edu.berkeley.cs", "firrtl-interpreter"))
val dropDeps = Seq(("edu.berkeley.cs", "rocketchip"))
allDependencies.value.filterNot { dep =>
dropDeps.contains((dep.organization, dep.name))
}
@@ -55,8 +48,8 @@ lazy val firesimDir = if (firesimAsLibrary) {
def freshProject(name: String, dir: File): Project = {
Project(id = name, base = dir / "src")
.settings(
scalaSource in Compile := baseDirectory.value / "main" / "scala",
resourceDirectory in Compile := baseDirectory.value / "main" / "resources"
Compile / scalaSource := baseDirectory.value / "main" / "scala",
Compile / resourceDirectory := baseDirectory.value / "main" / "resources"
)
}
@@ -67,34 +60,27 @@ def isolateAllTests(tests: Seq[TestDefinition]) = tests map { test =>
new Group(test.name, Seq(test), SubProcess(options))
} toSeq
val chiselVersion = "3.5.1"
lazy val chiselSettings = Seq(
libraryDependencies ++= Seq("edu.berkeley.cs" %% "chisel3" % chiselVersion),
addCompilerPlugin("edu.berkeley.cs" % "chisel3-plugin" % chiselVersion cross CrossVersion.full))
val firrtlVersion = "1.5.1"
lazy val firrtlSettings = Seq(libraryDependencies ++= Seq("edu.berkeley.cs" %% "firrtl" % firrtlVersion))
val chiselTestVersion = "2.5.1"
lazy val chiselTestSettings = Seq(libraryDependencies ++= Seq("edu.berkeley.cs" %% "chisel-iotesters" % chiselTestVersion))
// Subproject definitions begin
// -- Rocket Chip --
// This needs to stay in sync with the chisel3 and firrtl git submodules
val chiselVersion = "3.4.1"
lazy val chiselRef = ProjectRef(workspaceDirectory / "chisel3", "chisel")
lazy val chiselLib = "edu.berkeley.cs" %% "chisel3" % chiselVersion
lazy val chiselLibDeps = (chiselRef / Keys.libraryDependencies)
// While not built from source, *must* be in sync with the chisel3 git submodule
// Building from source requires extending sbt-sriracha or a similar plugin and
// keeping scalaVersion in sync with chisel3 to the minor version
lazy val chiselPluginLib = "edu.berkeley.cs" % "chisel3-plugin" % chiselVersion cross CrossVersion.full
val firrtlVersion = "1.4.1"
lazy val firrtlRef = ProjectRef(workspaceDirectory / "firrtl", "firrtl")
lazy val firrtlLib = "edu.berkeley.cs" %% "firrtl" % firrtlVersion
val firrtlLibDeps = settingKey[Seq[sbt.librarymanagement.ModuleID]]("FIRRTL Library Dependencies sans antlr4")
Global / firrtlLibDeps := {
// drop antlr4 compile dep. but keep antlr4-runtime dep. (compile needs the plugin to be setup)
(firrtlRef / Keys.libraryDependencies).value.filterNot(_.name == "antlr4")
}
// Rocket-chip dependencies (subsumes making RC a RootProject)
// Rocket-chip dependencies (subsumes making RC a RootProject)
lazy val hardfloat = (project in rocketChipDir / "hardfloat")
.sourceDependency(chiselRef, chiselLib)
.settings(addCompilerPlugin(chiselPluginLib))
.settings(libraryDependencies ++= chiselLibDeps.value)
.settings(chiselSettings)
.dependsOn(midasTargetUtils)
.settings(commonSettings)
.settings(
@@ -126,11 +112,9 @@ lazy val rocketConfig = (project in rocketChipDir / "api-config-chipsalliance/bu
)
lazy val rocketchip = freshProject("rocketchip", rocketChipDir)
.sourceDependency(chiselRef, chiselLib)
.settings(addCompilerPlugin(chiselPluginLib))
.settings(libraryDependencies ++= chiselLibDeps.value)
.dependsOn(hardfloat, rocketMacros, rocketConfig)
.settings(commonSettings)
.settings(chiselSettings)
.settings(
libraryDependencies ++= Seq(
"org.scala-lang" % "scala-reflect" % scalaVersion.value,
@@ -145,32 +129,9 @@ lazy val rocketchip = freshProject("rocketchip", rocketChipDir)
)
lazy val rocketLibDeps = (rocketchip / Keys.libraryDependencies)
// -- Chipyard-managed External Projects --
lazy val firrtl_interpreter = (project in file("tools/firrtl-interpreter"))
.sourceDependency(firrtlRef, firrtlLib)
.settings(commonSettings)
.settings(libraryDependencies ++= (Global / firrtlLibDeps).value)
lazy val firrtlInterpreterLibDeps = (firrtl_interpreter / Keys.libraryDependencies)
lazy val treadle = (project in file("tools/treadle"))
.sourceDependency(firrtlRef, firrtlLib)
.settings(commonSettings)
.settings(libraryDependencies ++= (Global / firrtlLibDeps).value)
lazy val treadleLibDeps = (treadle / Keys.libraryDependencies)
lazy val chisel_testers = (project in file("tools/chisel-testers"))
.sourceDependency(chiselRef, chiselLib)
.settings(addCompilerPlugin(chiselPluginLib))
.settings(libraryDependencies ++= chiselLibDeps.value)
.dependsOn(firrtl_interpreter, treadle)
.settings(libraryDependencies ++= firrtlInterpreterLibDeps.value)
.settings(libraryDependencies ++= treadleLibDeps.value)
.settings(commonSettings)
lazy val chiselTestersLibDeps = (chisel_testers / Keys.libraryDependencies)
// -- Normal Projects --
// Contains annotations & firrtl passes you may wish to use in rocket-chip without
// introducing a circular dependency between RC and MIDAS
lazy val midasTargetUtils = ProjectRef(firesimDir, "targetutils")
@@ -179,26 +140,27 @@ lazy val testchipip = (project in file("generators/testchipip"))
.dependsOn(rocketchip, sifive_blocks)
.settings(libraryDependencies ++= rocketLibDeps.value)
.settings(commonSettings)
lazy val testchipipLib = "edu.berkeley.cs" %% "testchipip" % "1.0-020719-SNAPSHOT"
lazy val chipyard = (project in file("generators/chipyard"))
.sourceDependency(testchipip, testchipipLib)
.dependsOn(rocketchip, boom, hwacha, sifive_blocks, sifive_cache, iocell,
.dependsOn(testchipip, rocketchip, boom, hwacha, sifive_blocks, sifive_cache, iocell,
sha3, // On separate line to allow for cleaner tutorial-setup patches
dsptools, `rocket-dsp-utils`,
gemmini, icenet, tracegen, cva6, nvdla, sodor)
gemmini, icenet, tracegen, cva6, nvdla, sodor, ibex, fft_generator)
.settings(libraryDependencies ++= rocketLibDeps.value)
.settings(commonSettings)
lazy val fft_generator = (project in file("generators/fft-generator"))
.dependsOn(rocketchip, `rocket-dsp-utils`)
.settings(libraryDependencies ++= rocketLibDeps.value)
.settings(commonSettings)
lazy val tracegen = (project in file("generators/tracegen"))
.sourceDependency(testchipip, testchipipLib)
.dependsOn(rocketchip, sifive_cache, boom)
.dependsOn(testchipip, rocketchip, sifive_cache, boom)
.settings(libraryDependencies ++= rocketLibDeps.value)
.settings(commonSettings)
lazy val icenet = (project in file("generators/icenet"))
.sourceDependency(testchipip, testchipipLib)
.dependsOn(rocketchip)
.dependsOn(testchipip, rocketchip)
.settings(libraryDependencies ++= rocketLibDeps.value)
.settings(commonSettings)
@@ -208,8 +170,7 @@ lazy val hwacha = (project in file("generators/hwacha"))
.settings(commonSettings)
lazy val boom = (project in file("generators/boom"))
.sourceDependency(testchipip, testchipipLib)
.dependsOn(rocketchip)
.dependsOn(testchipip, rocketchip)
.settings(libraryDependencies ++= rocketLibDeps.value)
.settings(commonSettings)
@@ -218,22 +179,26 @@ lazy val cva6 = (project in file("generators/cva6"))
.settings(libraryDependencies ++= rocketLibDeps.value)
.settings(commonSettings)
lazy val ibex = (project in file("generators/ibex"))
.dependsOn(rocketchip)
.settings(libraryDependencies ++= rocketLibDeps.value)
.settings(commonSettings)
lazy val sodor = (project in file("generators/riscv-sodor"))
.dependsOn(rocketchip)
.settings(libraryDependencies ++= rocketLibDeps.value)
.settings(commonSettings)
lazy val sha3 = (project in file("generators/sha3"))
.dependsOn(rocketchip, chisel_testers, midasTargetUtils)
.dependsOn(rocketchip, midasTargetUtils)
.settings(libraryDependencies ++= rocketLibDeps.value)
.settings(libraryDependencies ++= chiselTestersLibDeps.value)
.settings(chiselTestSettings)
.settings(commonSettings)
lazy val gemmini = (project in file("generators/gemmini"))
.sourceDependency(testchipip, testchipipLib)
.dependsOn(rocketchip, chisel_testers)
.dependsOn(testchipip, rocketchip)
.settings(libraryDependencies ++= rocketLibDeps.value)
.settings(libraryDependencies ++= chiselTestersLibDeps.value)
.settings(chiselTestSettings)
.settings(commonSettings)
lazy val nvdla = (project in file("generators/nvdla"))
@@ -241,40 +206,30 @@ lazy val nvdla = (project in file("generators/nvdla"))
.settings(libraryDependencies ++= rocketLibDeps.value)
.settings(commonSettings)
lazy val iocell = (project in file("./tools/barstools/iocell/"))
.sourceDependency(chiselRef, chiselLib)
.settings(addCompilerPlugin(chiselPluginLib))
.settings(libraryDependencies ++= chiselLibDeps.value)
lazy val iocell = Project(id = "iocell", base = file("./tools/barstools/") / "src")
.settings(
Compile / scalaSource := baseDirectory.value / "main" / "scala" / "barstools" / "iocell",
Compile / resourceDirectory := baseDirectory.value / "main" / "resources"
)
.settings(chiselSettings)
.settings(commonSettings)
lazy val tapeout = (project in file("./tools/barstools/tapeout/"))
.dependsOn(chisel_testers, chipyard) // must depend on chipyard to get scala resources
.settings(libraryDependencies ++= chiselTestersLibDeps.value)
.settings(commonSettings)
lazy val mdf = (project in file("./tools/barstools/mdf/scalalib/"))
.settings(commonSettings)
lazy val barstoolsMacros = (project in file("./tools/barstools/macros/"))
.sourceDependency(chiselRef, chiselLib)
.settings(addCompilerPlugin(chiselPluginLib))
.settings(libraryDependencies ++= chiselLibDeps.value)
.dependsOn(firrtl_interpreter, mdf, chisel_testers)
.settings(libraryDependencies ++= chiselTestersLibDeps.value)
.settings(libraryDependencies ++= firrtlInterpreterLibDeps.value)
lazy val tapeout = (project in file("./tools/barstools/"))
.settings(chiselSettings)
.settings(chiselTestSettings)
.enablePlugins(sbtassembly.AssemblyPlugin)
.settings(commonSettings)
lazy val dsptools = freshProject("dsptools", file("./tools/dsptools"))
.dependsOn(chisel_testers)
.settings(libraryDependencies ++= chiselTestersLibDeps.value)
.settings(
chiselSettings,
chiselTestSettings,
commonSettings,
libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "3.2.+" % "test",
"org.typelevel" %% "spire" % "0.16.2",
"org.scalanlp" %% "breeze" % "1.1",
"junit" % "junit" % "4.13" % "test",
"org.scalatest" %% "scalatest" % "3.0.+" % "test",
"org.scalacheck" %% "scalacheck" % "1.14.3" % "test",
))
@@ -299,7 +254,7 @@ lazy val sifive_blocks = (project in file("generators/sifive-blocks"))
lazy val sifive_cache = (project in file("generators/sifive-cache"))
.settings(
commonSettings,
scalaSource in Compile := baseDirectory.value / "design/craft")
Compile / scalaSource := baseDirectory.value / "design/craft")
.dependsOn(rocketchip)
.settings(libraryDependencies ++= rocketLibDeps.value)
@@ -308,12 +263,12 @@ lazy val midas = ProjectRef(firesimDir, "midas")
lazy val firesimLib = ProjectRef(firesimDir, "firesimLib")
lazy val firechip = (project in file("generators/firechip"))
.sourceDependency(testchipip, testchipipLib)
.dependsOn(chipyard, midasTargetUtils, midas, firesimLib % "test->test;compile->compile")
.settings(
chiselSettings,
commonSettings,
testGrouping in Test := isolateAllTests( (definedTests in Test).value ),
testOptions in Test += Tests.Argument("-oF")
Test / testGrouping := isolateAllTests( (Test / definedTests).value ),
Test / testOptions += Tests.Argument("-oF")
)
lazy val fpga_shells = (project in file("./fpga/fpga-shells"))
.dependsOn(rocketchip, sifive_blocks)

View File

@@ -18,7 +18,9 @@ HELP_COMPILATION_VARIABLES += \
" EXTRA_SIM_LDFLAGS = additional LDFLAGS for building simulators" \
" EXTRA_SIM_SOURCES = additional simulation sources needed for simulator" \
" EXTRA_SIM_REQS = additional make requirements to build the simulator" \
" ENABLE_SBT_THIN_CLIENT = if set, use sbt's experimental thin client (works best with sbtn or sbt script)"
" ENABLE_SBT_THIN_CLIENT = if set, use sbt's experimental thin client (works best when overridding SBT_BIN with the mainline sbt script)" \
" EXTRA_CHISEL_OPTIONS = additional options to pass to the Chisel compiler" \
" EXTRA_FIRRTL_OPTIONS = additional options to pass to the FIRRTL compiler"
EXTRA_GENERATOR_REQS ?= $(BOOTROM_TARGETS)
EXTRA_SIM_CXXFLAGS ?=
@@ -29,7 +31,8 @@ EXTRA_SIM_REQS ?=
#----------------------------------------------------------------------------
HELP_SIMULATION_VARIABLES += \
" EXTRA_SIM_FLAGS = additional runtime simulation flags (passed within +permissive)" \
" NUMACTL = set to '1' to wrap simulator in the appropriate numactl command"
" NUMACTL = set to '1' to wrap simulator in the appropriate numactl command" \
" BREAK_SIM_PREREQ = when running a binary, doesn't rebuild RTL on source changes"
EXTRA_SIM_FLAGS ?=
NUMACTL ?= 0
@@ -38,13 +41,14 @@ NUMA_PREFIX = $(if $(filter $(NUMACTL),0),,$(shell $(base_dir)/scripts/numa_pref
#----------------------------------------------------------------------------
HELP_COMMANDS += \
" run-binary = run [./$(shell basename $(sim))] and log instructions to file" \
" run-binary-fast = run [./$(shell basename $(sim))] and don't log instructions" \
" run-binary-debug = run [./$(shell basename $(sim_debug))] and log instructions and waveform to files" \
" verilog = generate intermediate verilog files from chisel elaboration and firrtl passes" \
" firrtl = generate intermediate firrtl files from chisel elaboration" \
" run-tests = run all assembly and benchmark tests" \
" launch-sbt = start sbt terminal"
" run-binary = run [./$(shell basename $(sim))] and log instructions to file" \
" run-binary-fast = run [./$(shell basename $(sim))] and don't log instructions" \
" run-binary-debug = run [./$(shell basename $(sim_debug))] and log instructions and waveform to files" \
" verilog = generate intermediate verilog files from chisel elaboration and firrtl passes" \
" firrtl = generate intermediate firrtl files from chisel elaboration" \
" run-tests = run all assembly and benchmark tests" \
" launch-sbt = start sbt terminal" \
" {shutdown,start}-sbt-server = shutdown or start sbt server if using ENABLE_SBT_THIN_CLIENT" \
#########################################################################################
# include additional subproject make fragments
@@ -54,19 +58,20 @@ include $(base_dir)/generators/cva6/cva6.mk
include $(base_dir)/generators/tracegen/tracegen.mk
include $(base_dir)/generators/nvdla/nvdla.mk
include $(base_dir)/tools/dromajo/dromajo.mk
include $(base_dir)/tools/torture.mk
#########################################################################################
# Prerequisite lists
#########################################################################################
# Returns a list of files in directory $1 with file extension $2.
# If available, use 'fd' to find the list of files, which is faster than 'find'.
ifeq ($(shell which fd),)
ifeq ($(shell which fd 2> /dev/null),)
lookup_srcs = $(shell find -L $(1)/ -name target -prune -o -iname "*.$(2)" -print 2> /dev/null)
else
lookup_srcs = $(shell fd -L ".*\.$(2)" $(1))
endif
SOURCE_DIRS = $(addprefix $(base_dir)/,generators sims/firesim/sim tools/barstools/iocell fpga/fpga-shells fpga/src)
SOURCE_DIRS = $(addprefix $(base_dir)/,generators sims/firesim/sim tools/barstools fpga/fpga-shells fpga/src)
SCALA_SOURCES = $(call lookup_srcs,$(SOURCE_DIRS),scala)
VLOG_SOURCES = $(call lookup_srcs,$(SOURCE_DIRS),sv) $(call lookup_srcs,$(SOURCE_DIRS),v)
# This assumes no SBT meta-build sources
@@ -101,13 +106,14 @@ $(FIRRTL_FILE) $(ANNO_FILE): generator_temp
@echo "" > /dev/null
# AG: must re-elaborate if cva6 sources have changed... otherwise just run firrtl compile
generator_temp: $(SCALA_SOURCES) $(sim_files) $(EXTRA_GENERATOR_REQS)
generator_temp: $(SCALA_SOURCES) $(sim_files) $(SCALA_BUILDTOOL_DEPS) $(EXTRA_GENERATOR_REQS)
mkdir -p $(build_dir)
$(call run_scala_main,$(SBT_PROJECT),$(GENERATOR_PACKAGE).Generator,\
--target-dir $(build_dir) \
--name $(long_name) \
--top-module $(MODEL_PACKAGE).$(MODEL) \
--legacy-configs $(CONFIG_PACKAGE):$(CONFIG))
--legacy-configs $(CONFIG_PACKAGE):$(CONFIG) \
$(EXTRA_CHISEL_OPTIONS))
.PHONY: firrtl
firrtl: $(FIRRTL_FILE)
@@ -128,7 +134,26 @@ $(TOP_TARGETS) $(HARNESS_TARGETS): firrtl_temp
@echo "" > /dev/null
firrtl_temp: $(FIRRTL_FILE) $(ANNO_FILE) $(VLOG_SOURCES)
$(call run_scala_main,tapeout,barstools.tapeout.transforms.GenerateTopAndHarness,-o $(TOP_FILE) -tho $(HARNESS_FILE) -i $(FIRRTL_FILE) --syn-top $(TOP) --harness-top $(VLOG_MODEL) -faf $(ANNO_FILE) -tsaof $(TOP_ANNO) -tdf $(sim_top_blackboxes) -tsf $(TOP_FIR) -thaof $(HARNESS_ANNO) -hdf $(sim_harness_blackboxes) -thf $(HARNESS_FIR) $(REPL_SEQ_MEM) $(HARNESS_CONF_FLAGS) -td $(build_dir) -ll $(FIRRTL_LOGLEVEL)) && touch $(sim_top_blackboxes) $(sim_harness_blackboxes)
$(call run_scala_main,tapeout,barstools.tapeout.transforms.GenerateTopAndHarness,\
--allow-unrecognized-annotations \
--output-file $(TOP_FILE) \
--harness-o $(HARNESS_FILE) \
--input-file $(FIRRTL_FILE) \
--syn-top $(TOP) \
--harness-top $(VLOG_MODEL) \
--annotation-file $(ANNO_FILE) \
--top-anno-out $(TOP_ANNO) \
--top-dotf-out $(sim_top_blackboxes) \
--top-fir $(TOP_FIR) \
--harness-anno-out $(HARNESS_ANNO) \
--harness-dotf-out $(sim_harness_blackboxes) \
--harness-fir $(HARNESS_FIR) \
$(REPL_SEQ_MEM) \
$(HARNESS_CONF_FLAGS) \
--target-dir $(build_dir) \
--log-level $(FIRRTL_LOGLEVEL) \
$(EXTRA_FIRRTL_OPTIONS))
touch $(sim_top_blackboxes) $(sim_harness_blackboxes)
# DOC include end: FirrtlCompiler
# This file is for simulation only. VLSI flows should replace this file with one containing hard SRAMs
@@ -138,7 +163,7 @@ $(TOP_SMEMS_FILE) $(TOP_SMEMS_FIR): top_macro_temp
@echo "" > /dev/null
top_macro_temp: $(TOP_SMEMS_CONF)
$(call run_scala_main,barstoolsMacros,barstools.macros.MacroCompiler,-n $(TOP_SMEMS_CONF) -v $(TOP_SMEMS_FILE) -f $(TOP_SMEMS_FIR) $(MACROCOMPILER_MODE))
$(call run_scala_main,tapeout,barstools.macros.MacroCompiler,-n $(TOP_SMEMS_CONF) -v $(TOP_SMEMS_FILE) -f $(TOP_SMEMS_FIR) $(MACROCOMPILER_MODE))
HARNESS_MACROCOMPILER_MODE = --mode synflops
.INTERMEDIATE: harness_macro_temp
@@ -146,13 +171,13 @@ $(HARNESS_SMEMS_FILE) $(HARNESS_SMEMS_FIR): harness_macro_temp
@echo "" > /dev/null
harness_macro_temp: $(HARNESS_SMEMS_CONF) | top_macro_temp
$(call run_scala_main,barstoolsMacros,barstools.macros.MacroCompiler, -n $(HARNESS_SMEMS_CONF) -v $(HARNESS_SMEMS_FILE) -f $(HARNESS_SMEMS_FIR) $(HARNESS_MACROCOMPILER_MODE))
$(call run_scala_main,tapeout,barstools.macros.MacroCompiler, -n $(HARNESS_SMEMS_CONF) -v $(HARNESS_SMEMS_FILE) -f $(HARNESS_SMEMS_FIR) $(HARNESS_MACROCOMPILER_MODE))
########################################################################################
# remove duplicate files and headers in list of simulation file inputs
########################################################################################
$(sim_common_files): $(sim_files) $(sim_top_blackboxes) $(sim_harness_blackboxes)
awk '{print $1;}' $^ | sort -u | grep -v '.*\.\(svh\|h\)$$' > $@
sort -u $^ | grep -v '.*\.\(svh\|h\)$$' > $@
#########################################################################################
# helper rule to just make verilog files
@@ -170,16 +195,22 @@ ifeq (,$(BINARY))
$(error BINARY variable is not set. Set it to the simulation binary)
endif
# allow you to override sim prereq
ifeq (,$(BREAK_SIM_PREREQ))
SIM_PREREQ = $(sim)
SIM_DEBUG_PREREQ = $(sim_debug)
endif
# run normal binary with hardware-logged insn dissassembly
run-binary: $(output_dir) $(sim) check-binary
run-binary: $(output_dir) $(SIM_PREREQ) check-binary
(set -o pipefail && $(NUMA_PREFIX) $(sim) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(VERBOSE_FLAGS) $(PERMISSIVE_OFF) $(BINARY) </dev/null 2> >(spike-dasm > $(sim_out_name).out) | tee $(sim_out_name).log)
# run simulator as fast as possible (no insn disassembly)
run-binary-fast: $(output_dir) $(sim) check-binary
run-binary-fast: $(output_dir) $(SIM_PREREQ) check-binary
(set -o pipefail && $(NUMA_PREFIX) $(sim) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(PERMISSIVE_OFF) $(BINARY) </dev/null | tee $(sim_out_name).log)
# run simulator with as much debug info as possible
run-binary-debug: $(output_dir) $(sim_debug) check-binary
run-binary-debug: $(output_dir) $(SIM_DEBUG_PREREQ) check-binary
(set -o pipefail && $(NUMA_PREFIX) $(sim_debug) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(VERBOSE_FLAGS) $(WAVEFORM_FLAG) $(PERMISSIVE_OFF) $(BINARY) </dev/null 2> >(spike-dasm > $(sim_out_name).out) | tee $(sim_out_name).log)
run-fast: run-asm-tests-fast run-bmark-tests-fast
@@ -191,19 +222,19 @@ $(binary_hex): $(output_dir) $(BINARY)
$(base_dir)/scripts/smartelf2hex.sh $(BINARY) > $(binary_hex)
run-binary-hex: check-binary
run-binary-hex: $(output_dir) $(sim) $(binary_hex)
run-binary-hex: $(output_dir) $(SIM_PREREQ) $(binary_hex)
run-binary-hex: run-binary
run-binary-hex: override LOADMEM_ADDR = 80000000
run-binary-hex: override LOADMEM = $(binary_hex)
run-binary-hex: override SIM_FLAGS += +loadmem=$(LOADMEM) +loadmem_addr=$(LOADMEM_ADDR)
run-binary-debug-hex: check-binary
run-binary-debug-hex: $(output_dir) $(sim) $(binary_hex)
run-binary-debug-hex: $(output_dir) $(SIM_DEBUG_REREQ) $(binary_hex)
run-binary-debug-hex: run-binary-debug
run-binary-debug-hex: override LOADMEM_ADDR = 80000000
run-binary-debug-hex: override LOADMEM = $(binary_hex)
run-binary-debug-hex: override SIM_FLAGS += +loadmem=$(LOADMEM) +loadmem_addr=$(LOADMEM_ADDR)
run-binary-fast-hex: check-binary
run-binary-fast-hex: $(output_dir) $(sim) $(binary_hex)
run-binary-fast-hex: $(output_dir) $(SIM_PREREQ) $(binary_hex)
run-binary-fast-hex: run-binary-fast
run-binary-fast-hex: override LOADMEM_ADDR = 80000000
run-binary-fast-hex: override LOADMEM = $(binary_hex)
@@ -218,16 +249,16 @@ $(output_dir):
$(output_dir)/%: $(RISCV)/riscv64-unknown-elf/share/riscv-tests/isa/% $(output_dir)
ln -sf $< $@
$(output_dir)/%.run: $(output_dir)/% $(sim)
$(output_dir)/%.run: $(output_dir)/% $(SIM_PREREQ)
(set -o pipefail && $(NUMA_PREFIX) $(sim) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(PERMISSIVE_OFF) $< </dev/null | tee $<.log) && touch $@
$(output_dir)/%.out: $(output_dir)/% $(sim)
$(output_dir)/%.out: $(output_dir)/% $(SIM_PREREQ)
(set -o pipefail && $(NUMA_PREFIX) $(sim) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(VERBOSE_FLAGS) $(PERMISSIVE_OFF) $< </dev/null 2> >(spike-dasm > $@) | tee $<.log)
#########################################################################################
# include build/project specific makefrags made from the generator
#########################################################################################
ifneq ($(filter run% %.run %.out %.vpd %.vcd,$(MAKECMDGOALS)),)
ifneq ($(filter run% %.run %.out %.vpd %.vcd %.fsdb,$(MAKECMDGOALS)),)
-include $(build_dir)/$(long_name).d
endif
@@ -250,6 +281,7 @@ SBT_COMMAND ?= shell
launch-sbt:
cd $(base_dir) && $(SBT_NON_THIN) "$(SBT_COMMAND)"
.PHONY: check-thin-client
check-thin-client:
ifeq (,$(ENABLE_SBT_THIN_CLIENT))
$(error ENABLE_SBT_THIN_CLIENT not set.)

View File

@@ -7,6 +7,8 @@ ARG CHIPYARD_HASH
MAINTAINER https://groups.google.com/forum/#!forum/chipyard
SHELL ["/bin/bash", "-c"]
# Install dependencies for ubuntu-req.sh
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
@@ -15,7 +17,9 @@ RUN apt-get update && \
sudo \
ca-certificates \
keyboard-configuration \
console-setup
console-setup \
bc \
unzip
WORKDIR /root
@@ -51,6 +55,19 @@ RUN cd chipyard && \
export MAKEFLAGS=-"j $(nproc)" && \
./scripts/build-toolchains.sh esp-tools 1>/dev/null
# Set up FireMarshal. Building and cleaning br-base.json builds the underlying
# buildroot image (which takes a long time) but doesn't keep all the br-base
# stuff around (since that's faster to rebuild).
RUN cd chipyard && \
source env.sh && \
cd software/firemarshal && \
./init-submodules.sh && \
pip3 install -r python-requirements.txt && \
marshal build br-base.json && \
marshal clean br-base.json
# Run script to set environment variables on entry
ENTRYPOINT ["chipyard/scripts/entrypoint.sh"]

View File

@@ -13,7 +13,8 @@ Build and Deploy the Container
sudo docker tag <IMAGE_ID> <PATH_NAME>:tag . # to tag the image after the build (ex. 0.0.3)
sudo docker login # login into the account to push to
sudo docker push <PATH_NAME>:tag # to push to repo with tag
sudo docker run -it <IMAGE_ID> bash # to run an interactive version of the container
sudo docker run -it --privileged <IMAGE_ID> bash # to run an interactive version of the container
Path Names
----------

View File

@@ -83,8 +83,20 @@ Torture tests
The RISC-V torture utility generates random RISC-V assembly streams, compiles them,
runs them on both the Spike functional model and the SW simulator, and verifies
identical program behavior. The torture utility can also be configured to run
continuously for stress-testing. The torture utility exists within the ``utilities``
directory.
continuously for stress-testing. The torture utility exists within the ``tools``
directory. To run torture tests, run ``make`` in the simulation directories:
.. code-block:: shell
make CONFIG=CustomConfig torture
To run overnight tests (repeated random tests), run
.. code-block:: shell
make CONFIG=CustomConfig TORTURE_ONIGHT_OPTIONS=<overnight options> torture-overnight
You can find the overnight options in `overnight/src/main/scala/main.scala` in the torture repo.
Firesim Debugging
---------------------------

View File

@@ -0,0 +1,54 @@
Managing Published Scala Dependencies
=====================================
In preparation for Chisel 3.5, in Chipyard 1.5 Chisel, FIRRTL, the FIRRTL
interpreter, and Treadle, were transitioned from being built-from-source to
managed as published dependencies. Their submodules have been removed.
Switching between published versions can be achieved by changing the versions
specified in Chipyard's ``build.sbt``.
Lists of available artifacts can be using search.maven.org or mvnrepository.org:
- `Chisel3 <https://mvnrepository.com/artifact/edu.berkeley.cs/chisel3>`_
- `FIRRTL <https://mvnrepository.com/artifact/edu.berkeley.cs/firrtl>`_
- `FIRRTL Interpreter <https://mvnrepository.com/artifact/edu.berkeley.cs/firrtl-interpreter>`_
- `Treadle <https://mvnrepository.com/artifact/edu.berkeley.cs/treadle>`_
Publishing Local Changes
-------------------------
Under the new system, the simplest means to make custom source modifications to the packages
above is to run ``sbt +publishLocal`` from within a locally modified clone of each
of their respective repositories. This will post your custom variant
to your local ivy2 repository, which can generally be found at ``~/.ivy2``. See the `SBT
documentation <https://www.scala-sbt.org/1.x/docs/Publishing.html#Publishing+locally>`_
for more detail.
In practice, this will require the following steps:
#. Check out and modify the desired projects.
#. Take note of, or modify, the versions of each projects (in
their ``build.sbt``). If you're cloning from ``master`` generally
these will have default versions of ``1.X-SNAPSHOT``, where ``X`` is
not-yet-released next major version. You can modify the version string, to say ``1.X-<MYSUFFIX>``, to uniquely identify your
change.
#. Call ``sbt +publishLocal`` in each subproject. You may need to rebuild other
published dependencies. SBT will be clear about what it is publishing and
where it is putting it. The ``+`` is generally necessary and ensures that
all cross versions of the package are published.
#. Update the Chisel or FIRRTL version in Chipyard's ``build.sbt`` to match the
versions of your locally published packages.
#. Use Chipyard as you would normally. Now when you call out to make in
Chipyard you should see SBT resolving dependencies to the locally
published instances in your local ivy2 repository.
#. When you're finished, consider removing your locally published packages (by
removing the appropriate directory in your ivy2 repository) to prevent
accidentally reusing them in the future.
A final word of caution: packages you publish to your local ivy repository will
be visible to other projects you may be building on your system. For example,
if you locally publish Chisel 3.5.0, other projects that depend on Chisel 3.5.0
will preferentially use the locally published variant over the version
available on Maven (the "real" 3.5.0). Take care to note versions you are
publishing and remove locally published versions once you are done with them.

View File

@@ -15,4 +15,5 @@ They expect you to know about Chisel, Parameters, configs, etc.
Resources
CDEs
Harness-Clocks
Managing-Published-Scala-Dependencies

View File

@@ -24,6 +24,10 @@ Processor Cores
An in-order RISC-V core written in System Verilog. Previously called Ariane.
See :ref:`Generators/CVA6:CVA6 Core` for more information.
**Ibex Core**
An in-order 32 bit RISC-V core written in System Verilog.
See :ref:`Generators/Ibex:Ibex Core` for more information.
Accelerators
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@@ -29,13 +29,17 @@ Setting up the Chipyard Repo
Start by fetching Chipyard's sources. Run:
.. code-block:: shell
.. parsed-literal::
git clone https://github.com/ucb-bar/chipyard.git
cd chipyard
# checkout latest official chipyard release
# note: this may not be the latest release if the documentation version != "stable"
git checkout |version|
./scripts/init-submodules-no-riscv-tools.sh
This will initialize and checkout all of the necessary git submodules.
This will also validate that you are on a tagged branch, otherwise it will prompt for confirmation.
When updating Chipyard to a new version, you will also want to rerun this script to update the submodules.
Using git directly will try to initialize all submodules; this is not recommended unless you expressly desire this behavior.

View File

@@ -38,7 +38,7 @@ All with the same Hwacha parameters.
Assigning Accelerators to Specific Tiles with MultiRoCC
-------------------------------------------------------
Located in ``generators/chipyard/src/main/scala/ConfigFragments.scala`` is a config fragment that provides support for adding RoCC accelerators to specific tiles in your SoC.
Located in ``generators/chipyard/src/main/scala/config/fragments/RoCCFragments.scala`` is a config fragment that provides support for adding RoCC accelerators to specific tiles in your SoC.
Named ``MultiRoCCKey``, this key allows you to attach RoCC accelerators based on the ``hartId`` of the tile.
For example, using this allows you to create a 8 tile system with a RoCC accelerator on only a subset of the tiles.
An example is shown below with two BOOM cores, and one Rocket tile with a RoCC accelerator (Hwacha) attached.

View File

@@ -1,98 +1,10 @@
Gemmini
====================================
The Gemmini project is developing a systolic-array based matrix multiplication unit generator for the investigation of software/hardware implications of such integrated SoC accelerators. It is inspired by recent trends in machine learning accelerators for edge and mobile SoCs.
The Gemmini project is developing a full-system, full-stack DNN hardware exploration and evaluation platform.
Gemmini enables architects to make useful insights into how different components of the system and software stack (outside of just the accelerator itself) interact to affect overall DNN performance.
Gemmini is implemented as a RoCC accelerator with non-standard RISC-V custom instructions. The Gemmini unit uses the RoCC port of a Rocket or BOOM `tile`, and by default connects to the memory system through the System Bus (i.e., directly to the L2 cache).
To add a Gemmini unit to an SoC, you should add the ``gemmini.DefaultGemminiConfig`` config fragment to the SoC configurations. To change the configuration of the Gemmini accelerator unit, you can write a custom configuration to replace the ``DefaultGemminiConfig``, which you can view under `generators/gemmini/src/main/scala/configs.scala <https://github.com/ucb-bar/gemmini/blob/master/src/main/scala/gemmini/Configs.scala>`__ to see the possible configuration parameters.
The example Chipyard config includes the following example SoC configuration which includes Gemmini:
.. literalinclude:: ../../generators/chipyard/src/main/scala/config/RocketConfigs.scala
:language: scala
:start-after: DOC include start: GemminiRocketConfig
:end-before: DOC include end: GemminiRocketConfig
To build a simulation of this example Chipyard config, run the following commands:
.. code-block:: shell
cd sims/verilator # or "cd sims/vcs"
make CONFIG=GemminiRocketConfig
Check out `Gemmini's documentation <https://github.com/ucb-bar/gemmini/blob/master/README.md>`__ to learn how to generate, simulate, and profile DNN accelerators with Gemmini and Chipyard.
.. image:: ../_static/images/gemmini-system.png
Generator Parameters
--------------------------
Major parameters of interest include:
* Systolic array dimensions (``tileRows``, ``tileColumns``, ``meshRows``, ``meshColumns``): The systolic array is composed of a 2-level hierarchy, in which each tile is fully combinational, while a mesh of tiles has pipeline registers between each tile.
.. image:: ../_static/images/gemmini-systolic-array.png
* Dataflow parameters (``dataflow``): Determine whether the systolic array in Gemmini is output-stationary or weight-stationary, or whether it supports both dataflows so that programmers may choose between them at runtime.
* 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. 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
------------------
The Gemmini non-standard ISA extension is specified in the `Gemmini repository <https://github.com/ucb-bar/gemmini/blob/master/README.md>`__.
The ISA includes configuration instructions, data movement instructions (from main memory to the Gemmini scratchpad, and from the Gemmini accumulators to main memory), and matrix multiplication execution instructions.
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 (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 ``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
^^^^^^^^^^^^^^^^^^^^^^^^^^^
To build Gemmini tests:
.. code-block:: shell
cd generators/gemmini/software/gemmini-rocc-tests/
./build.sh
Afterwards, the test binaries will be found in ``generators/gemmini/software/gemmini-rocc-tests/build``. Binaries whose names end in ``-baremetal`` are meant to be run in a bare-metal environment, while binaries whose names end in ``-linux`` are meant to run in a Linux environment. You can run the tests either on a cycle-accurate RTL simulator, or on a (much faster) functional ISA simulator called Spike.
The Gemmini generator implements a custom non-standard version of Spike. This implementation is found within the ``esp-tools`` Spike implementation, together with the Hwacha vector accelerator non-standard ISA-extension. In order to use this version of Spike, please make sure to build the ``esp-tools`` software toolchain, as described in :ref:`build-toolchains`.
In order to run Spike with the gemmini functional model, you will need to use the ``--extension=gemmini`` flag. For example:
.. code-block:: shell
spike --extension=gemmini <some/gemmini/baremetal/test>
Spike is built by default without a commit log. However, if you would like to add detailed functional log of gemmini operation to the spike model, you can rebuild spike manually (based on the instructions in the ``esp-tools/riscv-isa-sim/README`` file), with the ``--enable-gemminicommitlog`` option added to the ``configure`` step.
Alternative SoC Configs
--------------------------
The Gemmini generator includes additional alternative SoC configs (configs that are not in the Chipyard example project).
If you would like to build one of these alternative SoC configurations which are defined in within the Gemmini project repository, you can run the following commands. These commands are similar to the one required when building a simulation from the example project, but they specify that the location of the configs are in the Gemmini subproject, as opposed to the Chipyard example project:
.. code-block:: shell
cd sims/verilator # or "cd sims/vcs"
make CONFIG=GemminiAcceleratorConfig CONFIG_PACKAGE=gemmini MODEL_PACKAGE=freechips.rocketchip.system GENERATOR_PACKAGE=freechips.rocketchip.system TOP=ExampleRocketSystem

14
docs/Generators/Ibex.rst Normal file
View File

@@ -0,0 +1,14 @@
Ibex Core
====================================
`Ibex <https://github.com/lowRISC/ibex>`__ is a parameterizable RV32IMC embedded core written in SystemVerilog, currently maintained by `lowRISC <https://lowrisc.org>`__.
The `Ibex core` is wrapped in an `Ibex tile` so it can be used with the `Rocket Chip SoC generator`.
The core exposes a custom memory interface, interrupt ports, and other misc. ports that are connected from within the tile to TileLink buses and other parameterization signals.
.. Warning:: The Ibex mtvec register is 256 byte aligned. When writing/running tests, ensure that the trap vector is also 256 byte aligned.
.. Warning:: The Ibex reset vector is located at BOOT_ADDR + 0x80.
While the core itself is not a generator, we expose the same parameterization that the Ibex core provides so that all supported Ibex configurations are available.
For more information, see the `GitHub repository for Ibex <https://github.com/lowRISC/ibex>`__.

View File

@@ -18,7 +18,7 @@ Peripheral Devices
These peripheral devices usually affect the memory map of the SoC, and its top-level IO as well.
To integrate one of these devices in your SoC, you will need to define a custom config fragment with the approriate address for the device using the Rocket Chip parameter system. As an example, for a GPIO device you could add the following config fragment to set the GPIO address to ``0x10012000``. This address is the start address for the GPIO configuration registers.
.. literalinclude:: ../../generators/chipyard/src/main/scala/ConfigFragments.scala
.. literalinclude:: ../../generators/chipyard/src/main/scala/config/fragments/PeripheralFragments.scala
:language: scala
:start-after: DOC include start: gpio config fragment
:end-before: DOC include end: gpio config fragment

63
docs/Generators/fft.rst Normal file
View File

@@ -0,0 +1,63 @@
FFT Generator
====================================
The FFT generator is a parameterizable fft accelerator.
Configuration
--------------------------
The following configuration creates an 8-point FFT:
.. literalinclude:: ../../generators/chipyard/src/main/scala/config/RocketConfigs.scala
:language: scala
:start-after: DOC include start: FFTRocketConfig
:end-before: DOC include end: FFTRocketConfig
:code:`baseAddress` specifies the starting address of the FFT's read and write lanes. The FFT write lane is always located at :code:`baseAddress`. There is 1 read lane per output point; since this config specifies an 8-point FFT, there will be 8 read lanes. Read lane :code:`i` (which can be loaded from to retrieve output point :code:`i`) will be located at :code:`baseAddr + 64bits (assuming 64bit system) + (i * 8)`. :code:`baseAddress` should be 64-bit aligned
:code:`width` is the size of input points in binary. A width of :code:`w` means that each point will have :code:`w` bits for the real component and :code:`w` bits for the imaginary component, yielding a total of `2w` bits per point. :code:`decPt` is the location of the decimal point in the fixed-precision representation of each point's real and imaginary value. In the Config above, each point is `32` bits wide, with `16` bits used to represent the real component and `16` bits used to represent the imaginary component. Within the `16` bits for each component, the `8` LSB are used to represent the decimal component of the value and the remaining (8) MSB are used to represent the integer component. Both the real and imaginary components use a fixed-precision representation.
To build a simulation of this example Chipyard config, run the following commands:
.. code-block:: shell
cd sims/verilator # or "cd sims/vcs"
make CONFIG=FFTRocketConfig
Usage and Testing
--------------------------
Points are passed into the FFT via the single write lane. In C pseudocode, this might look like:
.. code-block:: C
for (int i = 0; i < num_points; i++) {
// FFT_WRITE_LANE = baseAddress
uint32_t write_val = points[i];
volatile uint32_t* ptr = (volatile uint32_t*) FFT_WRITE_LANE;
*ptr = write_val;
}
Once the correct number of inputs are passed in (in the config above, 8 values would be passed in), the read lanes can be read from (again in C pseudocode):
.. code-block:: C
for (int i = 0; i < num_points; i++) {
// FFT_RD_LANE_BASE = baseAddress + 64bits (for write lane)
volatile uint32_t* ptr_0 = (volatile uint32_t*) (FFT_RD_LANE_BASE + (i * 8));
uint32_t read_val = *ptr_0;
}
The :code:`fft.c` test file in the :code:`tests/` directory can be used to verify the fft's functionality on an SoC built with :code:`FFTRocketConfig`.
Acknowledgements
--------------------------
The code for the FFT Generator was adapted from the ADEPT Lab at UC Berkeley's `Hydra Spine <https://adept.eecs.berkeley.edu/projects/hydra-spine/>`_ project.
Authors for the original project (in no particular order):
* James Dunn, UC Berkeley (dunn [at] eecs [dot] berkeley [dot] edu)
* :code:`Deserialize.scala`
* :code:`Tail.scala`
* :code:`Unscramble.scala`
* Stevo Bailey (stevo.bailey [at] berkeley [dot] edu)
* :code:`FFT.scala`

View File

@@ -28,6 +28,8 @@ so changes to the generators themselves will automatically be used when building
SiFive-Generators
SHA3
CVA6
Ibex
fft
NVDLA
Sodor

View File

@@ -110,7 +110,7 @@ The 1st partition will be used to store the Linux binary (created with FireMarsh
Additionally, these instructions assume you are using Linux with ``sudo`` privileges and ``gdisk``, but you can follow a similar set of steps on Mac (using ``gpt`` or another similar program).
1. Wipe the GPT on the card using ``gdisk``.
Use the `z` command to zap everything from the expert menu (opened with 'x', closed with 'm').
Use the `z` command from the expert menu (opened with 'x', closed with 'm') to zap everything.
For rest of these instructions, we assume the SDCard path is ``/dev/sdc`` (replace this with the path to your SDCard).
.. code-block:: shell

View File

@@ -13,6 +13,15 @@ official RISC-V ISA reference implementation. Qemu is a high-performance
functional simulator that can run nearly as fast as native code, but can be
challenging to modify.
To initialize additional software repositories, such as wrappers for Coremark,
SPEC2017, and workloads for the NVDLA, run the following script. The
submodules are located in the ``software`` directory.
.. code-block:: shell
./scripts/init-software.sh
.. toctree::
:maxdepth: 2
:caption: Contents:

View File

@@ -178,7 +178,7 @@ transactions.
- ``EarlyAck.PutFulls`` - acknowledge on first beat if PutFull, otherwise acknowledge on last beat.
- ``EarlyAck.None`` - always acknowledge on last beat.
- ``holdFirstDenied: Boolean`` - (optional) Allow the Fragmenter to unsafely combine multibeat Gets by taking the first denied for the whole burst. (default: false)
- ``holdFirstDeny: Boolean`` - (optional) Allow the Fragmenter to unsafely combine multibeat Gets by taking the first denied for the whole burst. (default: false)
**Example Usage:**

View File

@@ -9,54 +9,53 @@ Project Structure
This example gives a suggested file structure and build system. The ``vlsi/`` folder will eventually contain the following files and folders:
* Makefile, sim.mk, power.mk
* ``Makefile``, ``sim.mk``, ``power.mk``
* Integration of Hammer's build system into Chipyard and abstracts away some Hammer commands.
* build
* ``build``
* Hammer output directory. Can be changed with the ``OBJ_DIR`` variable.
* Will contain subdirectories such as ``syn-rundir`` and ``par-rundir`` and the ``inputs.yml`` denoting the top module and input Verilog files.
* env.yml
* ``env.yml``
* A template file for tool environment configuration. Fill in the install and license server paths for your environment.
* example-vlsi
* ``example-vlsi``
* Entry point to Hammer. Contains example placeholders for hooks.
* example-asap7.yml, example-tools.yml
* ``example-asap7.yml``, ``example-tools.yml``
* Hammer IR for this tutorial.
* example-design.yml, example-nangate45.yml, example-tech.yml
* ``example-design.yml``, ``example-nangate45.yml``, ``example-tech.yml``
* Hammer IR not used for this tutorial but provided as templates.
* generated-src
* ``generated-src``
* All of the elaborated Chisel and FIRRTL.
* hammer, hammer-<vendor>-plugins, hammer-<tech>-plugin
* ``hammer``, ``hammer-<vendor>-plugins``, ``hammer-<tech>-plugin``
* Core, tool, tech repositories.
* view_gds.py
* ``view_gds.py``
* A convenience script to view a layout using gdspy. Note that this will be very slow for large layouts (e.g. a Rocket core)!
* A convenience script to view a layout using gdstk or gdspy. Only use this for small layouts (i.e. smaller than the TinyRocketConfig example) since the gdstk-produced SVG will be too big and gdspy's GUI is very slow for large layouts!
Prerequisites
-------------
* Python 3.4+
* numpy and gdspy packages. gdspy must be version 1.4.
* Genus, Innovus, and Calibre licenses
* For ASAP7 specifically:
* numpy and `gdstk <https://github.com/heitzmann/gdstk>`__ or `gdspy <https://github.com/heitzmann/gdspy>`__ packages. Note: gdspy must be version 1.4.
* Genus, Innovus, Voltus, VCS, and Calibre licenses
* For ASAP7 specifically (`README <https://github.com/ucb-bar/hammer/tree/master/src/hammer-vlsi/technology/asap7>`__ for more details):
* Download the `ASAP7 PDK v1p5 <http://asap.asu.edu/asap/>`__ tarball to a directory of choice but do not extract it. The tech plugin is configured to extract the PDK into a cache directory for you. Note: v1p5 of the PDK is not publicly available, and you will need to contact the developers for it. The v1p7 version that is `publicly released <https://github.com/The-OpenROAD-Project/asap7>`__ currently has several critical issues which prevent it from being fully integrated into the Hammer flow.
* If you have additional ASAP7 hard macros, their LEF & GDS need to be 4x upscaled @ 4000 DBU precision. They may live outside ``extra_libraries`` at your discretion.
* Innovus version must be >= 15.2 or <= 18.1 (ISRs excluded).
* First, download the `ASAP7 v1p7 PDK <https://github.com/The-OpenROAD-Project/asap7>`__ (we recommend shallow-cloning or downloading an archive of the repository). Then, download the `encrypted Calibre decks tarball <http://asap.asu.edu/asap/>`__ tarball to a directory of choice (e.g. the root directory of the PDK) but do not extract it like the instructions say. The tech plugin is configured to extract the tarball into a cache directory for you.
* If you have additional ASAP7 hard macros, their LEF & GDS need to be 4x upscaled @ 4000 DBU precision.
Initial Setup
-------------
@@ -66,7 +65,7 @@ In the Chipyard root, run:
./scripts/init-vlsi.sh asap7
to pull the Hammer & plugin submodules. Note that for technologies other than ``asap7``, the tech submodule must be added in the ``vlsi`` folder first.
to pull the Hammer & plugin submodules. Note that for technologies other than ``sky130`` or ``asap7``, the tech submodule must be added in the ``vlsi`` folder first.
Pull the Hammer environment into the shell:
@@ -95,13 +94,11 @@ example-vlsi
^^^^^^^^^^^^
This is the entry script with placeholders for hooks. In the ``ExampleDriver`` class, a list of hooks is passed in the ``get_extra_par_hooks``. Hooks are additional snippets of python and TCL (via ``x.append()``) to extend the Hammer APIs. Hooks can be inserted using the ``make_pre/post/replacement_hook`` methods as shown in this example. Refer to the Hammer documentation on hooks for a detailed description of how these are injected into the VLSI flow.
The ``scale_final_gds`` hook is a particularly powerful hook. It dumps a Python script provided by the ASAP7 tech plugin, an executes it within the Innovus TCL interpreter, and should be inserted after ``write_design``. This hook is necessary because the ASAP7 PDK does place-and-route using 4x upscaled LEFs for Innovus licensing reasons, thereby requiring the cells created in the post-P&R GDS to be scaled down by a factor of 4.
example.yml
^^^^^^^^^^^
example-asap7.yml
^^^^^^^^^^^^^^^^^
This contains the Hammer configuration for this example project. Example clock constraints, power straps definitions, placement constraints, and pin constraints are given. Additional configuration for the extra libraries and tools are at the bottom.
First, set ``technology.asap7.tarball_dir`` to the absolute path to the directory where the downloaded the ASAP7 PDK tarball lives.
First, set ``technology.asap7.tarball_dir`` to the absolute path to the directory where the downloaded the ASAP7 Calibre deck tarball lives. If it is not in the PDK's root directory, then also set ``technology.asap7.pdk_install_dir`` and ``technology.asap7.stdcell_install_dir``.
Synthesis
^^^^^^^^^
@@ -109,7 +106,7 @@ Synthesis
make syn CONFIG=TinyRocketConfig
Post-synthesis logs and collateral are in ``build/syn-rundir``. The raw QoR data is available at ``build/syn-rundir/reports``, and methods to extract this information for design space exploration are a WIP.
Post-synthesis logs and collateral are in ``build/syn-rundir``. The raw quality of results data is available at ``build/syn-rundir/reports``, and methods to extract this information for design space exploration are a work in progress.
Place-and-Route
^^^^^^^^^^^^^^^
@@ -127,7 +124,7 @@ Timing reports are found in ``build/par-rundir/timingReports``. They are gzipped
.. code-block:: shell
python3 view_gds.py build/chipyard.TestHarness.TinyRocketConfig/par-rundir/ChipTop.gds
./view_gds.py build/chipyard.TestHarness.TinyRocketConfig/par-rundir/ChipTop.gds
By default, this script only shows the M2 thru M4 routing. Layers can be toggled in the layout viewer's side pane and ``view_gds.py`` has a mapping of layer numbers to layer names.
@@ -143,21 +140,19 @@ To run DRC & LVS, and view the results in Calibre:
./build/lvs-rundir/generated-scripts/view-lvs
Some DRC errors are expected from this PDK, as explained in the `ASAP7 plugin readme <https://github.com/ucb-bar/hammer/tree/master/src/hammer-vlsi/technology/asap7>`__.
Furthermore, the dummy SRAMs that are provided in this tutorial and PDK do not have any geometry inside, so will certainly cause DRC and LVS errors.
Furthermore, the dummy SRAMs that are provided in this tutorial and PDK do not have any geometry inside, so will certainly cause DRC errors.
Simulation
^^^^^^^^^^
Simulation with VCS is supported, and can be run at the RTL- or gate-level (post-synthesis and P&R). The simulation infrastructure as included here is intended for running RISC-V binaries on a Chipyard config. For example, for an RTL-level simulation:
Simulation with VCS is supported, and can be run at the RTL- or gate-level (post-synthesis and post-P&R). The simulation infrastructure as included here is intended for running RISC-V binaries on a Chipyard config. For example, for an RTL-level simulation:
.. code-block:: shell
make sim-rtl CONFIG=TinyRocketConfig BINARY=$RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-simple
make sim-rtl CONFIG=TinyRocketConfig BINARY=$RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv32ui-p-simple
Post-synthesis and post-P&R simulations use the ``sim-syn`` and ``sim-par`` targets, respectively.
Post-synthesis and post-P&R simulations use the ``sim-syn`` and ``sim-par`` make targets, respectively.
There are also ``-debug`` and ``-debug-timing``, which will instruct VCS to write a SAIF + VPD and do timing-annotated simulations, respectively. See the ``sim.mk`` file for all available targets.
Note that for the ASAP7 example, gate-level simulations will currently timeout.
Appending ``-debug`` and ``-debug-timing`` to these make targets will instruct VCS to write a SAIF + VPD (or FSDB if the ``USE_FSDB`` flag is set) and do timing-annotated simulations, respectively. See the ``sim.mk`` file for all available targets.
Power/Rail Analysis
^^^^^^^^^^^^^^^^^^^
@@ -169,4 +164,4 @@ Post-P&R power and rail (IR drop) analysis is supported with Voltus:
If you append the ``BINARY`` variable to the command, it will use the activity file generated from a ``sim-<syn/par>-debug`` run and report dynamic power & IR drop from the toggles encoded in the waveform.
Note that for ASAP7, to bypass gate-level simulation, you will need to run the power tool manually (see the generated commands in the generated ``hammer.d`` buildfile). Static and active (vectorless) power & IR drop will be reported.
To bypass gate-level simulation, you will need to run the power tool manually (see the generated commands in the generated ``hammer.d`` buildfile). Static and active (vectorless) power & IR drop will be reported.

View File

@@ -49,9 +49,9 @@ Say you need to update some power straps settings in ``example.yml`` and want to
make redo-par HAMMER_REDO_ARGS='-p example.yml --only_step power_straps'
RTL/Gate-level Simulation, Power Estimation
-------------------------------------------
With the Synopsys plugin, RTL and gate-level simulation is supported using VCS at the chip-level. Also, post-par power estimation with Voltus in the Cadence plugin is also supported. While the provided example does not implement any simulation, some Make targets are provided in the ``vlsi/`` directory. Here is a brief description:
Hierarchical RTL/Gate-level Simulation, Power Estimation
--------------------------------------------------------
With the Synopsys plugin, hierarchical RTL and gate-level simulation is supported using VCS at the chip-level. Also, post-par power estimation with Voltus in the Cadence plugin is also supported. Special Make targets are provided in the ``vlsi/`` directory in ``sims.mk`` and ``power.mk``. Here is a brief description:
* ``sim-rtl``: RTL-level simulation
@@ -73,4 +73,6 @@ With the Synopsys plugin, RTL and gate-level simulation is supported using VCS a
* ``redo-`` can be appended to all above targets to break dependency tracking, like described above.
The simulation configuration (e.g. binaries) can be edited for your design. See the Makefile and refer to Hammer's documentation for how to set up simulation parameters for your design.
* ``-$(VLSI_TOP)`` suffixes denote simulations/power analysis on a submodule in a hierarchical flow. Note that you must provide the testbenches for these modules since the default testbench only simulates a Chipyard-based ``ChipTop`` DUT instance.
The simulation configuration (e.g. binaries) can be edited for your design. See the ``Makefile`` and refer to Hammer's documentation for how to set up simulation parameters for your design.

View File

@@ -12,7 +12,7 @@ In the Chipyard root, run:
.. code-block:: shell
./scripts/init-vlsi.sh <tech-plugin-name>
This will pull the Hammer & CAD tool plugin submodules, assuming the technology plugins are available on github.
Currently only the asap7 technology plugin is available on github.
If you have additional private technology plugins (this is a typical use-case for proprietry process technologies with require NDAs and secure servers), you can clone them directly
@@ -40,17 +40,17 @@ Setting up the Hammer Configuration Files
--------------------------------------------
The first configuration file that needs to be set up is the Hammer environment configuration file ``env.yml``. In this file you need to set the paths to the EDA tools and license servers you will be using. You do not have to fill all the fields in this configuration file, you only need to fill in the paths for the tools that you will be using.
If you are working within a shared server farm environment with an LSF cluster setup (for example, the Berkeley Wireless Research Center), please note the additional possible environment configuration listed in the :ref:`VLSI/Basic-Flow:Advanced Environment Setup` segment of this documentation page.
If you are working within a shared server farm environment with an LSF cluster setup (for example, the Berkeley Wireless Research Center), please note the additional possible environment configuration listed in the :ref:`VLSI/Basic-Flow:Advanced Environment Setup` segment of this documentation page.
Hammer relies on YAML-based configuration files. While these configuration can be consolidated within a single files (as is the case in the ASAP7 tutorial :ref:`tutorial` and the ``nangate45``
OpenRoad example), the generally suggested way to work with an arbitrary process technology or tools plugins would be to use three configuration files, matching the three Hammer concerns - tools, tech, and design.
OpenRoad example), the generally suggested way to work with an arbitrary process technology or tools plugins would be to use three configuration files, matching the three Hammer concerns - tools, tech, and design.
The ``vlsi`` directory includes three such example configuration files matching the three concerns: ``example-tools.yml``, ``example-tech.yml``, and ``example-design.yml``.
The ``example-tools.yml`` file configures which EDA tools hammer will use. This example file uses Cadence Innovus, Genus and Voltus, Synopsys VCS, and Mentor Calibre (which are likely the tools you will use if you're working in the Berkeley Wireless Research Center). Note that tool versions are highly sensitive to the process-technology in-use. Hence, tool versions that work with one process technology may not work with another (for example, ASAP7 will not work with an Innovus version newer than 18.1, while other proprietary process technologies will likely require newer versions such as 19.1).
The ``example-tools.yml`` file configures which EDA tools hammer will use. This example file uses Cadence Innovus, Genus and Voltus, Synopsys VCS, and Mentor Calibre (which are likely the tools you will use if you're working in the Berkeley Wireless Research Center). Note that tool versions are highly sensitive to the process-technology in-use. Hence, tool versions that work with one process technology may not work with another.
The ``example-design.yml`` file contains basic build system information (how many cores/threads to use, etc.), as well as configurations that are specific to the design we are working on such as clock signal name and frequency, power modes, floorplan, and additional constraints that we will add later on.
Finally, the ``example-tech`` file is a template file for a process technology plugin configuration. We will copy this file, and replace its fields with the appropriate process technology details for the tech plugin that we have access to. For example, for the ``asap7`` tech plugin we will replace the <tech_name> field with "asap7", the Node size "N" with "7", and the path to the process technology files installation directory.
Finally, the ``example-tech.yml`` file is a template file for a process technology plugin configuration. We will copy this file, and replace its fields with the appropriate process technology details for the tech plugin that we have access to. For example, for the ``asap7`` tech plugin, we will replace the <tech_name> field with "asap7" and the path to the process technology files installation directory. The technology plugin (which for ASAP7 is within Hammer) will define the technology node and other parameters.
We recommend copying these example configuration files and customizing them with a different name, so you can have different configuration files for different process technologies and designs (e.g. create tech-tsmintel3.yml from example-tech.yml)
@@ -60,10 +60,10 @@ Building the Design
After we have set the configuration files, we will now elaborate our Chipyard Chisel design into Verilog, while also performing the required transformations in order to make the Verilog VLSI-friendly.
Additionally, we will automatically generate another set of Hammer configuration files matching to this design, which will be used in order to configure the physical design tools.
We will do so by calling ``make buildfile`` with appropriate Chipyard configuration variables and Hammer configuration files.
As in the rest of the Chipyard flows, we specify our SoC configuration using the ``CONFIG`` make variable.
As in the rest of the Chipyard flows, we specify our SoC configuration using the ``CONFIG`` make variable.
However, unlike the rest of the Chipyard flows, in the case of physical design we might be interested in working in a hierarchical fashion and therefore we would like to work on a single module.
Therefore, we can also specify a ``VLSI_TOP`` make variable with the same of a specific Verilog module (which should also match the name of the equivalent Chisel module) which we would like to work on.
The makefile will automatically call tools such as Barstools and the MacroCompiler (:ref:`Tools/Barstools:barstools`) in order to make the generated Verilog more VLSI friendly.
The makefile will automatically call tools such as Barstools and the MacroCompiler (:ref:`Tools/Barstools:barstools`) in order to make the generated Verilog more VLSI friendly.
By default, the MacroCompiler will attempt to map memories into the SRAM options within the Hammer technology plugin. However, if you are working with a new process technology and prefer to work with flip-flop arrays, you can configure the MacroCompiler using the ``MACROCOMPILER_MODE`` make variable. For example, if your technology plugin does not have an SRAM compiler ready, you can use the ``MACROCOMPILER_MODE='--mode synflops'`` option (Note that synthesizing a design with only flipflops is very slow and will often may not meet constraints).
We call the ``make buildfile`` command while also specifying the name of the process technology we are working with (same ``tech_name`` for the configuration files and plugin name) and the configuration files we created. Note, in the ASAP7 tutorial ((:ref:`tutorial`)) these configuration files are merged into a single file called ``example-asap7.yml``.
@@ -88,7 +88,7 @@ Running a basic VLSI flow using the Hammer default configurations is fairly simp
Synthesis
^^^^^^^^^
In order to run synthesis, we run ``make syn`` with the matching Make variables.
In order to run synthesis, we run ``make syn`` with the matching Make variables.
Post-synthesis logs and collateral will be saved in ``build/<config-name>/syn-rundir``. The raw QoR data (area, timing, gate counts, etc.) will be found in ``build/<config-name>/syn-rundir/reports``.
Hence, if we want to monolithically synthesize the entire SoC, the relevant command would be:
@@ -142,13 +142,13 @@ The relevant ``make`` command would then be:
make par CONFIG=GemminiRocketConfig VLSI_TOP=Gemmini tech_name=tsmintel3 INPUT_CONFS="example-design.yml example-tools.yml example-tech.yml"
Note that the width and height specification can vary widely between different modulesi and level of the module hierarchy. Make sure to set sane width and height values.
Place-and-route generally requires more fine-grained input specifications regarding power nets, clock nets, pin assignments and floorplanning. While the template configuration files provide defaults for automatic tool defaults, these will usually result in very bad QoR, and therefore it is recommended to specify better-informed floorplans, pin assignments and power nets. For more information about cutomizing theses parameters, please refer to the :ref:`VLSI/Basic-Flow:Customizing Your VLSI Flow in Hammer` sections or to the Hammer documentation.
Additionally, some Hammer process technology plugins do not provide sufficient default values for requires settings such as power nets and pin assignments (for example, ASAP7). In those cases, these constraints will need to be specified manually in the top-level configuration yml files, as is the case in the ``example-asap7.yml`` configuration file.
Place-and-route generally requires more fine-grained input specifications regarding power nets, clock nets, pin assignments and floorplanning. While the template configuration files provide defaults for automatic tool defaults, these will usually result in very bad QoR, and therefore it is recommended to specify better-informed floorplans, pin assignments and power nets. For more information about cutomizing theses parameters, please refer to the :ref:`VLSI/Basic-Flow:Customizing Your VLSI Flow in Hammer` sections or to the Hammer documentation.
Additionally, some Hammer process technology plugins do not provide default values for required settings such as tool paths and pin assignments (for example, ASAP7). In those cases, these constraints will need to be specified manually in the top-level configuration yml files, as is the case in the ``example-asap7.yml`` configuration file.
Place-and-route tools are very sensitive to process technologes (significantly more sensitive than synthesis tools), and different process technologies may work only on specific tool versions. It is recommended to check what is the appropriate tool version for the specific process technology you are working with.
.. Note:: If you edit the yml configuration files in between synthesis and place-and-route, the `make par` command will automatically re-run synthesis. If you would like to avoid that and are confident that your configuration file changes do not affect synthesis results, you may use the `make redo-par` instead.
.. Note:: If you edit the yml configuration files in between synthesis and place-and-route, the ``make par`` command will automatically re-run synthesis. If you would like to avoid that and are confident that your configuration file changes do not affect synthesis results, you may use the ``make redo-par`` command instead with the variable ``HAMMER_EXTRA_ARGS='-p <your-changed.yml>'``.
@@ -175,10 +175,10 @@ The simulation-extracted power estimation flow implicitly uses Hammer's gate-lev
Signoff
^^^^^^^^^
During chip tapeout, you will need to perform sign-off check to make sure the generated GDSII can be fabricated as intended. This is done using dedicated signoff tools that perform design rule checking (DRC) and layout versus schematic (LVS) verification.
In most cases, placed-and-routed designs will not pass DRC and LVS on first attempts due to nuanced design rules and subtle/silent failures of the place-and-route tools. Passing DRC and LVS will often requires adding manual placement constraints to "force" the EDA tools into certain patterns.
During chip tapeout, you will need to perform sign-off check to make sure the generated GDSII can be fabricated as intended. This is done using dedicated signoff tools that perform design rule checking (DRC) and layout versus schematic (LVS) verification.
In most cases, placed-and-routed designs will not pass DRC and LVS on first attempts due to nuanced design rules and subtle/silent failures of the place-and-route tools. Passing DRC and LVS will often requires adding manual placement constraints to "force" the EDA tools into certain patterns.
If you have placed-and-routed a design with the goal of getting area and power estimates, DRC and LVS are not strictly neccessary and the results will likely be quite similar. If you are intending to tapeout and fabricate a chip, DRC and LVS are mandatory and will likely requires multiple-iterations of refining manual placement constraints.
Having a large number of DRC/LVS violations can have a significant impact on the runtime of the place-and-route procedure (since the tools will try to fix each of them several times). A large number of DRC/LVS violations may also be an indication that the design is not necessarily realistic for this particular process technology, which may have power/area implications.
Having a large number of DRC/LVS violations can have a significant impact on the runtime of the place-and-route procedure (since the tools will try to fix each of them several times). A large number of DRC/LVS violations may also be an indication that the design is not necessarily realistic for this particular process technology, which may have power/area implications.
Since signoff checks are required only for a complete chip tapeout, they are currently not fully automated in Hammer, and often require some additional manual inclusion of custom Makefiles associated with specific process technologies. However, the general steps from running signoff within Hammer (under the assumption of a fully automated tech plug-in) are Make commands similar to the previous steps.
@@ -193,7 +193,7 @@ DRC does not emit easily audited reports, as the rule names violated can be quit
In order to run LVS, the relevant ``make`` command is ``make lvs``. As in the previous stages, the make command should be accompanied by the relevant configuration Make variables:
.. code-block:: shell
make lvs CONFIG=GemminiRocketConfig VLSI_TOP=Gemmini tech_name=tsmintel3 INPUT_CONFS="example-design.yml example-tools.yml example-tech.yml"
@@ -228,7 +228,7 @@ If you have access to a shared LSF cluster and you would like Hammer to submit i
Composing a Hierarchical Design
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For large designs, a monolithic VLSI flow may take the EDA tools a very long time to process and optimize, to the extent that it may not be feasable sometimes.
For large designs, a monolithic VLSI flow may take the EDA tools a very long time to process and optimize, to the extent that it may not be feasable sometimes.
Hammer supports a hierarchical physical design flow, which decomposes the design into several specified sub-components and runs the flow on each sub-components separetly. Hammer is then able to assemble these blocks together into a top-level design. This hierarchical approach speeds up the VLSI flow for large designs, especially designs in which there may me multiple instantiations of the same sub-components(since the sub-component can simply be replicated in the layout).
While hierarchical physical design can be performed in multiple ways (top-down, bottom-up, abutment etc.), Hammer currently supports only the bottom-up approach.
The bottom-up approach traverses a tree representing the hierarchy starting from the leaves and towards the direction of the root (the "top level"), and runs the physical design flow on each node of the hierarchy tree using the previously layed-out children nodes.
@@ -311,4 +311,4 @@ In this specification, ``vlsi.inputs.hierarchical.mode`` indicates the manual sp
Customizing Generated Tcl Scripts
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The ``example-vlsi`` python script is the Hammer entry script with placeholders for hooks. Hooks are additional snippets of python and TCL (via ``x.append()``) to extend the Hammer APIs. Hooks can be inserted using the ``make_pre/post/replacement_hook`` methods as shown in the ``example-vlsi`` entry script example. In this particular example, a list of hooks is paased in the ``get_extra_par_hooks`` function in the ``ExampleDriver`` class. Refer to the `Hammer documentation on hooks <https://hammer-vlsi.readthedocs.io/en/latest/Hammer-Use/Hooks.html>`__ for a detailed description of how these are injected into the VLSI flow.
The ``example-vlsi`` python script is the Hammer entry script with placeholders for hooks. Hooks are additional snippets of python and TCL (via ``x.append()``) to extend the Hammer APIs. Hooks can be inserted using the ``make_pre/post/replacement_hook`` methods as shown in the ``example-vlsi`` entry script example. In this particular example, a list of hooks is passed in the ``get_extra_par_hooks`` function in the ``ExampleDriver`` class. Refer to the `Hammer documentation on hooks <https://hammer-vlsi.readthedocs.io/en/latest/Hammer-Use/Hooks.html>`__ for a detailed description of how these are injected into the VLSI flow.

View File

@@ -49,6 +49,6 @@ Running the VLSI tool flow
--------------------------
For the full documentation on how to use the VLSI tool flow, see the `Hammer Documentation <https://hammer-vlsi.readthedocs.io/>`__.
For an example of how to use the VLSI in the context of Chipyard, see :ref:`VLSI/Tutorial:ASAP7 Tutorial`.
For an example of how to use the VLSI in the context of Chipyard, see :ref:`VLSI/ASAP7-Tutorial:ASAP7 Tutorial`.

View File

@@ -0,0 +1,157 @@
.. _sky130-tutorial:
Sky130 Tutorial
===============
The ``vlsi`` folder of this repository contains an example Hammer flow with the SHA-3 accelerator and a dummy hard macro. This example tutorial uses the built-in Sky130 technology plugin and requires access to the included Cadence and Mentor tool plugin submodules. Cadence is necessary for synthesis & place-and-route, while Mentor is needed for DRC & LVS.
Project Structure
-----------------
This example gives a suggested file structure and build system. The ``vlsi/`` folder will eventually contain the following files and folders:
* ``Makefile``, ``sim.mk``, ``power.mk``
* Integration of Hammer's build system into Chipyard and abstracts away some Hammer commands.
* ``build``
* Hammer output directory. Can be changed with the ``OBJ_DIR`` variable.
* Will contain subdirectories such as ``syn-rundir`` and ``par-rundir`` and the ``inputs.yml`` denoting the top module and input Verilog files.
* ``env.yml``
* A template file for tool environment configuration. Fill in the install and license server paths for your environment.
* ``example-vlsi-sky130``
* Entry point to Hammer. Contains example placeholders for hooks.
* ``example-sky130.yml``, ``example-tools.yml``
* Hammer IR for this tutorial.
* ``example-design.yml``, ``example-nangate45.yml``, ``example-tech.yml``
* Hammer IR not used for this tutorial but provided as templates.
* ``generated-src``
* All of the elaborated Chisel and FIRRTL.
* ``hammer``, ``hammer-<vendor>-plugins``, ``hammer-<tech>-plugin``
* Core, tool, tech repositories.
Prerequisites
-------------
* Python 3.4+
* numpy package
* Genus, Innovus, Voltus, VCS, and Calibre licenses
* Sky130 PDK, install using `these directions <https://github.com/ucb-bar/hammer/blob/master/src/hammer-vlsi/technology/sky130/README.md>`__
Initial Setup
-------------
In the Chipyard root, run:
.. code-block:: shell
./scripts/init-vlsi.sh sky130
to pull the Hammer & plugin submodules. Note that for technologies other than ``sky130`` or ``asap7``, the tech submodule must be added in the ``vlsi`` folder first.
Pull the Hammer environment into the shell:
.. code-block:: shell
cd vlsi
export HAMMER_HOME=$PWD/hammer
source $HAMMER_HOME/sourceme.sh
Building the Design
--------------------
To elaborate the ``TinyRocketConfig`` and set up all prerequisites for the build system to push the design and SRAM macros through the flow:
.. code-block:: shell
make buildfile tech_name=sky130 CONFIG=TinyRocketConfig
The ``CONFIG=TinyRocketConfig`` selects the target generator config in the same manner as the rest of the Chipyard framework. This elaborates a stripped-down Rocket Chip in the interest of minimizing tool runtime.
For the curious, ``make buildfile`` generates a set of Make targets in ``build/hammer.d``. It needs to be re-run if environment variables are changed. It is recommended that you edit these variables directly in the Makefile rather than exporting them to your shell environment.
Running the VLSI Flow
---------------------
example-vlsi-sky130
^^^^^^^^^^^^^^^^^^^
This is the entry script with placeholders for hooks. In the ``ExampleDriver`` class, a list of hooks is passed in the ``get_extra_par_hooks``. Hooks are additional snippets of python and TCL (via ``x.append()``) to extend the Hammer APIs. Hooks can be inserted using the ``make_pre/post/replacement_hook`` methods as shown in this example. Refer to the Hammer documentation on hooks for a detailed description of how these are injected into the VLSI flow.
example-sky130.yml
^^^^^^^^^^^^^^^^^^
This contains the Hammer configuration for this example project. Example clock constraints, power straps definitions, placement constraints, and pin constraints are given. Additional configuration for the extra libraries and tools are at the bottom.
First, set ``technology.sky130.sky130A/sky130_nda/openram_lib`` to the absolute path of the respective directories containing the Sky130 PDK and SRAM files. See the
`Sky130 Hammer plugin README <https://github.com/ucb-bar/hammer/blob/master/src/hammer-vlsi/technology/sky130/README.md>`__
for details about the PDK setup.
Synthesis
^^^^^^^^^
.. code-block:: shell
make syn tech_name=sky130 CONFIG=TinyRocketConfig
Post-synthesis logs and collateral are in ``build/syn-rundir``. The raw quality of results data is available at ``build/syn-rundir/reports``, and methods to extract this information for design space exploration are a work in progress.
Place-and-Route
^^^^^^^^^^^^^^^
.. code-block:: shell
make par tech_name=sky130 CONFIG=TinyRocketConfig
After completion, the final database can be opened in an interactive Innovus session via ``./build/par-rundir/generated-scripts/open_chip``.
Intermediate database are written in ``build/par-rundir`` between each step of the ``par`` action, and can be restored in an interactive Innovus session as desired for debugging purposes.
Timing reports are found in ``build/par-rundir/timingReports``. They are gzipped text files.
DRC & LVS
^^^^^^^^^
To run DRC & LVS, and view the results in Calibre:
.. code-block:: shell
make drc tech_name=sky130 CONFIG=TinyRocketConfig
./build/chipyard.TestHarness.TinyRocketConfig-ChipTop/drc-rundir/generated-scripts/view_drc
make lvs tech_name=sky130 CONFIG=TinyRocketConfig
./build/chipyard.TestHarness.TinyRocketConfig-ChipTop/lvs-rundir/generated-scripts/view_lvs
Some DRC errors are expected from this PDK, especially with regards to the SRAMs, as explained in the
`Sky130 Hammer plugin README <https://github.com/ucb-bar/hammer/blob/master/src/hammer-vlsi/technology/sky130/README.md>`__.
For this reason, the ``example-vlsi-sky130`` script black-boxes the SRAMs for DRC/LVS analysis.
Simulation
^^^^^^^^^^
Simulation with VCS is supported, and can be run at the RTL- or gate-level (post-synthesis and post-P&R). The simulation infrastructure as included here is intended for running RISC-V binaries on a Chipyard config. For example, for an RTL-level simulation:
.. code-block:: shell
make sim-rtl CONFIG=TinyRocketConfig BINARY=$RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-simple
Post-synthesis and post-P&R simulations use the ``sim-syn`` and ``sim-par`` make targets, respectively.
Appending ``-debug`` and ``-debug-timing`` to these make targets will instruct VCS to write a SAIF + VPD (or FSDB if the ``USE_FSDB`` flag is set) and do timing-annotated simulations, respectively. See the ``sim.mk`` file for all available targets.
Power/Rail Analysis
^^^^^^^^^^^^^^^^^^^
Post-P&R power and rail (IR drop) analysis is supported with Voltus:
.. code-block:: shell
make power-par tech_name=sky130 CONFIG=TinyRocketConfig
If you append the ``BINARY`` variable to the command, it will use the activity file generated from a ``sim-<syn/par>-debug`` run and report dynamic power & IR drop from the toggles encoded in the waveform.
To bypass gate-level simulation, you will need to run the power tool manually (see the generated commands in the generated ``hammer.d`` buildfile). Static and active (vectorless) power & IR drop will be reported.

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

View File

@@ -20,6 +20,8 @@
# import sys
# sys.path.insert(0, os.path.abspath('.'))
import os
import subprocess
# -- General configuration ------------------------------------------------
@@ -59,11 +61,32 @@ author = u'Berkeley Architecture Research'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = u''
# The full version, including alpha/beta/rc tags.
release = u''
on_rtd = os.environ.get("READTHEDOCS") == "True"
if on_rtd:
for item, value in os.environ.items():
print("[READTHEDOCS] {} = {}".format(item, value))
if on_rtd:
rtd_version = os.environ.get("READTHEDOCS_VERSION")
if rtd_version == "latest":
version = "main" # TODO: default to what "latest" points to
elif rtd_version == "stable":
# get the latest git tag (which is what rtd normally builds under "stable")
# this works since rtd builds things within the repo
process = subprocess.Popen(["git", "describe", "--exact-match", "--tags"], stdout=subprocess.PIPE)
output = process.communicate()[0].decode("utf-8").strip()
if process.returncode == 0:
version = output
else:
version = "v?.?.?" # this should not occur as "stable" is always pointing to tagged version
else:
version = rtd_version # name of a branch
else:
version = "v?.?.?"
# for now make these match
release = version
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -132,6 +155,17 @@ html_logo = '_static/images/chipyard-logo.png'
# Output file base name for HTML help builder.
htmlhelp_basename = 'Chipyarddoc'
# -- Misc Options ---------------------------------------------------------
html_context = {
"version": version
}
# add rst to end of each rst source file
# can put custom strings here that are generated from this file
rst_epilog = f"""
.. |overall_version| replace:: {version}
"""
# -- Options for LaTeX output ---------------------------------------------

View File

@@ -1,10 +1,5 @@
.. Chipyard documentation master file, created by
sphinx-quickstart on Fri Mar 8 11:46:38 2019.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Chipyard's documentation!
====================================
Welcome to Chipyard's documentation (version "|version|")!
==========================================================
.. image:: ./_static/images/chipyard-logo.svg

View File

@@ -118,8 +118,8 @@ $(BIT_FILE): $(synth_list_f)
-tclargs \
-top-module "$(MODEL)" \
-F "$(synth_list_f)" \
-ip-vivado-tcls "$(shell find '$(build_dir)' -name '*.vivado.tcl')" \
-board "$(BOARD)"
-board "$(BOARD)" \
-ip-vivado-tcls "$(shell find '$(build_dir)' -name '*.vivado.tcl')"
.PHONY: bitstream
bitstream: $(BIT_FILE)

View File

@@ -72,8 +72,8 @@ class WithArtyJTAGHarnessBinder extends OverrideHarnessBinder({
class WithArtyUARTHarnessBinder extends OverrideHarnessBinder({
(system: HasPeripheryUARTModuleImp, th: ArtyFPGATestHarness, ports: Seq[UARTPortIO]) => {
withClockAndReset(th.clock_32MHz, th.ck_rst) {
IOBUF(th.uart_txd_in, ports.head.txd)
ports.head.rxd := IOBUF(th.uart_rxd_out)
IOBUF(th.uart_rxd_out, ports.head.txd)
ports.head.rxd := IOBUF(th.uart_txd_in)
}
}
})

View File

@@ -7,7 +7,7 @@ import freechips.rocketchip.config.{Parameters}
import sifive.fpgashells.shell.xilinx.artyshell.{ArtyShell}
import chipyard.{BuildTop, HasHarnessSignalReferences, HasTestHarnessFunctions}
import chipyard.{BuildTop, HasHarnessSignalReferences}
import chipyard.harness.{ApplyHarnessBinders}
import chipyard.iobinders.{HasIOBinders}
@@ -34,9 +34,6 @@ class ArtyFPGATestHarness(override implicit val p: Parameters) extends ArtyShell
val dutReset = dReset
// must be after HasHarnessSignalReferences assignments
lazyDut match { case d: HasTestHarnessFunctions =>
d.harnessFunctions.foreach(_(this))
}
lazyDut match { case d: HasIOBinders =>
ApplyHarnessBinders(this, d.lazySystem, d.portMap)
}

View File

@@ -17,7 +17,7 @@ import sifive.blocks.devices.uart._
import sifive.blocks.devices.spi._
import sifive.blocks.devices.gpio._
import chipyard.{HasHarnessSignalReferences, HasTestHarnessFunctions, BuildTop, ChipTop, ExtTLMem, CanHaveMasterTLMemPort, DefaultClockFrequencyKey, HasReferenceClockFreq}
import chipyard.{HasHarnessSignalReferences, BuildTop, ChipTop, ExtTLMem, CanHaveMasterTLMemPort, DefaultClockFrequencyKey}
import chipyard.iobinders.{HasIOBinders}
import chipyard.harness.{ApplyHarnessBinders}
@@ -129,17 +129,11 @@ class VCU118FPGATestHarnessImp(_outer: VCU118FPGATestHarness) extends LazyRawMod
childReset := buildtopReset
// harness binders are non-lazy
_outer.topDesign match { case d: HasTestHarnessFunctions =>
d.harnessFunctions.foreach(_(this))
}
_outer.topDesign match { case d: HasIOBinders =>
ApplyHarnessBinders(this, d.lazySystem, d.portMap)
}
// check the top-level reference clock is equal to the default
// non-exhaustive since you need all ChipTop clocks to equal the default
_outer.topDesign match {
case d: HasReferenceClockFreq => require(d.refClockFreqMHz == p(DefaultClockFrequencyKey))
case _ =>
}
require(getRefClockFreq == p(DefaultClockFrequencyKey))
}

View File

@@ -15,10 +15,6 @@ import barstools.iocell.chisel._
case object BuildSystem extends Field[Parameters => LazyModule]((p: Parameters) => new DigitalTop()(p))
trait HasReferenceClockFreq {
def refClockFreqMHz: Double
}
/**
* The base class used for building chips. This constructor instantiates a module specified by the BuildSystem parameter,
* named "system", which is an instance of DigitalTop by default. The diplomatic clocks of System, as well as its implicit clock,
@@ -27,31 +23,14 @@ trait HasReferenceClockFreq {
*/
class ChipTop(implicit p: Parameters) extends LazyModule with BindingScope
with HasTestHarnessFunctions with HasReferenceClockFreq with HasIOBinders {
with HasIOBinders {
// The system module specified by BuildSystem
lazy val lazySystem = LazyModule(p(BuildSystem)(p)).suggestName("system")
// The implicitClockSinkNode provides the implicit clock and reset for the system (connected by clocking scheme)
val implicitClockSinkNode = ClockSinkNode(Seq(ClockSinkParameters(name = Some("implicit_clock"))))
// Generate Clocks and Reset
val mvRefClkFreq = p(ClockingSchemeKey)(this)
def refClockFreqMHz: Double = mvRefClkFreq.getWrappedValue
// NOTE: Making this a LazyRawModule is moderately dangerous, as anonymous children
// of ChipTop (ex: ClockGroup) do not receive clock or reset.
// However. anonymous children of ChipTop should not need an implicit Clock or Reset
// anyways, they probably need to be explicitly clocked.
lazy val module: LazyModuleImpLike = new LazyRawModuleImp(this) {
// These become the implicit clock and reset to the System
val implicit_clock = implicitClockSinkNode.in.head._1.clock
val implicit_reset = implicitClockSinkNode.in.head._1.reset
// Connect the implicit clock/reset, if present
lazySystem.module match { case l: LazyModuleImp => {
l.clock := implicit_clock
l.reset := implicit_reset
}}
}
lazy val module: LazyModuleImpLike = new LazyRawModuleImp(this) { }
}

View File

@@ -1,128 +0,0 @@
package chipyard
import chisel3._
import scala.collection.mutable.{ArrayBuffer}
import freechips.rocketchip.prci._
import freechips.rocketchip.subsystem.{BaseSubsystem, SubsystemDriveAsyncClockGroupsKey, InstantiatesTiles}
import freechips.rocketchip.config.{Parameters, Field, Config}
import freechips.rocketchip.diplomacy.{ModuleValue, OutwardNodeHandle, InModuleBody, LazyModule}
import freechips.rocketchip.util.{ResetCatchAndSync}
import barstools.iocell.chisel._
import testchipip.{TLTileResetCtrl}
import chipyard.clocking._
import chipyard.iobinders._
/**
* A simple reset implementation that punches out reset ports
* for standard Module classes. The ChipTop reset pin is Async.
* Synchronization is performed in the ClockGroupResetSynchronizer
*/
object GenerateReset {
def apply(chiptop: ChipTop, clock: Clock): Reset = {
implicit val p = chiptop.p
// this needs directionality so generateIOFromSignal works
val async_reset_wire = Wire(Input(AsyncReset()))
val (reset_io, resetIOCell) = IOCell.generateIOFromSignal(async_reset_wire, "reset", p(IOCellKey),
abstractResetAsAsync = true)
chiptop.iocells ++= resetIOCell
chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => {
reset_io := th.dutReset
Nil
})
async_reset_wire
}
}
case object ClockingSchemeKey extends Field[ChipTop => ModuleValue[Double]](ClockingSchemeGenerators.dividerOnlyClockGenerator)
/*
* This is a Seq of assignment functions, that accept a clock name and return an optional frequency.
* Functions that appear later in this seq have higher precedence that earlier ones.
* If no function returns a non-empty value, the value specified in
* [[DefaultClockFrequencyKey]] will be used.
*/
case object ClockFrequencyAssignersKey extends Field[Seq[(String) => Option[Double]]](Seq.empty)
case object DefaultClockFrequencyKey extends Field[Double]()
class ClockNameMatchesAssignment(name: String, fMHz: Double) extends Config((site, here, up) => {
case ClockFrequencyAssignersKey => up(ClockFrequencyAssignersKey, site) ++
Seq((cName: String) => if (cName == name) Some(fMHz) else None)
})
class ClockNameContainsAssignment(name: String, fMHz: Double) extends Config((site, here, up) => {
case ClockFrequencyAssignersKey => up(ClockFrequencyAssignersKey, site) ++
Seq((cName: String) => if (cName.contains(name)) Some(fMHz) else None)
})
object ClockingSchemeGenerators {
val dividerOnlyClockGenerator: ChipTop => ModuleValue[Double] = { chiptop =>
implicit val p = chiptop.p
// Requires existence of undriven asyncClockGroups in subsystem
val systemAsyncClockGroup = chiptop.lazySystem match {
case l: BaseSubsystem if (p(SubsystemDriveAsyncClockGroupsKey).isEmpty) =>
l.asyncClockGroupsNode
}
// Add a control register for each tile's reset
val resetSetter = chiptop.lazySystem match {
case sys: BaseSubsystem with InstantiatesTiles => Some(TLTileResetCtrl(sys))
case _ => None
}
val resetSetterResetProvider = resetSetter.map(_.tileResetProviderNode).getOrElse(ClockGroupEphemeralNode())
val aggregator = LazyModule(new ClockGroupAggregator("allClocks")).node
// provides the implicit clock to the system
(chiptop.implicitClockSinkNode
:= ClockGroup()
:= aggregator)
// provides the system clock (ex. the bus clocks)
(systemAsyncClockGroup
:*= ClockGroupNamePrefixer()
:*= aggregator)
val referenceClockSource = ClockSourceNode(Seq(ClockSourceParameters()))
val dividerOnlyClkGenerator = LazyModule(new DividerOnlyClockGenerator("buildTopClockGenerator"))
// provides all the divided clocks (from the top-level clock)
(aggregator
:= ClockGroupFrequencySpecifier(p(ClockFrequencyAssignersKey), p(DefaultClockFrequencyKey))
:= ClockGroupResetSynchronizer()
:= resetSetterResetProvider
:= dividerOnlyClkGenerator.node
:= referenceClockSource)
val asyncResetBroadcast = FixedClockBroadcast(None)
resetSetter.foreach(_.asyncResetSinkNode := asyncResetBroadcast)
val asyncResetSource = ClockSourceNode(Seq(ClockSourceParameters()))
asyncResetBroadcast := asyncResetSource
InModuleBody {
val clock_wire = Wire(Input(Clock()))
val reset_wire = GenerateReset(chiptop, clock_wire)
val (clock_io, clockIOCell) = IOCell.generateIOFromSignal(clock_wire, "clock", p(IOCellKey))
chiptop.iocells ++= clockIOCell
referenceClockSource.out.unzip._1.map { o =>
o.clock := clock_wire
o.reset := reset_wire
}
asyncResetSource.out.unzip._1.map { o =>
o.clock := false.B.asClock // async reset broadcast network does not provide a clock
o.reset := reset_wire
}
chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => {
clock_io := th.buildtopClock
Nil })
// return the reference frequency
dividerOnlyClkGenerator.module.referenceFreq
}
}
}

View File

@@ -1,337 +0,0 @@
package chipyard.config
import scala.util.matching.Regex
import chisel3._
import chisel3.util.{log2Up}
import freechips.rocketchip.config.{Field, Parameters, Config}
import freechips.rocketchip.subsystem._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.devices.tilelink.{BootROMLocated}
import freechips.rocketchip.devices.debug.{Debug, ExportDebug, DebugModuleKey, DMI}
import freechips.rocketchip.groundtest.{GroundTestSubsystem}
import freechips.rocketchip.tile._
import freechips.rocketchip.rocket.{RocketCoreParams, MulDivParams, DCacheParams, ICacheParams}
import freechips.rocketchip.tilelink.{HasTLBusParams}
import freechips.rocketchip.util.{AsyncResetReg, Symmetric}
import freechips.rocketchip.prci._
import freechips.rocketchip.stage.phases.TargetDirKey
import testchipip._
import tracegen.{TraceGenSystem}
import hwacha.{Hwacha}
import gemmini._
import boom.common.{BoomTileAttachParams}
import cva6.{CVA6TileAttachParams}
import sifive.blocks.devices.gpio._
import sifive.blocks.devices.uart._
import sifive.blocks.devices.spi._
import chipyard._
// -----------------------
// Common Config Fragments
// -----------------------
class WithBootROM extends Config((site, here, up) => {
case BootROMLocated(x) => up(BootROMLocated(x), site).map(_.copy(contentFileName = s"${site(TargetDirKey)}/bootrom.rv${site(XLen)}.img"))
})
// DOC include start: gpio config fragment
class WithGPIO extends Config((site, here, up) => {
case PeripheryGPIOKey => Seq(
GPIOParams(address = 0x10012000, width = 4, includeIOF = false))
})
// DOC include end: gpio config fragment
class WithUART(baudrate: BigInt = 115200) extends Config((site, here, up) => {
case PeripheryUARTKey => Seq(
UARTParams(address = 0x54000000L, nTxEntries = 256, nRxEntries = 256, initBaudRate = baudrate))
})
class WithSPIFlash(size: BigInt = 0x10000000) extends Config((site, here, up) => {
// Note: the default size matches freedom with the addresses below
case PeripherySPIFlashKey => Seq(
SPIFlashParams(rAddress = 0x10040000, fAddress = 0x20000000, fSize = size))
})
class WithL2TLBs(entries: Int) extends Config((site, here, up) => {
case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
core = tp.tileParams.core.copy(nL2TLBEntries = entries)))
case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
core = tp.tileParams.core.copy(nL2TLBEntries = entries)))
case other => other
}
})
class WithTracegenSystem extends Config((site, here, up) => {
case BuildSystem => (p: Parameters) => new TraceGenSystem()(p)
})
/**
* Map from a hartId to a particular RoCC accelerator
*/
case object MultiRoCCKey extends Field[Map[Int, Seq[Parameters => LazyRoCC]]](Map.empty[Int, Seq[Parameters => LazyRoCC]])
/**
* Config fragment to enable different RoCCs based on the hartId
*/
class WithMultiRoCC extends Config((site, here, up) => {
case BuildRoCC => site(MultiRoCCKey).getOrElse(site(TileKey).hartId, Nil)
})
/**
* Assigns what was previously in the BuildRoCC key to specific harts with MultiRoCCKey
* Must be paired with WithMultiRoCC
*/
class WithMultiRoCCFromBuildRoCC(harts: Int*) extends Config((site, here, up) => {
case BuildRoCC => Nil
case MultiRoCCKey => up(MultiRoCCKey, site) ++ harts.distinct.map { i =>
(i -> up(BuildRoCC, site))
}
})
/**
* Config fragment to add Hwachas to cores based on hart
*
* For ex:
* Core 0, 1, 2, 3 have been defined earlier
* with hartIds of 0, 1, 2, 3 respectively
* And you call WithMultiRoCCHwacha(0,1)
* Then Core 0 and 1 will get a Hwacha
*
* @param harts harts to specify which will get a Hwacha
*/
class WithMultiRoCCHwacha(harts: Int*) extends Config(
new chipyard.config.WithHwachaTest ++
new Config((site, here, up) => {
case MultiRoCCKey => {
up(MultiRoCCKey, site) ++ harts.distinct.map{ i =>
(i -> Seq((p: Parameters) => {
val hwacha = LazyModule(new Hwacha()(p))
hwacha
}))
}
}
})
)
class WithMultiRoCCGemmini[T <: Data : Arithmetic, U <: Data, V <: Data](
harts: Int*)(gemminiConfig: GemminiArrayConfig[T,U,V] = GemminiConfigs.defaultConfig) extends Config((site, here, up) => {
case MultiRoCCKey => up(MultiRoCCKey, site) ++ harts.distinct.map { i =>
(i -> Seq((p: Parameters) => {
implicit val q = p
val gemmini = LazyModule(new Gemmini(gemminiConfig))
gemmini
}))
}
})
class WithTraceIO extends Config((site, here, up) => {
case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
trace = true))
case tp: CVA6TileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
trace = true))
case other => other
}
case TracePortKey => Some(TracePortParams())
})
class WithNPerfCounters(n: Int = 29) extends Config((site, here, up) => {
case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
core = tp.tileParams.core.copy(nPerfCounters = n)))
case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
core = tp.tileParams.core.copy(nPerfCounters = n)))
case other => other
}
})
class WithNPMPs(n: Int = 8) extends Config((site, here, up) => {
case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
core = tp.tileParams.core.copy(nPMPs = n)))
case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
core = tp.tileParams.core.copy(nPMPs = n)))
case other => other
}
})
class WithRocketICacheScratchpad extends Config((site, here, up) => {
case RocketTilesKey => up(RocketTilesKey, site) map { r =>
r.copy(icache = r.icache.map(_.copy(itimAddr = Some(0x300000 + r.hartId * 0x10000))))
}
})
class WithRocketDCacheScratchpad extends Config((site, here, up) => {
case RocketTilesKey => up(RocketTilesKey, site) map { r =>
r.copy(dcache = r.dcache.map(_.copy(nSets = 32, nWays = 1, scratch = Some(0x200000 + r.hartId * 0x10000))))
}
})
// Replaces the L2 with a broadcast manager for maintaining coherence
class WithBroadcastManager extends Config((site, here, up) => {
case BankedL2Key => up(BankedL2Key, site).copy(coherenceManager = CoherenceManagerWrapper.broadcastManager)
})
class WithHwachaTest extends Config((site, here, up) => {
case TestSuitesKey => (tileParams: Seq[TileParams], suiteHelper: TestSuiteHelper, p: Parameters) => {
up(TestSuitesKey).apply(tileParams, suiteHelper, p)
import hwacha.HwachaTestSuites._
suiteHelper.addSuites(rv64uv.map(_("p")))
suiteHelper.addSuites(rv64uv.map(_("vp")))
suiteHelper.addSuite(rv64sv("p"))
suiteHelper.addSuite(hwachaBmarks)
"SRC_EXTENSION = $(base_dir)/hwacha/$(src_path)/*.scala" + "\nDISASM_EXTENSION = --extension=hwacha"
}
})
// The default RocketChip BaseSubsystem drives its diplomatic clock graph
// with the implicit clocks of Subsystem. Don't do that, instead we extend
// the diplomacy graph upwards into the ChipTop, where we connect it to
// our clock drivers
class WithNoSubsystemDrivenClocks extends Config((site, here, up) => {
case SubsystemDriveAsyncClockGroupsKey => None
})
class WithDMIDTM extends Config((site, here, up) => {
case ExportDebug => up(ExportDebug, site).copy(protocols = Set(DMI))
})
class WithNoDebug extends Config((site, here, up) => {
case DebugModuleKey => None
})
class WithTLSerialLocation(masterWhere: TLBusWrapperLocation, slaveWhere: TLBusWrapperLocation) extends Config((site, here, up) => {
case SerialTLAttachKey => up(SerialTLAttachKey, site).copy(masterWhere = masterWhere, slaveWhere = slaveWhere)
})
class WithTLBackingMemory extends Config((site, here, up) => {
case ExtMem => None // disable AXI backing memory
case ExtTLMem => up(ExtMem, site) // enable TL backing memory
})
class WithSerialTLBackingMemory extends Config((site, here, up) => {
case ExtMem => None
case SerialTLKey => up(SerialTLKey, site).map { k => k.copy(
memParams = {
val memPortParams = up(ExtMem, site).get
require(memPortParams.nMemoryChannels == 1)
memPortParams.master
},
isMemoryDevice = true
)}
})
/**
* Mixins to define either a specific tile frequency for a single hart or all harts
*
* @param fMHz Frequency in MHz of the tile or all tiles
* @param hartId Optional hartid to assign the frequency to (if unspecified default to all harts)
*/
class WithTileFrequency(fMHz: Double, hartId: Option[Int] = None) extends ClockNameContainsAssignment({
hartId match {
case Some(id) => s"tile_$id"
case None => "tile"
}
},
fMHz)
class WithPeripheryBusFrequencyAsDefault extends Config((site, here, up) => {
case DefaultClockFrequencyKey => (site(PeripheryBusKey).dtsFrequency.get / (1000 * 1000)).toDouble
})
class WithSystemBusFrequencyAsDefault extends Config((site, here, up) => {
case DefaultClockFrequencyKey => (site(SystemBusKey).dtsFrequency.get / (1000 * 1000)).toDouble
})
class BusFrequencyAssignment[T <: HasTLBusParams](re: Regex, key: Field[T]) extends Config((site, here, up) => {
case ClockFrequencyAssignersKey => up(ClockFrequencyAssignersKey, site) ++
Seq((cName: String) => site(key).dtsFrequency.flatMap { f =>
re.findFirstIn(cName).map {_ => (f / (1000 * 1000)).toDouble }
})
})
/**
* Provides a diplomatic frequency for all clock sinks with an unspecified
* frequency bound to each bus.
*
* For example, the L2 cache, when bound to the sbus, receives a separate
* clock that appears as "subsystem_sbus_<num>". This fragment ensures that
* clock requests the same frequency as the sbus itself.
*/
class WithInheritBusFrequencyAssignments extends Config(
new BusFrequencyAssignment("subsystem_sbus_\\d+".r, SystemBusKey) ++
new BusFrequencyAssignment("subsystem_pbus_\\d+".r, PeripheryBusKey) ++
new BusFrequencyAssignment("subsystem_cbus_\\d+".r, ControlBusKey) ++
new BusFrequencyAssignment("subsystem_fbus_\\d+".r, FrontBusKey) ++
new BusFrequencyAssignment("subsystem_mbus_\\d+".r, MemoryBusKey)
)
/**
* Mixins to specify crossing types between the 5 traditional TL buses
*
* Note: these presuppose the legacy connections between buses and set
* parameters in SubsystemCrossingParams; they may not be resuable in custom
* topologies (but you can specify the desired crossings in your topology).
*
* @param xType The clock crossing type
*
*/
class WithSbusToMbusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => {
case SbusToMbusXTypeKey => xType
})
class WithSbusToCbusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => {
case SbusToCbusXTypeKey => xType
})
class WithCbusToPbusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => {
case CbusToPbusXTypeKey => xType
})
class WithFbusToSbusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => {
case FbusToSbusXTypeKey => xType
})
/**
* Mixins to set the dtsFrequency field of BusParams -- these will percolate its way
* up the diplomatic graph to the clock sources.
*/
class WithPeripheryBusFrequency(freqMHz: Double) extends Config((site, here, up) => {
case PeripheryBusKey => up(PeripheryBusKey, site).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
})
class WithMemoryBusFrequency(freqMHz: Double) extends Config((site, here, up) => {
case MemoryBusKey => up(MemoryBusKey, site).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
})
class WithSystemBusFrequency(freqMHz: Double) extends Config((site, here, up) => {
case SystemBusKey => up(SystemBusKey, site).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
})
class WithFrontBusFrequency(freqMHz: Double) extends Config((site, here, up) => {
case FrontBusKey => up(FrontBusKey, site).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
})
class WithControlBusFrequency(freqMHz: Double) extends Config((site, here, up) => {
case ControlBusKey => up(ControlBusKey, site).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
})
class WithRationalMemoryBusCrossing extends WithSbusToMbusCrossingType(RationalCrossing(Symmetric))
class WithAsynchrousMemoryBusCrossing extends WithSbusToMbusCrossingType(AsynchronousCrossing())
class WithTestChipBusFreqs extends Config(
// Frequency specifications
new chipyard.config.WithTileFrequency(1600.0) ++ // Matches the maximum frequency of U540
new chipyard.config.WithSystemBusFrequency(800.0) ++ // Put the system bus at a lower freq, representative of ncore working at a lower frequency than the tiles. Same freq as U540
new chipyard.config.WithMemoryBusFrequency(1000.0) ++ // 2x the U540 freq (appropriate for a 128b Mbus)
new chipyard.config.WithPeripheryBusFrequency(800.0) ++ // Match the sbus and pbus frequency
new chipyard.config.WithSystemBusFrequencyAsDefault ++ // All unspecified clock frequencies, notably the implicit clock, will use the sbus freq (800 MHz)
// Crossing specifications
new chipyard.config.WithCbusToPbusCrossingType(AsynchronousCrossing()) ++ // Add Async crossing between PBUS and CBUS
new chipyard.config.WithSbusToMbusCrossingType(AsynchronousCrossing()) ++ // Add Async crossings between backside of L2 and MBUS
new freechips.rocketchip.subsystem.WithRationalRocketTiles ++ // Add rational crossings between RocketTile and uncore
new boom.common.WithRationalBoomTiles ++ // Add rational crossings between BoomTile and uncore
new testchipip.WithAsynchronousSerialSlaveCrossing // Add Async crossing between serial and MBUS. Its master-side is tied to the FBUS
)

View File

@@ -31,6 +31,8 @@ class DigitalTop(implicit p: Parameters) extends ChipyardSystem
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
with chipyard.clocking.HasChipyardPRCI // Use Chipyard reset/clock distribution
with fftgenerator.CanHavePeripheryFFT // Enables optionally having an MMIO-based FFT block
{
override lazy val module = new DigitalTopModule(this)
}

View File

@@ -22,7 +22,8 @@ import barstools.iocell.chisel._
import testchipip._
import chipyard.{HasHarnessSignalReferences, HarnessClockInstantiatorKey}
import chipyard.iobinders.{GetSystemParameters, JTAGChipIO}
import chipyard.clocking.{HasChipyardPRCI}
import chipyard.iobinders.{GetSystemParameters, JTAGChipIO, ClockWithFreq}
import tracegen.{TraceGenSystemModuleImp}
import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly}
@@ -322,8 +323,23 @@ class WithSimDromajoBridge extends ComposeHarnessBinder({
}
})
class WithTieOffCustomBootPin extends OverrideHarnessBinder({
class WithCustomBootPinPlusArg extends OverrideHarnessBinder({
(system: CanHavePeripheryCustomBootPin, th: HasHarnessSignalReferences, ports: Seq[Bool]) => {
ports.foreach(_ := false.B)
val pin = PlusArg("custom_boot_pin", width=1)
ports.foreach(_ := pin)
}
})
class WithClockAndResetFromHarness extends OverrideHarnessBinder({
(system: HasChipyardPRCI, th: HasHarnessSignalReferences, ports: Seq[Data]) => {
implicit val p = GetSystemParameters(system)
ports.map ({
case c: ClockWithFreq => {
th.setRefClockFreq(c.freqMHz)
c.clock := th.buildtopClock
}
case r: AsyncReset => r := th.buildtopReset.asAsyncReset
})
}
})

View File

@@ -11,7 +11,7 @@ import freechips.rocketchip.subsystem._
import freechips.rocketchip.system.{SimAXIMem}
import freechips.rocketchip.amba.axi4.{AXI4Bundle, AXI4SlaveNode, AXI4MasterNode, AXI4EdgeParameters}
import freechips.rocketchip.util._
import freechips.rocketchip.prci.{ClockSinkNode, ClockSinkParameters}
import freechips.rocketchip.prci._
import freechips.rocketchip.groundtest.{GroundTestSubsystemModuleImp, GroundTestSubsystem}
import sifive.blocks.devices.gpio._
@@ -23,6 +23,7 @@ import barstools.iocell.chisel._
import testchipip._
import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly}
import chipyard.clocking.{HasChipyardPRCI, DividerOnlyClockGenerator}
import scala.reflect.{ClassTag}
@@ -296,7 +297,7 @@ class WithAXI4MMIOPunchthrough extends OverrideLazyIOBinder({
(system: CanHaveMasterAXI4MMIOPort) => {
implicit val p: Parameters = GetSystemParameters(system)
val clockSinkNode = p(ExtBus).map(_ => ClockSinkNode(Seq(ClockSinkParameters())))
clockSinkNode.map(_ := system.asInstanceOf[HasTileLinkLocations].locateTLBusWrapper(MBUS).fixedClockNode)
clockSinkNode.map(_ := system.asInstanceOf[HasTileLinkLocations].locateTLBusWrapper(SBUS).fixedClockNode)
def clockBundle = clockSinkNode.get.in.head._1
InModuleBody {
@@ -384,3 +385,45 @@ class WithDontTouchPorts extends OverrideIOBinder({
(system: DontTouch) => system.dontTouchPorts(); (Nil, Nil)
})
class ClockWithFreq(val freqMHz: Double) extends Bundle {
val clock = Clock()
}
class WithDividerOnlyClockGenerator extends OverrideLazyIOBinder({
(system: HasChipyardPRCI) => {
// Connect the implicit clock
implicit val p = GetSystemParameters(system)
val implicitClockSinkNode = ClockSinkNode(Seq(ClockSinkParameters(name = Some("implicit_clock"))))
system.connectImplicitClockSinkNode(implicitClockSinkNode)
InModuleBody {
val implicit_clock = implicitClockSinkNode.in.head._1.clock
val implicit_reset = implicitClockSinkNode.in.head._1.reset
system.asInstanceOf[BaseSubsystem].module match { case l: LazyModuleImp => {
l.clock := implicit_clock
l.reset := implicit_reset
}}
}
// Connect all other requested clocks
val referenceClockSource = ClockSourceNode(Seq(ClockSourceParameters()))
val dividerOnlyClockGen = LazyModule(new DividerOnlyClockGenerator("buildTopClockGenerator"))
(system.allClockGroupsNode
:= dividerOnlyClockGen.node
:= referenceClockSource)
InModuleBody {
val clock_wire = Wire(Input(new ClockWithFreq(dividerOnlyClockGen.module.referenceFreq)))
val reset_wire = Wire(Input(AsyncReset()))
val (clock_io, clockIOCell) = IOCell.generateIOFromSignal(clock_wire, "clock", p(IOCellKey))
val (reset_io, resetIOCell) = IOCell.generateIOFromSignal(reset_wire, "reset", p(IOCellKey))
referenceClockSource.out.unzip._1.map { o =>
o.clock := clock_wire.clock
o.reset := reset_wire
}
(Seq(clock_io, reset_io), clockIOCell ++ resetIOCell)
}
}
})

View File

@@ -17,13 +17,14 @@ import chipyard.clocking.{SimplePllConfiguration, ClockDividerN}
// -------------------------------
case object BuildTop extends Field[Parameters => LazyModule]((p: Parameters) => new ChipTop()(p))
trait HasTestHarnessFunctions {
val harnessFunctions = ArrayBuffer.empty[HasHarnessSignalReferences => Seq[Any]]
}
case object DefaultClockFrequencyKey extends Field[Double](100.0) // MHz
trait HasHarnessSignalReferences {
implicit val p: Parameters
// clock/reset of the chiptop reference clock (can be different than the implicit harness clock/reset)
var refClockFreq: Double = p(DefaultClockFrequencyKey)
def setRefClockFreq(freqMHz: Double) = { refClockFreq = freqMHz }
def getRefClockFreq: Double = refClockFreq
def buildtopClock: Clock
def buildtopReset: Reset
def dutReset: Reset
@@ -90,25 +91,18 @@ class TestHarness(implicit val p: Parameters) extends Module with HasHarnessSign
io.success := false.B
val freqMHz = lazyDut match {
case d: HasReferenceClockFreq => d.refClockFreqMHz
case _ => p(DefaultClockFrequencyKey)
}
val refClkBundle = p(HarnessClockInstantiatorKey).requestClockBundle("buildtop_reference_clock", freqMHz * (1000 * 1000))
buildtopClock := refClkBundle.clock
buildtopReset := WireInit(refClkBundle.reset)
val dutReset = refClkBundle.reset.asAsyncReset
val dutReset = buildtopReset.asAsyncReset
val success = io.success
lazyDut match { case d: HasTestHarnessFunctions =>
d.harnessFunctions.foreach(_(this))
}
lazyDut match { case d: HasIOBinders =>
ApplyHarnessBinders(this, d.lazySystem, d.portMap)
}
val refClkBundle = p(HarnessClockInstantiatorKey).requestClockBundle("buildtop_reference_clock", getRefClockFreq * (1000 * 1000))
buildtopClock := refClkBundle.clock
buildtopReset := WireInit(refClkBundle.reset)
val implicitHarnessClockBundle = Wire(new ClockBundle(ClockBundleParameters()))
implicitHarnessClockBundle.clock := clock
implicitHarnessClockBundle.reset := reset

View File

@@ -0,0 +1,81 @@
package chipyard.clocking
import chisel3._
import chisel3.util._
import chisel3.experimental.{Analog, IO}
import freechips.rocketchip.config._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.prci._
import freechips.rocketchip.util._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.regmapper._
import freechips.rocketchip.subsystem._
object ClockGroupCombiner {
def apply()(implicit p: Parameters, valName: ValName): ClockGroupAdapterNode = {
LazyModule(new ClockGroupCombiner()).node
}
}
case object ClockGroupCombinerKey extends Field[Seq[(String, ClockSinkParameters => Boolean)]](Nil)
// All clock groups with a name containing any substring in names will be combined into a single clock group
class WithClockGroupsCombinedByName(grouped_name: String, names: String*) extends Config((site, here, up) => {
case ClockGroupCombinerKey => {
val combiner: ClockSinkParameters => Boolean = { m => names.map(n => m.name.get.contains(n)).reduce(_||_) }
up(ClockGroupCombinerKey) ++ Seq((grouped_name, combiner))
}
})
/** This node combines sets of clock groups according to functions provided in the ClockGroupCombinerKey
* The ClockGroupCombinersKey contains a list of tuples of:
* - The name of the combined group
* - A function on the ClockSinkParameters, returning True if the associated clock group should be grouped by this node
* This node will fail if
* - Multiple grouping functions match a single clock group
* - A grouping function matches zero clock groups
* - A grouping function matches clock groups with different requested frequncies
*/
class ClockGroupCombiner(implicit p: Parameters, v: ValName) extends LazyModule {
val combiners = p(ClockGroupCombinerKey)
val sourceFn: ClockGroupSourceParameters => ClockGroupSourceParameters = { m => m }
val sinkFn: ClockGroupSinkParameters => ClockGroupSinkParameters = { u =>
var i = 0
val (grouped, rest) = combiners.map(_._2).foldLeft((Seq[ClockSinkParameters](), u.members)) { case ((grouped, rest), c) =>
val (g, r) = rest.partition(c(_))
val name = combiners(i)._1
i = i + 1
require(g.size >= 1)
require(g.forall(_.take.get == g.head.take.get))
(grouped ++ Seq(ClockSinkParameters(take = g.head.take, name = Some(name))), r)
}
ClockGroupSinkParameters(
name = u.name,
members = grouped ++ rest
)
}
val node = ClockGroupAdapterNode(sourceFn, sinkFn)
lazy val module = new LazyRawModuleImp(this) {
(node.out zip node.in).map { case ((o, oe), (i, ie)) =>
{
val inMap = (i.member.data zip ie.sink.members).map { case (id, im) =>
im.name.get -> id
}.toMap
(o.member.data zip oe.sink.members).map { case (od, om) =>
val matches = combiners.filter(c => c._2(om))
require(matches.size <= 1)
if (matches.size == 0) {
od := inMap(om.name.get)
} else {
od := inMap(matches(0)._1)
}
}
}
}
}
}

View File

@@ -2,10 +2,23 @@ package chipyard.clocking
import chisel3._
import freechips.rocketchip.config.{Parameters}
import freechips.rocketchip.config.{Parameters, Config, Field}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.prci._
case object ClockFrequencyAssignersKey extends Field[Seq[(String) => Option[Double]]](Seq.empty)
class ClockNameMatchesAssignment(name: String, fMHz: Double) extends Config((site, here, up) => {
case ClockFrequencyAssignersKey => up(ClockFrequencyAssignersKey, site) ++
Seq((cName: String) => if (cName == name) Some(fMHz) else None)
})
class ClockNameContainsAssignment(name: String, fMHz: Double) extends Config((site, here, up) => {
case ClockFrequencyAssignersKey => up(ClockFrequencyAssignersKey, site) ++
Seq((cName: String) => if (cName.contains(name)) Some(fMHz) else None)
})
/**
* This sort of node can be used when it is a connectivity passthrough, but modifies
* the flow of parameters (which may result in changing the names of the underlying signals).

View File

@@ -0,0 +1,79 @@
package chipyard.clocking
import chisel3._
import scala.collection.mutable.{ArrayBuffer}
import freechips.rocketchip.config.{Parameters, Field, Config}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.regmapper._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.util._
import freechips.rocketchip.tile._
import freechips.rocketchip.prci._
import testchipip.{TLTileResetCtrl}
import chipyard.{DefaultClockFrequencyKey}
case class ChipyardPRCIControlParams(
slaveWhere: TLBusWrapperLocation = CBUS,
baseAddress: BigInt = 0x100000,
enableTileClockGating: Boolean = true
)
case object ChipyardPRCIControlKey extends Field[ChipyardPRCIControlParams](ChipyardPRCIControlParams())
trait HasChipyardPRCI { this: BaseSubsystem with InstantiatesTiles =>
require(p(SubsystemDriveAsyncClockGroupsKey).isEmpty, "Subsystem asyncClockGroups must be undriven")
implicit val n = ValName("chipyardPRCI")
val prciParams = p(ChipyardPRCIControlKey)
// Set up clock domain
private val tlbus = locateTLBusWrapper(prciParams.slaveWhere)
val prci_ctrl_domain = LazyModule(new ClockSinkDomain(name=Some("chipyard-prci-control")))
prci_ctrl_domain.clockNode := tlbus.fixedClockNode
// Aggregate all the clock groups into a single node
val aggregator = LazyModule(new ClockGroupAggregator("allClocks")).node
val allClockGroupsNode = ClockGroupEphemeralNode()
// There are two "sets" of clocks which must be dealt with
// 1. The implicit clock from the subsystem. RC is moving away from depending on this
// clock, but some modules still use it. Since the implicit clock sink node
// is created in the ChipTop (the hierarchy wrapping the subsystem), this function
// is provided to allow connecting that clock to the clock aggregator. This function
// should be called in the ChipTop context
def connectImplicitClockSinkNode(sink: ClockSinkNode) =
(sink
:= ClockGroup()
:= aggregator)
// 2. The rest of the diplomatic clocks in the subsystem are routed to this asyncClockGroupsNode
(asyncClockGroupsNode
:*= ClockGroupNamePrefixer()
:*= aggregator)
// Once all the clocks are gathered in the aggregator node, several steps remain
// 1. Assign frequencies to any clock groups which did not specify a frequency.
// 2. Combine duplicated clock groups (clock groups which physically should be in the same clock domain)
// 3. Synchronize reset to each clock group
// 4. Clock gate the clock groups corresponding to Tiles (if desired).
// 5. Add reset control registers to the tiles (if desired)
// The final clock group here contains physically distinct clock domains, which some PRCI node in a
// diplomatic IOBinder should drive
(aggregator
:= ClockGroupFrequencySpecifier(p(ClockFrequencyAssignersKey), p(DefaultClockFrequencyKey))
:= ClockGroupCombiner()
:= ClockGroupResetSynchronizer()
:= prci_ctrl_domain { TileClockGater(prciParams.baseAddress + 0x00000, tlbus, prciParams.enableTileClockGating) }
:= prci_ctrl_domain { TileResetSetter(prciParams.baseAddress + 0x10000, tlbus, tile_prci_domains.map(_.tile_reset_domain.clockNode.portParams(0).name.get), Nil) }
:= allClockGroupsNode)
}

View File

@@ -0,0 +1,55 @@
package chipyard.clocking
import chisel3._
import chisel3.util._
import chisel3.experimental.{Analog, IO}
import freechips.rocketchip.config._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.prci._
import freechips.rocketchip.util._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.regmapper._
import freechips.rocketchip.subsystem._
/** This node adds clock gating control registers.
* If deploying on a platform which does not support clock gating, deasserting the enable
* flag will generate the registers, preserving the same memory map and behavior, but will not
* generate any gaters
*/
class TileClockGater(address: BigInt, beatBytes: Int, enable: Boolean)(implicit p: Parameters, valName: ValName) extends LazyModule
{
val device = new SimpleDevice(s"clock-gater", Nil)
val clockNode = ClockGroupIdentityNode()
val tlNode = TLRegisterNode(Seq(AddressSet(address, 4096-1)), device, "reg/control", beatBytes=beatBytes)
lazy val module = new LazyModuleImp(this) {
val sources = clockNode.in.head._1.member.data.toSeq
val sinks = clockNode.out.head._1.member.elements.toSeq
val nSinks = sinks.size
val regs = (0 until nSinks).map({i =>
val sinkName = sinks(i)._1
val reg = withReset(sources(i).reset) { Module(new AsyncResetRegVec(w=1, init=1)) }
if (sinkName.contains("tile") && enable) {
println(s"ClockGate for ${sinkName} regmapped at ${(address+i*4).toString(16)}")
sinks(i)._2.clock := ClockGate(sources(i).clock, reg.io.q.asBool)
sinks(i)._2.reset := sources(i).reset
} else {
sinks(i)._2 := sources(i)
}
reg
})
tlNode.regmap((0 until nSinks).map({i =>
i*4 -> Seq(RegField.rwReg(1, regs(i).io))
}): _*)
}
}
object TileClockGater {
def apply(address: BigInt, tlbus: TLBusWrapper, enable: Boolean)(implicit p: Parameters, v: ValName) = {
val gater = LazyModule(new TileClockGater(address, tlbus.beatBytes, enable))
tlbus.toVariableWidthSlave(Some("clock-gater")) { gater.tlNode := TLBuffer() }
gater.clockNode
}
}

View File

@@ -0,0 +1,72 @@
package chipyard.clocking
import chisel3._
import chisel3.util._
import chisel3.experimental.{Analog, IO}
import freechips.rocketchip.config._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.prci._
import freechips.rocketchip.util._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.regmapper._
import freechips.rocketchip.subsystem._
// Currently only works if all tiles are already driven by independent clock groups
// TODO: After https://github.com/chipsalliance/rocket-chip/pull/2842 is merged, we should
// always put all tiles on independent clock groups
class TileResetSetter(address: BigInt, beatBytes: Int, tileNames: Seq[String], initResetHarts: Seq[Int])(implicit p: Parameters)
extends LazyModule {
val device = new SimpleDevice("tile-reset-setter", Nil)
val tlNode = TLRegisterNode(Seq(AddressSet(address, 4096-1)), device, "reg/control", beatBytes=beatBytes)
val clockNode = ClockGroupIdentityNode()
lazy val module = new LazyModuleImp(this) {
val nTiles = p(TilesLocated(InSubsystem)).size
require (nTiles <= 4096 / 4)
val tile_async_resets = Wire(Vec(nTiles, Reset()))
val r_tile_resets = (0 until nTiles).map({ i =>
tile_async_resets(i) := true.B.asAsyncReset // Remove this line after https://github.com/chipsalliance/rocket-chip/pull/2842
withReset (tile_async_resets(i)) {
Module(new AsyncResetRegVec(w=1, init=(if (initResetHarts.contains(i)) 1 else 0)))
}
})
tlNode.regmap((0 until nTiles).map({ i =>
i * 4 -> Seq(RegField.rwReg(1, r_tile_resets(i).io)),
}): _*)
val tileMap = tileNames.zipWithIndex.map({ case (n, i) =>
n -> (tile_async_resets(i), r_tile_resets(i).io.q)
})
(clockNode.out zip clockNode.in).map { case ((o, _), (i, _)) =>
(o.member.elements zip i.member.elements).foreach { case ((name, oD), (_, iD)) =>
oD.clock := iD.clock
oD.reset := iD.reset
for ((n, (rIn, rOut)) <- tileMap) {
if (name.contains(n)) {
println(name, n)
// Async because the reset coming out of the AsyncResetRegVec is
// clocked to the bus this is attached to, not the clock in this
// clock bundle. We expect a ClockGroupResetSynchronizer downstream
// to synchronize the resets
// Also, this or enforces that the tiles come out of reset after the reset of the system
oD.reset := (rOut.asBool || iD.reset.asBool).asAsyncReset
rIn := iD.reset
}
}
}
}
}
}
object TileResetSetter {
def apply(address: BigInt, tlbus: TLBusWrapper, tileNames: Seq[String], initResetHarts: Seq[Int])(implicit p: Parameters, v: ValName) = {
val setter = LazyModule(new TileResetSetter(address, tlbus.beatBytes, tileNames, initResetHarts))
tlbus.toVariableWidthSlave(Some("tile-reset-setter")) { setter.tlNode := TLBuffer() }
setter.clockNode
}
}

View File

@@ -21,7 +21,8 @@ class AbstractConfig extends Config(
new chipyard.harness.WithSimAXIMMIO ++ // add SimAXIMem for axi4 mmio port, if enabled
new chipyard.harness.WithTieOffInterrupts ++ // tie-off interrupt ports, if present
new chipyard.harness.WithTieOffL2FBusAXI ++ // tie-off external AXI4 master, if present
new chipyard.harness.WithTieOffCustomBootPin ++
new chipyard.harness.WithCustomBootPinPlusArg ++
new chipyard.harness.WithClockAndResetFromHarness ++
// The IOBinders instantiate ChipTop IOs to match desired digital IOs
// IOCells are generated for "Chip-like" IOs, while simulation-only IOs are directly punched through
@@ -34,12 +35,13 @@ class AbstractConfig extends Config(
new chipyard.iobinders.WithDebugIOCells ++
new chipyard.iobinders.WithUARTIOCells ++
new chipyard.iobinders.WithGPIOCells ++
new chipyard.iobinders.WithUARTIOCells ++
new chipyard.iobinders.WithSPIIOCells ++
new chipyard.iobinders.WithTraceIOPunchthrough ++
new chipyard.iobinders.WithExtInterruptIOCells ++
new chipyard.iobinders.WithCustomBootPin ++
new chipyard.iobinders.WithDividerOnlyClockGenerator ++
new testchipip.WithSerialTLWidth(32) ++ // fatten the serialTL interface to improve testing performance
new testchipip.WithDefaultSerialTL ++ // use serialized tilelink port to external serialadapter/harnessRAM
new chipyard.config.WithBootROM ++ // use default bootrom
new chipyard.config.WithUART ++ // add a UART

View File

@@ -0,0 +1,15 @@
package chipyard
import chisel3._
import freechips.rocketchip.config.{Config}
// ---------------------
// Ibex Configs
// ---------------------
// Multi-core and 32b heterogeneous configs are supported
class IbexConfig extends Config(
new ibex.WithNIbexCores(1) ++
new chipyard.config.AbstractConfig)

View File

@@ -21,6 +21,13 @@ class TinyRocketConfig extends Config(
new freechips.rocketchip.subsystem.With1TinyCore ++ // single tiny rocket-core
new chipyard.config.AbstractConfig)
// DOC include start: FFTRocketConfig
class FFTRocketConfig extends Config(
new fftgenerator.WithFFTGenerator(baseAddr=0x2000, numPoints=8, width=16, decPt=8) ++ // add 8-point mmio fft at 0x2000 with 16bit fixed-point numbers.
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig)
// DOC include end: FFTRocketConfig
class HwachaRocketConfig extends Config(
new chipyard.config.WithHwachaTest ++
new hwacha.DefaultHwachaConfig ++ // use Hwacha vector accelerator
@@ -135,14 +142,20 @@ class LoopbackNICRocketConfig extends Config(
// DOC include start: l1scratchpadrocket
class ScratchpadOnlyRocketConfig extends Config(
new testchipip.WithSerialPBusMem ++
new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++ // remove offchip mem port
new chipyard.config.WithL2TLBs(0) ++
new freechips.rocketchip.subsystem.WithNBanks(0) ++
new freechips.rocketchip.subsystem.WithNoMemPort ++
new freechips.rocketchip.subsystem.WithNoMemPort ++ // remove offchip mem port
new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use rocket l1 DCache scratchpad as base phys mem
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig)
// DOC include end: l1scratchpadrocket
class MMIOScratchpadOnlyRocketConfig extends Config(
new freechips.rocketchip.subsystem.WithDefaultMMIOPort ++ // add default external master port
new freechips.rocketchip.subsystem.WithDefaultSlavePort ++ // add default external slave port
new ScratchpadOnlyRocketConfig
)
class L1ScratchpadRocketConfig extends Config(
new chipyard.config.WithRocketICacheScratchpad ++ // use rocket ICache scratchpad
new chipyard.config.WithRocketDCacheScratchpad ++ // use rocket DCache scratchpad

View File

@@ -6,8 +6,10 @@ import freechips.rocketchip.rocket.{DCacheParams}
class AbstractTraceGenConfig extends Config(
new chipyard.harness.WithBlackBoxSimMem ++
new chipyard.harness.WithTraceGenSuccess ++
new chipyard.harness.WithClockAndResetFromHarness ++
new chipyard.iobinders.WithAXI4MemPunchthrough ++
new chipyard.iobinders.WithTraceGenSuccessPunchthrough ++
new chipyard.iobinders.WithDividerOnlyClockGenerator ++
new chipyard.config.WithTracegenSystem ++
new chipyard.config.WithNoSubsystemDrivenClocks ++
new chipyard.config.WithPeripheryBusFrequencyAsDefault ++

View File

@@ -0,0 +1,132 @@
package chipyard.config
import scala.util.matching.Regex
import chisel3._
import chisel3.util.{log2Up}
import freechips.rocketchip.config.{Field, Parameters, Config}
import freechips.rocketchip.subsystem._
import freechips.rocketchip.prci._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.util.{Symmetric}
import freechips.rocketchip.tilelink.{HasTLBusParams}
import chipyard._
import chipyard.clocking._
// The default RocketChip BaseSubsystem drives its diplomatic clock graph
// with the implicit clocks of Subsystem. Don't do that, instead we extend
// the diplomacy graph upwards into the ChipTop, where we connect it to
// our clock drivers
class WithNoSubsystemDrivenClocks extends Config((site, here, up) => {
case SubsystemDriveAsyncClockGroupsKey => None
})
/**
* Mixins to define either a specific tile frequency for a single hart or all harts
*
* @param fMHz Frequency in MHz of the tile or all tiles
* @param hartId Optional hartid to assign the frequency to (if unspecified default to all harts)
*/
class WithTileFrequency(fMHz: Double, hartId: Option[Int] = None) extends ClockNameContainsAssignment({
hartId match {
case Some(id) => s"tile_$id"
case None => "tile"
}
},
fMHz)
class WithPeripheryBusFrequencyAsDefault extends Config((site, here, up) => {
case DefaultClockFrequencyKey => (site(PeripheryBusKey).dtsFrequency.get / (1000 * 1000)).toDouble
})
class WithSystemBusFrequencyAsDefault extends Config((site, here, up) => {
case DefaultClockFrequencyKey => (site(SystemBusKey).dtsFrequency.get / (1000 * 1000)).toDouble
})
class BusFrequencyAssignment[T <: HasTLBusParams](re: Regex, key: Field[T]) extends Config((site, here, up) => {
case ClockFrequencyAssignersKey => up(ClockFrequencyAssignersKey, site) ++
Seq((cName: String) => site(key).dtsFrequency.flatMap { f =>
re.findFirstIn(cName).map {_ => (f / (1000 * 1000)).toDouble }
})
})
/**
* Provides a diplomatic frequency for all clock sinks with an unspecified
* frequency bound to each bus.
*
* For example, the L2 cache, when bound to the sbus, receives a separate
* clock that appears as "subsystem_sbus_<num>". This fragment ensures that
* clock requests the same frequency as the sbus itself.
*/
class WithInheritBusFrequencyAssignments extends Config(
new BusFrequencyAssignment("subsystem_sbus_\\d+".r, SystemBusKey) ++
new BusFrequencyAssignment("subsystem_pbus_\\d+".r, PeripheryBusKey) ++
new BusFrequencyAssignment("subsystem_cbus_\\d+".r, ControlBusKey) ++
new BusFrequencyAssignment("subsystem_fbus_\\d+".r, FrontBusKey) ++
new BusFrequencyAssignment("subsystem_mbus_\\d+".r, MemoryBusKey)
)
/**
* Mixins to specify crossing types between the 5 traditional TL buses
*
* Note: these presuppose the legacy connections between buses and set
* parameters in SubsystemCrossingParams; they may not be resuable in custom
* topologies (but you can specify the desired crossings in your topology).
*
* @param xType The clock crossing type
*
*/
class WithSbusToMbusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => {
case SbusToMbusXTypeKey => xType
})
class WithSbusToCbusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => {
case SbusToCbusXTypeKey => xType
})
class WithCbusToPbusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => {
case CbusToPbusXTypeKey => xType
})
class WithFbusToSbusCrossingType(xType: ClockCrossingType) extends Config((site, here, up) => {
case FbusToSbusXTypeKey => xType
})
/**
* Mixins to set the dtsFrequency field of BusParams -- these will percolate its way
* up the diplomatic graph to the clock sources.
*/
class WithPeripheryBusFrequency(freqMHz: Double) extends Config((site, here, up) => {
case PeripheryBusKey => up(PeripheryBusKey, site).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
})
class WithMemoryBusFrequency(freqMHz: Double) extends Config((site, here, up) => {
case MemoryBusKey => up(MemoryBusKey, site).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
})
class WithSystemBusFrequency(freqMHz: Double) extends Config((site, here, up) => {
case SystemBusKey => up(SystemBusKey, site).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
})
class WithFrontBusFrequency(freqMHz: Double) extends Config((site, here, up) => {
case FrontBusKey => up(FrontBusKey, site).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
})
class WithControlBusFrequency(freqMHz: Double) extends Config((site, here, up) => {
case ControlBusKey => up(ControlBusKey, site).copy(dtsFrequency = Some(BigInt((freqMHz * 1e6).toLong)))
})
class WithRationalMemoryBusCrossing extends WithSbusToMbusCrossingType(RationalCrossing(Symmetric))
class WithAsynchrousMemoryBusCrossing extends WithSbusToMbusCrossingType(AsynchronousCrossing())
class WithTestChipBusFreqs extends Config(
// Frequency specifications
new chipyard.config.WithTileFrequency(1600.0) ++ // Matches the maximum frequency of U540
new chipyard.config.WithSystemBusFrequency(800.0) ++ // Put the system bus at a lower freq, representative of ncore working at a lower frequency than the tiles. Same freq as U540
new chipyard.config.WithMemoryBusFrequency(1000.0) ++ // 2x the U540 freq (appropriate for a 128b Mbus)
new chipyard.config.WithPeripheryBusFrequency(800.0) ++ // Match the sbus and pbus frequency
new chipyard.config.WithSystemBusFrequencyAsDefault ++ // All unspecified clock frequencies, notably the implicit clock, will use the sbus freq (800 MHz)
// Crossing specifications
new chipyard.config.WithCbusToPbusCrossingType(AsynchronousCrossing()) ++ // Add Async crossing between PBUS and CBUS
new chipyard.config.WithSbusToMbusCrossingType(AsynchronousCrossing()) ++ // Add Async crossings between backside of L2 and MBUS
new freechips.rocketchip.subsystem.WithRationalRocketTiles ++ // Add rational crossings between RocketTile and uncore
new boom.common.WithRationalBoomTiles ++ // Add rational crossings between BoomTile and uncore
new testchipip.WithAsynchronousSerialSlaveCrossing // Add Async crossing between serial and MBUS. Its master-side is tied to the FBUS
)

View File

@@ -0,0 +1,74 @@
package chipyard.config
import scala.util.matching.Regex
import chisel3._
import chisel3.util.{log2Up}
import freechips.rocketchip.config.{Config}
import freechips.rocketchip.devices.tilelink.{BootROMLocated}
import freechips.rocketchip.devices.debug.{Debug, ExportDebug, DebugModuleKey, DMI}
import freechips.rocketchip.stage.phases.TargetDirKey
import freechips.rocketchip.subsystem._
import freechips.rocketchip.tile.{XLen}
import sifive.blocks.devices.gpio._
import sifive.blocks.devices.uart._
import sifive.blocks.devices.spi._
import testchipip._
import chipyard.{ExtTLMem}
// Set the bootrom to the Chipyard bootrom
class WithBootROM extends Config((site, here, up) => {
case BootROMLocated(x) => up(BootROMLocated(x), site)
.map(_.copy(contentFileName = s"${site(TargetDirKey)}/bootrom.rv${site(XLen)}.img"))
})
// DOC include start: gpio config fragment
class WithGPIO extends Config((site, here, up) => {
case PeripheryGPIOKey => Seq(
GPIOParams(address = 0x10012000, width = 4, includeIOF = false))
})
// DOC include end: gpio config fragment
class WithUART(baudrate: BigInt = 115200) extends Config((site, here, up) => {
case PeripheryUARTKey => Seq(
UARTParams(address = 0x54000000L, nTxEntries = 256, nRxEntries = 256, initBaudRate = baudrate))
})
class WithSPIFlash(size: BigInt = 0x10000000) extends Config((site, here, up) => {
// Note: the default size matches freedom with the addresses below
case PeripherySPIFlashKey => Seq(
SPIFlashParams(rAddress = 0x10040000, fAddress = 0x20000000, fSize = size))
})
class WithDMIDTM extends Config((site, here, up) => {
case ExportDebug => up(ExportDebug, site).copy(protocols = Set(DMI))
})
class WithNoDebug extends Config((site, here, up) => {
case DebugModuleKey => None
})
class WithTLSerialLocation(masterWhere: TLBusWrapperLocation, slaveWhere: TLBusWrapperLocation) extends Config((site, here, up) => {
case SerialTLAttachKey => up(SerialTLAttachKey, site).copy(masterWhere = masterWhere, slaveWhere = slaveWhere)
})
class WithTLBackingMemory extends Config((site, here, up) => {
case ExtMem => None // disable AXI backing memory
case ExtTLMem => up(ExtMem, site) // enable TL backing memory
})
class WithSerialTLBackingMemory extends Config((site, here, up) => {
case ExtMem => None
case SerialTLKey => up(SerialTLKey, site).map { k => k.copy(
memParams = {
val memPortParams = up(ExtMem, site).get
require(memPortParams.nMemoryChannels == 1)
memPortParams.master
},
isMemoryDevice = true
)}
})

View File

@@ -0,0 +1,87 @@
package chipyard.config
import chisel3._
import freechips.rocketchip.config.{Field, Parameters, Config}
import freechips.rocketchip.tile._
import freechips.rocketchip.diplomacy._
import hwacha.{Hwacha}
import gemmini._
import chipyard.{TestSuitesKey, TestSuiteHelper}
/**
* Map from a hartId to a particular RoCC accelerator
*/
case object MultiRoCCKey extends Field[Map[Int, Seq[Parameters => LazyRoCC]]](Map.empty[Int, Seq[Parameters => LazyRoCC]])
/**
* Config fragment to enable different RoCCs based on the hartId
*/
class WithMultiRoCC extends Config((site, here, up) => {
case BuildRoCC => site(MultiRoCCKey).getOrElse(site(TileKey).hartId, Nil)
})
/**
* Assigns what was previously in the BuildRoCC key to specific harts with MultiRoCCKey
* Must be paired with WithMultiRoCC
*/
class WithMultiRoCCFromBuildRoCC(harts: Int*) extends Config((site, here, up) => {
case BuildRoCC => Nil
case MultiRoCCKey => up(MultiRoCCKey, site) ++ harts.distinct.map { i =>
(i -> up(BuildRoCC, site))
}
})
/**
* Config fragment to add Hwachas to cores based on hart
*
* For ex:
* Core 0, 1, 2, 3 have been defined earlier
* with hartIds of 0, 1, 2, 3 respectively
* And you call WithMultiRoCCHwacha(0,1)
* Then Core 0 and 1 will get a Hwacha
*
* @param harts harts to specify which will get a Hwacha
*/
class WithMultiRoCCHwacha(harts: Int*) extends Config(
new chipyard.config.WithHwachaTest ++
new Config((site, here, up) => {
case MultiRoCCKey => {
up(MultiRoCCKey, site) ++ harts.distinct.map{ i =>
(i -> Seq((p: Parameters) => {
val hwacha = LazyModule(new Hwacha()(p))
hwacha
}))
}
}
})
)
class WithHwachaTest extends Config((site, here, up) => {
case TestSuitesKey => (tileParams: Seq[TileParams], suiteHelper: TestSuiteHelper, p: Parameters) => {
up(TestSuitesKey).apply(tileParams, suiteHelper, p)
import hwacha.HwachaTestSuites._
suiteHelper.addSuites(rv64uv.map(_("p")))
suiteHelper.addSuites(rv64uv.map(_("vp")))
suiteHelper.addSuite(rv64sv("p"))
suiteHelper.addSuite(hwachaBmarks)
"SRC_EXTENSION = $(base_dir)/hwacha/$(src_path)/*.scala" + "\nDISASM_EXTENSION = --extension=hwacha"
}
})
/**
* The MultiRoCCGemmini fragment functions similarly to the
* WithMultiRoCCHwacha fragment defined above
*/
class WithMultiRoCCGemmini[T <: Data : Arithmetic, U <: Data, V <: Data](
harts: Int*)(gemminiConfig: GemminiArrayConfig[T,U,V] = GemminiConfigs.defaultConfig) extends Config((site, here, up) => {
case MultiRoCCKey => up(MultiRoCCKey, site) ++ harts.distinct.map { i =>
(i -> Seq((p: Parameters) => {
implicit val q = p
val gemmini = LazyModule(new Gemmini(gemminiConfig))
gemmini
}))
}
})

View File

@@ -0,0 +1,13 @@
package chipyard.config
import freechips.rocketchip.config.{Config}
import freechips.rocketchip.subsystem.{SystemBusKey, BankedL2Key, CoherenceManagerWrapper}
// Replaces the L2 with a broadcast manager for maintaining coherence
class WithBroadcastManager extends Config((site, here, up) => {
case BankedL2Key => up(BankedL2Key, site).copy(coherenceManager = CoherenceManagerWrapper.broadcastManager)
})
class WithSystemBusWidth(bitWidth: Int) extends Config((site, here, up) => {
case SystemBusKey => up(SystemBusKey, site).copy(beatBytes=bitWidth/8)
})

View File

@@ -0,0 +1,67 @@
package chipyard.config
import chisel3._
import freechips.rocketchip.config.{Field, Parameters, Config}
import freechips.rocketchip.tile._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.rocket.{RocketCoreParams, MulDivParams, DCacheParams, ICacheParams}
import boom.common.{BoomTileAttachParams}
import cva6.{CVA6TileAttachParams}
import testchipip._
class WithL2TLBs(entries: Int) extends Config((site, here, up) => {
case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
core = tp.tileParams.core.copy(nL2TLBEntries = entries)))
case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
core = tp.tileParams.core.copy(nL2TLBEntries = entries)))
case other => other
}
})
class WithTraceIO extends Config((site, here, up) => {
case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
trace = true))
case tp: CVA6TileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
trace = true))
case other => other
}
case TracePortKey => Some(TracePortParams())
})
class WithNPerfCounters(n: Int = 29) extends Config((site, here, up) => {
case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
core = tp.tileParams.core.copy(nPerfCounters = n)))
case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
core = tp.tileParams.core.copy(nPerfCounters = n)))
case other => other
}
})
class WithNPMPs(n: Int = 8) extends Config((site, here, up) => {
case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map {
case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
core = tp.tileParams.core.copy(nPMPs = n)))
case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy(
core = tp.tileParams.core.copy(nPMPs = n)))
case other => other
}
})
class WithRocketICacheScratchpad extends Config((site, here, up) => {
case RocketTilesKey => up(RocketTilesKey, site) map { r =>
r.copy(icache = r.icache.map(_.copy(itimAddr = Some(0x300000 + r.hartId * 0x10000))))
}
})
class WithRocketDCacheScratchpad extends Config((site, here, up) => {
case RocketTilesKey => up(RocketTilesKey, site) map { r =>
r.copy(dcache = r.dcache.map(_.copy(nSets = 32, nWays = 1, scratch = Some(0x200000 + r.hartId * 0x10000))))
}
})

View File

@@ -0,0 +1,14 @@
package chipyard.config
import freechips.rocketchip.config.{Config, Field, Parameters}
import tracegen.{TraceGenSystem}
import chipyard.{BuildSystem}
import chipyard.clocking.{HasChipyardPRCI}
class TraceGenTop(implicit p: Parameters) extends TraceGenSystem
with HasChipyardPRCI
class WithTracegenSystem extends Config((site, here, up) => {
case BuildSystem => (p: Parameters) => new TraceGenTop()(p)
})

View File

@@ -52,7 +52,7 @@ class InitZeroModuleImp(outer: InitZero) extends LazyModuleImp(outer) {
state := s_resp
}
when (mem.d.fire()) {
when (mem.d.fire) {
state := Mux(bytesLeft === 0.U, s_done, s_write)
}
}

View File

@@ -28,6 +28,7 @@ case class MyCoreParams(
enableToFromHostCaching: Boolean = false,
) extends CoreParams {
val useVM: Boolean = true
val useHypervisor: Boolean = false
val useUser: Boolean = true
val useSupervisor: Boolean = false
val useDebug: Boolean = true
@@ -41,6 +42,7 @@ case class MyCoreParams(
val fpu: Option[FPUParams] = Some(FPUParams()) // copied fma latencies from Rocket
val nLocalInterrupts: Int = 0
val useNMI: Boolean = false
val nPTECacheEntries: Int = 0 // TODO: Check
val nPMPs: Int = 0 // TODO: Check
val pmpGranularity: Int = 4 // copied from Rocket
val nBreakpoints: Int = 0 // TODO: Check

View File

@@ -25,8 +25,6 @@ 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)
@@ -43,8 +41,6 @@ object GenericFIRCellIO {
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)
@@ -119,7 +115,7 @@ class GenericFIRDirectCell[T<:Data:Ring](genIn: T, genOut: T) extends Module {
// 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()) {
when (io.in.fire) {
hasNewData := 1.U
inputReg := io.in.bits.data
}
@@ -127,7 +123,7 @@ class GenericFIRDirectCell[T<:Data:Ring](genIn: T, genOut: T) extends Module {
// 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.valid := hasNewData & io.in.fire
io.out.bits.data := inputReg
// Compute carry

View File

@@ -26,8 +26,6 @@ case object StreamingPassthroughKey extends Field[Option[StreamingPassthroughPar
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)

View File

@@ -10,6 +10,5 @@ trait ChipyardCli { this: Shell =>
parser.note("Chipyard Generator Options")
Seq(
UnderscoreDelimitedConfigsAnnotation
)
.foreach(_.addOptions(parser))
).foreach(_.addOptions(parser))
}

View File

@@ -13,7 +13,7 @@ import freechips.rocketchip.system.RocketChipStage
import firrtl.options.{Phase, PhaseManager, PreservesAll, Shell, Stage, StageError, StageMain, Dependency}
import firrtl.options.phases.DeletedWrapper
class ChipyardStage extends ChiselStage with PreservesAll[Phase] {
class ChipyardStage extends ChiselStage {
override val shell = new Shell("chipyard") with ChipyardCli with RocketChipCli with ChiselCli with FirrtlCli
override val targets: Seq[PhaseDependency] = Seq(
Dependency[freechips.rocketchip.stage.phases.Checks],
@@ -33,4 +33,5 @@ class ChipyardStage extends ChiselStage with PreservesAll[Phase] {
Dependency[chipyard.stage.phases.GenerateTestSuiteMakefrags],
Dependency[freechips.rocketchip.stage.phases.GenerateArtefacts],
)
override final def invalidates(a: Phase): Boolean = false
}

View File

@@ -22,7 +22,7 @@ import freechips.rocketchip.tile.XLen
import chipyard.TestSuiteHelper
import chipyard.TestSuitesKey
class AddDefaultTests extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils {
class AddDefaultTests extends Phase with HasRocketChipStageUtils {
// Make sure we run both after RocketChip's version of this phase, and Rocket Chip's annotation emission phase
// because the RocketTestSuiteAnnotation is not serializable (but is not marked as such).
override val prerequisites = Seq(
@@ -52,4 +52,6 @@ class AddDefaultTests extends Phase with PreservesAll[Phase] with HasRocketChipS
implicit val p = getConfig(view[RocketChipOptions](annotations).configNames.get).toInstance
addTestSuiteAnnotations ++ oAnnos
}
override final def invalidates(a: Phase): Boolean = false
}

View File

@@ -21,7 +21,7 @@ trait MakefragSnippet { self: Annotation =>
case class CustomMakefragSnippet(val toMakefrag: String) extends NoTargetAnnotation with MakefragSnippet with Unserializable
/** Generates a make script to run tests in [[RocketTestSuiteAnnotation]]. */
class GenerateTestSuiteMakefrags extends Phase with PreservesAll[Phase] with HasRocketChipStageUtils {
class GenerateTestSuiteMakefrags extends Phase with HasRocketChipStageUtils {
// Our annotations tend not to be serializable, but are not marked as such.
override val prerequisites = Seq(Dependency[freechips.rocketchip.stage.phases.GenerateFirrtlAnnos],
@@ -46,4 +46,6 @@ class GenerateTestSuiteMakefrags extends Phase with PreservesAll[Phase] with Has
writeOutputFile(targetDir, fileName, TestGeneration.generateMakeFrag ++ makefragBuilder.toString)
outputAnnotations
}
override final def invalidates(a: Phase): Boolean = false
}

Some files were not shown because too many files have changed in this diff Show More