Merge pull request #189 from ucb-bar/dev

Fix master with dev changes
This commit is contained in:
Abraham Gonzalez
2019-08-11 11:41:52 -07:00
committed by GitHub
93 changed files with 3369 additions and 793 deletions

View File

@@ -1,7 +1,7 @@
REBAR CI
========
Chipyard CI
===========
Website: https://circleci.com/gh/ucb-bar/project-template
Website: https://circleci.com/gh/ucb-bar/chipyard
CircleCI Brief Explanation
---------------------------
@@ -32,17 +32,18 @@ Here the key is built from a string where the `checksum` portion converts the fi
.circleci directory
-------------------
This directory contains all the collateral for the REBAR CI to work.
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
build-verilator.sh # build verilator
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
config.yml # main circleci config script to enumerate jobs/workflows
How things are setup for REBAR
------------------------------
`build-toolchains.sh` # build either riscv-tools or esp-tools
`build-verilator.sh` # build verilator (remotely)
`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
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).
@@ -52,3 +53,18 @@ The docker image sets up the `PATH` and `RISCV` variable so that `riscv-tools` i
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).
4th, finally run the tests that were wanted.
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

@@ -6,10 +6,13 @@
# turn echo on and error on earliest command
set -ex
if [ ! -d "$HOME/$1-install" ]; then
# get shared variables
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
source $SCRIPT_DIR/defaults.sh
cd $HOME/
if [ ! -d "$HOME/$1-install" ]; then
cd $HOME
# init all submodules including the tools
REBAR_DIR=$HOME/project ./project/scripts/build-toolchains.sh $1
CHIPYARD_DIR=$LOCAL_CHIPYARD_DIR $LOCAL_CHIPYARD_DIR/scripts/build-toolchains.sh $1
fi

View File

@@ -5,11 +5,31 @@
# turn echo on and error on earliest command
set -ex
cd $HOME/project
# get shared variables
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
source $SCRIPT_DIR/defaults.sh
cd sims/verisim
# call clean on exit
trap clean EXIT
if [ ! -d "$HOME/project/sims/verisim/verilator" ]; then
# make verilator
make verilator_install
run_script $LOCAL_CHIPYARD_DIR/.circleci/clean-old-files.sh $CI_DIR
if [ ! -d "$LOCAL_VERILATOR_DIR" ]; then
# set stricthostkeychecking to no (must happen before rsync)
run "echo \"Ping $SERVER\""
clean
run "mkdir -p $REMOTE_CHIPYARD_DIR"
copy $LOCAL_CHIPYARD_DIR/ $SERVER:$REMOTE_CHIPYARD_DIR
run "make -C $REMOTE_SIM_DIR VERILATOR_INSTALL_DIR=$REMOTE_VERILATOR_DIR verilator_install"
# copy so that circleci can cache
mkdir -p $LOCAL_CHIPYARD_DIR
mkdir -p $LOCAL_VERILATOR_DIR
copy $SERVER:$REMOTE_CHIPYARD_DIR/ $LOCAL_CHIPYARD_DIR
copy $SERVER:$REMOTE_VERILATOR_DIR/ $LOCAL_VERILATOR_DIR
cp -r $LOCAL_VERILATOR_DIR/install/bin/* $LOCAL_VERILATOR_DIR/install/share/verilator/bin/.
fi

45
.circleci/check-commit.sh Executable file
View File

@@ -0,0 +1,45 @@
#!/bin/bash
# check to see that submodule commits are present on the master branch
# turn echo on and error on earliest command
set -ex
# get shared variables
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
source $SCRIPT_DIR/defaults.sh
# enter bhd repo
cd $LOCAL_CHIPYARD_DIR
# initialize submodules and get the hashes
git config submodule.vlsi/hammer-cad-plugins.update none
git submodule update --init
status=$(git submodule status)
search () {
for submodule in "${submodules[@]}"
do
echo "Running check on submodule $submodule in $dir"
hash=$(echo "$status" | grep $submodule | awk '{print$1}' | grep -o "[[:alnum:]]*")
echo "Searching for $hash in origin/master of $submodule"
git -C $dir/$submodule branch -r --contains "$hash" | grep "origin/master" # needs init'ed submodules
done
}
submodules=("boom" "hwacha" "icenet" "rocket-chip" "sifive-blocks" "sifive-cache" "testchipip")
dir="generators"
search
submodules=("esp-tools" "riscv-tools")
dir="toolchains"
search
submodules=("barstools" "chisel3" "firrtl" "torture")
dir="tools"
search
echo "Done checking all submodules"

29
.circleci/clean-old-files.sh Executable file
View File

@@ -0,0 +1,29 @@
#!/bin/bash
# clean directories that are older than 30 days
# argument is used as the directory to look in
age () {
local AGE_SEC
local CUR_SEC
local DIFF_SEC
local SEC_PER_DAY
SEC_PER_DAY=86400
CUR_SEC=$(date +%s)
AGE_SEC=$(stat -c %Y -- "$1")
DIFF_SEC=$(expr $CUR_SEC - $AGE_SEC)
echo $(expr $DIFF_SEC / $SEC_PER_DAY)
}
for d in $1/*/ ; do
DIR_AGE="$(age $d)"
if [ $DIR_AGE -ge 30 ]; then
echo "Deleting $d since is it $DIR_AGE old"
rm -rf $d
else
echo "Keep $d since it is $DIR_AGE old"
fi
done

View File

@@ -5,471 +5,455 @@ version: 2
# set of jobs to run
jobs:
install-riscv-toolchain:
commit-on-master-check:
docker:
- image: riscvboom/riscvboom-images:0.0.5
- image: riscvboom/riscvboom-images:0.0.10
environment:
JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
TERM: dumb
steps:
- checkout
- run:
name: Check commits of each submodule
command: |
.circleci/check-commit.sh
install-riscv-toolchain:
docker:
- image: riscvboom/riscvboom-images:0.0.10
environment:
JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
TERM: dumb
steps:
# Checkout the code
- checkout
- run:
name: Create hash of toolchains
command: |
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
- run:
name: Building riscv-tools toolchain
command: |
.circleci/build-toolchains.sh riscv-tools
no_output_timeout: 120m
- save_cache:
key: riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
paths:
- "/home/riscvuser/riscv-tools-install"
install-esp-toolchain:
docker:
- image: riscvboom/riscvboom-images:0.0.5
- image: riscvboom/riscvboom-images:0.0.10
environment:
JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
TERM: dumb
steps:
# Checkout the code
- checkout
- run:
name: Create hash of toolchains
command: |
.circleci/create-hash.sh
- restore_cache:
keys:
- esp-tools-installed-v1-{{ checksum "../esp-tools.hash" }}
- run:
name: Building esp-tools toolchain
command: |
.circleci/build-toolchains.sh esp-tools
no_output_timeout: 120m
- save_cache:
key: esp-tools-installed-v1-{{ checksum "../esp-tools.hash" }}
paths:
- "/home/riscvuser/esp-tools-install"
install-verilator:
docker:
- image: riscvboom/riscvboom-images:0.0.5
- image: riscvboom/riscvboom-images:0.0.10
environment:
JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
TERM: dumb
steps:
# Checkout the code
- add_ssh_keys:
fingerprints:
- "3e:c3:02:5b:ed:64:8c:b7:b0:04:43:bc:83:43:73:1e"
- checkout
- restore_cache:
keys:
- verilator-installed-v1-{{ checksum "sims/verisim/verilator.mk" }}
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Build Verilator
command: |
.circleci/build-verilator.sh
no_output_timeout: 120m
- save_cache:
key: verilator-installed-v1-{{ checksum "sims/verisim/verilator.mk" }}
key: verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
paths:
- "/home/riscvuser/project/sims/verisim/verilator"
- "/home/riscvuser/verilator"
prepare-example:
docker:
- image: riscvboom/riscvboom-images:0.0.5
- image: riscvboom/riscvboom-images:0.0.10
environment:
JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
TERM: dumb
steps:
# Checkout the code
- add_ssh_keys:
fingerprints:
- "3e:c3:02:5b:ed:64:8c:b7:b0:04:43:bc:83:43:73:1e"
- checkout
- run:
name: Create hash of toolchains
command: |
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v1-{{ checksum "sims/verisim/verilator.mk" }}
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Building the example subproject using Verilator
command: .circleci/do-rtl-build.sh SUB_PROJECT=example
command: .circleci/do-rtl-build.sh example
no_output_timeout: 120m
- save_cache:
key: example-{{ .Branch }}-{{ .Revision }}
paths:
- "/home/riscvuser/project"
prepare-boomexample:
docker:
- image: riscvboom/riscvboom-images:0.0.5
- image: riscvboom/riscvboom-images:0.0.10
environment:
JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
TERM: dumb
steps:
# Checkout the code
- add_ssh_keys:
fingerprints:
- "3e:c3:02:5b:ed:64:8c:b7:b0:04:43:bc:83:43:73:1e"
- checkout
- run:
name: Create hash of toolchains
command: |
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v1-{{ checksum "sims/verisim/verilator.mk" }}
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Building the boomexample subproject using Verilator
command: .circleci/do-rtl-build.sh SUB_PROJECT=example CONFIG=SmallDefaultBoomConfig
command: .circleci/do-rtl-build.sh boomexample
no_output_timeout: 120m
- save_cache:
key: boomexample-{{ .Branch }}-{{ .Revision }}
paths:
- "/home/riscvuser/project"
prepare-boomrocketexample:
docker:
- image: riscvboom/riscvboom-images:0.0.5
- image: riscvboom/riscvboom-images:0.0.10
environment:
JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
TERM: dumb
steps:
# Checkout the code
- add_ssh_keys:
fingerprints:
- "3e:c3:02:5b:ed:64:8c:b7:b0:04:43:bc:83:43:73:1e"
- checkout
- run:
name: Create hash of toolchains
command: |
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v1-{{ checksum "sims/verisim/verilator.mk" }}
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Building the boomrocketexample subproject using Verilator
command: .circleci/do-rtl-build.sh SUB_PROJECT=example CONFIG=SmallDefaultBoomAndRocketConfig
command: .circleci/do-rtl-build.sh boomrocketexample
no_output_timeout: 120m
- save_cache:
key: boomrocketexample-{{ .Branch }}-{{ .Revision }}
paths:
- "/home/riscvuser/project"
prepare-boom:
docker:
- image: riscvboom/riscvboom-images:0.0.5
- image: riscvboom/riscvboom-images:0.0.10
environment:
JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
TERM: dumb
steps:
# Checkout the code
- add_ssh_keys:
fingerprints:
- "3e:c3:02:5b:ed:64:8c:b7:b0:04:43:bc:83:43:73:1e"
- checkout
- run:
name: Create hash of toolchains
command: |
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v1-{{ checksum "sims/verisim/verilator.mk" }}
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Building the boom subproject using Verilator
command: .circleci/do-rtl-build.sh SUB_PROJECT=boom
command: .circleci/do-rtl-build.sh boom
no_output_timeout: 120m
- save_cache:
key: boom-{{ .Branch }}-{{ .Revision }}
paths:
- "/home/riscvuser/project"
prepare-rocketchip:
docker:
- image: riscvboom/riscvboom-images:0.0.5
- image: riscvboom/riscvboom-images:0.0.10
environment:
JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
TERM: dumb
steps:
# Checkout the code
- add_ssh_keys:
fingerprints:
- "3e:c3:02:5b:ed:64:8c:b7:b0:04:43:bc:83:43:73:1e"
- checkout
- run:
name: Create hash of toolchains
command: |
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v1-{{ checksum "sims/verisim/verilator.mk" }}
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Building the rocketchip subproject using Verilator
command: .circleci/do-rtl-build.sh SUB_PROJECT=rocketchip
command: .circleci/do-rtl-build.sh rocketchip
no_output_timeout: 120m
- save_cache:
key: rocketchip-{{ .Branch }}-{{ .Revision }}
paths:
- "/home/riscvuser/project"
prepare-hwacha-verilog-only:
prepare-blockdevrocketchip:
docker:
- image: riscvboom/riscvboom-images:0.0.5
- image: riscvboom/riscvboom-images:0.0.10
environment:
JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
TERM: dumb
steps:
# Checkout the code
- add_ssh_keys:
fingerprints:
- "3e:c3:02:5b:ed:64:8c:b7:b0:04:43:bc:83:43:73:1e"
- checkout
- run:
name: Create hash of toolchains
command: |
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v1-{{ checksum "sims/verisim/verilator.mk" }}
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Building the blockdevrocketchip subproject using Verilator
command: .circleci/do-rtl-build.sh blockdevrocketchip
no_output_timeout: 120m
- save_cache:
key: blockdevrocketchip-{{ .Branch }}-{{ .Revision }}
paths:
- "/home/riscvuser/project"
prepare-hwacha:
docker:
- image: riscvboom/riscvboom-images:0.0.10
environment:
JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
TERM: dumb
steps:
- add_ssh_keys:
fingerprints:
- "3e:c3:02:5b:ed:64:8c:b7:b0:04:43:bc:83:43:73:1e"
- checkout
- run:
name: Create hash of toolchains
command: |
.circleci/create-hash.sh
- restore_cache:
keys:
- esp-tools-installed-v1-{{ checksum "../esp-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Building the hwacha subproject using Verilator
command: .circleci/do-rtl-build.sh SUB_PROJECT=hwacha verilog
command: .circleci/do-rtl-build.sh hwacha
no_output_timeout: 120m
- save_cache:
key: hwacha-{{ .Branch }}-{{ .Revision }}
paths:
- "/home/riscvuser/project"
example-run-benchmark-tests:
example-run-tests:
docker:
- image: riscvboom/riscvboom-images:0.0.5
- image: riscvboom/riscvboom-images:0.0.10
environment:
JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
TERM: dumb
steps:
# Checkout the code
- checkout
- run:
name: Create hash of toolchains
command: |
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- example-{{ .Branch }}-{{ .Revision }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Run example benchmark tests
command: make run-bmark-tests -C sims/verisim SUB_PROJECT=example
boomexample-run-benchmark-tests:
name: Run example tests
command: .circleci/run-tests.sh example
boomexample-run-tests:
docker:
- image: riscvboom/riscvboom-images:0.0.5
- image: riscvboom/riscvboom-images:0.0.10
environment:
JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
TERM: dumb
steps:
# Checkout the code
- checkout
- run:
name: Create hash of toolchains
command: |
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- boomexample-{{ .Branch }}-{{ .Revision }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Run boomexample benchmark tests
command: make run-bmark-tests -C sims/verisim SUB_PROJECT=example CONFIG=SmallDefaultBoomConfig
boomrocketexample-run-benchmark-tests:
name: Run boomexample tests
command: .circleci/run-tests.sh boomexample
boomrocketexample-run-tests:
docker:
- image: riscvboom/riscvboom-images:0.0.5
- image: riscvboom/riscvboom-images:0.0.10
environment:
JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
TERM: dumb
steps:
# Checkout the code
- checkout
- run:
name: Create hash of toolchains
command: |
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- boomrocketexample-{{ .Branch }}-{{ .Revision }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Run boomrocketexample benchmark tests
command: make run-bmark-tests -C sims/verisim SUB_PROJECT=example CONFIG=SmallDefaultBoomAndRocketConfig
boom-run-benchmark-tests:
name: Run boomrocketexample tests
command: .circleci/run-tests.sh boomrocketexample
boom-run-tests:
docker:
- image: riscvboom/riscvboom-images:0.0.5
- image: riscvboom/riscvboom-images:0.0.10
environment:
JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
TERM: dumb
steps:
# Checkout the code
- checkout
- run:
name: Create hash of toolchains
command: |
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- boom-{{ .Branch }}-{{ .Revision }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Run boom benchmark tests
command: make run-bmark-tests -C sims/verisim SUB_PROJECT=boom
rocketchip-run-benchmark-tests:
name: Run boom tests
command: .circleci/run-tests.sh boom
rocketchip-run-tests:
docker:
- image: riscvboom/riscvboom-images:0.0.5
- image: riscvboom/riscvboom-images:0.0.10
environment:
JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
TERM: dumb
steps:
# Checkout the code
- checkout
- run:
name: Create hash of toolchains
command: |
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- rocketchip-{{ .Branch }}-{{ .Revision }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Run rocketchip benchmark tests
command: make run-bmark-tests -C sims/verisim SUB_PROJECT=rocketchip
# hwacha-run-benchmark-tests:
# docker:
# - image: riscvboom/riscvboom-images:0.0.5
# environment:
# JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
# TERM: dumb
#
# steps:
# # Checkout the code
# - checkout
#
# - run:
# name: Create hash of toolchains
# command: |
# .circleci/create-hash.sh
#
# - restore_cache:
# keys:
# - riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
#
# - restore_cache:
# keys:
# - hwacha-{{ .Branch }}-{{ .Revision }}
#
# - run:
# name: Run hwacha benchmark tests
# command: make run-bmark-tests -C sims/verisim SUB_PROJECT=hwacha
name: Run rocketchip tests
command: .circleci/run-tests.sh rocketchip
hwacha-run-tests:
docker:
- image: riscvboom/riscvboom-images:0.0.10
environment:
JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
TERM: dumb
steps:
- checkout
- run:
name: Create hash of toolchains
command: |
.circleci/create-hash.sh
- restore_cache:
keys:
- esp-tools-installed-v1-{{ checksum "../esp-tools.hash" }}
- restore_cache:
keys:
- hwacha-{{ .Branch }}-{{ .Revision }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Run hwacha tests
command: .circleci/run-tests.sh hwacha
# Order and dependencies of jobs to run
workflows:
version: 2
build-and-test-rebar-integration:
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
@@ -504,42 +488,39 @@ workflows:
- install-riscv-toolchain
- install-verilator
- prepare-hwacha-verilog-only:
- prepare-blockdevrocketchip:
requires:
- install-riscv-toolchain
- install-verilator
- prepare-hwacha:
requires:
- install-riscv-toolchain # TODO: Remove when esp-tools is used
- install-esp-toolchain
- install-verilator
# Run the respective tests
# Run the example tests
- example-run-benchmark-tests:
- example-run-tests:
requires:
- install-riscv-toolchain
- prepare-example
- boomexample-run-benchmark-tests:
- boomexample-run-tests:
requires:
- install-riscv-toolchain
- prepare-boomexample
- boomrocketexample-run-benchmark-tests:
- boomrocketexample-run-tests:
requires:
- install-riscv-toolchain
- prepare-boomrocketexample
- boom-run-benchmark-tests:
- boom-run-tests:
requires:
- install-riscv-toolchain
- prepare-boom
- rocketchip-run-benchmark-tests:
- rocketchip-run-tests:
requires:
- install-riscv-toolchain
- prepare-rocketchip
# - hwacha-run-benchmark-tests:
# requires:
# - install-riscv-toolchain # TODO: Remove when esp-tools is used
# - install-esp-toolchain
# - prepare-hwacha
- hwacha-run-tests:
requires:
- prepare-hwacha

View File

@@ -5,8 +5,12 @@
# turn echo on and error on earliest command
set -ex
# get shared variables
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
source $SCRIPT_DIR/defaults.sh
# enter bhd repo
cd $HOME/project
cd $LOCAL_CHIPYARD_DIR
# get the version of riscv-tools from the git submodule hash
git submodule status | grep "riscv-tools" | awk '{print$1}' | grep -o "[[:alnum:]]*" >> $HOME/riscv-tools.hash

44
.circleci/defaults.sh Executable file
View File

@@ -0,0 +1,44 @@
#!/bin/bash
copy () {
rsync -avzp -e 'ssh' $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"
}
# remote variables
REMOTE_WORK_DIR=$CI_DIR/$CIRCLE_PROJECT_REPONAME-$CIRCLE_BRANCH-$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
REMOTE_VERILATOR_DIR=$REMOTE_WORK_DIR/verilator
REMOTE_SIM_DIR=$REMOTE_CHIPYARD_DIR/sims/verilator
# 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_VERILATOR_DIR=$HOME/verilator
LOCAL_SIM_DIR=$LOCAL_CHIPYARD_DIR/sims/verilator
# key value store to get the build strings
declare -A mapping
mapping["example"]="SUB_PROJECT=example"
mapping["boomexample"]="SUB_PROJECT=example CONFIG=DefaultBoomConfig"
mapping["boomrocketexample"]="SUB_PROJECT=example CONFIG=DefaultBoomAndRocketConfig"
mapping["boom"]="SUB_PROJECT=example CONFIG=SmallBoomConfig"
mapping["rocketchip"]="SUB_PROJECT=rocketchip"
mapping["blockdevrocketchip"]="SUB_PROJECT=example CONFIG=BlockDeviceModelRocketConfig TOP=BoomRocketTopWithBlockDevice"
mapping["hwacha"]="SUB_PROJECT=example CONFIG=HwachaL2Config GENERATOR_PACKAGE=hwacha"

View File

@@ -6,15 +6,44 @@
# turn echo on and error on earliest command
set -ex
# init all submodules
cd $HOME/project
# 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
# enter the verisim directory and build the specific config
cd sims/verisim
make clean
# set stricthostkeychecking to no (must happen before rsync)
run "echo \"Ping $SERVER\""
# run the particular build command
make JAVA_ARGS="-Xmx2G -Xss8M" $@
clean
rm -rf ../../project
# copy over riscv/esp-tools, verilator, and chipyard to remote
run "mkdir -p $REMOTE_CHIPYARD_DIR"
run "mkdir -p $REMOTE_VERILATOR_DIR"
copy $LOCAL_CHIPYARD_DIR/ $SERVER:$REMOTE_CHIPYARD_DIR
copy $LOCAL_VERILATOR_DIR/ $SERVER:$REMOTE_VERILATOR_DIR
TOOLS_DIR=$REMOTE_RISCV_DIR
LD_LIB_DIR=$REMOTE_RISCV_DIR/lib
if [ $1 = "hwacha" ]; then
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
# enter the verilator directory and build the specific config on remote server
run "make -C $REMOTE_SIM_DIR clean"
run "export RISCV=\"$TOOLS_DIR\"; export LD_LIBRARY_PATH=\"$LD_LIB_DIR\"; export VERILATOR_ROOT=$REMOTE_VERILATOR_DIR/install/share/verilator; make -C $REMOTE_SIM_DIR VERILATOR_INSTALL_DIR=$REMOTE_VERILATOR_DIR JAVA_ARGS=\"-Xmx8G -Xss8M\" ${mapping[$1]}"
run "rm -rf $REMOTE_CHIPYARD_DIR/project"
# copy back the final build
mkdir -p $LOCAL_CHIPYARD_DIR
copy $SERVER:$REMOTE_CHIPYARD_DIR/ $LOCAL_CHIPYARD_DIR

53
.circleci/run-tests.sh Executable file
View File

@@ -0,0 +1,53 @@
#!/bin/bash
# run the different tests
# turn echo on and error on earliest command
set -ex
# get remote exec variables
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
source $SCRIPT_DIR/defaults.sh
export VERILATOR_ROOT=$LOCAL_VERILATOR_DIR/install/share/verilator
run_bmark () {
make run-bmark-tests-fast -C $LOCAL_SIM_DIR VERILATOR_INSTALL_DIR=$LOCAL_VERILATOR_DIR $@
}
run_asm () {
make run-asm-tests-fast -C $LOCAL_SIM_DIR VERILATOR_INSTALL_DIR=$LOCAL_VERILATOR_DIR $@
}
run_both () {
run_bmark $@
run_asm $@
}
case $1 in
example)
run_bmark ${mapping[$1]}
;;
boomexample)
run_bmark ${mapping[$1]}
;;
boomrocketexample)
run_bmark ${mapping[$1]}
;;
boom)
run_bmark ${mapping[$1]}
;;
rocketchip)
run_bmark ${mapping[$1]}
;;
hwacha)
export RISCV=$LOCAL_ESP_DIR
export LD_LIBRARY_PATH=$LOCAL_ESP_DIR/lib
export PATH=$RISCV/bin:$PATH
make run-rv64uv-p-asm-tests -C $LOCAL_SIM_DIR VERILATOR_INSTALL_DIR=$LOCAL_VERILATOR_DIR ${mapping[$1]}
;;
*)
echo "No set of tests for $1. Did you spell it right?"
exit 1
;;
esac

3
.gitignore vendored
View File

@@ -5,8 +5,11 @@ target
*.stamp
*.vcd
*.swp
*#
*~
.idea
.DS_Store
env.sh
riscv-tools-install
tags
*~

27
.gitmodules vendored
View File

@@ -13,12 +13,6 @@
[submodule "tools/firrtl"]
path = tools/firrtl
url = https://github.com/freechipsproject/firrtl
[submodule "riscv-tools"]
path = toolchains/riscv-tools
url = https://github.com/riscv/riscv-tools.git
[submodule "esp-tools"]
path = toolchains/esp-tools
url = https://github.com/ucb-bar/esp-tools.git
[submodule "tools/torture"]
path = tools/torture
url = https://github.com/ucb-bar/riscv-torture.git
@@ -31,3 +25,24 @@
[submodule "generators/hwacha"]
path = generators/hwacha
url = https://github.com/ucb-bar/hwacha.git
[submodule "sims/firesim"]
path = sims/firesim
url = https://github.com/firesim/firesim.git
[submodule "generators/icenet"]
path = generators/icenet
url = https://github.com/firesim/icenet.git
[submodule "generators/block-inclusivecache-sifive"]
path = generators/sifive-cache
url = https://github.com/sifive/block-inclusivecache-sifive.git
[submodule "toolchains/riscv-tools"]
path = toolchains/riscv-tools
url = https://github.com/freechipsproject/rocket-tools.git
[submodule "toolchains/esp-tools"]
path = toolchains/esp-tools
url = https://github.com/ucb-bar/esp-tools.git
[submodule "vlsi/hammer"]
path = vlsi/hammer
url = https://github.com/ucb-bar/hammer.git
[submodule "vlsi/hammer-cad-plugins"]
path = vlsi/hammer-cad-plugins
url = https://github.com/ucb-bar/hammer-cad-plugins.git

View File

@@ -1,20 +1,20 @@
# REBAR Framework [![CircleCI](https://circleci.com/gh/ucb-bar/project-template/tree/master.svg?style=svg)](https://circleci.com/gh/ucb-bar/project-template/tree/master)
# Chipyard Framework [![CircleCI](https://circleci.com/gh/ucb-bar/chipyard/tree/master.svg?style=svg)](https://circleci.com/gh/ucb-bar/chipyard/tree/master)
## Using REBAR
## Using Chipyard
To get started using REBAR, see the documentation on the REBAR documentation site: https://bar-project-template.readthedocs.io/en/latest/
To get started using Chipyard, see the documentation on the Chipyard documentation site: https://chipyard.readthedocs.io/en/latest/
## What is REBAR
## What is Chipyard
REBAR is an open source starter template for your custom Chisel project.
Chipyard is an open source starter template for your custom Chisel project.
It will allow you to leverage the Chisel HDL, Rocket Chip SoC generator, and other [Berkeley][berkeley] projects to produce a [RISC-V][riscv] SoC with everything from MMIO-mapped peripherals to custom accelerators.
It contains processor cores ([Rocket][rocket-chip], [BOOM][boom]), accelerators ([Hwacha][hwacha]), FPGA simulation tools ([FireSim][firesim]), ASIC tools ([HAMMER][hammer]) and other tooling to help create a full featured SoC.
REBAR is actively developed in the [Berkeley Architecture Research Group][ucb-bar] in the [Electrical Engineering and Computer Sciences Department][eecs] at the [University of California, Berkeley][berkeley].
Chipyard is actively developed in the [Berkeley Architecture Research Group][ucb-bar] in the [Electrical Engineering and Computer Sciences Department][eecs] at the [University of California, Berkeley][berkeley].
## Resources
* REBAR Website: ...TBD at a later date...
* REBAR Documentation: https://bar-project-template.readthedocs.io/
* Chipyard Website: ...TBD at a later date...
* Chipyard Documentation: https://chipyard.readthedocs.io/
[hwacha]:http://hwacha.org
[hammer]:https://github.com/ucb-bar/hammer

View File

@@ -1,3 +1,5 @@
import Tests._
lazy val commonSettings = Seq(
organization := "edu.berkeley.cs",
version := "1.0",
@@ -9,7 +11,7 @@ lazy val commonSettings = Seq(
case _ => MergeStrategy.first}},
scalacOptions ++= Seq("-deprecation","-unchecked","-Xsource:2.11"),
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % "test",
libraryDependencies += "org.json4s" %% "json4s-native" % "3.6.1",
libraryDependencies += "org.json4s" %% "json4s-jackson" % "3.6.1",
libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value,
libraryDependencies += "edu.berkeley.cs" %% "firrtl-interpreter" % "1.2-SNAPSHOT",
libraryDependencies += "com.github.scopt" %% "scopt" % "3.7.0",
@@ -19,18 +21,14 @@ lazy val commonSettings = Seq(
Resolver.sonatypeRepo("releases"),
Resolver.mavenLocal))
lazy val rebarFirrtl = (project in file("tools/firrtl"))
.settings(commonSettings)
val rocketChipDir = file("generators/rocket-chip")
lazy val rocketchip = RootProject(file("generators/rocket-chip"))
lazy val rebarrocketchip = project
.dependsOn(rocketchip)
.settings(commonSettings)
lazy val testchipip = (project in file("generators/testchipip"))
.dependsOn(rebarrocketchip)
.settings(commonSettings)
lazy val firesimAsLibrary = sys.env.get("FIRESIM_STANDALONE") == None
lazy val firesimDir = if (firesimAsLibrary) {
file("sims/firesim/sim/")
} else {
file("../../")
}
// Checks for -DROCKET_USE_MAVEN.
// If it's there, use a maven dependency.
@@ -45,33 +43,90 @@ def conditionalDependsOn(prj: Project): Project = {
}
}
// Fork each scala test for now, to work around persistent mutable state
// in Rocket-Chip based generators
def isolateAllTests(tests: Seq[TestDefinition]) = tests map { test =>
val options = ForkOptions()
new Group(test.name, Seq(test), SubProcess(options))
} toSeq
// Subproject definitions begin
// NB: FIRRTL dependency is unmanaged (and dropped in sim/lib)
lazy val chisel = (project in rocketChipDir / "chisel3")
// 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")
// Rocket-chip dependencies (subsumes making RC a RootProject)
lazy val hardfloat = (project in rocketChipDir / "hardfloat")
.settings(commonSettings).dependsOn(midasTargetUtils)
lazy val rocketMacros = (project in rocketChipDir / "macros")
.settings(commonSettings)
// HACK: I'm strugging to override settings in rocket-chip's build.sbt (i want
// the subproject to register a new library dependendency on midas's targetutils library)
// So instead, avoid the existing build.sbt altogether and specify the project's root at src/
lazy val rocketchip = (project in rocketChipDir / "src")
.settings(
commonSettings,
scalaSource in Compile := baseDirectory.value / "main" / "scala",
resourceDirectory in Compile := baseDirectory.value / "main" / "resources")
.dependsOn(chisel, hardfloat, rocketMacros)
lazy val testchipip = (project in file("generators/testchipip"))
.dependsOn(rocketchip)
.settings(commonSettings)
lazy val example = conditionalDependsOn(project in file("generators/example"))
.dependsOn(boom, hwacha, sifive_blocks)
.dependsOn(boom, hwacha, sifive_blocks, sifive_cache)
.settings(commonSettings)
lazy val utilities = conditionalDependsOn(project in file("generators/utilities"))
.settings(commonSettings)
lazy val hwacha = (project in file ("generators/hwacha"))
.dependsOn(rebarrocketchip)
lazy val icenet = (project in file("generators/icenet"))
.dependsOn(rocketchip, testchipip)
.settings(commonSettings)
lazy val hwacha = (project in file("generators/hwacha"))
.dependsOn(rocketchip)
.settings(commonSettings)
lazy val boom = (project in file("generators/boom"))
.dependsOn(rebarrocketchip)
.dependsOn(rocketchip)
.settings(commonSettings)
lazy val tapeout = conditionalDependsOn(project in file("./tools/barstools/tapeout/"))
.dependsOn(rebarFirrtl)
.settings(commonSettings)
lazy val mdf = (project in file("./tools/barstools/mdf/scalalib/"))
.settings(commonSettings)
lazy val `barstools-macros` = (project in file("./tools/barstools/macros/"))
.dependsOn(mdf, rebarrocketchip, rebarFirrtl)
lazy val barstoolsMacros = (project in file("./tools/barstools/macros/"))
.dependsOn(mdf, rocketchip)
.enablePlugins(sbtassembly.AssemblyPlugin)
.settings(commonSettings)
lazy val sifive_blocks = (project in file("generators/sifive-blocks"))
.dependsOn(rebarrocketchip)
.dependsOn(rocketchip)
.settings(commonSettings)
lazy val sifive_cache = (project in file("generators/sifive-cache")).settings(
commonSettings,
scalaSource in Compile := baseDirectory.value / "craft"
).dependsOn(rocketchip)
// Library components of FireSim
lazy val midas = ProjectRef(firesimDir, "midas")
lazy val firesimLib = ProjectRef(firesimDir, "firesimLib")
lazy val firechip = (project in file("generators/firechip"))
.dependsOn(boom, icenet, testchipip, sifive_blocks, sifive_cache, midasTargetUtils, midas, firesimLib % "test->test;compile->compile")
.settings(
commonSettings,
testGrouping in Test := isolateAllTests( (definedTests in Test).value )
)

View File

@@ -8,63 +8,67 @@ SHELL=/bin/bash
#########################################################################################
lookup_scala_srcs = $(shell find -L $(1)/ -iname "*.scala" 2> /dev/null)
PACKAGES=rocket-chip testchipip boom hwacha sifive-blocks example
SCALA_SOURCES=$(foreach pkg,$(PACKAGES),$(call lookup_scala_srcs,$(base_dir)/generators/$(pkg)/src/main/scala))
PACKAGES=$(addprefix generators/, rocket-chip testchipip boom hwacha sifive-blocks sifive-cache example) \
$(addprefix sims/firesim/sim/, . firesim-lib midas midas/targetutils)
SCALA_SOURCES=$(foreach pkg,$(PACKAGES),$(call lookup_scala_srcs,$(base_dir)/$(pkg)/src/main/scala))
#########################################################################################
# rocket and testchipip classes
#########################################################################################
ROCKET_CLASSES ?= "$(ROCKETCHIP_DIR)/target/scala-$(SCALA_VERSION_MAJOR)/classes:$(ROCKETCHIP_DIR)/chisel3/target/scala-$(SCALA_VERSION_MAJOR)/*"
# NB: target/ lives under source ----V , due to how we're handling midas dependency injection
ROCKET_CLASSES ?= "$(ROCKETCHIP_DIR)/src/target/scala-$(SCALA_VERSION_MAJOR)/classes:$(ROCKETCHIP_DIR)/chisel3/target/scala-$(SCALA_VERSION_MAJOR)/*"
TESTCHIPIP_CLASSES ?= "$(TESTCHIP_DIR)/target/scala-$(SCALA_VERSION_MAJOR)/classes"
#########################################################################################
# jar creation variables and rules
#########################################################################################
FIRRTL_JAR ?= $(ROCKETCHIP_DIR)/lib/firrtl.jar
FIRRTL_JAR := $(base_dir)/lib/firrtl.jar
$(FIRRTL_JAR): $(call lookup_scala_srcs, $(REBAR_FIRRTL_DIR)/src/main/scala)
$(MAKE) -C $(REBAR_FIRRTL_DIR) SBT="$(SBT)" root_dir=$(REBAR_FIRRTL_DIR) build-scala
mkdir -p $(dir $@)
cp -p $(REBAR_FIRRTL_DIR)/utils/bin/firrtl.jar $@
$(FIRRTL_JAR): $(call lookup_scala_srcs, $(CHIPYARD_FIRRTL_DIR)/src/main/scala)
$(MAKE) -C $(CHIPYARD_FIRRTL_DIR) SBT="$(SBT)" root_dir=$(CHIPYARD_FIRRTL_DIR) build-scala
mkdir -p $(@D)
cp -p $(CHIPYARD_FIRRTL_DIR)/utils/bin/firrtl.jar $@
touch $@
#########################################################################################
# create simulation args file rule
#########################################################################################
$(sim_dotf): $(call lookup_scala_srcs,$(base_dir)/generators/utilities/src/main/scala) $(FIRRTL_JAR)
$(sim_files): $(call lookup_scala_srcs,$(base_dir)/generators/utilities/src/main/scala) $(FIRRTL_JAR)
cd $(base_dir) && $(SBT) "project utilities" "runMain utilities.GenerateSimFiles -td $(build_dir) -sim $(sim_name)"
#########################################################################################
# create firrtl file rule and variables
#########################################################################################
CHISEL_ARGS ?=
$(FIRRTL_FILE) $(ANNO_FILE): $(SCALA_SOURCES) $(sim_dotf)
$(FIRRTL_FILE) $(ANNO_FILE): $(SCALA_SOURCES) $(sim_files)
mkdir -p $(build_dir)
cd $(base_dir) && $(SBT) "project $(SBT_PROJECT)" "runMain $(GENERATOR_PACKAGE).Generator $(CHISEL_ARGS) $(build_dir) $(MODEL_PACKAGE) $(MODEL) $(CONFIG_PACKAGE) $(CONFIG)"
cd $(base_dir) && $(SBT) "project $(SBT_PROJECT)" "runMain $(GENERATOR_PACKAGE).Generator $(build_dir) $(MODEL_PACKAGE) $(MODEL) $(CONFIG_PACKAGE) $(CONFIG)"
#########################################################################################
# create verilog files rules and variables
#########################################################################################
REPL_SEQ_MEM = --infer-rw --repl-seq-mem -c:$(MODEL):-o:$(SMEMS_CONF)
HARNESS_REPL_SEQ_MEM = --infer-rw --repl-seq-mem -c:$(MODEL):-o:$(HARNESS_SMEMS_CONF)
REPL_SEQ_MEM = --infer-rw --repl-seq-mem -c:$(MODEL):-o:$(TOP_SMEMS_CONF)
HARNESS_CONF_FLAGS = -thconf $(HARNESS_SMEMS_CONF)
$(VERILOG_FILE) $(SMEMS_CONF) $(TOP_ANNO) $(TOP_FIR) $(sim_top_blackboxes): $(FIRRTL_FILE) $(ANNO_FILE)
cd $(base_dir) && $(SBT) "project tapeout" "runMain barstools.tapeout.transforms.GenerateTop -o $(VERILOG_FILE) -i $(FIRRTL_FILE) --syn-top $(TOP) --harness-top $(MODEL) -faf $(ANNO_FILE) -tsaof $(TOP_ANNO) -tsf $(TOP_FIR) $(REPL_SEQ_MEM) -td $(build_dir)"
cp $(build_dir)/firrtl_black_box_resource_files.f $(sim_top_blackboxes)
TOP_TARGETS = $(TOP_FILE) $(TOP_SMEMS_CONF) $(TOP_ANNO) $(TOP_FIR) $(sim_top_blackboxes)
HARNESS_TARGETS = $(HARNESS_FILE) $(HARNESS_SMEMS_CONF) $(HARNESS_ANNO) $(HARNESS_FIR) $(sim_harness_blackboxes)
$(HARNESS_FILE) $(HARNESS_ANNO) $(HARNESS_FIR) $(sim_harness_blackboxes): $(FIRRTL_FILE) $(ANNO_FILE) $(sim_top_blackboxes)
cd $(base_dir) && $(SBT) "project tapeout" "runMain barstools.tapeout.transforms.GenerateHarness -o $(HARNESS_FILE) -i $(FIRRTL_FILE) --syn-top $(TOP) --harness-top $(VLOG_MODEL) -faf $(ANNO_FILE) -thaof $(HARNESS_ANNO) -thf $(HARNESS_FIR) $(HARNESS_REPL_SEQ_MEM) -td $(build_dir)"
grep -v "SimSerial.cc\|SimDTM.cc\|SimJTAG.cc" $(build_dir)/firrtl_black_box_resource_files.f > $(sim_harness_blackboxes)
$(TOP_TARGETS) $(HARNESS_TARGETS): $(FIRRTL_FILE) $(ANNO_FILE)
cd $(base_dir) && $(SBT) "project tapeout" "runMain 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)"
# This file is for simulation only. VLSI flows should replace this file with one containing hard SRAMs
MACROCOMPILER_MODE ?= --mode synflops
$(SMEMS_FILE) $(SMEMS_FIR): $(SMEMS_CONF)
cd $(base_dir) && $(SBT) "project barstools-macros" "runMain barstools.macros.MacroCompiler -n $(SMEMS_CONF) -v $(SMEMS_FILE) -f $(SMEMS_FIR) $(MACROCOMPILER_MODE)"
$(TOP_SMEMS_FILE) $(TOP_SMEMS_FIR): $(TOP_SMEMS_CONF)
cd $(base_dir) && $(SBT) "project barstoolsMacros" "runMain barstools.macros.MacroCompiler -n $(TOP_SMEMS_CONF) -v $(TOP_SMEMS_FILE) -f $(TOP_SMEMS_FIR) $(MACROCOMPILER_MODE)"
HARNESS_MACROCOMPILER_MODE = --mode synflops
$(HARNESS_SMEMS_FILE) $(HARNESS_SMEMS_FIR): $(HARNESS_SMEMS_CONF)
cd $(base_dir) && $(SBT) "project barstools-macros" "runMain barstools.macros.MacroCompiler -n $(HARNESS_SMEMS_CONF) -v $(HARNESS_SMEMS_FILE) -f $(HARNESS_SMEMS_FIR) $(HARNESS_MACROCOMPILER_MODE)"
cd $(base_dir) && $(SBT) "project barstoolsMacros" "runMain barstools.macros.MacroCompiler -n $(HARNESS_SMEMS_CONF) -v $(HARNESS_SMEMS_FILE) -f $(HARNESS_SMEMS_FIR) $(HARNESS_MACROCOMPILER_MODE)"
########################################################################################
# remove duplicate files in blackbox/simfiles
########################################################################################
$(sim_common_files): $(sim_files) $(sim_top_blackboxes) $(sim_harness_blackboxes)
awk '{print $1;}' $^ | sort -u > $@
#########################################################################################
# helper rule to just make verilog files
@@ -73,10 +77,25 @@ $(HARNESS_SMEMS_FILE) $(HARNESS_SMEMS_FIR): $(HARNESS_SMEMS_CONF)
verilog: $(sim_vsrcs)
#########################################################################################
# helper rules to run simulator
# helper rules to run simulations
#########################################################################################
.PHONY: run-binary run-binary-fast run-binary-debug run-fast
run-binary: $(sim)
$(sim) $(PERMISSIVE_ON) $(SIM_FLAGS) $(PERMISSIVE_OFF) $(BINARY) 3>&1 1>&2 2>&3 | spike-dasm > $(sim_out_name).out
(set -o pipefail && $(sim) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(VERBOSE_FLAGS) $(PERMISSIVE_OFF) $(BINARY) 3>&1 1>&2 2>&3 | spike-dasm > $(sim_out_name).out)
#########################################################################################
# helper rules to run simulator as fast as possible
#########################################################################################
run-binary-fast: $(sim)
(set -o pipefail && $(sim) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(PERMISSIVE_OFF) $(BINARY) 3>&1 1>&2 2>&3 | spike-dasm > $(sim_out_name).out)
#########################################################################################
# helper rules to run simulator with as much debug info as possible
#########################################################################################
run-binary-debug: $(sim_debug)
(set -o pipefail && $(sim_debug) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(VERBOSE_FLAG) $(WAVEFORM_FLAG) $(PERMISSIVE_OFF) $(BINARY) 3>&1 1>&2 2>&3 | spike-dasm > $(sim_out_name).out)
run-fast: run-asm-tests-fast run-bmark-tests-fast
#########################################################################################
# run assembly/benchmarks rules
@@ -86,10 +105,10 @@ $(output_dir)/%: $(RISCV)/riscv64-unknown-elf/share/riscv-tests/isa/%
ln -sf $< $@
$(output_dir)/%.run: $(output_dir)/% $(sim)
$(sim) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(PERMISSIVE_OFF) $< && touch $@
$(sim) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(PERMISSIVE_OFF) $< && touch $@
$(output_dir)/%.out: $(output_dir)/% $(sim)
$(sim) $(PERMISSIVE_ON) +verbose +max-cycles=$(timeout_cycles) $(PERMISSIVE_OFF) $< 3>&1 1>&2 2>&3 | spike-dasm > $@
(set -o pipefail && $(sim) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(VERBOSE_FLAGS) $(PERMISSIVE_OFF) $< 3>&1 1>&2 2>&3 | spike-dasm > $@)
#########################################################################################
# include build/project specific makefrags made from the generator

View File

@@ -0,0 +1,50 @@
Debugging with DTM/JTAG
===============================
By default, Chipyard is not setup to use the Debug Test Module (DTM) to bringup the core.
Instead, Chipyard uses TSI commands to bringup the core (which normally results in a faster simulation).
TSI simulations use the SimSerial interface to directly write the test binary into memory, while the DTM
executes a small loop of code to write the test binary byte-wise into memory.
However, if you want to use JTAG, you must do the following steps to setup a DTM enabled system.
Creating a DTM/JTAG Config
-------------------------------------------
First, a DTM config must be created for the system that you want to create.
This involves specifying the SoC top-level to add a DTM as well as configuring that DTM to use JTAG.
.. code-block:: scala
class DTMBoomConfig extends Config(
new WithDTMBoomRocketTop ++
new WithBootROM ++
new WithJtagDTM ++
new boom.common.SmallBoomConfig)
In this example, the ``WithDTMBoomRocketTop`` mixin specifies that the top-level SoC will instantiate a DTM.
The ``WithJtagDTM`` will configure that instantiated DTM to use JTAG as the bringup method (note: this can be removed if you want a DTM-only bringup).
The rest of the mixins specify the rest of the system (cores, accelerators, etc).
Starting the DTM Simulation
-------------------------------------------
After creating the config, call the ``make`` command like the following:
.. code-block:: bash
cd sims/verilator
# or
cd sims/vcs
make CONFIG=DTMBoomConfig TOP=BoomRocketTopWithDTM MODEL=TestHarnessWithDTM
In this example, this will use the config that you previously specified, as well as set the other parameters that are needed to satisfy the build system.
After that point, you should have a JTAG enabled simulation that you can attach to using OpenOCD and GDB!
Debugging with JTAG
-------------------------------------------------------
Please refer to the following resources on how to debug with JTAG.
* https://github.com/chipsalliance/rocket-chip#-debugging-with-gdb
* https://github.com/riscv/riscv-isa-sim#debugging-with-gdb

View File

@@ -0,0 +1,38 @@
Accessing Scala Resources
===============================
A simple way to copy over a source file to the build directory to be used for a simulation compile or VLSI flow is to use the ``setResource`` or ``addResource`` functions given by FIRRTL.
They can be used in the following way:
.. code-block:: scala
class SimSerial(w: Int) extends BlackBox with HasBlackBoxResource {
val io = IO(new Bundle {
val clock = Input(Clock())
val reset = Input(Bool())
val serial = Flipped(new SerialIO(w))
val exit = Output(Bool())
})
setResource("/testchipip/vsrc/SimSerial.v")
setResource("/testchipip/csrc/SimSerial.cc")
}
In this example, the ``SimSerial`` files will be copied from a specific folder (in this case the ``path/to/testchipip/src/main/resources/testchipip/...``) to the build folder.
The ``set/addResource`` path retrieves resources from the ``src/main/resources`` directory.
So to get an item at ``src/main/resources/fileA.v`` you can use ``setResource("/fileA.v")``.
However, one caveat of this approach is that to retrieve the file during the FIRRTL compile, you must have that project in the FIRRTL compiler's classpath.
Thus, you need to add the SBT project as a dependency to the FIRRTL compiler in the Chipyard ``build.sbt``, which in Chipyards case is the ``tapeout`` project.
For example, you added a new project called ``myAwesomeAccel`` in the Chipyard ``build.sbt``.
Then you can add it as a ``dependsOn`` dependency to the ``tapeout`` project.
For example:
.. code-block:: scala
lazy val myAwesomeAccel = (project in file("generators/myAwesomeAccelFolder"))
.dependsOn(rocketchip)
.settings(commonSettings)
lazy val tapeout = conditionalDependsOn(project in file("./tools/barstools/tapeout/"))
.dependsOn(myAwesomeAccel)
.settings(commonSettings)

View File

@@ -0,0 +1,12 @@
Advanced Usage
================================
The following sections are advanced topics about how to use Chipyard and special features of the framework.
They expect you to know about Chisel, Parameters, Configs, etc.
.. toctree::
:maxdepth: 2
:caption: Advanced Usage:
DTM-Debugging
Resources

View File

@@ -0,0 +1,6 @@
.. _build-a-chip:
Building A Chip
==============================
TODO

View File

@@ -1,10 +1,12 @@
REBAR Basics
.. _chipyard-components:
Chipyard Components
===============================
Generators
-------------------------------------------
The REBAR Framework currently consists of the following RTL generators:
The Chipyard Framework currently consists of the following RTL generators:
Processor Cores
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -72,7 +74,7 @@ Toolchains
A collection of software toolchains used to develop and execute software on the RISC-V ISA.
The include compiler and assembler toolchains, functional ISA simulator (spike), the Berkeley Boot Loader (BBL) and proxy kernel.
The riscv-tools repository was previously required to run any RISC-V software, however, many of the riscv-tools components have since been upstreamed to their respective open-source projects (Linux, GNU, etc.).
Nevertheless, for consistent versioning, as well as software design flexibility for custom hardware, we include the riscv-tools repository and installation in the REBAR framework.
Nevertheless, for consistent versioning, as well as software design flexibility for custom hardware, we include the riscv-tools repository and installation in the Chipyard framework.
**esp-tools**
A fork of riscv-tools, designed to work with the Hwacha non-standard RISC-V extension.
@@ -81,14 +83,14 @@ Toolchains
Sims
-------------------------------------------
**verisim (Verilator wrapper)**
**verilator (Verilator wrapper)**
Verilator is an open source Verilog simulator.
The ``verisim`` directory provides wrappers which construct Verilator-based simulators from relevant generated RTL, allowing for execution of test RISC-V programs on the simulator (including vcd waveform files).
The ``verilator`` directory provides wrappers which construct Verilator-based simulators from relevant generated RTL, allowing for execution of test RISC-V programs on the simulator (including vcd waveform files).
See :ref:`Verilator` for more information.
**vsim (VCS wrapper)**
**vcs (VCS wrapper)**
VCS is a proprietary Verilog simulator.
Assuming the user has valid VCS licenses and installations, the ``vsim`` directory provides wrappers which construct VCS-based simulators from relevant generated RTL, allowing for execution of test RISC-V programs on the simulator (including vcd/vpd waveform files).
Assuming the user has valid VCS licenses and installations, the ``vcs`` directory provides wrappers which construct VCS-based simulators from relevant generated RTL, allowing for execution of test RISC-V programs on the simulator (including vcd/vpd waveform files).
See :ref:`VCS` for more information.
**FireSim**

View File

@@ -1,7 +1,7 @@
Configs, Parameters, Mix-ins, and Everything In Between
========================================================
A significant portion of generators in the REBAR framework use the Rocket Chip parameter system.
A significant portion of generators in the Chipyard framework use the Rocket Chip parameter system.
This parameter system enables for the flexible configuration of the SoC without invasive RTL changes.
In order to use the parameter system correctly, we will use several terms and conventions:
@@ -69,7 +69,7 @@ Cake Pattern
-------------------------
A cake pattern is a Scala programming pattern, which enable "mixing" of multiple traits or interface definitions (sometimes referred to as dependency injection).
It is used in the Rocket Chip SoC library and REBAR framework in merging multiple system components and IO interfaces into a large system component.
It is used in the Rocket Chip SoC library and Chipyard framework in merging multiple system components and IO interfaces into a large system component.
:numref:`cake-example` shows a Rocket Chip based SoC that merges multiple system components (BootROM, UART, etc) into a single top-level design.

View File

@@ -1,12 +1,12 @@
Development Ecosystem
===============================
REBAR Approach
Chipyard Approach
-------------------------------------------
The trend towards agile hardware design and evaluation provides an ecosystem of debugging and implementation tools, that make it easier for computer architecture researchers to develop novel concepts.
REBAR hopes to build on this prior work in order to create a singular location to which multiple projects within the `Berkeley Architecture Research <https://bar.eecs.berkeley.edu/index.html>`__ can coexist and be used together.
REBAR aims to be the "one-stop shop" for creating and testing your own unique System on a Chip (SoC).
Chipyard hopes to build on this prior work in order to create a singular location to which multiple projects within the `Berkeley Architecture Research <https://bar.eecs.berkeley.edu/index.html>`__ can coexist and be used together.
Chipyard aims to be the "one-stop shop" for creating and testing your own unique System on a Chip (SoC).
Chisel/FIRRTL
-------------------------------------------

View File

@@ -8,8 +8,8 @@ After cloning this repo, you will need to initialize all of the submodules.
.. code-block:: shell
git clone https://github.com/ucb-bar/project-template.git
cd project-template
git clone https://github.com/ucb-bar/chipyard.git
cd chipyard
./scripts/init-submodules-no-riscv-tools.sh
Building a Toolchain
@@ -26,7 +26,7 @@ But to get a basic installation, just the following steps are necessary.
# OR
./scripts/build-toolchains.sh hwacha # for a hwacha modified risc-v toolchain
./scripts/build-toolchains.sh esp-tools # for a modified risc-v toolchain with Hwacha vector instructions
Once the script is run, a ``env.sh`` file is emitted at sets the ``PATH``, ``RISCV``, and ``LD_LIBRARY_PATH`` environment variables.
You can put this in your ``.bashrc`` or equivalent environment setup file to get the proper variables.

View File

@@ -1,13 +1,13 @@
Running A Simulation
========================================================
REBAR provides support and integration for multiple simulation flows, for various user levels and requirements.
Chipyard provides support and integration for multiple simulation flows, for various user levels and requirements.
In the majority of cases during a digital design development process, simple software RTL simulation is needed.
When more advanced full-system evaluation is required, with long running workloads, FPGA-accelerated simulation will then become a preferable solution.
Software RTL Simulation
------------------------
The REBAR framework provides wrappers for two common software RTL simulators:
The Chipyard framework provides wrappers for two common software RTL simulators:
the open-source Verilator simulator and the proprietary VCS simulator.
For more information on either of these simulators, please refer to :ref:`Verilator` or :ref:`VCS`.
The following instructions assume at least one of these simulators is installed.
@@ -15,9 +15,9 @@ The following instructions assume at least one of these simulators is installed.
Verilator/VCS Flows
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Verilator is an open-source RTL simulator.
We run Verilator simulations from within the ``sims/verisim`` directory which provides the necessary ``Makefile`` to both install and run Verilator simulations.
We run Verilator simulations from within the ``sims/verilator`` directory which provides the necessary ``Makefile`` to both install and run Verilator simulations.
On the other hand, VCS is a proprietary RTL simulator.
We run VCS simulations from within the ``sims/vsim`` directory.
We run VCS simulations from within the ``sims/vcs`` directory.
Assuming VCS is already installed on the machine running simulations (and is found on our ``PATH``), then this guide is the same for both Verilator and VCS.
First, we will start by entering the Verilator or VCS directory:
@@ -25,12 +25,12 @@ First, we will start by entering the Verilator or VCS directory:
.. code-block:: shell
# Enter Verilator directory
cd sims/verisim
cd sims/verilator
# OR
# Enter VCS directory
cd sims/vsim
cd sims/vcs
In order to construct the simulator with our custom design, we run the following command within the simulator directory:
@@ -97,7 +97,7 @@ FireSim enables simulations at 1000x-100000x the speed of standard software simu
This is enabled using FPGA-acceleration on F1 instances of the AWS (Amazon Web Services) public cloud.
Therefore FireSim simulation requires to be set-up on the AWS public cloud rather than on our local development machine.
To run an FPGA-accelerated simulation using FireSim, a we need to clone the REBAR repository (or our fork of the REBAR repository) to an AWS EC2, and follow the setup instructions specified in the FireSim Initial Setup documentation page.
To run an FPGA-accelerated simulation using FireSim, a we need to clone the Chipyard repository (or our fork of the Chipyard repository) to an AWS EC2, and follow the setup instructions specified in the FireSim Initial Setup documentation page.
After setting up the FireSim environment, we now need to generate a FireSim simulation around our selected digital design.
We will work from within the ``sims/firesim`` directory.

View File

@@ -0,0 +1,24 @@
Chipyard Basics
================================
These guides will walk you through the basics of the Chipyard framework:
- First, we will go over the components of the framework.
- Next, we will go over the different configurations available.
- Then, we will go over initial framework setup.
- Finally, we will briefly walk through what you can do with the Chipyard tools.
Hit next to get started!
.. toctree::
:maxdepth: 2
:caption: Chipyard Basics:
Chipyard-Components
Configs-Parameters-Mixins
Initial-Repo-Setup
Running-A-Simulation
Building-A-Chip

View File

@@ -1,3 +1,5 @@
.. _adding-an-accelerator:
Adding An Accelerator/Device
===============================
@@ -28,7 +30,7 @@ Integrating into the Generator Build System
-------------------------------------------
While developing, you want to include Chisel code in a submodule so that it can be shared by different projects.
To add a submodule to the REBAR framework, make sure that your project is organized as follows.
To add a submodule to the Chipyard framework, make sure that your project is organized as follows.
.. code-block:: none
@@ -45,11 +47,11 @@ Then add it as a submodule to under the following directory hierarchy: ``generat
cd generators/
git submodule add https://git-repository.com/yourproject.git
Then add ``yourproject`` to the REBAR top-level build.sbt file.
Then add ``yourproject`` to the Chipyard top-level build.sbt file.
.. code-block:: scala
lazy val yourproject = project.settings(commonSettings).dependsOn(rocketchip)
lazy val yourproject = (project in file("generators/yourproject")).settings(commonSettings).dependsOn(rocketchip)
You can then import the classes defined in the submodule in a new project if
you add it as a dependency. For instance, if you want to use this code in
@@ -59,9 +61,15 @@ the ``example`` project, change the final line in build.sbt to the following.
lazy val example = (project in file(".")).settings(commonSettings).dependsOn(testchipip, yourproject)
Finally, add ``yourproject`` to the ``PACKAGES`` variable in the ``common.mk`` file in the REBAR top level.
Finally, add ``yourproject`` to the ``PACKAGES`` variable in the ``common.mk`` file in the Chipyard top level.
This will allow make to detect that your source files have changed when building the Verilog/FIRRTL files.
.. code-block:: shell
PACKAGES=$(addprefix generators/, rocket-chip testchipip boom hwacha sifive-blocks sifive-cache example yourproject) \
$(addprefix sims/firesim/sim/, . firesim-lib midas midas/targetutils)
MMIO Peripheral
------------------
@@ -227,7 +235,7 @@ Now with all of that done, we can go ahead and run our simulation.
.. code-block:: shell
cd verisim
cd verilator
make CONFIG=PWMConfig
./simulator-example-PWMConfig ../tests/pwm.riscv

View File

@@ -0,0 +1,126 @@
Heterogeneous SoCs
===============================
The Chipyard framework involves multiple cores and accelerators that can be composed in arbitrary ways.
This discussion will focus on how you combine Rocket, BOOM and Hwacha in particular ways to create a unique SoC.
Creating a Rocket and BOOM System
-------------------------------------------
Instantiating an SoC with Rocket and BOOM cores is all done with the configuration system and two specific mixins.
Both BOOM and Rocket have mixins labelled ``WithNBoomCores(X)`` and ``WithNBigCores(X)`` that automatically create ``X`` copies of the core.
When used together you can create a heterogeneous system.
The following example shows a dual core BOOM with a single core Rocket.
.. code-block:: scala
class DualBoomAndOneRocketConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new boom.system.WithRenumberHarts ++
new boom.common.WithRVC ++
new boom.common.DefaultBoomConfig ++
new boom.system.WithNBoomCores(2) ++
new freechips.rocketchip.subsystem.WithoutTLMonitors ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
In this example, the ``WithNBoomCores`` and ``WithNBigCores`` mixins set up the default parameters for the multiple BOOM and Rocket cores, respectively.
However, for BOOM, an extra mixin called ``DefaultBoomConfig`` is added to override the default parameters with a different set of more common default parameters.
This mixin applies to all BOOM cores in the system and changes the parameters for each.
Great! Now you have a heterogeneous setup with BOOMs and Rockets.
The final thing you need to make this system work is to renumber the ``hartId``'s of the cores so that each core has a unique ``hartId`` (a ``hartId`` is the hardware thread id of the core).
This is done with ``WithRenumberHarts`` (which can label the Rocket cores first or the BOOM cores first).
The reason this is needed is because by default the ``WithN...Cores(X)`` mixin assumes that there are only BOOM or only Rocket cores in the system.
Thus, without the ``WithRenumberHarts`` mixin, each set of cores is labeled starting from zero causing multiple cores to be assigned the same ``hartId``.
Another alternative option to create a multi heterogeneous core system is to override the parameters yourself so you can specify the core parameters per core.
The mixin to add to your system would look something like the following.
.. code-block:: scala
// create 6 cores (4 boom and 2 rocket)
class WithHeterCoresSetup extends Config((site, here, up) => {
case BoomTilesKey => {
val boomTile0 = BoomTileParams(...) // params for boom core 0
val boomTile1 = BoomTileParams(...) // params for boom core 1
val boomTile2 = BoomTileParams(...) // params for boom core 2
val boomTile3 = BoomTileParams(...) // params for boom core 3
boomTile0 ++ boomTile1 ++ boomTile2 ++ boomTile3
}
case RocketTilesKey => {
val rocketTile0 = RocketTileParams(...) // params for rocket core 0
val rocketTile1 = RocketTileParams(...) // params for rocket core 1
rocketTile0 ++ rocketTile1
}
})
Then you could use this new mixin like the following.
.. code-block:: scala
class SixCoreConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new WithHeterCoresSetup ++
new freechips.rocketchip.system.BaseConfig)
Note, in this setup you need to specify the ``hartId`` of each core in the "TileParams", where each ``hartId`` is unique.
Adding Hwachas
-------------------------------------------
Adding a Hwacha accelerator is as easy as adding the ``DefaultHwachaConfig`` so that it can setup the Hwacha parameters and add itself to the ``BuildRoCC`` parameter.
An example of adding a Hwacha to all tiles in the system is below.
.. code-block:: scala
class DualBoomAndRocketWithHwachasConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new hwacha.DefaultHwachaConfig ++
new boom.system.WithRenumberHarts ++
new boom.common.WithRVC ++
new boom.common.DefaultBoomConfig ++
new boom.system.WithNBoomCores(2) ++
new freechips.rocketchip.subsystem.WithoutTLMonitors ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
In this example, Hwachas are added to both BOOM tiles and to the Rocket tile.
All with the same Hwacha parameters.
Assigning Accelerators to Specific Tiles with MultiRoCC
-------------------------------------------------------
Located in ``generators/example/src/main/scala/ConfigMixins.scala`` is a mixin 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.
.. code-block:: scala
class DualBoomAndOneHwachaRocketConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new WithMultiRoCC ++
new WithMultiRoCCHwacha(0) ++ // put Hwacha just on hart0 which was renumbered to Rocket
new boom.system.WithRenumberHarts(rocketFirst = true) ++
new hwacha.DefaultHwachaConfig ++
new boom.common.WithRVC ++
new boom.common.DefaultBoomConfig ++
new boom.system.WithNBoomCores(2) ++
new freechips.rocketchip.subsystem.WithoutTLMonitors ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
In this example, the ``WithRenumberHarts`` relabels the ``hartId``'s of all the BOOM/Rocket cores.
Then after that is applied to the parameters, the ``WithMultiRoCCHwacha(0)`` is used to assign to ``hartId`` zero a Hwacha (in this case ``hartId`` zero is Rocket).
Finally, the ``WithMultiRoCC`` mixin is called.
This mixin sets the ``BuildRoCC`` key to use the ``MultiRoCCKey`` instead of the default.
This must be used after all the RoCC parameters are set because it needs to override the ``BuildRoCC`` parameter.
If this is used earlier in the configuration sequence, then MultiRoCC does not work.
This mixin can be changed to put more accelerators on more cores by changing the arguments to cover more ``hartId``'s (i.e. ``WithMultiRoCCHwacha(0,1,3,6,...)``).

View File

@@ -0,0 +1,4 @@
Memory Hierarchy
===============================
TODO: Talk about SiFive Cache, and integration with L1 and backing main memory models
(maybe even Tilelink)

View File

@@ -0,0 +1,18 @@
Customization
================================
These guides will walk you through customization of your system-on-chip:
- Contructing heterogenous systems-on-chip using the Chipyard generators and configuration system.
- Adding custom accelerators to your system-on-chip.
Hit next to get started!
.. toctree::
:maxdepth: 2
:caption: Customization:
Heterogeneous-SoCs
Adding-An-Accelerator
Memory-Hierarchy

View File

@@ -5,7 +5,7 @@ Generator can be thought of as a generalized RTL design, written using a mix of
This type of meta-programming is enabled by the Chisel hardware description language (see :ref:`Chisel`).
A standard RTL design is essentially just a single instance of a design coming from a generator.
However, by using meta-programming and parameter systems, generators can allow for integration of complex hardware designs in automated ways.
The following pages introduce the generators integrated with the REBAR framework.
The following pages introduce the generators integrated with the Chipyard framework.
.. toctree::
:maxdepth: 2

View File

@@ -1,21 +0,0 @@
Getting Started
================================
These guides will walk you through the basics of the REBAR framework:
- First, we will go over the different configurations available.
- Then, we will walk through adding a custom accelerator.
Hit next to get started!
.. toctree::
:maxdepth: 2
:caption: Getting Started:
REBAR-Basics
Configs-Parameters-Mixins
Adding-An-Accelerator-Tutorial
Initial-Repo-Setup
Running-A-Simulation
rebar-generator-mixins

View File

@@ -4,7 +4,7 @@
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = python -msphinx
SPHINXPROJ = REBAR
SPHINXPROJ = Chipyard
SOURCEDIR = .
BUILDDIR = _build

49
docs/Quick-Start.rst Normal file
View File

@@ -0,0 +1,49 @@
Quick Start
===============================
Setting up the Chipyard Repo
-------------------------------------------
Start by fetching Chipyard's sources. Run:
.. code-block:: shell
git clone https://github.com/ucb-bar/chipyard.git
cd chipyard
./scripts/init-submodules-no-riscv-tools.sh
This will have initialized the git submodules.
Installing the RISC-V Tools
-------------------------------------------
We need to install the RISC-V toolchain in order to be able to run RISC-V programs using the Chipyard infrastructure.
This will take about 20-30 minutes. You can expedite the process by setting a ``make`` environment variable to use parallel cores: ``export MAKEFLAGS=-j8``.
To build the toolchains, you should run:
.. code-block:: shell
./scripts/build-toolchains.sh
.. Note:: If you are planning to use the Hwacha vector unit, or other RoCC-based accelerators, you should build the esp-tools toolchains by adding the ``esp-tools`` argument to the script above.
If you are running on an Amazon Web Services EC2 instance, intending to use FireSim, you can also use the ``--ec2fast`` flag for an expedited installation of a pre-compiled toolchain.
What's Next?
-------------------------------------------
This depends on what you are planning to do with Chipyard.
* If you want to learn about the structure of Chipyard, go to :ref:`chipyard-components`.
* If you intend to build one of the vanilla Chipyard examples, go to :ref:`build-a-chip` and follow the instructions.
* If you intend to add a new accelerator, go to :ref:`adding-an-accelerator` and follow the instructions.
* If you intend to run a simulation of one of the vanilla Chipyard examples, go to :ref:`sw-rtl-sim-intro` and follow the instructions.
* If you intend to run a simulation of a custom Chipyard SoC Configuration, go to <> and follow the instructions.
* If you intend to run a full-system FireSim simulation, go to :ref:`firesim-sim-intro` and follow the instructions.
* If you intend to run a VLSI flow using one of the vanilla Chipyard examples, go to <> and follow the instructions.

View File

@@ -1,39 +0,0 @@
Commercial Software RTL Simulators
==============================
VCS
-----------------------
`VCS <https://www.synopsys.com/verification/simulation/vcs.html>`__ is a commercial RTL simulator developed by Synopsys.
It requires commercial licenses.
The REBAR framework can compile and execute simulations using VCS.
VCS simulation will generally compile faster than Verilator simulations.
To run a simulation using VCS, perform the following steps:
Make sure that the VCS simulator is on your ``PATH``.
To compile the example design, run make in the ``sims/vsim`` directory.
This will elaborate the ``DefaultRocketConfig`` in the example project.
An executable called ``simulator-example-DefaultRocketConfig`` will be produced.
This executable is a simulator that has been compiled based on the design that was built.
You can then use this executable to run any compatible RV64 code.
For instance, to run one of the riscv-tools assembly tests.
.. code-block:: shell
./simulator-example-DefaultRocketConfig $RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-simple
If you later create your own project, you can use environment variables to build an alternate configuration.
.. code-block:: shell
make SUB_PROJECT=yourproject
./simulator-<yourproject>-<yourconfig> ...
If you would like to extract waveforms from the simulation, run the command ``make debug`` instead of just ``make``.
This will generate a vpd file (this is a proprietary waveform representation format used by Synopsys) that can be loaded to vpd-supported waveform viewers.
If you have Synopsys licenses, we recommend using the DVE waveform viewer.
Please refer to :ref:`Running A Simulation` for a step by step tutorial on how to get a simulator up and running.

View File

@@ -0,0 +1,90 @@
.. _firesim-sim-intro:
FPGA-Accelerated Simulators
==============================
FireSim
-----------------------
`FireSim <https://fires.im/>`__ is an open-source cycle-accurate FPGA-accelerated full-system hardware simulation platform that runs on cloud FPGAs (Amazon EC2 F1).
FireSim allows RTL-level simulation at orders-of-magnitude faster speeds than software RTL simulators.
FireSim also provides additional device models to allow full-system simulation, including memory models and network models.
FireSim currently supports running only on Amazon EC2 F1 FPGA-enabled virtual instances.
In order to simulate your Chipyard design using FireSim, if you have not
already, follow the initial EC2 setup instructions as detailed in the `FireSim
documentation <http://docs.fires.im/en/latest/Initial-Setup/index.html>`__.
Then clone Chipyard onto your FireSim manager
instance, and setup your Chipyard repository as you would normally.
Next, initalize FireSim as library in Chipyard by running:
.. code-block:: shell
# At the root of your chipyard repo
./scripts/firesim-setup.sh --fast
``firesim-setup.sh`` initializes additional submodules and then invokes
firesim's ``build-setup.sh`` script adding ``--library`` to properly
initialize FireSim as a library submodule in chipyard. You may run
``./sims/firesim/build-setup.sh --help`` to see more options.
Finally, source the following environment at the root of the firesim directory:
.. code-block:: shell
cd sims/firesim
# (Recommended) The default manager environment (includes env.sh)
source sourceme-f1-manager.sh
`Every time you want to use FireSim with a fresh shell, you must source this sourceme.sh`
At this point you're ready to use FireSim with Chipyard. If you're not already
familiar with FireSim, please return to the `FireSim Docs
<https://docs.fires.im/en/latest/Initial-Setup/Setting-up-your-Manager-Instance.html#completing-setup-using-the-manager>`__,
and proceed with the rest of the tutorial.
Current Limitations:
++++++++++++++++++++
FireSim integration in Chipyard is still a work in progress. Presently, you
cannot build a FireSim simulator from any generator project in Chipyard except ``firechip``,
which properly invokes MIDAS on the target RTL.
In the interim, workaround this limitation by importing Config and Module
classes from other generator projects into FireChip. For example, assuming you Chipyard
config looks as following:
.. code-block:: scala
class CustomConfig extends Config(
new WithInclusiveCache ++
new myproject.MyCustomConfig ++
new DefaultRocketConfig
)
Then the equivalent FireChip config (in `generators/firechip/src/main/scala/TargetConfigs.scala`) based on `FireSimRocketChipConfig`
will look as follows:
.. code-block:: scala
class FireSimCustomConfig extends Config(
new WithBootROM ++
new WithPeripheryBusFrequency(BigInt(3200000000L)) ++
new WithExtMemSize(0x400000000L) ++ // 16GB
new WithoutTLMonitors ++
new WithUARTKey ++
new WithNICKey ++
new WithBlockDevice ++
new WithRocketL2TLBs(1024) ++
new WithPerfCounters ++
new WithoutClockGating ++
new WithInclusiveCache ++
new myproject.MyCustomConfig ++
new freechips.rocketchip.system.DefaultConfig)
You should then be able to refer to those classes or an alias of them in your ``DESIGN`` or ``TARGET_CONFIG``
variables. Note that if your target machine has I/O not provided in the default
FireChip targets (see ``generators/firechip/src/main/scala/Targets.scala``) you may need
to write a custom endpoint.

View File

@@ -1,17 +0,0 @@
FPGA-Based Simulators
==============================
FireSim
-----------------------
`FireSim <https://fires.im/>`__ is an open-source cycle-accurate FPGA-accelerated full-system hardware simulation platform that runs on cloud FPGAs (Amazon EC2 F1).
FireSim allows RTL-level simulation at orders-of-magnitude faster speeds than software RTL simulators.
FireSim also provides additional device models to allow full-system simulation, including memory models and network models.
FireSim currently supports running only on Amazon EC2 F1 FPGA-enabled virtual instances on the public cloud.
In order to simulate your REBAR design using FireSim, you should follow the following steps:
Follow the initial EC2 setup instructions as detailed in the `FireSim documentation <http://docs.fires.im/en/latest/Initial-Setup/index.html>`__.
Then clone your full REBAR repository onto your Amazon EC2 FireSim manager instance.
Enter the ``sims/FireSim`` directory, and follow the FireSim instructions for `running a simulation <http://docs.fires.im/en/latest/Running-Simulations-Tutorial/index.html>`__.

View File

@@ -1,35 +0,0 @@
Open Source Software RTL Simulators
==============================
Verilator
-----------------------
`Verilator <https://www.veripool.org/wiki/verilator>`__ is an open-source LGPL-Licensed simulator maintained by `Veripool <https://www.veripool.org/>`__.
The REBAR framework can download, build, and execute simulations using Verilator.
To run a simulation using Verilator, perform the following steps:
To compile the example design, run ``make`` in the ``sims/verisim`` directory.
This will elaborate the ``DefaultRocketConfig`` in the example project.
An executable called ``simulator-example-DefaultRocketConfig`` will be produced.
This executable is a simulator that has been compiled based on the design that was built.
You can then use this executable to run any compatible RV64 code.
For instance, to run one of the riscv-tools assembly tests.
.. code-block:: shell
./simulator-example-DefaultRocketConfig $RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-simple
If you later create your own project, you can use environment variables to build an alternate configuration.
.. code-block:: shell
make SUB_PROJECT=yourproject
./simulator-<yourproject>-<yourconfig> ...
If you would like to extract waveforms from the simulation, run the command ``make debug`` instead of just ``make``.
This will generate a vcd file (vcd is a standard waveform representation file format) that can be loaded to any common waveform viewer.
An open-source vcd-capable waveform viewer is `GTKWave <http://gtkwave.sourceforge.net/>`__.
Please refer to :ref:`Running A Simulation` for a step by step tutorial on how to get a simulator up and running.

View File

@@ -0,0 +1,75 @@
.. _sw-rtl-sim-intro:
Software RTL Simulators
===================================
Verilator (Open-Source)
-----------------------
`Verilator <https://www.veripool.org/wiki/verilator>`__ is an open-source LGPL-Licensed simulator maintained by `Veripool <https://www.veripool.org/>`__.
The Chipyard framework can download, build, and execute simulations using Verilator.
To run a simulation using Verilator, perform the following steps:
To compile the example design, run ``make`` in the ``sims/verilator`` directory.
This will elaborate the ``DefaultRocketConfig`` in the example project.
An executable called ``simulator-example-DefaultRocketConfig`` will be produced.
This executable is a simulator that has been compiled based on the design that was built.
You can then use this executable to run any compatible RV64 code.
For instance, to run one of the riscv-tools assembly tests.
.. code-block:: shell
./simulator-example-DefaultRocketConfig $RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-simple
If you later create your own project, you can use environment variables to build an alternate configuration.
.. code-block:: shell
make SUB_PROJECT=yourproject
./simulator-<yourproject>-<yourconfig> ...
If you would like to extract waveforms from the simulation, run the command ``make debug`` instead of just ``make``.
This will generate a vcd file (vcd is a standard waveform representation file format) that can be loaded to any common waveform viewer.
An open-source vcd-capable waveform viewer is `GTKWave <http://gtkwave.sourceforge.net/>`__.
Please refer to :ref:`Running A Simulation` for a step by step tutorial on how to get a simulator up and running.
Commercial Software RTL Simulators
Synopsys VCS (License Required)
--------------------------------
`VCS <https://www.synopsys.com/verification/simulation/vcs.html>`__ is a commercial RTL simulator developed by Synopsys.
It requires commercial licenses.
The Chipyard framework can compile and execute simulations using VCS.
VCS simulation will generally compile faster than Verilator simulations.
To run a simulation using VCS, perform the following steps:
Make sure that the VCS simulator is on your ``PATH``.
To compile the example design, run make in the ``sims/vcs`` directory.
This will elaborate the ``DefaultRocketConfig`` in the example project.
An executable called ``simulator-example-DefaultRocketConfig`` will be produced.
This executable is a simulator that has been compiled based on the design that was built.
You can then use this executable to run any compatible RV64 code.
For instance, to run one of the riscv-tools assembly tests.
.. code-block:: shell
./simulator-example-DefaultRocketConfig $RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-simple
If you later create your own project, you can use environment variables to build an alternate configuration.
.. code-block:: shell
make SUB_PROJECT=yourproject
./simulator-<yourproject>-<yourconfig> ...
If you would like to extract waveforms from the simulation, run the command ``make debug`` instead of just ``make``.
This will generate a vpd file (this is a proprietary waveform representation format used by Synopsys) that can be loaded to vpd-supported waveform viewers.
If you have Synopsys licenses, we recommend using the DVE waveform viewer.
Please refer to :ref:`Running A Simulation` for a step by step tutorial on how to get a simulator up and running.

View File

@@ -1,15 +1,20 @@
Simulators
=======================
REBAR provides support and integration for multiple simulation flows, for various user levels and requirements.
In the majority of cases during a digital design development process, a simple software RTL simulation will do.
When more advanced full-system evaluation is required, with long running workloads, FPGA-accelerated simulation will then become a preferable solution.
The following pages provide detailed information about the simulation possibilities within the REBAR framework.
Chipyard supports two classes of simulation:
#. Software RTL simulation using commercial or open-source (Verilator) RTL simulators
#. FPGA-accelerated full-system simulation using FireSim
Software RTL simulators of Chipyard designs run at O(1 KHz), but compile
quickly and provide full waveforms. Conversly, FPGA-accelerated simulators run
at O(100 MHz), making them appropriate for booting an operating system and
running a complete workload, but have multi-hour compile times and poorer debug
visability.
.. toctree::
:maxdepth: 2
:caption: Simulators:
Open-Source-Simulators
Commercial-Simulators
FPGA-Based-Simulators
Software-RTL-Simulators
FPGA-Accelerated-Simulators

View File

@@ -1,7 +1,7 @@
Tools
==============================
The REBAR framework relays heavily on a set of Scala-based tools.
The Chipyard framework relays heavily on a set of Scala-based tools.
The following pages will introduce them, and how we can use them in order to generate flexible designs.
.. toctree::

View File

@@ -1,7 +1,58 @@
HAMMER
Core HAMMER
================================
`HAMMER <https://github.com/ucb-bar/hammer>`__ is a physical design generator that wraps around vendor specific technologies and tools to provide a single API to create ASICs.
HAMMER allows for reusability in ASIC design while still providing the designers leeway to make their own modifications.
For more information, read the `HAMMER paper <https://people.eecs.berkeley.edu/~edwardw/pubs/hammer-woset-2018.pdf>`__ and see the `GitHub repository <https://github.com/ucb-bar/hammer>`__.
Actions
-------
Actions are the top-level tasks Hammer is capable of executing (e.g. synthesis, place-and-route, etc.)
Steps
-------
Steps are the sub-components of actions that individually addressable in Hammer (e.g. placement in the place-and-route action).
Hooks
-------
Hooks are modifications to steps or actions that are programmatically defined in a Hammer configuration.
Tool Plugins
============
Hammer supports separately managed plugins for different CAD tool vendors.
The types of tools (in there hammer names) supported currently include:
* synthesis
* par
* drc
* lvs
* sram_generator
* pcb
In order to configure your tool plugin of choice, you will need to set several configuration variables.
First, you should select which specific tool you want to use by setting ``vlsi.core.<tool_type>_tool`` to the name of your tool.
For example ``vlsi.core.par_tool: "innovus"``.
You will also need to point hammer to the folder that contains your tool plugin by setting ``vlsi.core.<tool_type>_tool_path``.
This directory should include a folder with the name of the tool as specified previously, which itself includes a python file ``__init__.py`` and a yaml file ``defaults.yml`` specifying the default values for any tool specific variables.
In addition you can also customize the version of the tools you use by setting ``<tool_type>.<tool_name>.version`` to a tool specific string.
Looking at the tools ``defaults.yml`` will inform you if there are other variables you would like to set for your use of this tool.
The ``__init__.py`` file should contain a variable, ``tool``, that points to the class implementing this tools Hammer support.
This class should be a subclass of ``Hammer<tool_type>Tool``, which will be a subclass of ``HammerTool``.
Technology Plugins
==================
Hammer supports separately managed plugins for different technologies.
Configuration
=============
To configure a hammer flow the user needs to supply a yaml or json configuration file the chooses the tool and technology plugins and versions as well as any design specific configuration APIs.
You can see the current set of all available Hammer APIs `here <https://github.com/ucb-bar/hammer/blob/master/src/hammer-vlsi/defaults.yml>`__.

View File

@@ -1,11 +1,11 @@
VLSI Production
VLSI Flow
================================
The REBAR framework aim to provide wrappers to a general VLSI flow.
In particular, we aim to support the HAMMER flow.
The Chipyard framework aims to provide wrappers for a general VLSI flow.
In particular, we aim to support the HAMMER physical design generator flow.
.. toctree::
:maxdepth: 2
:caption: VLSI Production:
:caption: VLSI Flow:
HAMMER

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
# REBAR documentation build configuration file, created by
# Chipyard documentation build configuration file, created by
# sphinx-quickstart on Fri Mar 8 11:46:38 2019.
#
# This file is execfile()d with the current directory set to its
@@ -52,7 +52,7 @@ source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
project = u'REBAR'
project = u'Chipyard'
copyright = u'2019, Berkeley Architecture Research'
author = u'Berkeley Architecture Research'
@@ -125,7 +125,7 @@ html_sidebars = {
# -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'REBARdoc'
htmlhelp_basename = 'Chipyarddoc'
# -- Options for LaTeX output ---------------------------------------------
@@ -152,7 +152,7 @@ latex_elements = {
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'REBAR.tex', u'REBAR Documentation',
(master_doc, 'Chipyard.tex', u'Chipyard Documentation',
u'Berkeley Architecture Research', 'manual'),
]
@@ -162,7 +162,7 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'rebar', u'REBAR Documentation',
(master_doc, 'chipyard', u'Chipyard Documentation',
[author], 1)
]
@@ -173,8 +173,8 @@ man_pages = [
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'REBAR', u'REBAR Documentation',
author, 'REBAR', 'One line description of project.',
(master_doc, 'Chipyard', u'Chipyard Documentation',
author, 'Chipyard', 'One line description of project.',
'Miscellaneous'),
]

View File

@@ -1,21 +1,23 @@
.. REBAR documentation master file, created by
.. 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 REBAR's documentation!
=================================
Welcome to Chipyard's documentation!
====================================
REBAR is a a framework for designing and evaluating full-system hardware using agile teams.
Chipyard is a a framework for designing and evaluating full-system hardware using agile teams.
It is composed of a collection of tools and libraries designed to provide an intergration between open-source and commercial tools for the development of systems-on-chip.
New to REBAR? Jump to the :ref:`Getting Started` page for more info.
New to Chipyard? Jump to the :ref:`Chipyard Basics` page for more info.
.. include:: Quick-Start.rst
.. toctree::
:maxdepth: 3
:caption: Contents:
:numbered:
Getting-Started/index
Chipyard-Basics/index
:maxdepth: 3
:caption: Simulation:
@@ -37,6 +39,17 @@ New to REBAR? Jump to the :ref:`Getting Started` page for more info.
:numbered:
VLSI/index
:maxdepth: 3
:caption: Customization:
:numbered:
Customization/index
:maxdepth: 3
:caption: Advanced Usage:
:numbered:
Advanced-Usage/index
Indices and tables
==================

View File

@@ -0,0 +1,90 @@
package example
import chisel3._
import freechips.rocketchip.config.{Config}
import freechips.rocketchip.subsystem.{WithJtagDTM}
import boom.common._
// ---------------------
// BOOM Configs
// ---------------------
class SmallBoomConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new boom.common.SmallBoomConfig)
class MediumBoomConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new boom.common.MediumBoomConfig)
class LargeBoomConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new boom.common.LargeBoomConfig)
class MegaBoomConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new boom.common.MegaBoomConfig)
class jtagSmallBoomConfig extends Config(
new WithDTMBoomRocketTop ++
new WithBootROM ++
new WithJtagDTM ++
new boom.common.SmallBoomConfig)
class jtagMediumBoomConfig extends Config(
new WithDTMBoomRocketTop ++
new WithBootROM ++
new WithJtagDTM ++
new boom.common.MediumBoomConfig)
class jtagLargeBoomConfig extends Config(
new WithDTMBoomRocketTop ++
new WithBootROM ++
new WithJtagDTM ++
new boom.common.LargeBoomConfig)
class jtagMegaBoomConfig extends Config(
new WithDTMBoomRocketTop ++
new WithBootROM ++
new WithJtagDTM ++
new boom.common.MegaBoomConfig)
class SmallDualBoomConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new boom.common.SmallDualBoomConfig)
class TracedSmallBoomConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new boom.common.TracedSmallBoomConfig)
class SmallRV32UnifiedBoomConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new boom.common.SmallRV32UnifiedBoomConfig)
// --------------------------
// BOOM + Rocket Configs
// --------------------------
class SmallBoomAndRocketConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new boom.common.SmallBoomAndRocketConfig)
class MediumBoomAndRocketConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new boom.common.MediumBoomAndRocketConfig)
class DualMediumBoomAndDualRocketConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new boom.common.DualMediumBoomAndDualRocketConfig)

View File

@@ -58,6 +58,15 @@ class WithNormalBoomRocketTop extends Config((site, here, up) => {
}
})
/**
* Class to specify a top level BOOM and/or Rocket system with DTM
*/
class WithDTMBoomRocketTop extends Config((site, here, up) => {
case BuildBoomRocketTopWithDTM => (clock: Clock, reset: Bool, p: Parameters) => {
Module(LazyModule(new BoomRocketTopWithDTM()(p)).module)
}
})
/**
* Class to specify a top level BOOM and/or Rocket system with PWM
*/

View File

@@ -3,7 +3,7 @@ package example
import chisel3._
import freechips.rocketchip.config.{Config}
import freechips.rocketchip.subsystem.{WithRoccExample, WithNMemoryChannels, WithNBigCores, WithRV32, WithExtMemSize, WithNBanks}
import freechips.rocketchip.subsystem.{WithRoccExample, WithNMemoryChannels, WithNBigCores, WithRV32, WithExtMemSize, WithNBanks, WithInclusiveCache}
import testchipip._
@@ -62,17 +62,26 @@ class GB1MemoryConfig extends Config(
new WithExtMemSize((1<<30) * 1L) ++
new DefaultRocketConfig)
class RocketL2Config extends Config(
new WithInclusiveCache ++
new DefaultRocketConfig)
class HwachaL2Config extends Config(
new hwacha.DefaultHwachaConfig ++
new WithInclusiveCache ++
new DefaultRocketConfig)
// ------------
// BOOM Configs
// ------------
class BaseBoomConfig extends Config(
new WithBootROM ++
new boom.system.BoomConfig)
new boom.common.LargeBoomConfig)
class SmallBaseBoomConfig extends Config(
new WithBootROM ++
new boom.system.SmallBoomConfig)
new boom.common.SmallBoomConfig)
class DefaultBoomConfig extends Config(
new WithNormalBoomRocketTop ++
@@ -121,8 +130,9 @@ class DualCoreBoomConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new boom.common.WithRVC ++
new boom.common.DefaultBoomConfig ++
new boom.system.WithNBoomCores(2) ++
new boom.common.WithLargeBooms ++
new boom.common.BaseBoomConfig ++
new boom.common.WithNBoomCores(2) ++
new freechips.rocketchip.subsystem.WithoutTLMonitors ++
new freechips.rocketchip.system.BaseConfig)
@@ -131,15 +141,19 @@ class DualCoreSmallBoomConfig extends Config(
new WithBootROM ++
new boom.common.WithRVC ++
new boom.common.WithSmallBooms ++
new boom.common.DefaultBoomConfig ++
new boom.system.WithNBoomCores(2) ++
new boom.common.BaseBoomConfig ++
new boom.common.WithNBoomCores(2) ++
new freechips.rocketchip.subsystem.WithoutTLMonitors ++
new freechips.rocketchip.system.BaseConfig)
class RV32UnifiedBoomConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new boom.system.SmallRV32UnifiedBoomConfig)
new boom.common.SmallRV32UnifiedBoomConfig)
class BoomL2Config extends Config(
new WithInclusiveCache ++
new SmallDefaultBoomConfig)
// ---------------------
// BOOM and Rocket Configs
@@ -147,21 +161,22 @@ class RV32UnifiedBoomConfig extends Config(
class BaseBoomAndRocketConfig extends Config(
new WithBootROM ++
new boom.system.WithRenumberHarts ++
new boom.common.WithRenumberHarts ++
new boom.common.WithRVC ++
new boom.common.DefaultBoomConfig ++
new boom.system.WithNBoomCores(1) ++
new boom.common.WithLargeBooms ++
new boom.common.BaseBoomConfig ++
new boom.common.WithNBoomCores(1) ++
new freechips.rocketchip.subsystem.WithoutTLMonitors ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
class SmallBaseBoomAndRocketConfig extends Config(
new WithBootROM ++
new boom.system.WithRenumberHarts ++
new boom.common.WithRenumberHarts ++
new boom.common.WithRVC ++
new boom.common.WithSmallBooms ++
new boom.common.DefaultBoomConfig ++
new boom.system.WithNBoomCores(1) ++
new boom.common.BaseBoomConfig ++
new boom.common.WithNBoomCores(1) ++
new freechips.rocketchip.subsystem.WithoutTLMonitors ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
@@ -208,24 +223,26 @@ class GPIOBoomAndRocketConfig extends Config(
class DualCoreBoomAndOneRocketConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new boom.system.WithRenumberHarts ++
new boom.common.WithRenumberHarts ++
new boom.common.WithRVC ++
new boom.common.DefaultBoomConfig ++
new boom.system.WithNBoomCores(2) ++
new boom.common.WithLargeBooms ++
new boom.common.BaseBoomConfig ++
new boom.common.WithNBoomCores(2) ++
new freechips.rocketchip.subsystem.WithoutTLMonitors ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
class DualCoreBoomAndOneHwachaRocketConfig extends Config(
class DualBoomAndOneHwachaRocketConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new WithMultiRoCC ++
new WithMultiRoCCHwacha(0) ++ // put Hwacha just on hart0 which was renumbered to Rocket
new boom.system.WithRenumberHarts ++
new boom.common.WithRenumberHarts(rocketFirst = true) ++
new hwacha.DefaultHwachaConfig ++
new boom.common.WithRVC ++
new boom.common.DefaultBoomConfig ++
new boom.system.WithNBoomCores(2) ++
new boom.common.WithLargeBooms ++
new boom.common.BaseBoomConfig ++
new boom.common.WithNBoomCores(2) ++
new freechips.rocketchip.subsystem.WithoutTLMonitors ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
@@ -233,12 +250,17 @@ class DualCoreBoomAndOneHwachaRocketConfig extends Config(
class RV32BoomAndRocketConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new boom.system.WithRenumberHarts ++
new boom.common.WithRenumberHarts ++
new boom.common.WithBoomRV32 ++
new boom.common.WithRVC ++
new boom.common.DefaultBoomConfig ++
new boom.system.WithNBoomCores(1) ++
new boom.common.WithLargeBooms ++
new boom.common.BaseBoomConfig ++
new boom.common.WithNBoomCores(1) ++
new freechips.rocketchip.subsystem.WithoutTLMonitors ++
new WithRV32 ++
new freechips.rocketchip.subsystem.WithRV32 ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
class DualCoreRocketL2Config extends Config(
new WithInclusiveCache ++
new DualCoreRocketConfig)

View File

@@ -1,140 +1,22 @@
package example
import scala.collection.mutable.LinkedHashSet
import chisel3._
import chisel3.experimental._
import firrtl.transforms.{BlackBoxResourceAnno, BlackBoxSourceHelper}
import freechips.rocketchip.subsystem.{RocketTilesKey}
import freechips.rocketchip.diplomacy.{LazyModule}
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.config.{Parameters}
import freechips.rocketchip.util.{GeneratorApp}
import freechips.rocketchip.tile.{XLen}
import freechips.rocketchip.system.{TestGeneration, RegressionTestSuite}
import boom.system.{BoomTilesKey, BoomTestSuites}
object Generator extends GeneratorApp {
val rv64RegrTestNames = LinkedHashSet(
"rv64ud-v-fcvt",
"rv64ud-p-fdiv",
"rv64ud-v-fadd",
"rv64uf-v-fadd",
"rv64um-v-mul",
"rv64mi-p-breakpoint",
"rv64uc-v-rvc",
"rv64ud-v-structural",
"rv64si-p-wfi",
"rv64um-v-divw",
"rv64ua-v-lrsc",
"rv64ui-v-fence_i",
"rv64ud-v-fcvt_w",
"rv64uf-v-fmin",
"rv64ui-v-sb",
"rv64ua-v-amomax_d",
"rv64ud-v-move",
"rv64ud-v-fclass",
"rv64ua-v-amoand_d",
"rv64ua-v-amoxor_d",
"rv64si-p-sbreak",
"rv64ud-v-fmadd",
"rv64uf-v-ldst",
"rv64um-v-mulh",
"rv64si-p-dirty")
val rv32RegrTestNames = LinkedHashSet(
"rv32mi-p-ma_addr",
"rv32mi-p-csr",
"rv32ui-p-sh",
"rv32ui-p-lh",
"rv32uc-p-rvc",
"rv32mi-p-sbreak",
"rv32ui-p-sll")
// add unique test suites
override def addTestSuites {
import freechips.rocketchip.system.DefaultTestSuites._
val xlen = params(XLen)
// TODO: for now only generate tests for the first rocket/boom tile in the subsystem
// TODO: support heterogenous systems?
// rocket specific tests
params(RocketTilesKey).headOption.map { tileParams =>
val coreParams = tileParams.core
val vm = coreParams.useVM
val env = if (vm) List("p","v") else List("p")
coreParams.fpu foreach { case cfg =>
if (xlen == 32) {
TestGeneration.addSuites(env.map(rv32uf))
if (cfg.fLen >= 64)
TestGeneration.addSuites(env.map(rv32ud))
} else {
TestGeneration.addSuite(rv32udBenchmarks)
TestGeneration.addSuites(env.map(rv64uf))
if (cfg.fLen >= 64)
TestGeneration.addSuites(env.map(rv64ud))
}
}
if (coreParams.useAtomics) {
if (tileParams.dcache.flatMap(_.scratch).isEmpty)
TestGeneration.addSuites(env.map(if (xlen == 64) rv64ua else rv32ua))
else
TestGeneration.addSuites(env.map(if (xlen == 64) rv64uaSansLRSC else rv32uaSansLRSC))
}
if (coreParams.useCompressed) TestGeneration.addSuites(env.map(if (xlen == 64) rv64uc else rv32uc))
val (rvi, rvu) =
if (xlen == 64) ((if (vm) rv64i else rv64pi), rv64u)
else ((if (vm) rv32i else rv32pi), rv32u)
TestGeneration.addSuites(rvi.map(_("p")))
TestGeneration.addSuites((if (vm) List("v") else List()).flatMap(env => rvu.map(_(env))))
TestGeneration.addSuite(benchmarks)
TestGeneration.addSuite(new RegressionTestSuite(if (xlen == 64) rv64RegrTestNames else rv32RegrTestNames))
}
// boom specific tests
params(BoomTilesKey).headOption.map { tileParams =>
val coreParams = tileParams.core
val vm = coreParams.useVM
val env = if (vm) List("p","v") else List("p")
coreParams.fpu foreach { case cfg =>
if (xlen == 32) {
TestGeneration.addSuites(env.map(rv32uf))
if (cfg.fLen >= 64) {
TestGeneration.addSuites(env.map(rv32ud))
}
} else if (cfg.fLen >= 64) {
TestGeneration.addSuites(env.map(rv64ud))
TestGeneration.addSuites(env.map(rv64uf))
TestGeneration.addSuite(rv32udBenchmarks)
}
}
if (coreParams.useAtomics) {
if (tileParams.dcache.flatMap(_.scratch).isEmpty) {
TestGeneration.addSuites(env.map(if (xlen == 64) rv64ua else rv32ua))
} else {
TestGeneration.addSuites(env.map(if (xlen == 64) rv64uaSansLRSC else rv32uaSansLRSC))
}
}
if (coreParams.useCompressed) TestGeneration.addSuites(env.map(if (xlen == 64) rv64uc else rv32uc))
// Include our BOOM-specific overrides.
val (rvi, rvu) =
if (xlen == 64) ((if (vm) BoomTestSuites.rv64i else BoomTestSuites.rv64pi), rv64u)
else ((if (vm) rv32i else rv32pi), rv32u)
TestGeneration.addSuites(rvi.map(_("p")))
TestGeneration.addSuites(rvu.map(_("p")))
TestGeneration.addSuites((if (vm) List("v") else List()).flatMap(env => rvu.map(_(env))))
TestGeneration.addSuite(benchmarks)
rv64RegrTestNames -= "rv64mi-p-breakpoint" // TODO: breakpoints not implemented yet
TestGeneration.addSuite(new RegressionTestSuite(if (xlen == 64) rv64RegrTestNames else rv32RegrTestNames))
}
implicit val p: Parameters = params
TestSuiteHelper.addRocketTestSuites
TestSuiteHelper.addBoomTestSuites
}
// specify the name that the generator outputs files as
val longName = names.topModuleProject + "." + names.topModuleClass + "." + names.configs
// generate files
generateFirrtl
generateAnno
generateTestSuiteMakefrags

View File

@@ -8,14 +8,19 @@ import firrtl.transforms.{BlackBoxResourceAnno, BlackBoxSourceHelper}
import freechips.rocketchip.diplomacy.LazyModule
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.util.GeneratorApp
import freechips.rocketchip.devices.debug.{Debug}
// --------------------------
// -------------------------------
// BOOM and/or Rocket Test Harness
// --------------------------
// -------------------------------
case object BuildBoomRocketTop extends Field[(Clock, Bool, Parameters) => BoomRocketTopModule[BoomRocketTop]]
case object BuildBoomRocketTopWithDTM extends Field[(Clock, Bool, Parameters) => BoomRocketTopWithDTMModule[BoomRocketTopWithDTM]]
class BoomRocketTestHarness(implicit val p: Parameters) extends Module {
/**
* Test harness using TSI to bringup the system
*/
class TestHarness(implicit val p: Parameters) extends Module {
val io = IO(new Bundle {
val success = Output(Bool())
})
@@ -24,6 +29,7 @@ class BoomRocketTestHarness(implicit val p: Parameters) extends Module {
override def desiredName = "TestHarness"
val dut = p(BuildBoomRocketTop)(clock, reset.toBool, p)
dut.debug := DontCare
dut.connectSimAXIMem()
dut.connectSimAXIMMIO()
@@ -41,5 +47,41 @@ class BoomRocketTestHarness(implicit val p: Parameters) extends Module {
axi.w.bits := DontCare
}
})
io.success := dut.connectSimSerial()
}
/**
* Test harness using the Debug Test Module (DTM) to bringup the system
*/
class TestHarnessWithDTM(implicit p: Parameters) extends Module
{
val io = IO(new Bundle {
val success = Output(Bool())
})
// force Chisel to rename module
override def desiredName = "TestHarness"
val dut = p(BuildBoomRocketTopWithDTM)(clock, reset.toBool, p)
dut.reset := reset.asBool | dut.debug.ndreset
dut.connectSimAXIMem()
dut.connectSimAXIMMIO()
dut.dontTouchPorts()
dut.tieOffInterrupts()
dut.l2_frontend_bus_axi4.foreach(axi => {
axi.tieoff()
experimental.DataMirror.directionOf(axi.ar.ready) match {
case core.ActualDirection.Input =>
axi.r.bits := DontCare
axi.b.bits := DontCare
case core.ActualDirection.Output =>
axi.aw.bits := DontCare
axi.ar.bits := DontCare
axi.w.bits := DontCare
}
})
Debug.connectDebug(dut.debug, clock, reset.asBool, io.success)
}

View File

@@ -0,0 +1,142 @@
package example
import scala.collection.mutable.{LinkedHashSet}
import freechips.rocketchip.subsystem.{RocketTilesKey}
import freechips.rocketchip.tile.{XLen}
import freechips.rocketchip.config.{Parameters}
import freechips.rocketchip.util.{GeneratorApp}
import freechips.rocketchip.system.{TestGeneration, RegressionTestSuite}
import boom.system.{BoomTilesKey}
/**
* A set of pre-chosen regression tests
*/
object RegressionTestSuites
{
val rv64RegrTestNames = LinkedHashSet(
"rv64ud-v-fcvt",
"rv64ud-p-fdiv",
"rv64ud-v-fadd",
"rv64uf-v-fadd",
"rv64um-v-mul",
"rv64mi-p-breakpoint",
"rv64uc-v-rvc",
"rv64ud-v-structural",
"rv64si-p-wfi",
"rv64um-v-divw",
"rv64ua-v-lrsc",
"rv64ui-v-fence_i",
"rv64ud-v-fcvt_w",
"rv64uf-v-fmin",
"rv64ui-v-sb",
"rv64ua-v-amomax_d",
"rv64ud-v-move",
"rv64ud-v-fclass",
"rv64ua-v-amoand_d",
"rv64ua-v-amoxor_d",
"rv64si-p-sbreak",
"rv64ud-v-fmadd",
"rv64uf-v-ldst",
"rv64um-v-mulh",
"rv64si-p-dirty")
val rv32RegrTestNames = LinkedHashSet(
"rv32mi-p-ma_addr",
"rv32mi-p-csr",
"rv32ui-p-sh",
"rv32ui-p-lh",
"rv32uc-p-rvc",
"rv32mi-p-sbreak",
"rv32ui-p-sll")
}
/**
* Helper functions to add BOOM or Rocket tests
*/
object TestSuiteHelper
{
import freechips.rocketchip.system.DefaultTestSuites._
import RegressionTestSuites._
/**
* Add BOOM tests (asm, bmark, regression)
*/
def addBoomTestSuites(implicit p: Parameters) = {
val xlen = p(XLen)
p(BoomTilesKey).find(_.hartId == 0).map { tileParams =>
val coreParams = tileParams.core
val vm = coreParams.useVM
val env = if (vm) List("p","v") else List("p")
coreParams.fpu foreach { case cfg =>
if (xlen == 32) {
TestGeneration.addSuites(env.map(rv32uf))
if (cfg.fLen >= 64) {
TestGeneration.addSuites(env.map(rv32ud))
}
} else if (cfg.fLen >= 64) {
TestGeneration.addSuites(env.map(rv64ud))
TestGeneration.addSuites(env.map(rv64uf))
TestGeneration.addSuite(rv32udBenchmarks)
}
}
if (coreParams.useAtomics) {
if (tileParams.dcache.flatMap(_.scratch).isEmpty) {
TestGeneration.addSuites(env.map(if (xlen == 64) rv64ua else rv32ua))
} else {
TestGeneration.addSuites(env.map(if (xlen == 64) rv64uaSansLRSC else rv32uaSansLRSC))
}
}
if (coreParams.useCompressed) TestGeneration.addSuites(env.map(if (xlen == 64) rv64uc else rv32uc))
val (rvi, rvu) =
if (xlen == 64) ((if (vm) rv64i else rv64pi), rv64u)
else ((if (vm) rv32i else rv32pi), rv32u)
TestGeneration.addSuites(rvi.map(_("p")))
TestGeneration.addSuites(rvu.map(_("p")))
TestGeneration.addSuites((if (vm) List("v") else List()).flatMap(env => rvu.map(_(env))))
TestGeneration.addSuite(benchmarks)
TestGeneration.addSuite(new RegressionTestSuite(if (xlen == 64) rv64RegrTestNames else rv32RegrTestNames))
}
}
/**
* Add Rocket tests (asm, bmark, regression)
*/
def addRocketTestSuites(implicit p: Parameters) = {
val xlen = p(XLen)
p(RocketTilesKey).find(_.hartId == 0).map { tileParams =>
val coreParams = tileParams.core
val vm = coreParams.useVM
val env = if (vm) List("p","v") else List("p")
coreParams.fpu foreach { case cfg =>
if (xlen == 32) {
TestGeneration.addSuites(env.map(rv32uf))
if (cfg.fLen >= 64)
TestGeneration.addSuites(env.map(rv32ud))
} else {
TestGeneration.addSuite(rv32udBenchmarks)
TestGeneration.addSuites(env.map(rv64uf))
if (cfg.fLen >= 64)
TestGeneration.addSuites(env.map(rv64ud))
}
}
if (coreParams.useAtomics) {
if (tileParams.dcache.flatMap(_.scratch).isEmpty)
TestGeneration.addSuites(env.map(if (xlen == 64) rv64ua else rv32ua))
else
TestGeneration.addSuites(env.map(if (xlen == 64) rv64uaSansLRSC else rv32uaSansLRSC))
}
if (coreParams.useCompressed) TestGeneration.addSuites(env.map(if (xlen == 64) rv64uc else rv32uc))
val (rvi, rvu) =
if (xlen == 64) ((if (vm) rv64i else rv64pi), rv64u)
else ((if (vm) rv32i else rv32pi), rv32u)
TestGeneration.addSuites(rvi.map(_("p")))
TestGeneration.addSuites((if (vm) List("v") else List()).flatMap(env => rvu.map(_(env))))
TestGeneration.addSuite(benchmarks)
TestGeneration.addSuite(new RegressionTestSuite(if (xlen == 64) rv64RegrTestNames else rv32RegrTestNames))
}
}
}

View File

@@ -12,17 +12,17 @@ import testchipip._
import sifive.blocks.devices.gpio._
// -------------------------------
// ------------------------------------
// BOOM and/or Rocket Top Level Systems
// -------------------------------
// ------------------------------------
class BoomRocketTop(implicit p: Parameters) extends boom.system.ExampleBoomAndRocketSystem
class BoomRocketTop(implicit p: Parameters) extends boom.system.BoomRocketSystem
with HasNoDebug
with HasPeripherySerial {
override lazy val module = new BoomRocketTopModule(this)
}
class BoomRocketTopModule[+L <: BoomRocketTop](l: L) extends boom.system.ExampleBoomAndRocketSystemModule(l)
class BoomRocketTopModule[+L <: BoomRocketTop](l: L) extends boom.system.BoomRocketSystemModule(l)
with HasNoDebugModuleImp
with HasPeripherySerialModuleImp
with DontTouch
@@ -67,3 +67,12 @@ class BoomRocketTopWithGPIO(implicit p: Parameters) extends BoomRocketTop
class BoomRocketTopWithGPIOModule(l: BoomRocketTopWithGPIO)
extends BoomRocketTopModule(l)
with HasPeripheryGPIOModuleImp
//---------------------------------------------------------------------------------------------------------
class BoomRocketTopWithDTM(implicit p: Parameters) extends boom.system.BoomRocketSystem
{
override lazy val module = new BoomRocketTopWithDTMModule(this)
}
class BoomRocketTopWithDTMModule[+L <: BoomRocketTopWithDTM](l: L) extends boom.system.BoomRocketSystemModule(l)

View File

@@ -0,0 +1,133 @@
//See LICENSE for license details.
package firesim.firesim
import java.io.{File}
import chisel3.experimental.RawModule
import chisel3.internal.firrtl.{Circuit, Port}
import freechips.rocketchip.diplomacy.{ValName, AutoBundle}
import freechips.rocketchip.devices.debug.DebugIO
import freechips.rocketchip.util.{HasGeneratorUtilities, ParsedInputNames, ElaborationArtefacts}
import freechips.rocketchip.system.DefaultTestSuites._
import freechips.rocketchip.system.{TestGeneration, RegressionTestSuite}
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.subsystem.RocketTilesKey
import freechips.rocketchip.tile.XLen
import boom.system.{BoomTilesKey, BoomTestSuites}
import firesim.util.{GeneratorArgs, HasTargetAgnosticUtilites, HasFireSimGeneratorUtilities}
trait HasTestSuites {
val rv64RegrTestNames = collection.mutable.LinkedHashSet(
"rv64ud-v-fcvt",
"rv64ud-p-fdiv",
"rv64ud-v-fadd",
"rv64uf-v-fadd",
"rv64um-v-mul",
// "rv64mi-p-breakpoint", // Not implemented in BOOM
// "rv64uc-v-rvc", // Not implemented in BOOM
"rv64ud-v-structural",
"rv64si-p-wfi",
"rv64um-v-divw",
"rv64ua-v-lrsc",
"rv64ui-v-fence_i",
"rv64ud-v-fcvt_w",
"rv64uf-v-fmin",
"rv64ui-v-sb",
"rv64ua-v-amomax_d",
"rv64ud-v-move",
"rv64ud-v-fclass",
"rv64ua-v-amoand_d",
"rv64ua-v-amoxor_d",
"rv64si-p-sbreak",
"rv64ud-v-fmadd",
"rv64uf-v-ldst",
"rv64um-v-mulh",
"rv64si-p-dirty")
val rv32RegrTestNames = collection.mutable.LinkedHashSet(
"rv32mi-p-ma_addr",
"rv32mi-p-csr",
"rv32ui-p-sh",
"rv32ui-p-lh",
"rv32uc-p-rvc",
"rv32mi-p-sbreak",
"rv32ui-p-sll")
def addTestSuites(targetName: String, params: Parameters) {
val coreParams =
if (params(RocketTilesKey).nonEmpty) {
params(RocketTilesKey).head.core
} else {
params(BoomTilesKey).head.core
}
val xlen = params(XLen)
val vm = coreParams.useVM
val env = if (vm) List("p","v") else List("p")
coreParams.fpu foreach { case cfg =>
if (xlen == 32) {
TestGeneration.addSuites(env.map(rv32uf))
if (cfg.fLen >= 64)
TestGeneration.addSuites(env.map(rv32ud))
} else {
TestGeneration.addSuite(rv32udBenchmarks)
TestGeneration.addSuites(env.map(rv64uf))
if (cfg.fLen >= 64)
TestGeneration.addSuites(env.map(rv64ud))
}
}
if (coreParams.useAtomics) TestGeneration.addSuites(env.map(if (xlen == 64) rv64ua else rv32ua))
if (coreParams.useCompressed) TestGeneration.addSuites(env.map(if (xlen == 64) rv64uc else rv32uc))
val (rvi, rvu) =
if (params(BoomTilesKey).nonEmpty) ((if (vm) BoomTestSuites.rv64i else BoomTestSuites.rv64pi), rv64u)
else if (xlen == 64) ((if (vm) rv64i else rv64pi), rv64u)
else ((if (vm) rv32i else rv32pi), rv32u)
TestGeneration.addSuites(rvi.map(_("p")))
TestGeneration.addSuites((if (vm) List("v") else List()).flatMap(env => rvu.map(_(env))))
TestGeneration.addSuite(benchmarks)
TestGeneration.addSuite(new RegressionTestSuite(if (xlen == 64) rv64RegrTestNames else rv32RegrTestNames))
TestGeneration.addSuite(FastBlockdevTests)
TestGeneration.addSuite(SlowBlockdevTests)
if (!targetName.contains("NoNIC"))
TestGeneration.addSuite(NICLoopbackTests)
}
}
// Mixed into an App or into a TestSuite
trait IsFireSimGeneratorLike extends HasFireSimGeneratorUtilities with HasTestSuites {
/** Output software test Makefrags, which provide targets for integration testing. */
def generateTestSuiteMakefrags {
addTestSuites(names.topModuleClass, targetParams)
writeOutputFile(s"$longName.d", TestGeneration.generateMakefrag) // Subsystem-specific test suites
}
// Output miscellaneous files produced as a side-effect of elaboration
def generateArtefacts {
ElaborationArtefacts.files.foreach { case (extension, contents) =>
writeOutputFile(s"${longName}.${extension}", contents ())
}
}
}
object FireSimGenerator extends App with IsFireSimGeneratorLike {
lazy val generatorArgs = GeneratorArgs(args)
lazy val genDir = new File(names.targetDir)
elaborateAndCompileWithMidas
generateTestSuiteMakefrags
generateHostVerilogHeader
generateArtefacts
generateTclEnvFile
}
// For now, provide a separate generator app when not specifically building for FireSim
object Generator extends freechips.rocketchip.util.GeneratorApp with HasTestSuites {
val longName = names.topModuleProject + "." + names.topModuleClass + "." + names.configs
generateFirrtl
generateAnno
generateTestSuiteMakefrags
generateArtefacts
}

View File

@@ -0,0 +1,54 @@
//See LICENSE for license details.
package firesim.firesim
import freechips.rocketchip.config.{Parameters, Config, Field}
import midas.{EndpointKey}
import midas.widgets.{EndpointMap}
import midas.models._
import firesim.endpoints._
import firesim.configs._
/*******************************************************************************
* Full PLATFORM_CONFIG Configurations. These set simulator parameters.
*
* In general, if you're adding or removing features from any of these, you
* should CREATE A NEW ONE, WITH A NEW NAME. This is because the manager
* will store this name as part of the tags for the AGFI, so that later you can
* reconstruct what is in a particular AGFI. These tags are also used to
* determine which driver to build.
*******************************************************************************/
class FireSimConfig extends Config(
new WithSerialWidget ++
new WithUARTWidget ++
new WithSimpleNICWidget ++
new WithBlockDevWidget ++
new WithDefaultMemModel ++
new WithTracerVWidget ++
new BasePlatformConfig)
class FireSimClockDivConfig extends Config(
new WithDefaultMemModel(clockDivision = 2) ++
new FireSimConfig)
class FireSimDDR3Config extends Config(
new FCFS16GBQuadRank ++
new FireSimConfig)
class FireSimDDR3LLC4MBConfig extends Config(
new FCFS16GBQuadRankLLC4MB ++
new FireSimConfig)
class FireSimDDR3FRFCFSConfig extends Config(
new FRFCFS16GBQuadRank ++
new FireSimConfig)
class FireSimDDR3FRFCFSLLC4MBConfig extends Config(
new FRFCFS16GBQuadRankLLC4MB ++
new FireSimConfig)
class FireSimDDR3FRFCFSLLC4MB3ClockDivConfig extends Config(
new FRFCFS16GBQuadRankLLC4MB3Div ++
new FireSimConfig)

View File

@@ -0,0 +1,205 @@
package firesim.firesim
import java.io.File
import chisel3.util.{log2Up}
import freechips.rocketchip.config.{Parameters, Config}
import freechips.rocketchip.tile._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.devices.tilelink.BootROMParams
import freechips.rocketchip.devices.debug.DebugModuleParams
import boom.system.BoomTilesKey
import testchipip.{WithBlockDevice, BlockDeviceKey, BlockDeviceConfig}
import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTParams}
import icenet._
class WithBootROM extends Config((site, here, up) => {
case BootROMParams => {
val chipyardBootROM = new File(s"./generators/testchipip/bootrom/bootrom.rv${site(XLen)}.img")
val firesimBootROM = new File(s"./target-rtl/chipyard/generators/testchipip/bootrom/bootrom.rv${site(XLen)}.img")
val bootROMPath = if (chipyardBootROM.exists()) {
chipyardBootROM.getAbsolutePath()
} else {
firesimBootROM.getAbsolutePath()
}
BootROMParams(contentFileName = bootROMPath)
}
})
class WithPeripheryBusFrequency(freq: BigInt) extends Config((site, here, up) => {
case PeripheryBusKey => up(PeripheryBusKey).copy(frequency=freq)
})
class WithUARTKey extends Config((site, here, up) => {
case PeripheryUARTKey => List(UARTParams(
address = BigInt(0x54000000L),
nTxEntries = 256,
nRxEntries = 256))
})
class WithNICKey extends Config((site, here, up) => {
case NICKey => NICConfig(
inBufFlits = 8192,
ctrlQueueDepth = 64)
})
class WithRocketL2TLBs(entries: Int) extends Config((site, here, up) => {
case RocketTilesKey => up(RocketTilesKey) map (tile => tile.copy(
core = tile.core.copy(
nL2TLBEntries = entries
)
))
})
class WithPerfCounters extends Config((site, here, up) => {
case RocketTilesKey => up(RocketTilesKey) map (tile => tile.copy(
core = tile.core.copy(nPerfCounters = 29)
))
})
class WithBoomL2TLBs(entries: Int) extends Config((site, here, up) => {
case BoomTilesKey => up(BoomTilesKey) map (tile => tile.copy(
core = tile.core.copy(nL2TLBEntries = entries)
))
})
// Disables clock-gating; doesn't play nice with our FAME-1 pass
class WithoutClockGating extends Config((site, here, up) => {
case DebugModuleParams => up(DebugModuleParams, site).copy(clockGate = false)
})
// Testing configurations
// This enables printfs used in testing
class WithScalaTestFeatures extends Config((site, here, up) => {
case PrintTracePort => true
})
/*******************************************************************************
* Full TARGET_CONFIG configurations. These set parameters of the target being
* simulated.
*
* In general, if you're adding or removing features from any of these, you
* should CREATE A NEW ONE, WITH A NEW NAME. This is because the manager
* will store this name as part of the tags for the AGFI, so that later you can
* reconstruct what is in a particular AGFI. These tags are also used to
* determine which driver to build.
*******************************************************************************/
class FireSimRocketChipConfig extends Config(
new WithBootROM ++
new WithPeripheryBusFrequency(BigInt(3200000000L)) ++
new WithExtMemSize(0x400000000L) ++ // 16GB
new WithoutTLMonitors ++
new WithUARTKey ++
new WithNICKey ++
new WithBlockDevice ++
new WithRocketL2TLBs(1024) ++
new WithPerfCounters ++
new WithoutClockGating ++
new freechips.rocketchip.system.DefaultConfig)
class WithNDuplicatedRocketCores(n: Int) extends Config((site, here, up) => {
case RocketTilesKey => List.tabulate(n)(i => up(RocketTilesKey).head.copy(hartId = i))
})
// single core config
class FireSimRocketChipSingleCoreConfig extends Config(new FireSimRocketChipConfig)
// dual core config
class FireSimRocketChipDualCoreConfig extends Config(
new WithNDuplicatedRocketCores(2) ++
new FireSimRocketChipSingleCoreConfig)
// quad core config
class FireSimRocketChipQuadCoreConfig extends Config(
new WithNDuplicatedRocketCores(4) ++
new FireSimRocketChipSingleCoreConfig)
// hexa core config
class FireSimRocketChipHexaCoreConfig extends Config(
new WithNDuplicatedRocketCores(6) ++
new FireSimRocketChipSingleCoreConfig)
// octa core config
class FireSimRocketChipOctaCoreConfig extends Config(
new WithNDuplicatedRocketCores(8) ++
new FireSimRocketChipSingleCoreConfig)
class FireSimBoomConfig extends Config(
new WithBootROM ++
new WithPeripheryBusFrequency(BigInt(3200000000L)) ++
new WithExtMemSize(0x400000000L) ++ // 16GB
new WithoutTLMonitors ++
new WithUARTKey ++
new WithNICKey ++
new WithBlockDevice ++
new WithBoomL2TLBs(1024) ++
new WithoutClockGating ++
// Using a small config because it has 64-bit system bus, and compiles quickly
new boom.system.SmallBoomConfig)
// A safer implementation than the one in BOOM in that it
// duplicates whatever BOOMTileKey.head is present N times. This prevents
// accidentally (and silently) blowing away configurations that may change the
// tile in the "up" view
class WithNDuplicatedBoomCores(n: Int) extends Config((site, here, up) => {
case BoomTilesKey => List.tabulate(n)(i => up(BoomTilesKey).head.copy(hartId = i))
case MaxHartIdBits => log2Up(site(BoomTilesKey).size)
})
class FireSimBoomDualCoreConfig extends Config(
new WithNDuplicatedBoomCores(2) ++
new FireSimBoomConfig)
class FireSimBoomQuadCoreConfig extends Config(
new WithNDuplicatedBoomCores(4) ++
new FireSimBoomConfig)
//**********************************************************************************
//* Supernode Configurations
//*********************************************************************************/
class WithNumNodes(n: Int) extends Config((pname, site, here) => {
case NumNodes => n
})
class SupernodeFireSimRocketChipConfig extends Config(
new WithNumNodes(4) ++
new WithExtMemSize(0x200000000L) ++ // 8GB
new FireSimRocketChipConfig)
class SupernodeFireSimRocketChipSingleCoreConfig extends Config(
new WithNumNodes(4) ++
new WithExtMemSize(0x200000000L) ++ // 8GB
new FireSimRocketChipSingleCoreConfig)
class SupernodeSixNodeFireSimRocketChipSingleCoreConfig extends Config(
new WithNumNodes(6) ++
new WithExtMemSize(0x40000000L) ++ // 1GB
new FireSimRocketChipSingleCoreConfig)
class SupernodeEightNodeFireSimRocketChipSingleCoreConfig extends Config(
new WithNumNodes(8) ++
new WithExtMemSize(0x40000000L) ++ // 1GB
new FireSimRocketChipSingleCoreConfig)
class SupernodeFireSimRocketChipDualCoreConfig extends Config(
new WithNumNodes(4) ++
new WithExtMemSize(0x200000000L) ++ // 8GB
new FireSimRocketChipDualCoreConfig)
class SupernodeFireSimRocketChipQuadCoreConfig extends Config(
new WithNumNodes(4) ++
new WithExtMemSize(0x200000000L) ++ // 8GB
new FireSimRocketChipQuadCoreConfig)
class SupernodeFireSimRocketChipHexaCoreConfig extends Config(
new WithNumNodes(4) ++
new WithExtMemSize(0x200000000L) ++ // 8GB
new FireSimRocketChipHexaCoreConfig)
class SupernodeFireSimRocketChipOctaCoreConfig extends Config(
new WithNumNodes(4) ++
new WithExtMemSize(0x200000000L) ++ // 8GB
new FireSimRocketChipOctaCoreConfig)

View File

@@ -0,0 +1,45 @@
//See LICENSE for license details.
package firesim.firesim
import scala.collection.mutable.LinkedHashSet
import freechips.rocketchip.system.{TestGeneration, RocketTestSuite}
/* This imports tests from FireChip to test devices that aren't natively
* tested by the riscv assembly tests.
* Firesim's target-specific makefrag gives the recipes for building the
* binaries.
*/
class BlockdevTestSuite(prefix: String, val names: LinkedHashSet[String]) extends RocketTestSuite {
val envName = ""
// fc_test_dir is is defined in firesim's Makefrag
val dir = "$(fc_test_dir)"
val makeTargetName = prefix + "-blkdev-tests"
def kind = "blockdev"
// Blockdev tests need an image, which complicates this
def additionalArgs = "+blkdev-in-mem0=128 +nic-loopback0"
override def toString = s"$makeTargetName = \\\n" +
// Make variable with the binaries of the suite
names.map(n => s"\t$n.riscv").mkString(" \\\n") + "\n\n" +
// Variables with binary specific arguments
names.map(n => s"$n.riscv_ARGS=$additionalArgs").mkString(" \n") +
postScript
}
object FastBlockdevTests extends BlockdevTestSuite("fast", LinkedHashSet("blkdev"))
object SlowBlockdevTests extends BlockdevTestSuite("slow", LinkedHashSet("big-blkdev"))
class NICTestSuite(prefix: String, val names: LinkedHashSet[String]) extends RocketTestSuite {
val envName = ""
val dir = "$(fc_test_dir)"
val makeTargetName = prefix + "-nic-tests"
def kind = "nic"
def additionalArgs = "+netbw0=100 +linklatency0=6405 +netburst0=8 +slotid=0 +nic-loopback0"
override def toString = s"$makeTargetName = \\\n" +
names.map(n => s"\t$n.riscv").mkString(" \\\n") + "\n\n" +
names.map(n => s"$n.riscv_ARGS=$additionalArgs").mkString(" \n") +
postScript
}
object NICLoopbackTests extends NICTestSuite("loopback", LinkedHashSet("nic-loopback"))

View File

@@ -0,0 +1,106 @@
package firesim.firesim
import chisel3._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.amba.axi4._
import freechips.rocketchip.util._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.rocket.TracedInstruction
import firesim.endpoints.{TraceOutputTop, DeclockedTracedInstruction}
import midas.models.AXI4BundleWithEdge
import midas.targetutils.ExcludeInstanceAsserts
/** Copied from RC and modified to change the IO type of the Imp to include the Diplomatic edges
* associated with each port. This drives FASED functional model sizing
*/
trait CanHaveFASEDOptimizedMasterAXI4MemPort { this: BaseSubsystem =>
val module: CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp
val memAXI4Node = p(ExtMem).map { case MemoryPortParams(memPortParams, nMemoryChannels) =>
val portName = "axi4"
val device = new MemoryDevice
val memAXI4Node = AXI4SlaveNode(Seq.tabulate(nMemoryChannels) { channel =>
val base = AddressSet.misaligned(memPortParams.base, memPortParams.size)
val filter = AddressSet(channel * mbus.blockBytes, ~((nMemoryChannels-1) * mbus.blockBytes))
AXI4SlavePortParameters(
slaves = Seq(AXI4SlaveParameters(
address = base.flatMap(_.intersect(filter)),
resources = device.reg,
regionType = RegionType.UNCACHED, // cacheable
executable = true,
supportsWrite = TransferSizes(1, mbus.blockBytes),
supportsRead = TransferSizes(1, mbus.blockBytes),
interleavedId = Some(0))), // slave does not interleave read responses
beatBytes = memPortParams.beatBytes)
})
memAXI4Node := mbus.toDRAMController(Some(portName)) {
AXI4UserYanker() := AXI4IdIndexer(memPortParams.idBits) := TLToAXI4()
}
memAXI4Node
}
}
/** Actually generates the corresponding IO in the concrete Module */
trait CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp extends LazyModuleImp {
val outer: CanHaveFASEDOptimizedMasterAXI4MemPort
val mem_axi4 = outer.memAXI4Node.map(x => IO(HeterogeneousBag(AXI4BundleWithEdge.fromNode(x.in))))
(mem_axi4 zip outer.memAXI4Node) foreach { case (io, node) =>
(io zip node.in).foreach { case (io, (bundle, _)) => io <> bundle }
}
def connectSimAXIMem() {
(mem_axi4 zip outer.memAXI4Node).foreach { case (io, node) =>
(io zip node.in).foreach { case (io, (_, edge)) =>
val mem = LazyModule(new SimAXIMem(edge, size = p(ExtMem).get.master.size))
Module(mem.module).io.axi4.head <> io
}
}
}
}
/* Wires out tile trace ports to the top; and wraps them in a Bundle that the
* TracerV endpoint can match on.
*/
object PrintTracePort extends Field[Boolean](false)
trait HasTraceIO {
this: HasTiles =>
val module: HasTraceIOImp
// Bind all the trace nodes to a BB; we'll use this to generate the IO in the imp
val traceNexus = BundleBridgeNexus[Vec[TracedInstruction]]
val tileTraceNodes = tiles.map(tile => tile.traceNode)
tileTraceNodes foreach { traceNexus := _ }
}
trait HasTraceIOImp extends LazyModuleImp {
val outer: HasTraceIO
val traceIO = IO(Output(new TraceOutputTop(
DeclockedTracedInstruction.fromNode(outer.traceNexus.in))))
(traceIO.traces zip outer.traceNexus.in).foreach({ case (port, (tileTrace, _)) =>
port := DeclockedTracedInstruction.fromVec(tileTrace)
})
// Enabled to test TracerV trace capture
if (p(PrintTracePort)) {
val traceprint = Wire(UInt(512.W))
traceprint := traceIO.asUInt
printf("TRACEPORT: %x\n", traceprint)
}
}
// Prevent MIDAS from synthesizing assertions in the dummy TLB included in BOOM
trait ExcludeInvalidBoomAssertions extends LazyModuleImp {
ExcludeInstanceAsserts(("NonBlockingDCache", "dtlb"))
}

View File

@@ -0,0 +1,176 @@
package firesim.firesim
import chisel3._
import freechips.rocketchip._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.util.{HeterogeneousBag}
import freechips.rocketchip.amba.axi4.AXI4Bundle
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.diplomacy.LazyModule
import boom.system.{BoomRocketSubsystem, BoomRocketSubsystemModuleImp}
import icenet._
import testchipip._
import testchipip.SerialAdapter.SERIAL_IF_WIDTH
import sifive.blocks.devices.uart._
import midas.models.AXI4BundleWithEdge
import java.io.File
/*******************************************************************************
* Top level DESIGN configurations. These describe the basic instantiations of
* the designs being simulated.
*
* In general, if you're adding or removing features from any of these, you
* should CREATE A NEW ONE, WITH A NEW NAME. This is because the manager
* will store this name as part of the tags for the AGFI, so that later you can
* reconstruct what is in a particular AGFI. These tags are also used to
* determine which driver to build.
*******************************************************************************/
class FireSim(implicit p: Parameters) extends RocketSubsystem
with HasHierarchicalBusTopology
with CanHaveFASEDOptimizedMasterAXI4MemPort
with HasPeripheryBootROM
with HasNoDebug
with HasPeripherySerial
with HasPeripheryUART
with HasPeripheryIceNIC
with HasPeripheryBlockDevice
with HasTraceIO
{
override lazy val module = new FireSimModuleImp(this)
}
class FireSimModuleImp[+L <: FireSim](l: L) extends RocketSubsystemModuleImp(l)
with HasRTCModuleImp
with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp
with HasPeripheryBootROMModuleImp
with HasNoDebugModuleImp
with HasPeripherySerialModuleImp
with HasPeripheryUARTModuleImp
with HasPeripheryIceNICModuleImpValidOnly
with HasPeripheryBlockDeviceModuleImp
with HasTraceIOImp
class FireSimNoNIC(implicit p: Parameters) extends RocketSubsystem
with HasHierarchicalBusTopology
with CanHaveFASEDOptimizedMasterAXI4MemPort
with HasPeripheryBootROM
with HasNoDebug
with HasPeripherySerial
with HasPeripheryUART
with HasPeripheryBlockDevice
with HasTraceIO
{
override lazy val module = new FireSimNoNICModuleImp(this)
}
class FireSimNoNICModuleImp[+L <: FireSimNoNIC](l: L) extends RocketSubsystemModuleImp(l)
with HasRTCModuleImp
with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp
with HasPeripheryBootROMModuleImp
with HasNoDebugModuleImp
with HasPeripherySerialModuleImp
with HasPeripheryUARTModuleImp
with HasPeripheryBlockDeviceModuleImp
with HasTraceIOImp
class FireBoom(implicit p: Parameters) extends BoomRocketSubsystem
with HasHierarchicalBusTopology
with CanHaveFASEDOptimizedMasterAXI4MemPort
with HasPeripheryBootROM
with HasNoDebug
with HasPeripherySerial
with HasPeripheryUART
with HasPeripheryIceNIC
with HasPeripheryBlockDevice
with HasTraceIO
{
override lazy val module = new FireBoomModuleImp(this)
}
class FireBoomModuleImp[+L <: FireBoom](l: L) extends BoomRocketSubsystemModuleImp(l)
with HasRTCModuleImp
with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp
with HasPeripheryBootROMModuleImp
with HasNoDebugModuleImp
with HasPeripherySerialModuleImp
with HasPeripheryUARTModuleImp
with HasPeripheryIceNICModuleImpValidOnly
with HasPeripheryBlockDeviceModuleImp
with HasTraceIOImp
with ExcludeInvalidBoomAssertions
class FireBoomNoNIC(implicit p: Parameters) extends BoomRocketSubsystem
with HasHierarchicalBusTopology
with CanHaveFASEDOptimizedMasterAXI4MemPort
with HasPeripheryBootROM
with HasNoDebug
with HasPeripherySerial
with HasPeripheryUART
with HasPeripheryBlockDevice
with HasTraceIO
{
override lazy val module = new FireBoomNoNICModuleImp(this)
}
class FireBoomNoNICModuleImp[+L <: FireBoomNoNIC](l: L) extends BoomRocketSubsystemModuleImp(l)
with HasRTCModuleImp
with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp
with HasPeripheryBootROMModuleImp
with HasNoDebugModuleImp
with HasPeripherySerialModuleImp
with HasPeripheryUARTModuleImp
with HasPeripheryBlockDeviceModuleImp
with HasTraceIOImp
with ExcludeInvalidBoomAssertions
case object NumNodes extends Field[Int]
class SupernodeIO(
nNodes: Int,
serialWidth: Int,
bagPrototype: HeterogeneousBag[AXI4BundleWithEdge])(implicit p: Parameters)
extends Bundle {
val serial = Vec(nNodes, new SerialIO(serialWidth))
val mem_axi = Vec(nNodes, bagPrototype.cloneType)
val bdev = Vec(nNodes, new BlockDeviceIO)
val net = Vec(nNodes, new NICIOvonly)
val uart = Vec(nNodes, new UARTPortIO)
override def cloneType = new SupernodeIO(nNodes, serialWidth, bagPrototype).asInstanceOf[this.type]
}
class FireSimSupernode(implicit p: Parameters) extends Module {
val nNodes = p(NumNodes)
val nodes = Seq.fill(nNodes) {
Module(LazyModule(new FireSim).module)
}
val io = IO(new SupernodeIO(nNodes, SERIAL_IF_WIDTH, nodes(0).mem_axi4.get))
io.mem_axi.zip(nodes.map(_.mem_axi4)).foreach {
case (out, mem_axi4) => out <> mem_axi4.get
}
io.serial <> nodes.map(_.serial)
io.bdev <> nodes.map(_.bdev)
io.net <> nodes.map(_.net)
io.uart <> nodes.map(_.uart(0))
nodes.foreach{ case n => {
n.debug.clockeddmi.get.dmi.req.valid := false.B
n.debug.clockeddmi.get.dmi.resp.ready := false.B
n.debug.clockeddmi.get.dmiClock := clock
n.debug.clockeddmi.get.dmiReset := reset.toBool
n.debug.clockeddmi.get.dmi.req.bits.data := DontCare
n.debug.clockeddmi.get.dmi.req.bits.addr := DontCare
n.debug.clockeddmi.get.dmi.req.bits.op := DontCare
} }
}

View File

@@ -0,0 +1,138 @@
//See LICENSE for license details.
package firesim.firesim
import java.io.File
import scala.concurrent.{Future, Await, ExecutionContext}
import scala.sys.process.{stringSeqToProcess, ProcessLogger}
import scala.io.Source
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.system.{RocketTestSuite, BenchmarkTestSuite}
import freechips.rocketchip.system.TestGeneration._
import freechips.rocketchip.system.DefaultTestSuites._
import firesim.util.GeneratorArgs
abstract class FireSimTestSuite(
topModuleClass: String,
targetConfigs: String,
platformConfigs: String,
N: Int = 8
) extends firesim.TestSuiteCommon with IsFireSimGeneratorLike {
import scala.concurrent.duration._
import ExecutionContext.Implicits.global
lazy val generatorArgs = GeneratorArgs(
midasFlowKind = "midas",
targetDir = "generated-src",
topModuleProject = "firesim.firesim",
topModuleClass = topModuleClass,
targetConfigProject = "firesim.firesim",
targetConfigs = targetConfigs ++ "_WithScalaTestFeatures",
platformConfigProject = "firesim.firesim",
platformConfigs = platformConfigs)
// From HasFireSimGeneratorUtilities
// For the firesim utilities to use the same directory as the test suite
override lazy val testDir = genDir
// From TestSuiteCommon
val targetTuple = generatorArgs.tupleName
val commonMakeArgs = Seq(s"DESIGN=${generatorArgs.topModuleClass}",
s"TARGET_CONFIG=${generatorArgs.targetConfigs}",
s"PLATFORM_CONFIG=${generatorArgs.platformConfigs}")
override lazy val platform = hostParams(midas.Platform)
def invokeMlSimulator(backend: String, name: String, debug: Boolean, additionalArgs: Seq[String] = Nil) = {
make((Seq(s"${outDir.getAbsolutePath}/${name}.%s".format(if (debug) "vpd" else "out"),
s"EMUL=${backend}")
++ additionalArgs):_*)
}
def runTest(backend: String, name: String, debug: Boolean, additionalArgs: Seq[String] = Nil) = {
behavior of s"${name} running on ${backend} in MIDAS-level simulation"
compileMlSimulator(backend, debug)
if (isCmdAvailable(backend)) {
it should s"pass" in {
assert(invokeMlSimulator(backend, name, debug, additionalArgs) == 0)
}
}
}
//def runReplay(backend: String, replayBackend: String, name: String) = {
// val dir = (new File(outDir, backend)).getAbsolutePath
// (Seq("make", s"replay-$replayBackend",
// s"SAMPLE=${dir}/${name}.sample", s"output_dir=$dir") ++ makeArgs).!
//}
def runSuite(backend: String, debug: Boolean = false)(suite: RocketTestSuite) {
// compile emulators
behavior of s"${suite.makeTargetName} running on $backend"
if (isCmdAvailable(backend)) {
val postfix = suite match {
case _: BenchmarkTestSuite | _: BlockdevTestSuite | _: NICTestSuite => ".riscv"
case _ => ""
}
val results = suite.names.toSeq sliding (N, N) map { t =>
val subresults = t map (name =>
Future(name -> invokeMlSimulator(backend, s"$name$postfix", debug)))
Await result (Future sequence subresults, Duration.Inf)
}
results.flatten foreach { case (name, exitcode) =>
it should s"pass $name" in { assert(exitcode == 0) }
}
//replayBackends foreach { replayBackend =>
// if (platformParams(midas.EnableSnapshot) && isCmdAvailable("vcs")) {
// assert((Seq("make", s"vcs-$replayBackend") ++ makeArgs).! == 0) // compile vcs
// suite.names foreach { name =>
// it should s"replay $name in $replayBackend" in {
// assert(runReplay(backend, replayBackend, s"$name$postfix") == 0)
// }
// }
// } else {
// suite.names foreach { name =>
// ignore should s"replay $name in $backend"
// }
// }
//}
} else {
ignore should s"pass $backend"
}
}
// Checks the collected trace log matches the behavior of a chisel printf
def diffTracelog(verilatedLog: String) {
behavior of "captured instruction trace"
it should s"match the chisel printf in ${verilatedLog}" in {
def getLines(file: File, dropLines: Int = 0): Seq[String] = {
val lines = Source.fromFile(file).getLines.toList
lines.filter(_.startsWith("TRACEPORT")).drop(dropLines)
}
val resetLength = 50
val verilatedOutput = getLines(new File(outDir, s"/${verilatedLog}"))
val synthPrintOutput = getLines(new File(genDir, s"/TRACEFILE"), resetLength + 1)
assert(verilatedOutput.size == synthPrintOutput.size, "Outputs differ in length")
assert(verilatedOutput.nonEmpty)
for ( (vPrint, sPrint) <- verilatedOutput.zip(synthPrintOutput) ) {
assert(vPrint == sPrint)
}
}
}
clean
mkdirs
elaborateAndCompileWithMidas
generateTestSuiteMakefrags
runTest("verilator", "rv64ui-p-simple", false, Seq(s"""EXTRA_SIM_ARGS=+trace-test-output0"""))
diffTracelog("rv64ui-p-simple.out")
runSuite("verilator")(benchmarks)
runSuite("verilator")(FastBlockdevTests)
}
class RocketF1Tests extends FireSimTestSuite("FireSimNoNIC", "FireSimRocketChipConfig", "FireSimConfig")
class RocketF1ClockDivTests extends FireSimTestSuite("FireSimNoNIC", "FireSimRocketChipConfig", "FireSimClockDivConfig")
class BoomF1Tests extends FireSimTestSuite("FireBoomNoNIC", "FireSimBoomConfig", "FireSimConfig")
class RocketNICF1Tests extends FireSimTestSuite("FireSim", "FireSimRocketChipConfig", "FireSimConfig") {
runSuite("verilator")(NICLoopbackTests)
}

1
generators/icenet Submodule

Submodule generators/icenet added at bba264d68d

View File

@@ -0,0 +1,17 @@
#!/usr/bin/env bash
# This ungodly script surreptitiously builds an archive from existing fesvr objects
# Invoke from riscv-fesvr/build
if [ "x$RISCV" = "x" ]
then
echo "Please set the RISCV environment variable to your preferred install path."
exit 1
fi
set -e
objs=$(head -n 1 <(make -f <( echo -e 'include Makefile\n$(info $(value fesvr_objs))') -n))
ar rcs -o libfesvr.a $objs
cp -f libfesvr.a $RISCV/lib

View File

@@ -1,38 +1,160 @@
#!/usr/bin/env bash
#this script is based on the firesim build toolchains script
# exit script if any command fails
set -e
set -o pipefail
unamestr=$(uname)
RDIR=$(pwd)
: ${REBAR_DIR:=$(pwd)} #default value is the PWD unless overridden
: ${CHIPYARD_DIR:=$(pwd)} #default value is the PWD unless overridden
if [ $# -ne 0 ]; then
TOOLCHAIN=$1
if [ $1 == "riscv" ]; then
TOOLCHAIN="riscv-tools"
elif [ $1 == "hwacha" ]; then
TOOLCHAIN="esp-tools"
fi
else
TOOLCHAIN="riscv-tools"
PRECOMPILED_REPO_HASH=56a40961c98db5e8f904f15dc6efd0870bfefd9e
function usage
{
echo "usage: ./scripts/build-toolchains.sh [riscv-tools] [esp-tools] [ec2fast | --ec2fast] "
echo " riscv: if set, builds the riscv toolchain (this is also the default)"
echo " hwacha: if set, builds esp-tools toolchain"
echo " ec2fast: if set, pulls in a pre-compiled RISC-V toolchain for an EC2 manager instance"
}
#taken from riscv-tools to check for open-ocd autoconf versions
check_version() {
$1 --version | awk "NR==1 {if (\$NF>$2) {exit 0} exit 1}" || (
echo $3 requires at least version $2 of $1. Aborting.
exit 1
)
}
if [ "$1" == "--help" -o "$1" == "-h" -o "$1" == "-H" ]; then
usage
exit 3
fi
TOOLCHAIN="riscv-tools"
EC2FASTINSTALL="false"
FASTINSTALL="false"
while test $# -gt 0
do
case "$1" in
riscv-tools)
TOOLCHAIN="riscv-tools"
;;
esp-tools)
TOOLCHAIN="esp-tools"
;;
ec2fast | --ec2fast) # I don't want to break this api
EC2FASTINSTALL=true
;;
-h | -H | --help)
usage
exit 3
;;
--*) echo "ERROR: bad option $1"
usage
exit 1
;;
*) echo "ERROR: bad argument $1"
usage
exit 2
;;
esac
shift
done
if [ "$EC2FASTINSTALL" = "true" ]; then
if [ "$TOOLCHAIN" = "riscv-tools" ]; then
cd $RDIR
git clone https://github.com/firesim/firesim-riscv-tools-prebuilt.git
cd firesim-riscv-tools-prebuilt
git checkout $PRECOMPILED_REPO_HASH
PREBUILTHASH="$(cat HASH)"
git -C $CHIPYARD_DIR submodule update --init toolchains/$TOOLCHAIN
cd "$CHIPYARD_DIR/toolchains/$TOOLCHAIN"
GITHASH="$(git rev-parse HEAD)"
cd $RDIR
echo "prebuilt hash: $PREBUILTHASH"
echo "git hash: $GITHASH"
if [[ $PREBUILTHASH == $GITHASH && "$EC2FASTINSTALL" == "true" ]]; then
FASTINSTALL=true
echo "Using fast pre-compiled install for riscv-tools"
else
echo "Error: hash of precompiled toolchain doesn't match the riscv-tools submodule hash."
exit
fi
else
echo "Error: No precompiled toolchain for esp-tools or other non-native riscv-tools."
exit
fi
fi
INSTALL_DIR="$TOOLCHAIN-install"
mkdir -p "$(pwd)/$INSTALL_DIR"
RISCV="$(pwd)/$INSTALL_DIR"
# install risc-v tools
export RISCV="$RISCV"
git -C $REBAR_DIR submodule update --init --recursive toolchains/$TOOLCHAIN #--jobs 8
cd "$REBAR_DIR/toolchains/$TOOLCHAIN"
export MAKEFLAGS="-j16"
./build.sh
if [ "$FASTINSTALL" = true ]; then
cd firesim-riscv-tools-prebuilt
./installrelease.sh
mv distrib "$RISCV"
# copy HASH in case user wants it later
cp HASH "$RISCV"
cd $RDIR
rm -rf firesim-riscv-tools-prebuilt
else
mkdir -p "$RISCV"
git -C $CHIPYARD_DIR submodule update --init --recursive toolchains/$TOOLCHAIN #--jobs 8
cd "$CHIPYARD_DIR/toolchains/$TOOLCHAIN"
export MAKEFLAGS="-j16"
#build the actual toolchain
#./build.sh
source build.common
echo "Starting RISC-V Toolchain build process"
build_project riscv-fesvr --prefix=$RISCV
build_project riscv-isa-sim --prefix=$RISCV --with-fesvr=$RISCV
build_project riscv-gnu-toolchain --prefix=$RISCV
CC= CXX= build_project riscv-pk --prefix=$RISCV --host=riscv64-unknown-elf
build_project riscv-tests --prefix=$RISCV/riscv64-unknown-elf
echo -e "\\nRISC-V Toolchain installation completed!"
# build static libfesvr library for linking into firesim driver (or others)
cd riscv-fesvr/build
$CHIPYARD_DIR/scripts/build-static-libfesvr.sh
cd $RDIR
# build linux toolchain
cd "$CHIPYARD_DIR/toolchains/$TOOLCHAIN/riscv-gnu-toolchain/build"
make -j16 linux
echo -e "\\nRISC-V Linux GNU Toolchain installation completed!"
fi
cd $RDIR
echo "export RISCV=$RISCV" > env.sh
echo "export CHIPYARD_TOOLCHAIN_SOURCED=1" > env.sh
echo "export RISCV=$RISCV" >> env.sh
echo "export PATH=$RISCV/bin:$RDIR/$DTCversion:\$PATH" >> env.sh
echo "export LD_LIBRARY_PATH=$RISCV/lib" >> env.sh
echo "export LD_LIBRARY_PATH=$RISCV/lib\${LD_LIBRARY_PATH:+":${LD_LIBRARY_PATH}"}" >> env.sh
echo "Toolchain Build Complete!"
if [ "$FASTINSTALL" = "false" ]; then
# commands that can't run on EC2 (specifically, OpenOCD because of autoconf version_
# see if the instance info page exists. if not, we are not on ec2.
# this is one of the few methods that works without sudo
if wget -T 1 -t 3 -O /dev/null http://169.254.169.254/; then
echo "Skipping RISC-V OpenOCD"
else
echo "Building RISC-V OpenOCD"
cd "$CHIPYARD_DIR/toolchains/$TOOLCHAIN"
check_version automake 1.14 "OpenOCD build"
check_version autoconf 2.64 "OpenOCD build"
build_project riscv-openocd --prefix=$RISCV --enable-remote-bitbang --enable-jtag_vpi --disable-werror
echo -e "\\nRISC-V OpenOCD installation completed!"
cd $RDIR
fi
fi

18
scripts/firesim-setup.sh Executable file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env bash
# Sets up FireSim for use as a library within REBAR
set -e
set -o pipefail
RDIR=$(pwd)
scripts_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
cd $scripts_dir/..
# Reenable the FireSim submodule
git config --unset submodule.sims/firesim.update || true
git submodule update --init sims/firesim
cd sims/firesim
./build-setup.sh $@ --library
cd $RDIR

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env bash
# run this script in the main rebar directory to generate ctags for all relevant repos
# run this script in the main Chipyard directory to generate ctags for all relevant repos
# note: this requires exuberant-ctags
# tested with: Exuberant Ctags 5.8
# instructions:
# cd /path/to/rebar/
# cd /path/to/chipyard/
# ./scripts/gen-tags.sh
#
# input:

View File

@@ -6,14 +6,31 @@ set -o pipefail
unamestr=$(uname)
RDIR=$(pwd)
scripts_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
# ignore riscv-tools for submodule init recursive
# you must do this globally (otherwise riscv-tools deep
# in the submodule tree will get pulled anyway
git config --global submodule.riscv-tools.update none
git config --global submodule.esp-tools.update none
git config submodule.toolchains/riscv-tools.update none
git config submodule.toolchains/esp-tools.update none
git config --global submodule.experimental-blocks.update none
# Disable updates to the FireSim submodule until explicitly requested
git config submodule.sims/firesim.update none
# Disable updates to the hammer-cad-plugins repo
git config submodule.vlsi/hammer-cad-plugins.update none
git submodule update --init --recursive #--jobs 8
# unignore riscv-tools,catapult-shell2 globally
git config --global --unset submodule.riscv-tools.update
git config --unset submodule.toolchains/riscv-tools.update
git config --unset submodule.toolchains/esp-tools.update
git config --global --unset submodule.experimental-blocks.update
git config --unset submodule.vlsi/hammer-cad-plugins.update
# Renable firesim and init only the required submodules to provide
# all required scala deps, without doing a full build-setup
git config --unset submodule.sims/firesim.update
cd $scripts_dir/../sims/
git submodule update --init firesim
cd firesim/sim
git submodule update --init midas
cd $RDIR
git config submodule.sims/firesim.update none

13
scripts/init-vlsi.sh Executable file
View File

@@ -0,0 +1,13 @@
#!/usr/bin/env bash
# exit script if any command fails
set -e
set -o pipefail
# Initialize HAMMER and CAD-plugins
git submodule update --init --recursive vlsi/hammer
git submodule update --init --recursive vlsi/hammer-cad-plugins
# Initialize HAMMER tech plugin
git submodule update --init --recursive vlsi/hammer-$1-plugin

View File

@@ -1,31 +0,0 @@
#!/bin/bash
# NOTE: TEMPORARY UNTIL CI IS ONLINE
# Run by just giving the test to run (run-bmark-tests | run-asm-tests)
# Runs in vsim and verisim
set -ex
set -euo pipefail
cd sims/vsim/
make SUB_PROJECT=rocketchip CONFIG=DefaultConfig
make SUB_PROJECT=rocketchip CONFIG=DefaultConfig $1
make SUB_PROJECT=boom CONFIG=BoomConfig
make SUB_PROJECT=boom CONFIG=BoomConfig $1
make SUB_PROJECT=example CONFIG=DefaultRocketConfig
make SUB_PROJECT=example CONFIG=DefaultRocketConfig $1
make SUB_PROJECT=boomexample CONFIG=DefaultBoomConfig
make SUB_PROJECT=boomexample CONFIG=DefaultBoomConfig $1
cd ../verisim/
make SUB_PROJECT=rocketchip CONFIG=DefaultConfig
make SUB_PROJECT=rocketchip CONFIG=DefaultConfig $1
make SUB_PROJECT=boom CONFIG=BoomConfig
make SUB_PROJECT=boom CONFIG=BoomConfig $1
make SUB_PROJECT=example CONFIG=DefaultRocketConfig
make SUB_PROJECT=example CONFIG=DefaultRocketConfig $1
make SUB_PROJECT=boomexample CONFIG=DefaultBoomConfig
make SUB_PROJECT=boomexample CONFIG=DefaultBoomConfig $1

1
sims/firesim Submodule

Submodule sims/firesim added at 4cd75833df

View File

@@ -28,6 +28,8 @@ sim_debug = $(sim_dir)/$(sim_prefix)-$(MODEL_PACKAGE)-$(CONFIG)-debug
PERMISSIVE_ON=+permissive
PERMISSIVE_OFF=+permissive-off
WAVEFORM_FLAG=+vcdplusfile=$(sim_out_name).vpd
.PHONY: default debug
default: $(sim)
debug: $(sim_debug)
@@ -54,13 +56,12 @@ VCS_NONCC_OPTS = \
-error=PCWM-L \
-timescale=1ns/10ps \
-quiet \
-q \
+rad \
+v2k \
+vcs+lic+wait \
+vc+list \
-f $(sim_top_blackboxes) \
-f $(sim_harness_blackboxes) \
-f $(sim_dotf) \
-f $(sim_common_files) \
-sverilog \
+incdir+$(build_dir) \
+define+CLOCK_PERIOD=1.0 \
@@ -78,29 +79,23 @@ VCS_OPTS = -notice -line $(VCS_CC_OPTS) $(VCS_NONCC_OPTS)
#########################################################################################
# vcs simulator rules
#########################################################################################
$(sim): $(sim_vsrcs) $(sim_dotf)
$(sim): $(sim_vsrcs) $(sim_common_files)
rm -rf csrc && $(VCS) $(VCS_OPTS) -o $@ \
-debug_pp
$(sim_debug) : $(sim_vsrcs) $(sim_dotf)
$(sim_debug) : $(sim_vsrcs) $(sim_common_files)
rm -rf csrc && $(VCS) $(VCS_OPTS) -o $@ \
+define+DEBUG -debug_pp
#########################################################################################
# helper rules to run simulator with debug
#########################################################################################
run-binary-debug: $(sim_debug)
$(sim_debug) $(PERMISSIVE_ON) $(SIM_FLAGS) +vcdplusfile=$(sim_out_name).vpd $(PERMISSIVE_OFF) $(BINARY) 3>&1 1>&2 2>&3 | spike-dasm > $(sim_out_name).out
#########################################################################################
# create a vcs vpd rule
#########################################################################################
$(output_dir)/%.vpd: $(output_dir)/% $(sim_debug)
$(sim_debug) $(PERMISSIVE_ON) +vcdplusfile=$@ +max-cycles=$(timeout_cycles) $(PERMISSIVE_OFF) $<
$(sim_debug) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(VERBOSE_FLAGS) +vcdplusfile=$@ $(PERMISSIVE_OFF) $<
#########################################################################################
# general cleanup rule
#########################################################################################
.PHONY: clean
clean:
rm -rf $(gen_dir)/* csrc $(sim_prefix)-* ucli.key vc_hdrs.h
rm -rf $(gen_dir) csrc $(sim_prefix)-* ucli.key vc_hdrs.h

View File

@@ -28,6 +28,8 @@ sim_debug = $(sim_dir)/$(sim_prefix)-$(MODEL_PACKAGE)-$(CONFIG)-debug
PERMISSIVE_ON=
PERMISSIVE_OFF=
WAVEFORM_FLAG=-v$(sim_out_name).vcd
.PHONY: default debug
default: $(sim)
debug: $(sim_debug)
@@ -38,6 +40,31 @@ debug: $(sim_debug)
include $(base_dir)/common.mk
include $(sim_dir)/verilator.mk
#########################################################################################
# verilator binary and flags
#########################################################################################
VERILATOR := $(INSTALLED_VERILATOR) --cc --exe
CXXFLAGS := $(CXXFLAGS) -O1 -std=c++11 -I$(RISCV)/include -D__STDC_FORMAT_MACROS
LDFLAGS := $(LDFLAGS) -L$(RISCV)/lib -Wl,-rpath,$(RISCV)/lib -L$(sim_dir) -lfesvr -lpthread
VERILATOR_CC_OPTS = \
-O3 \
-CFLAGS "$(CXXFLAGS) -DTEST_HARNESS=V$(VLOG_MODEL) -DVERILATOR" \
-CFLAGS "-I$(build_dir) -include $(build_dir)/$(long_name).plusArgs" \
-LDFLAGS "$(LDFLAGS)"
VERILATOR_NONCC_OPTS = \
--top-module $(VLOG_MODEL) \
+define+PRINTF_COND=\$$c\(\"verbose\",\"\&\&\"\,\"done_reset\"\) \
+define+STOP_COND=\$$c\(\"done_reset\"\) \
--assert \
--output-split 20000 \
$(sim_vsrcs) \
-f $(sim_common_files)
VERILATOR_OPTS = $(VERILATOR_CC_OPTS) $(VERILATOR_NONCC_OPTS)
#########################################################################################
# verilator build paths and file names
#########################################################################################
@@ -53,50 +80,39 @@ model_mk_debug = $(model_dir_debug)/V$(VLOG_MODEL).mk
#########################################################################################
# build makefile fragment that builds the verilator sim rules
#########################################################################################
LDFLAGS := $(LDFLAGS) -L$(RISCV)/lib -Wl,-rpath,$(RISCV)/lib -L$(sim_dir) -lfesvr -lpthread
$(model_mk): $(sim_vsrcs) $(sim_dotf) $(INSTALLED_VERILATOR)
$(model_mk): $(sim_vsrcs) $(sim_common_files) $(INSTALLED_VERILATOR)
rm -rf $(build_dir)/$(long_name)
mkdir -p $(build_dir)/$(long_name)
$(VERILATOR) $(VERILATOR_FLAGS) -Mdir $(build_dir)/$(long_name) \
-o $(sim) $(sim_vsrcs) -f $(sim_dotf) -f $(sim_top_blackboxes) -f $(sim_harness_blackboxes) -LDFLAGS "$(LDFLAGS)" \
-CFLAGS "-I$(build_dir) -include $(build_dir)/$(long_name).plusArgs -include $(model_header)"
$(VERILATOR) $(VERILATOR_OPTS) -o $(sim) -Mdir $(model_dir) -CFLAGS "-include $(model_header)"
touch $@
$(model_mk_debug): $(sim_vsrcs) $(sim_dotf) $(INSTALLED_VERILATOR)
$(model_mk_debug): $(sim_vsrcs) $(sim_common_files) $(INSTALLED_VERILATOR)
rm -rf $(build_dir)/$(long_name)
mkdir -p $(build_dir)/$(long_name).debug
$(VERILATOR) $(VERILATOR_FLAGS) -Mdir $(build_dir)/$(long_name).debug --trace \
-o $(sim_debug) $(sim_vsrcs) -f $(sim_dotf) -f $(sim_top_blackboxes) -f $(sim_harness_blackboxes) -LDFLAGS "$(LDFLAGS)" \
-CFLAGS "-I$(build_dir) -include $(build_dir)/$(long_name).plusArgs -include $(model_header_debug)"
$(VERILATOR) $(VERILATOR_OPTS) -o $(sim_debug) --trace -Mdir $(model_dir_debug) -CFLAGS "-include $(model_header_debug)"
touch $@
#########################################################################################
# invoke make to make verilator sim rules
#########################################################################################
$(sim): $(model_mk)
$(MAKE) VM_PARALLEL_BUILDS=1 -C $(build_dir)/$(long_name) -f V$(VLOG_MODEL).mk
$(MAKE) VM_PARALLEL_BUILDS=1 -C $(model_dir) -f V$(VLOG_MODEL).mk
$(sim_debug): $(model_mk_debug)
$(MAKE) VM_PARALLEL_BUILDS=1 -C $(build_dir)/$(long_name).debug -f V$(VLOG_MODEL).mk
$(MAKE) VM_PARALLEL_BUILDS=1 -C $(model_dir_debug) -f V$(VLOG_MODEL).mk
#########################################################################################
# helper rules to run simulator with debug
#########################################################################################
run-binary-debug: $(sim_debug)
$(sim_debug) $(SIM_FLAGS) -v$(sim_out_name).vcd $(BINARY) 3>&1 1>&2 2>&3 | spike-dasm > $(sim_out_name).out
#########################################################################################
# create a verisim vpd rule
# create a verilator vpd rule
#########################################################################################
$(output_dir)/%.vpd: $(output_dir)/% $(sim_debug)
rm -f $@.vcd && mkfifo $@.vcd
vcd2vpd $@.vcd $@ > /dev/null &
$(sim_debug) -v$@.vcd +max-cycles=$(timeout_cycles) $<
$(sim_debug) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(VERBOSE_FLAGS) -v$@.vcd $(PERMISSIVE_OFF) $<
#########################################################################################
# general cleanup rule
#########################################################################################
.PHONY: clean
clean:
rm -rf $(gen_dir)/* $(sim_prefix)-*
rm -rf $(gen_dir) $(sim_prefix)-*

View File

@@ -5,9 +5,10 @@
#########################################################################################
# verilator version, binary, and path
#########################################################################################
VERILATOR_VERSION=4.008
VERILATOR_SRCDIR=verilator/src/verilator-$(VERILATOR_VERSION)
INSTALLED_VERILATOR=$(abspath verilator/install/bin/verilator)
VERILATOR_VERSION = 4.016
VERILATOR_INSTALL_DIR ?= verilator_install
VERILATOR_SRCDIR = $(VERILATOR_INSTALL_DIR)/src/verilator-$(VERILATOR_VERSION)
INSTALLED_VERILATOR = $(abspath $(VERILATOR_INSTALL_DIR)/install/bin/verilator)
#########################################################################################
# build and install our own verilator to work around versioning issues
@@ -15,7 +16,7 @@ INSTALLED_VERILATOR=$(abspath verilator/install/bin/verilator)
$(INSTALLED_VERILATOR): $(VERILATOR_SRCDIR)/bin/verilator
$(MAKE) -C $(VERILATOR_SRCDIR) installbin installdata
touch $@
.PHONY:
verilator_install: $(INSTALLED_VERILATOR)
@@ -25,26 +26,14 @@ $(VERILATOR_SRCDIR)/bin/verilator: $(VERILATOR_SRCDIR)/Makefile
$(VERILATOR_SRCDIR)/Makefile: $(VERILATOR_SRCDIR)/configure
mkdir -p $(dir $@)
cd $(dir $@) && ./configure --prefix=$(abspath verilator/install)
cd $(dir $@) && ./configure --prefix=$(abspath $(VERILATOR_INSTALL_DIR)/install)
$(VERILATOR_SRCDIR)/configure: verilator/verilator-$(VERILATOR_VERSION).tar.gz
$(VERILATOR_SRCDIR)/configure: $(VERILATOR_INSTALL_DIR)/verilator-$(VERILATOR_VERSION).tar.gz
rm -rf $(dir $@)
mkdir -p $(dir $@)
cat $^ | tar -xz --strip-components=1 -C $(dir $@)
touch $@
verilator/verilator-$(VERILATOR_VERSION).tar.gz:
$(VERILATOR_INSTALL_DIR)/verilator-$(VERILATOR_VERSION).tar.gz:
mkdir -p $(dir $@)
wget http://www.veripool.org/ftp/verilator-$(VERILATOR_VERSION).tgz -O $@
#########################################################################################
# verilator binary and flags
#########################################################################################
VERILATOR := $(INSTALLED_VERILATOR) --cc --exe
CXXFLAGS := $(CXXFLAGS) -O1 -std=c++11 -I$(RISCV)/include -D__STDC_FORMAT_MACROS
VERILATOR_FLAGS := --top-module $(VLOG_MODEL) \
+define+PRINTF_COND=\$$c\(\"verbose\",\"\&\&\"\,\"done_reset\"\) \
+define+STOP_COND=\$$c\(\"done_reset\"\) --assert \
--output-split 20000 \
-Wno-STMTDLY --x-assign unique \
-O3 -CFLAGS "$(CXXFLAGS) -DTEST_HARNESS=V$(VLOG_MODEL) -DVERILATOR"
wget https://www.veripool.org/ftp/verilator-$(VERILATOR_VERSION).tgz -O $@

View File

@@ -3,7 +3,7 @@ OBJDUMP=riscv64-unknown-elf-objdump
CFLAGS=-mcmodel=medany -std=gnu99 -O2 -fno-common -fno-builtin-printf -Wall
LDFLAGS=-static -nostdlib -nostartfiles -lgcc
PROGRAMS = pwm blkdev accum charcount
PROGRAMS = pwm blkdev accum charcount nic-loopback big-blkdev pingd
default: $(addsuffix .riscv,$(PROGRAMS))

79
tests/big-blkdev.c Normal file
View File

@@ -0,0 +1,79 @@
#include <stdio.h>
#include <stdlib.h>
#include "mmio.h"
#include "blkdev.h"
#define SECTOR_WORDS (BLKDEV_SECTOR_SIZE / sizeof(uint64_t))
#define TEST_SECTORS 128
unsigned long sector_buf[SECTOR_WORDS];
void write_sector(unsigned int secnum)
{
int req_tag, resp_tag;
for (int i = 0; i < SECTOR_WORDS; i++)
sector_buf[i] = (secnum << 6) | i;
while (reg_read8(BLKDEV_NREQUEST) == 0);
req_tag = blkdev_send_request((unsigned long) sector_buf, secnum, 1, 1);
while (reg_read8(BLKDEV_NCOMPLETE) == 0);
resp_tag = reg_read8(BLKDEV_COMPLETE);
if (req_tag != resp_tag) {
printf("Response tag %d does not match request tag %d\n",
req_tag, resp_tag);
exit(EXIT_FAILURE);
}
}
void check_sector(unsigned int secnum)
{
int req_tag, resp_tag;
while (reg_read8(BLKDEV_NREQUEST) == 0);
req_tag = blkdev_send_request((unsigned long) sector_buf, secnum, 1, 0);
while (reg_read8(BLKDEV_NCOMPLETE) == 0);
resp_tag = reg_read8(BLKDEV_COMPLETE);
if (req_tag != resp_tag) {
printf("Response tag %d does not match request tag %d\n",
req_tag, resp_tag);
exit(EXIT_FAILURE);
}
for (int i = 0; i < SECTOR_WORDS; i++) {
unsigned long expected = (secnum << 6) | i;
unsigned long actual = sector_buf[i];
if (actual != expected) {
printf("Word %d in sector %x does not match expected\n",
i, secnum);
printf("Expected %lx, got %lx\n",
expected, actual);
exit(EXIT_FAILURE);
}
}
}
int main(void)
{
unsigned int nsectors = blkdev_nsectors();
unsigned int stride = nsectors / TEST_SECTORS;
printf("Writing %u of %u sectors\n", TEST_SECTORS, nsectors);
for (int i = 0; i < TEST_SECTORS; i++) {
int sector = i * stride;
write_sector(sector);
}
printf("Checking sectors\n", nsectors);
for (int i = 0; i < TEST_SECTORS; i++) {
int sector = i * stride;
check_sector(sector);
}
return 0;
}

View File

@@ -2,30 +2,7 @@
#include <stdio.h>
#include "mmio.h"
#define BLKDEV_BASE 0x10015000
#define BLKDEV_ADDR BLKDEV_BASE
#define BLKDEV_OFFSET (BLKDEV_BASE + 8)
#define BLKDEV_LEN (BLKDEV_BASE + 12)
#define BLKDEV_WRITE (BLKDEV_BASE + 16)
#define BLKDEV_REQUEST (BLKDEV_BASE + 17)
#define BLKDEV_NREQUEST (BLKDEV_BASE + 18)
#define BLKDEV_COMPLETE (BLKDEV_BASE + 19)
#define BLKDEV_NCOMPLETE (BLKDEV_BASE + 20)
#define BLKDEV_NSECTORS (BLKDEV_BASE + 24)
#define BLKDEV_MAX_REQUEST_LENGTH (BLKDEV_BASE + 28)
#define BLKDEV_SECTOR_SIZE 512
#define BLKDEV_SECTOR_SHIFT 9
size_t blkdev_nsectors(void)
{
return reg_read32(BLKDEV_NSECTORS);
}
size_t blkdev_max_req_len(void)
{
return reg_read32(BLKDEV_MAX_REQUEST_LENGTH);
}
#include "blkdev.h"
void blkdev_read(void *addr, unsigned long offset, size_t nsectors)
{
@@ -38,12 +15,9 @@ void blkdev_read(void *addr, unsigned long offset, size_t nsectors)
printf("sending %d reads\n", ntags);
for (i = 0; i < ntags; i++) {
reg_write64(BLKDEV_ADDR, (unsigned long) addr);
reg_write32(BLKDEV_OFFSET, offset);
reg_write32(BLKDEV_LEN, nsectors_per_tag);
reg_write8(BLKDEV_WRITE, 0);
req_tag = reg_read8(BLKDEV_REQUEST);
req_tag = blkdev_send_request(
(unsigned long) addr, offset,
nsectors_per_tag, 0);
addr += (nsectors_per_tag << BLKDEV_SECTOR_SHIFT);
offset += nsectors_per_tag;
}
@@ -67,12 +41,9 @@ void blkdev_write(unsigned long offset, void *addr, size_t nsectors)
printf("sending %d writes\n", ntags);
for (i = 0; i < ntags; i++) {
reg_write64(BLKDEV_ADDR, (unsigned long) addr);
reg_write32(BLKDEV_OFFSET, offset);
reg_write32(BLKDEV_LEN, nsectors_per_tag);
reg_write8(BLKDEV_WRITE, 1);
req_tag = reg_read8(BLKDEV_REQUEST);
req_tag = blkdev_send_request(
(unsigned long) addr, offset,
nsectors_per_tag, 1);
addr += (nsectors_per_tag << BLKDEV_SECTOR_SHIFT);
offset += nsectors_per_tag;
}

38
tests/blkdev.h Normal file
View File

@@ -0,0 +1,38 @@
#define BLKDEV_BASE 0x10015000
#define BLKDEV_ADDR BLKDEV_BASE
#define BLKDEV_OFFSET (BLKDEV_BASE + 8)
#define BLKDEV_LEN (BLKDEV_BASE + 12)
#define BLKDEV_WRITE (BLKDEV_BASE + 16)
#define BLKDEV_REQUEST (BLKDEV_BASE + 17)
#define BLKDEV_NREQUEST (BLKDEV_BASE + 18)
#define BLKDEV_COMPLETE (BLKDEV_BASE + 19)
#define BLKDEV_NCOMPLETE (BLKDEV_BASE + 20)
#define BLKDEV_NSECTORS (BLKDEV_BASE + 24)
#define BLKDEV_MAX_REQUEST_LENGTH (BLKDEV_BASE + 28)
#define BLKDEV_SECTOR_SIZE 512
#define BLKDEV_SECTOR_SHIFT 9
static inline size_t blkdev_nsectors(void)
{
return reg_read32(BLKDEV_NSECTORS);
}
static inline size_t blkdev_max_req_len(void)
{
return reg_read32(BLKDEV_MAX_REQUEST_LENGTH);
}
static inline unsigned int blkdev_send_request(
unsigned long addr,
unsigned int offset,
unsigned int len,
unsigned char write)
{
reg_write64(BLKDEV_ADDR, addr);
reg_write32(BLKDEV_OFFSET, offset);
reg_write32(BLKDEV_LEN, len);
reg_write8(BLKDEV_WRITE, write);
asm volatile ("fence");
return reg_read8(BLKDEV_REQUEST);
}

98
tests/nic-loopback.c Normal file
View File

@@ -0,0 +1,98 @@
#include "mmio.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "nic.h"
#include "encoding.h"
#define NPACKETS 10
#define TEST_OFFSET 3
#define TEST_LEN 356
#define ARRAY_LEN 360
#define NTRIALS 3
uint32_t src[NPACKETS][ARRAY_LEN];
uint32_t dst[NPACKETS][ARRAY_LEN];
uint64_t lengths[NPACKETS];
static inline void send_recv()
{
uint64_t send_packet, recv_addr;
int ncomps, send_comps_left = NPACKETS, recv_comps_left = NPACKETS;
int recv_idx = 0;
for (int i = 0; i < NPACKETS; i++) {
uint64_t pkt_size = TEST_LEN * sizeof(uint32_t);
uint64_t src_addr = (uint64_t) &src[i][TEST_OFFSET];
send_packet = (pkt_size << 48) | src_addr;
recv_addr = (uint64_t) dst[i];
reg_write64(SIMPLENIC_SEND_REQ, send_packet);
reg_write64(SIMPLENIC_RECV_REQ, recv_addr);
}
while (send_comps_left > 0 || recv_comps_left > 0) {
ncomps = nic_send_comp_avail();
asm volatile ("fence");
for (int i = 0; i < ncomps; i++)
reg_read16(SIMPLENIC_SEND_COMP);
send_comps_left -= ncomps;
ncomps = nic_recv_comp_avail();
asm volatile ("fence");
for (int i = 0; i < ncomps; i++) {
lengths[recv_idx] = reg_read16(SIMPLENIC_RECV_COMP);
recv_idx++;
}
recv_comps_left -= ncomps;
}
}
void run_test(void)
{
unsigned long start, end;
int i, j;
memset(dst, 0, sizeof(dst));
asm volatile ("fence");
start = rdcycle();
send_recv();
end = rdcycle();
printf("send/recv %lu cycles\n", end - start);
for (i = 0; i < NPACKETS; i++) {
if (lengths[i] != TEST_LEN * sizeof(uint32_t)) {
printf("recv got wrong # bytes\n");
exit(EXIT_FAILURE);
}
for (j = 0; j < TEST_LEN; j++) {
if (dst[i][j] != src[i][j + TEST_OFFSET]) {
printf("Data mismatch @ %d, %d: %x != %x\n",
i, j, dst[i][j], src[i][j + TEST_OFFSET]);
exit(EXIT_FAILURE);
}
}
}
}
int main(void)
{
int i, j;
for (i = 0; i < NPACKETS; i++) {
for (j = 0; j < ARRAY_LEN; j++)
src[i][j] = i * ARRAY_LEN + j;
}
for (i = 0; i < NTRIALS; i++) {
printf("Trial %d\n", i);
run_test();
}
printf("All correct\n");
return 0;
}

View File

@@ -8,22 +8,22 @@
static inline int nic_send_req_avail(void)
{
return reg_read16(SIMPLENIC_COUNTS) & 0xf;
return reg_read32(SIMPLENIC_COUNTS) & 0xff;
}
static inline int nic_recv_req_avail(void)
{
return (reg_read16(SIMPLENIC_COUNTS) >> 4) & 0xf;
return (reg_read32(SIMPLENIC_COUNTS) >> 8) & 0xff;
}
static inline int nic_send_comp_avail(void)
{
return (reg_read16(SIMPLENIC_COUNTS) >> 8) & 0xf;
return (reg_read32(SIMPLENIC_COUNTS) >> 16) & 0xff;
}
static inline int nic_recv_comp_avail(void)
{
return (reg_read16(SIMPLENIC_COUNTS) >> 12) & 0xf;
return (reg_read32(SIMPLENIC_COUNTS) >> 24) & 0xff;
}
static void nic_send(void *data, unsigned long len)

254
tests/pingd.c Normal file
View File

@@ -0,0 +1,254 @@
#include "mmio.h"
#include "nic.h"
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define ETH_MAX_WORDS 190
#define NET_IP_ALIGN 2
#define ETH_HEADER_SIZE 14
#define MAC_ADDR_SIZE 6
#define IP_ADDR_SIZE 4
#define IPV4_ETHTYPE 0x0800
#define ARP_ETHTYPE 0x0806
#define ICMP_PROT 1
#define ECHO_REPLY 0
#define ECHO_REQUEST 8
#define ARP_REQUEST 1
#define ARP_REPLY 2
#define HTYPE_ETH 1
static inline uint16_t ntohs(uint16_t nint)
{
return ((nint & 0xff) << 8) | ((nint >> 8) & 0xff);
}
static inline uint16_t htons(uint16_t nint)
{
return ntohs(nint);
}
struct eth_header {
uint8_t padding[NET_IP_ALIGN];
uint8_t dst_mac[MAC_ADDR_SIZE];
uint8_t src_mac[MAC_ADDR_SIZE];
uint16_t ethtype;
};
struct arp_header {
uint16_t htype;
uint16_t ptype;
uint8_t hlen;
uint8_t plen;
uint16_t oper;
uint8_t sha[MAC_ADDR_SIZE];
uint8_t spa[IP_ADDR_SIZE];
uint8_t tha[MAC_ADDR_SIZE];
uint8_t tpa[IP_ADDR_SIZE];
};
struct ipv4_header {
uint8_t ver_ihl;
uint8_t dscp_ecn;
uint16_t length;
uint16_t ident;
uint16_t flags_frag_off;
uint8_t ttl;
uint8_t prot;
uint16_t cksum;
uint32_t src_addr;
uint32_t dst_addr;
};
struct icmp_header {
uint8_t type;
uint8_t code;
uint16_t cksum;
uint32_t rest;
};
static int checksum(uint16_t *data, int len)
{
int i;
uint32_t sum = 0;
for (i = 0; i < len; i++)
sum += ntohs(data[i]);
while ((sum >> 16) != 0)
sum = (sum & 0xffff) + (sum >> 16);
sum = ~sum & 0xffff;
return sum;
}
#define ceil_div(n, d) (((n) - 1) / (d) + 1)
static int process_arp(void *buf, uint8_t *mac)
{
struct eth_header *eth = buf;
struct arp_header *arp;
size_t size = ETH_HEADER_SIZE + sizeof(*arp);
uint8_t tmp_addr[IP_ADDR_SIZE];
// Verify arp packet
arp = buf + sizeof(*eth);
if (ntohs(arp->oper) != ARP_REQUEST) {
printf("Wrong arp operation: %d\n", ntohs(arp->oper));
return -1;
}
if (ntohs(arp->htype) != HTYPE_ETH) {
printf("Wrong ARP HTYPE\n");
return -1;
}
if (ntohs(arp->ptype) != IPV4_ETHTYPE) {
printf("Wrong ARP PTYPE\n");
return -1;
}
if (arp->hlen != 6) {
printf("Wrong ARP HLEN: %d\n", arp->hlen);
return -1;
}
if (arp->plen != 4) {
printf("Wrong ARP PLEN: %d\n", arp->plen);
return -1;
}
// Make the source the destination, and add our mac address
memcpy(eth->dst_mac, eth->src_mac, MAC_ADDR_SIZE);
memcpy(eth->src_mac, mac, MAC_ADDR_SIZE);
// create ARP reply
arp->oper = htons(ARP_REPLY);
// Make tha the sha, and fill in sha with actual mac address
memcpy(arp->tha, arp->sha, MAC_ADDR_SIZE);
memcpy(arp->sha, mac, MAC_ADDR_SIZE);
// Swap spa and tpa in arp packet
memcpy(tmp_addr, arp->tpa, IP_ADDR_SIZE);
memcpy(arp->tpa, arp->spa, IP_ADDR_SIZE);
memcpy(arp->spa, tmp_addr, IP_ADDR_SIZE);
size = ceil_div(size + NET_IP_ALIGN, 8) * 8;
nic_send(buf, size);
return 0;
}
static int process_icmp(void *buf, uint8_t *mac)
{
struct eth_header *eth = buf;
struct ipv4_header *ipv4;
struct icmp_header *icmp;
int ihl, icmp_size;
ssize_t size;
uint32_t tmp_addr;
// verify IPv4
ipv4 = buf + sizeof(*eth);
ihl = ipv4->ver_ihl & 0xf;
if (checksum((uint16_t *) ipv4, ihl << 1) != 0) {
printf("Bad IP header checksum %04x\n", ipv4->cksum);
return -1;
}
if (ipv4->prot != ICMP_PROT) {
printf("Wrong IP protocol %d\n", ipv4->prot);
return -1;
}
// verify ICMP
icmp = (buf + sizeof(*eth) + (ihl << 2));
if (icmp->type != ECHO_REQUEST) {
printf("Wrong ICMP type %d\n", icmp->type);
return -1;
}
if (icmp->code != 0) {
printf("Wrong ICMP code %d\n", icmp->code);
return -1;
}
icmp_size = ntohs(ipv4->length) - (ihl << 2);
if (checksum((uint16_t *) icmp, icmp_size >> 1) != 0) {
printf("Bad ICMP checksum %04x\n", icmp->cksum);
return -1;
}
// Set the destination and source MACs
memcpy(eth->dst_mac, eth->src_mac, MAC_ADDR_SIZE);
memcpy(eth->src_mac, mac, MAC_ADDR_SIZE);
// Swap the source and destination IP addresses
tmp_addr = ipv4->dst_addr;
ipv4->dst_addr = ipv4->src_addr;
ipv4->src_addr = tmp_addr;
// compute the IPv4 header checksum
ipv4->cksum = 0;
ipv4->cksum = htons(checksum((uint16_t *) ipv4, ihl << 1));
// set the ICMP type to reply and compute checksum
icmp->cksum = 0;
icmp->type = ECHO_REPLY;
icmp->cksum = htons(checksum((uint16_t *) icmp, icmp_size >> 1));
size = ntohs(ipv4->length) + ETH_HEADER_SIZE;
size = ceil_div(size + NET_IP_ALIGN, 8) * 8;
nic_send(buf, size);
return 0;
}
static int process_packet(void *buf, uint8_t *mac)
{
struct eth_header *eth;
// read the ICMP request
nic_recv(buf);
eth = buf;
printf("Got packet: [ethtype=%04x]\n", ntohs(eth->ethtype));
// Check ethernet type
switch (ntohs(eth->ethtype)) {
case IPV4_ETHTYPE:
return process_icmp(buf, mac);
case ARP_ETHTYPE:
return process_arp(buf, mac);
default:
printf("Wrong ethtype %x\n", ntohs(eth->ethtype));
return -1;
}
}
uint64_t buffer[ETH_MAX_WORDS];
int main(void)
{
uint64_t macaddr_long;
uint8_t *macaddr;
macaddr_long = nic_macaddr();
macaddr = (uint8_t *) &macaddr_long;
printf("macaddr - %02x", macaddr[0]);
for (int i = 1; i < MAC_ADDR_SIZE; i++)
printf(":%02x", macaddr[i]);
printf("\n");
for (;;) {
if (process_packet(buffer, macaddr))
return -1;
}
return 0;
}

View File

@@ -29,7 +29,7 @@ SUB_PROJECT ?= example
ifeq ($(SUB_PROJECT),example)
SBT_PROJECT ?= example
MODEL ?= BoomRocketTestHarness
MODEL ?= TestHarness
VLOG_MODEL ?= TestHarness
MODEL_PACKAGE ?= $(SBT_PROJECT)
CONFIG ?= DefaultRocketConfig
@@ -38,21 +38,9 @@ ifeq ($(SUB_PROJECT),example)
TB ?= TestDriver
TOP ?= BoomRocketTop
endif
# for BOOM developers
ifeq ($(SUB_PROJECT),boom)
SBT_PROJECT ?= boom
MODEL ?= TestHarness
VLOG_MODEL ?= TestHarness
MODEL_PACKAGE ?= boom.system
CONFIG ?= BoomConfig
CONFIG_PACKAGE ?= boom.system
GENERATOR_PACKAGE ?= boom.system
TB ?= TestDriver
TOP ?= ExampleBoomAndRocketSystem
endif
# for Rocket-chip developers
ifeq ($(SUB_PROJECT),rocketchip)
SBT_PROJECT ?= rebarrocketchip
SBT_PROJECT ?= rocketchip
MODEL ?= TestHarness
VLOG_MODEL ?= TestHarness
MODEL_PACKAGE ?= freechips.rocketchip.system
@@ -74,13 +62,26 @@ ifeq ($(SUB_PROJECT),hwacha)
TB ?= TestDriver
TOP ?= ExampleRocketSystem
endif
# Stand-in firechip variables:
# TODO: need a seperate generator and test harnesses for each target
#ifeq ($(SUB_PROJECT),firechip)
# SBT_PROJECT ?= $(SUB_PROJECT)
# MODEL ?= TestHarness
# VLOG_MODEL ?= TestHarness
# MODEL_PACKAGE ?= freechips.rocketchip.system
# CONFIG ?= FireSimRocketChipConfig
# CONFIG_PACKAGE ?= firesim.firesim
# GENERATOR_PACKAGE ?= firesim.firesim
# TB ?= TestDriver
# TOP ?= FireSimNoNIC
#endif
#########################################################################################
# path to rocket-chip and testchipip
#########################################################################################
ROCKETCHIP_DIR = $(base_dir)/generators/rocket-chip
TESTCHIP_DIR = $(base_dir)/generators/testchipip
REBAR_FIRRTL_DIR = $(base_dir)/tools/firrtl
ROCKETCHIP_DIR = $(base_dir)/generators/rocket-chip
TESTCHIP_DIR = $(base_dir)/generators/testchipip
CHIPYARD_FIRRTL_DIR = $(base_dir)/tools/firrtl
#########################################################################################
# names of various files needed to compile and run things
@@ -95,23 +96,27 @@ ifeq ($(GENERATOR_PACKAGE),hwacha)
long_name=$(MODEL_PACKAGE).$(CONFIG)
endif
FIRRTL_FILE ?= $(build_dir)/$(long_name).fir
ANNO_FILE ?= $(build_dir)/$(long_name).anno.json
VERILOG_FILE ?= $(build_dir)/$(long_name).top.v
TOP_FIR ?= $(build_dir)/$(long_name).top.fir
TOP_ANNO ?= $(build_dir)/$(long_name).top.anno.json
FIRRTL_FILE ?= $(build_dir)/$(long_name).fir
ANNO_FILE ?= $(build_dir)/$(long_name).anno.json
TOP_FILE ?= $(build_dir)/$(long_name).top.v
TOP_FIR ?= $(build_dir)/$(long_name).top.fir
TOP_ANNO ?= $(build_dir)/$(long_name).top.anno.json
TOP_SMEMS_FILE ?= $(build_dir)/$(long_name).top.mems.v
TOP_SMEMS_CONF ?= $(build_dir)/$(long_name).top.mems.conf
TOP_SMEMS_FIR ?= $(build_dir)/$(long_name).top.mems.fir
HARNESS_FILE ?= $(build_dir)/$(long_name).harness.v
HARNESS_FIR ?= $(build_dir)/$(long_name).harness.fir
HARNESS_ANNO ?= $(build_dir)/$(long_name).harness.anno.json
HARNESS_SMEMS_FILE ?= $(build_dir)/$(long_name).harness.mems.v
HARNESS_SMEMS_CONF ?= $(build_dir)/$(long_name).harness.mems.conf
HARNESS_SMEMS_FIR ?= $(build_dir)/$(long_name).harness.mems.fir
SMEMS_FILE ?= $(build_dir)/$(long_name).mems.v
SMEMS_CONF ?= $(build_dir)/$(long_name).mems.conf
SMEMS_FIR ?= $(build_dir)/$(long_name).mems.fir
sim_dotf ?= $(build_dir)/sim_files.f
sim_harness_blackboxes ?= $(build_dir)/firrtl_black_box_resource_files.harness.f
sim_top_blackboxes ?= $(build_dir)/firrtl_black_box_resource_files.top.f
sim_files ?= $(build_dir)/sim_files.f
sim_top_blackboxes ?= $(build_dir)/firrtl_black_box_resource_files.top.f
sim_harness_blackboxes ?= $(build_dir)/firrtl_black_box_resource_files.harness.f
sim_common_files ?= $(build_dir)/sim_files.common.f
#########################################################################################
# java arguments used in sbt
@@ -135,7 +140,8 @@ output_dir=$(sim_dir)/output/$(long_name)
# helper variables to run binaries
#########################################################################################
BINARY ?=
SIM_FLAGS ?= +max-cycles=$(timeout_cycles)
SIM_FLAGS ?=
VERBOSE_FLAGS ?= +verbose
sim_out_name = $(notdir $(basename $(BINARY))).$(long_name)
#########################################################################################
@@ -153,9 +159,9 @@ rocketchip_vsrc_dir = $(ROCKETCHIP_DIR)/src/main/resources/vsrc
# sources needed to run simulators
#########################################################################################
sim_vsrcs = \
$(VERILOG_FILE) \
$(TOP_FILE) \
$(HARNESS_FILE) \
$(SMEMS_FILE) \
$(TOP_SMEMS_FILE) \
$(HARNESS_SMEMS_FILE)
#########################################################################################

6
vlsi/.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
inputs.yml
__pycache__
hammer*.log
build
src/test/output-*.json
generated-src

107
vlsi/Makefile Normal file
View File

@@ -0,0 +1,107 @@
#########################################################################################
# vlsi makefile
#########################################################################################
#########################################################################################
# general path variables
#########################################################################################
base_dir=$(abspath ..)
vlsi_dir=$(abspath .)
sim_dir=$(abspath .)
#########################################################################################
# include shared variables
#########################################################################################
include $(base_dir)/variables.mk
#########################################################################################
# vlsi types and rules
#########################################################################################
sim_name ?= vcs # needed for GenerateSimFiles, but is unused
tech_name ?=
tech_dir ?= $(vlsi_dir)/hammer-$(tech_name)-plugin/$(tech_name)
SMEMS_COMP ?= $(tech_dir)/sram-compiler.json
SMEMS_CACHE ?= $(tech_dir)/sram-cache.json
SMEMS_HAMMER ?= $(build_dir)/$(long_name).mems.hammer.json
MACROCOMPILER_MODE ?= -l $(SMEMS_CACHE) -hir $(SMEMS_HAMMER)
OBJ_DIR ?= $(vlsi_dir)/build
ENV_YML ?= $(vlsi_dir)/bwrc-env.yml
INPUT_CONFS ?= example.yml $(dir $(tech_dir))/bwrc.yml
HAMMER_EXEC ?= ./example-vlsi
#########################################################################################
# general rules
#########################################################################################
ALL_RTL = $(TOP_FILE) $(TOP_SMEMS_FILE) $(extra_v_includes)
extra_v_includes = $(build_dir)/EICG_wrapper.v
.PHONY: default verilog
default: all
all: drc lvs
verilog: $(ALL_RTL)
#########################################################################################
# import other necessary rules and variables
#########################################################################################
include $(base_dir)/common.mk
#########################################################################################
# srams
#########################################################################################
SRAM_GENERATOR_CONF = $(build_dir)/sram_generator-input.yml
SRAM_CONF=$(build_dir)/sram_generator-output.json
## SRAM Generator
.PHONY: sram_generator srams
srams: sram_generator
sram_generator: $(SRAM_CONF)
# This should be built alongside $(SMEMS_FILE)
$(SMEMS_HAMMER): $(SMEMS_FILE)
$(SRAM_GENERATOR_CONF): $(SMEMS_HAMMER)
mkdir -p $(dir $@)
echo "vlsi.inputs.sram_parameters: '$(SMEMS_HAMMER)'" >> $@
echo "vlsi.inputs.sram_parameters_meta: [\"transclude\", \"json2list\"]">> $@
$(SRAM_CONF): $(SRAM_GENERATOR_CONF)
cd $(vlsi_dir) && $(HAMMER_EXEC) -e $(ENV_YML) $(foreach x,$(INPUT_CONFS) $(SRAM_GENERATOR_CONF), -p $(x)) --obj_dir $(build_dir) sram_generator
cd $(vlsi_dir) && cp output.json $@
#########################################################################################
# synthesis input configuration
#########################################################################################
SYN_CONF = $(OBJ_DIR)/inputs.yml
GENERATED_CONFS = $(SYN_CONF) $(SRAM_CONF)
$(SYN_CONF): $(ALL_RTL) $(extra_v_includes) $(sim_top_blackboxes)
mkdir -p $(dir $@)
echo "synthesis.inputs:" > $@
echo " top_module: $(TOP)" >> $@
echo " input_files:" >> $@
for x in $(ALL_RTL) $(extra_v_includes) `cat $(sim_top_blackboxes)`; do \
echo ' - "'$$x'"' >> $@; \
done
#########################################################################################
# AUTO BUILD FLOW
#########################################################################################
.PHONY: buildfile
buildfile: $(OBJ_DIR)/hammer.d
# Tip: Set HAMMER_D_DEPS to an empty string to avoid unnecessary RTL rebuilds
# TODO: make this dependency smarter so that we don't need this at all
HAMMER_D_DEPS ?= $(GENERATED_CONFS)
$(OBJ_DIR)/hammer.d: $(HAMMER_D_DEPS)
$(HAMMER_EXEC) -e $(ENV_YML) $(foreach x,$(INPUT_CONFS) $(GENERATED_CONFS), -p $(x)) --obj_dir $(OBJ_DIR) build
-include $(OBJ_DIR)/hammer.d
#########################################################################################
# general cleanup rule
#########################################################################################
.PHONY: clean
clean:
rm -rf $(OBJ_DIR) hammer-vlsi*.log __pycache__ output.json $(GENERATED_CONFS) $(gen_dir)

9
vlsi/README.md Normal file
View File

@@ -0,0 +1,9 @@
This is the starting point for a vlsi flow from this repository.
This flow will not work without the necessary CAD and technology plugins for HAMMER.
If you are a UCB-affiliate, you may be able to acquire access to the tech-plugins.
# Initial Setup Instructions (For All technologies)
Run the `init-vlsi.sh` script to pull correct versions of hammer, hammer-cad-plugins, and the hammer-tech-plugins
```scripts/init-vlsi.sh TECH_NAME```

19
vlsi/example-vlsi Executable file
View File

@@ -0,0 +1,19 @@
#!/usr/bin/env python3
import hammer_vlsi
from hammer_vlsi import CLIDriver, HammerToolHookAction
from typing import Dict, Callable, Optional, List
def example_place_tap_cells(x: hammer_vlsi.HammerTool) -> bool:
x.append('''
# TODO
''')
return True
class ExampleDriver(CLIDriver):
def get_extra_par_hooks(self) -> List[HammerToolHookAction]:
return [hammer_vlsi.HammerTool.make_replacement_hook("place_tap_cells", example_place_tap_cells)]
if __name__ == '__main__':
ExampleDriver().main()

1
vlsi/hammer Submodule

Submodule vlsi/hammer added at a27886fb42