Merge branch 'dev' into docs-generators-change

This commit is contained in:
Brendan Sweeney
2019-09-25 20:03:05 -07:00
committed by GitHub
99 changed files with 3850 additions and 1040 deletions

1
.ciignore Normal file
View File

@@ -0,0 +1 @@
docs/*

11
.circleci/build-extra-tests.sh Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/bash
# turn echo on and error on earliest command
set -ex
# get shared variables
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
source $SCRIPT_DIR/defaults.sh
make -C $LOCAL_CHIPYARD_DIR/tests clean
make -C $LOCAL_CHIPYARD_DIR/tests

View File

@@ -23,7 +23,7 @@ if [ ! -d "$LOCAL_VERILATOR_DIR" ]; then
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"
run "make -j$NPROC -C $REMOTE_SIM_DIR VERILATOR_INSTALL_DIR=$REMOTE_VERILATOR_DIR verilator_install"
# copy so that circleci can cache
mkdir -p $LOCAL_CHIPYARD_DIR

View File

@@ -88,6 +88,32 @@ jobs:
key: verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
paths:
- "/home/riscvuser/verilator"
build-extra-tests:
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:
- riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
- run:
name: Build extra tests
command: .circleci/build-extra-tests.sh
no_output_timeout: 120m
- save_cache:
key: extra-tests-{{ .Branch }}-{{ .Revision }}
paths:
- "/home/riscvuser/project/tests"
prepare-example:
docker:
- image: riscvboom/riscvboom-images:0.0.10
@@ -117,35 +143,6 @@ jobs:
key: example-{{ .Branch }}-{{ .Revision }}
paths:
- "/home/riscvuser/project"
prepare-boomexample:
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:
- riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Building the boomexample subproject using Verilator
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.10
@@ -170,7 +167,7 @@ jobs:
- run:
name: Building the boomrocketexample subproject using Verilator
command: .circleci/do-rtl-build.sh boomrocketexample
no_output_timeout: 120m
no_output_timeout: 240m
- save_cache:
key: boomrocketexample-{{ .Branch }}-{{ .Revision }}
paths:
@@ -291,6 +288,114 @@ jobs:
key: hwacha-{{ .Branch }}-{{ .Revision }}
paths:
- "/home/riscvuser/project"
prepare-firesim:
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:
- riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Building FireSim MIDAS simulator using Verilator
command: .circleci/do-firesim-build.sh firesim
no_output_timeout: 120m
- save_cache:
key: firesim-{{ .Branch }}-{{ .Revision }}
paths:
- "/home/riscvuser/project"
prepare-fireboom:
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:
- riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Building FireSim MIDAS simulator using Verilator
command: .circleci/do-firesim-build.sh fireboom
no_output_timeout: 120m
- save_cache:
key: fireboom-{{ .Branch }}-{{ .Revision }}
paths:
- "/home/riscvuser/project"
prepare-firesim-clockdiv:
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:
- riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Building FireSim MIDAS simulator using Verilator
command: .circleci/do-firesim-build.sh firesim-clockdiv
no_output_timeout: 120m
- save_cache:
key: firesim-clockdiv-{{ .Branch }}-{{ .Revision }}
paths:
- "/home/riscvuser/project"
midasexamples-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:
- riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Run midasexamples tests
command: .circleci/run-midasexamples-tests.sh
example-run-tests:
docker:
- image: riscvboom/riscvboom-images:0.0.10
@@ -315,30 +420,6 @@ jobs:
- run:
name: Run example tests
command: .circleci/run-tests.sh example
boomexample-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:
- 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 tests
command: .circleci/run-tests.sh boomexample
boomrocketexample-run-tests:
docker:
- image: riscvboom/riscvboom-images:0.0.10
@@ -435,6 +516,89 @@ jobs:
- run:
name: Run hwacha tests
command: .circleci/run-tests.sh hwacha
firesim-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:
- riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- firesim-{{ .Branch }}-{{ .Revision }}
- restore_cache:
keys:
- extra-tests-{{ .Branch }}-{{ .Revision }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Run FireSim tests
command: .circleci/run-firesim-tests.sh firesim
fireboom-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:
- riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- fireboom-{{ .Branch }}-{{ .Revision }}
- restore_cache:
keys:
- extra-tests-{{ .Branch }}-{{ .Revision }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Run FireSim tests
command: .circleci/run-firesim-tests.sh fireboom
no_output_timeout: 20m
firesim-clockdiv-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:
- riscv-tools-installed-v1-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- firesim-clockdiv-{{ .Branch }}-{{ .Revision }}
- restore_cache:
keys:
- extra-tests-{{ .Branch }}-{{ .Revision }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Run FireSim tests
command: .circleci/run-firesim-tests.sh firesim-clockdiv
# Order and dependencies of jobs to run
workflows:
@@ -453,7 +617,6 @@ workflows:
build-and-test-chipyard-integration:
jobs:
# Make the toolchains
- install-riscv-toolchain
@@ -462,13 +625,13 @@ workflows:
# Build verilator
- install-verilator
# Prepare the verilator builds
- prepare-example:
# Build extra tests
- build-extra-tests:
requires:
- install-riscv-toolchain
- install-verilator
- prepare-boomexample:
# Prepare the verilator builds
- prepare-example:
requires:
- install-riscv-toolchain
- install-verilator
@@ -498,17 +661,34 @@ workflows:
- install-esp-toolchain
- install-verilator
- prepare-firesim:
requires:
- install-riscv-toolchain
- install-verilator
- prepare-fireboom:
requires:
- install-riscv-toolchain
- install-verilator
- prepare-firesim-clockdiv:
requires:
- install-riscv-toolchain
- install-verilator
# Run the respective tests
# Run midasexamples test
- midasexamples-run-tests:
requires:
- install-riscv-toolchain
- install-verilator
# Run the example tests
- example-run-tests:
requires:
- prepare-example
- boomexample-run-tests:
requires:
- prepare-boomexample
- boomrocketexample-run-tests:
requires:
- prepare-boomrocketexample
@@ -524,3 +704,19 @@ workflows:
- hwacha-run-tests:
requires:
- prepare-hwacha
# Run the firesim tests
- firesim-run-tests:
requires:
- prepare-firesim
- build-extra-tests
- fireboom-run-tests:
requires:
- prepare-fireboom
- build-extra-tests
- firesim-clockdiv-run-tests:
requires:
- prepare-firesim-clockdiv
- build-extra-tests

View File

@@ -17,6 +17,9 @@ clean () {
run "rm -rf $REMOTE_WORK_DIR"
}
# make parallelism
NPROC=8
# 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
@@ -24,6 +27,8 @@ 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
REMOTE_FIRESIM_DIR=$REMOTE_CHIPYARD_DIR/sims/firesim/sim
REMOTE_JAVA_ARGS="-Xmx8G -Xss8M -Dsbt.ivy.home=$REMOTE_WORK_DIR/.ivy2 -Dsbt.global.base=$REMOTE_WORK_DIR/.sbt -Dsbt.boot.directory=$REMOTE_WORK_DIR/.sbt/boot"
# local variables (aka within the docker container)
LOCAL_CHECKOUT_DIR=$HOME/project
@@ -32,13 +37,16 @@ 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
LOCAL_FIRESIM_DIR=$LOCAL_CHIPYARD_DIR/sims/firesim/sim
# 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["boomrocketexample"]="SUB_PROJECT=example CONFIG=LargeBoomAndRocketConfig"
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"
mapping["blockdevrocketchip"]="SUB_PROJECT=example CONFIG=SimBlockDeviceRocketConfig TOP=TopWithBlockDevice"
mapping["hwacha"]="SUB_PROJECT=example CONFIG=HwachaRocketConfig GENERATOR_PACKAGE=hwacha"
mapping["firesim"]="DESIGN=FireSim TARGET_CONFIG=FireSimRocketChipConfig PLATFORM_CONFIG=FireSimConfig"
mapping["fireboom"]="DESIGN=FireBoom TARGET_CONFIG=FireSimBoomConfig PLATFORM_CONFIG=FireSimConfig"
mapping["firesim-clockdiv"]="DESIGN=FireSim TARGET_CONFIG=FireSimRocketChipConfig PLATFORM_CONFIG=FireSimClockDivConfig"

63
.circleci/do-firesim-build.sh Executable file
View File

@@ -0,0 +1,63 @@
#!/bin/bash
# create the different verilator builds
# argument is the make command string
# turn echo on and error on earliest command
set -ex
# get shared variables
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
source $SCRIPT_DIR/defaults.sh
# call clean on exit
trap clean EXIT
cd $LOCAL_CHIPYARD_DIR
./scripts/init-submodules-no-riscv-tools.sh
cd sims/firesim/sim/midas && git submodule update --init
# set stricthostkeychecking to no (must happen before rsync)
run "echo \"Ping $SERVER\""
clean
# 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
run "cp -r ~/.ivy2 $REMOTE_WORK_DIR"
run "cp -r ~/.sbt $REMOTE_WORK_DIR"
TOOLS_DIR=$REMOTE_RISCV_DIR
LD_LIB_DIR=$REMOTE_RISCV_DIR/lib
VERILATOR_BIN_DIR=$REMOTE_VERILATOR_DIR/install/bin
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
# Build MIDAS-level verilator sim
FIRESIM_VARS="${mapping[$1]}"
run "export FIRESIM_ENV_SOURCED=1; make -C $REMOTE_FIRESIM_DIR clean"
run "export RISCV=\"$TOOLS_DIR\"; export LD_LIBRARY_PATH=\"$LD_LIB_DIR\"; \
export PATH=\"$VERILATOR_BIN_DIR:\$PATH\"; export FIRESIM_ENV_SOURCED=1; \
export VERILATOR_ROOT=$REMOTE_VERILATOR_DIR/install/share/verilator; \
make -C $REMOTE_FIRESIM_DIR JAVA_ARGS=\"$REMOTE_JAVA_ARGS\" $FIRESIM_VARS verilator"
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
# Fix dramsim2_ini symlink
export $FIRESIM_VARS
ln -sf $LOCAL_FIRESIM_DIR/midas/src/main/resources/dramsim2_ini $LOCAL_FIRESIM_DIR/generated-src/f1/${DESIGN}-${TARGET_CONFIG}-${PLATFORM_CONFIG}/dramsim2_ini

View File

@@ -27,6 +27,9 @@ run "mkdir -p $REMOTE_VERILATOR_DIR"
copy $LOCAL_CHIPYARD_DIR/ $SERVER:$REMOTE_CHIPYARD_DIR
copy $LOCAL_VERILATOR_DIR/ $SERVER:$REMOTE_VERILATOR_DIR
run "cp -r ~/.ivy2 $REMOTE_WORK_DIR"
run "cp -r ~/.sbt $REMOTE_WORK_DIR"
TOOLS_DIR=$REMOTE_RISCV_DIR
LD_LIB_DIR=$REMOTE_RISCV_DIR/lib
if [ $1 = "hwacha" ]; then
@@ -41,7 +44,9 @@ 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 "export RISCV=\"$TOOLS_DIR\"; export LD_LIBRARY_PATH=\"$LD_LIB_DIR\"; \
export VERILATOR_ROOT=$REMOTE_VERILATOR_DIR/install/share/verilator; \
make -j$NPROC -C $REMOTE_SIM_DIR VERILATOR_INSTALL_DIR=$REMOTE_VERILATOR_DIR JAVA_ARGS=\"$REMOTE_JAVA_ARGS\" ${mapping[$1]}"
run "rm -rf $REMOTE_CHIPYARD_DIR/project"
# copy back the final build

21
.circleci/run-firesim-tests.sh Executable file
View File

@@ -0,0 +1,21 @@
#!/bin/bash
# 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 PATH=$LOCAL_VERILATOR_DIR/install/bin:$PATH
export FIRESIM_ENV_SOURCED=1
SIMULATION_ARGS="${mapping[$1]}"
run_test_suite () {
make -C $LOCAL_FIRESIM_DIR $SIMULATION_ARGS run-${1}-tests-fast
}
run_test_suite bmark
run_test_suite nic
run_test_suite blockdev

View File

@@ -0,0 +1,46 @@
#!/bin/bash
# turn echo on and error on earliest command
set -ex
# get shared variables
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
source $SCRIPT_DIR/defaults.sh
# call clean on exit
trap clean EXIT
cd $LOCAL_CHIPYARD_DIR
./scripts/init-submodules-no-riscv-tools.sh
cd sims/firesim/sim/midas && git submodule update --init
# set stricthostkeychecking to no (must happen before rsync)
run "echo \"Ping $SERVER\""
clean
# copy over riscv-tools, verilator, and chipyard to remote
run "mkdir -p $REMOTE_CHIPYARD_DIR"
run "mkdir -p $REMOTE_VERILATOR_DIR"
run "mkdir -p $REMOTE_RISCV_DIR"
copy $LOCAL_CHIPYARD_DIR/ $SERVER:$REMOTE_CHIPYARD_DIR
copy $LOCAL_VERILATOR_DIR/ $SERVER:$REMOTE_VERILATOR_DIR
copy $LOCAL_RISCV_DIR/ $SERVER:$REMOTE_RISCV_DIR
# Copy ivy2 and sbt directories
run "cp -r ~/.ivy2 $REMOTE_WORK_DIR"
run "cp -r ~/.sbt $REMOTE_WORK_DIR"
TOOLS_DIR=$REMOTE_RISCV_DIR
LD_LIB_DIR=$REMOTE_RISCV_DIR/lib
VERILATOR_BIN_DIR=$REMOTE_VERILATOR_DIR/install/bin
# Run midasexamples test
run "export FIRESIM_ENV_SOURCED=1; make -C $REMOTE_FIRESIM_DIR clean"
run "export RISCV=\"$TOOLS_DIR\"; export LD_LIBRARY_PATH=\"$LD_LIB_DIR\"; \
export PATH=\"$VERILATOR_BIN_DIR:\$PATH\"; export FIRESIM_ENV_SOURCED=1; \
export VERILATOR_ROOT=$REMOTE_VERILATOR_DIR/install/share/verilator; \
make -C $REMOTE_FIRESIM_DIR JAVA_ARGS=\"$REMOTE_JAVA_ARGS\" TARGET_PROJECT=midasexamples test"

View File

@@ -12,11 +12,11 @@ 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 $@
make run-bmark-tests-fast -j$NPROC -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 $@
make run-asm-tests-fast -j$NPROC -C $LOCAL_SIM_DIR VERILATOR_INSTALL_DIR=$LOCAL_VERILATOR_DIR $@
}
run_both () {
@@ -44,7 +44,7 @@ case $1 in
export RISCV=$LOCAL_ESP_DIR
export LD_LIBRARY_PATH=$LOCAL_ESP_DIR/lib
export PATH=$RISCV/bin:$PATH
make run-rv64uv-p-asm-tests -C $LOCAL_SIM_DIR VERILATOR_INSTALL_DIR=$LOCAL_VERILATOR_DIR ${mapping[$1]}
make run-rv64uv-p-asm-tests -j$NPROC -C $LOCAL_SIM_DIR VERILATOR_INSTALL_DIR=$LOCAL_VERILATOR_DIR ${mapping[$1]}
;;
*)
echo "No set of tests for $1. Did you spell it right?"

View File

@@ -0,0 +1,31 @@
#!/usr/bin/env bash
if [[ ! -a .ciignore ]]; then
exit # If .ciignore doesn't exists, just quit this Git hook
fi
# Load in every file that will be changed via this commit into an array
changes=( `git diff --name-only --cached` )
# Load the patterns we want to skip into an array
mapfile -t blacklist < .ciignore
for i in "${blacklist[@]}"
do
# Remove the current pattern from the list of changes
changes=( ${changes[@]/$i/} )
if [[ ${#changes[@]} -eq 0 ]]; then
# If we've exhausted the list of changes before we've finished going
# through patterns, that's okay, just quit the loop
break
fi
done
if [[ ${#changes[@]} -gt 0 ]]; then
# If there's still changes left, then we have stuff to build, leave the commit alone.
exit
fi
# Prefix the commit message with "[skip ci]"
sed -i '1s/^/[skip ci] /' "$1"

3
.gitignore vendored
View File

@@ -5,6 +5,7 @@ target
*.stamp
*.vcd
*.swp
*.log
*#
*~
.idea
@@ -12,4 +13,4 @@ target
env.sh
riscv-tools-install
tags
*~
*~

15
.gitmodules vendored
View File

@@ -46,3 +46,18 @@
[submodule "vlsi/hammer-cad-plugins"]
path = vlsi/hammer-cad-plugins
url = https://github.com/ucb-bar/hammer-cad-plugins.git
[submodule "tools/dsptools"]
path = tools/dsptools
url = https://github.com/ucb-bar/dsptools.git
[submodule "tools/chisel-testers"]
path = tools/chisel-testers
url = https://github.com/freechipsproject/chisel-testers.git
[submodule "tools/treadle"]
path = tools/treadle
url = https://github.com/freechipsproject/treadle.git
[submodule "generators/rocc-template"]
path = generators/sha3
url = https://github.com/ucb-bar/rocc-template.git
[submodule "tools/firrtl-interpreter"]
path = tools/firrtl-interpreter
url = https://github.com/freechipsproject/firrtl-interpreter.git

View File

@@ -1,5 +1,9 @@
import Tests._
// This gives us a nicer handle to the root project instead of using the
// implicit one
lazy val chipyardRoot = RootProject(file("."))
lazy val commonSettings = Seq(
organization := "edu.berkeley.cs",
version := "1.0",
@@ -13,9 +17,12 @@ lazy val commonSettings = Seq(
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % "test",
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",
libraryDependencies += "org.scala-lang.modules" % "scala-jline" % "2.12.1",
libraryDependencies += "com.typesafe.play" %% "play-json" % "2.6.10",
addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full),
unmanagedBase := (chipyardRoot / unmanagedBase).value,
allDependencies := allDependencies.value.filterNot(_.organization == "edu.berkeley.cs"),
resolvers ++= Seq(
Resolver.sonatypeRepo("snapshots"),
Resolver.sonatypeRepo("releases"),
@@ -43,6 +50,22 @@ def conditionalDependsOn(prj: Project): Project = {
}
}
/**
* It has been a struggle for us to override settings in subprojects.
* An example would be adding a dependency to rocketchip on midas's targetutils library,
* or replacing dsptools's maven dependency on chisel with the local chisel project.
*
* This function works around this by specifying the project's root at src/ and overriding
* scalaSource and resourceDirectory.
*/
def freshProject(name: String, dir: File): Project = {
Project(id = name, base = dir / "src")
.settings(
scalaSource in Compile := baseDirectory.value / "main" / "scala",
resourceDirectory in Compile := baseDirectory.value / "main" / "resources"
)
}
// 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 =>
@@ -51,11 +74,32 @@ def isolateAllTests(tests: Seq[TestDefinition]) = tests map { test =>
} toSeq
// Subproject definitions begin
//
// FIRRTL is handled as an unmanaged dependency. Make will build the firrtl jar
// before launching sbt if any of the firrtl source files has been updated
// The jar is dropped in chipyard's lib/ directory, which is used as the unmanagedBase
// for all subprojects
lazy val chisel = (project in file("tools/chisel3"))
// NB: FIRRTL dependency is unmanaged (and dropped in sim/lib)
lazy val chisel = (project in rocketChipDir / "chisel3")
lazy val firrtl_interpreter = (project in file("tools/firrtl-interpreter"))
.settings(commonSettings)
// Contains annotations & firrtl passes you may wish to use in rocket-chip without
lazy val treadle = (project in file("tools/treadle"))
.settings(commonSettings)
lazy val chisel_testers = (project in file("tools/chisel-testers"))
.dependsOn(chisel, firrtl_interpreter, treadle)
.settings(
commonSettings,
libraryDependencies ++= Seq(
"junit" % "junit" % "4.12",
"org.scalatest" %% "scalatest" % "3.0.5",
"org.scalacheck" %% "scalacheck" % "1.14.0",
"com.github.scopt" %% "scopt" % "3.7.0"
)
)
// 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")
@@ -66,14 +110,8 @@ lazy val hardfloat = (project in rocketChipDir / "hardfloat")
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")
lazy val rocketchip = freshProject("rocketchip", rocketChipDir)
.settings(commonSettings)
.dependsOn(chisel, hardfloat, rocketMacros)
lazy val testchipip = (project in file("generators/testchipip"))
@@ -81,10 +119,15 @@ lazy val testchipip = (project in file("generators/testchipip"))
.settings(commonSettings)
lazy val example = conditionalDependsOn(project in file("generators/example"))
.dependsOn(boom, hwacha, sifive_blocks, sifive_cache)
.dependsOn(boom, hwacha, sifive_blocks, sifive_cache, utilities, sha3)
.settings(commonSettings)
lazy val tracegen = conditionalDependsOn(project in file("generators/tracegen"))
.dependsOn(rocketchip, sifive_cache)
.settings(commonSettings)
lazy val utilities = conditionalDependsOn(project in file("generators/utilities"))
.dependsOn(rocketchip, boom)
.settings(commonSettings)
lazy val icenet = (project in file("generators/icenet"))
@@ -99,17 +142,38 @@ lazy val boom = (project in file("generators/boom"))
.dependsOn(rocketchip)
.settings(commonSettings)
lazy val sha3 = (project in file("generators/sha3"))
.dependsOn(rocketchip, chisel_testers)
.settings(commonSettings)
lazy val tapeout = conditionalDependsOn(project in file("./tools/barstools/tapeout/"))
.dependsOn(chisel_testers)
.settings(commonSettings)
lazy val mdf = (project in file("./tools/barstools/mdf/scalalib/"))
.settings(commonSettings)
lazy val barstoolsMacros = (project in file("./tools/barstools/macros/"))
.dependsOn(mdf, rocketchip)
.dependsOn(firrtl_interpreter, mdf, rocketchip)
.enablePlugins(sbtassembly.AssemblyPlugin)
.settings(commonSettings)
lazy val dsptools = (project in file("./tools/dsptools"))
.dependsOn(chisel, chisel_testers)
.settings(
commonSettings,
libraryDependencies ++= Seq(
"org.typelevel" %% "spire" % "0.14.1",
"org.scalanlp" %% "breeze" % "0.13.2",
"junit" % "junit" % "4.12" % "test",
"org.scalatest" %% "scalatest" % "3.0.5" % "test",
"org.scalacheck" %% "scalacheck" % "1.14.0" % "test"
))
lazy val `rocket-dsptools` = (project in file("./tools/dsptools/rocket"))
.dependsOn(rocketchip, dsptools)
.settings(commonSettings)
lazy val sifive_blocks = (project in file("generators/sifive-blocks"))
.dependsOn(rocketchip)
.settings(commonSettings)
@@ -124,7 +188,7 @@ 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")
.dependsOn(boom, icenet, testchipip, sifive_blocks, sifive_cache, utilities, tracegen, midasTargetUtils, midas, firesimLib % "test->test;compile->compile")
.settings(
commonSettings,
testGrouping in Test := isolateAllTests( (definedTests in Test).value )

View File

@@ -6,11 +6,10 @@ SHELL=/bin/bash
#########################################################################################
# variables to get all *.scala files
#########################################################################################
lookup_scala_srcs = $(shell find -L $(1)/ -iname "*.scala" 2> /dev/null)
lookup_scala_srcs = $(shell find -L $(1)/ -name target -prune -o -iname "*.scala" -print 2> /dev/null)
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))
SOURCE_DIRS=$(addprefix $(base_dir)/,generators sims/firesim/sim)
SCALA_SOURCES=$(call lookup_scala_srcs,$(SOURCE_DIRS))
#########################################################################################
# rocket and testchipip classes
@@ -31,7 +30,7 @@ $(FIRRTL_JAR): $(call lookup_scala_srcs, $(CHIPYARD_FIRRTL_DIR)/src/main/scala)
touch $@
#########################################################################################
# create simulation args file rule
# create list of simulation file inputs
#########################################################################################
$(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)"
@@ -39,7 +38,9 @@ $(sim_files): $(call lookup_scala_srcs,$(base_dir)/generators/utilities/src/main
#########################################################################################
# create firrtl file rule and variables
#########################################################################################
$(FIRRTL_FILE) $(ANNO_FILE): $(SCALA_SOURCES) $(sim_files)
.INTERMEDIATE: generator_temp
$(FIRRTL_FILE) $(ANNO_FILE): generator_temp
generator_temp: $(SCALA_SOURCES) $(sim_files)
mkdir -p $(build_dir)
cd $(base_dir) && $(SBT) "project $(SBT_PROJECT)" "runMain $(GENERATOR_PACKAGE).Generator $(build_dir) $(MODEL_PACKAGE) $(MODEL) $(CONFIG_PACKAGE) $(CONFIG)"
@@ -52,23 +53,29 @@ HARNESS_CONF_FLAGS = -thconf $(HARNESS_SMEMS_CONF)
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)
$(TOP_TARGETS) $(HARNESS_TARGETS): $(FIRRTL_FILE) $(ANNO_FILE)
.INTERMEDIATE: firrtl_temp
$(TOP_TARGETS) $(HARNESS_TARGETS): firrtl_temp
firrtl_temp: $(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
$(TOP_SMEMS_FILE) $(TOP_SMEMS_FIR): $(TOP_SMEMS_CONF)
.INTERMEDIATE: top_macro_temp
$(TOP_SMEMS_FILE) $(TOP_SMEMS_FIR): top_macro_temp
top_macro_temp: $(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)
.INTERMEDIATE: harness_macro_temp
$(HARNESS_SMEMS_FILE) $(HARNESS_SMEMS_FIR): harness_macro_temp
harness_macro_temp: $(HARNESS_SMEMS_CONF)
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
# remove duplicate files and headers in list of simulation file inputs
########################################################################################
$(sim_common_files): $(sim_files) $(sim_top_blackboxes) $(sim_harness_blackboxes)
awk '{print $1;}' $^ | sort -u > $@
awk '{print $1;}' $^ | sort -u | grep -v '.*\.h' > $@
#########################################################################################
# helper rule to just make verilog files
@@ -93,7 +100,7 @@ run-binary-fast: $(sim)
# 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)
(set -o pipefail && $(sim_debug) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(VERBOSE_FLAGS) $(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
@@ -116,39 +123,3 @@ $(output_dir)/%.out: $(output_dir)/% $(sim)
ifneq ($(filter run% %.run %.out %.vpd %.vcd,$(MAKECMDGOALS)),)
-include $(build_dir)/$(long_name).d
endif
#########################################################################################
# default regression tests variables and rules
# TODO: Remove in favor of each project having its own regression tests?
#########################################################################################
regression-tests = \
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
.PHONY: run-regression-tests run-regression-tests-fast run-regression-tests-debug
run-regression-tests: $(addprefix $(output_dir)/,$(addsuffix .out,$(regression-tests)))
run-regression-tests-fast: $(addprefix $(output_dir)/,$(addsuffix .run,$(regression-tests)))
run-regression-tests-debug: $(addprefix $(output_dir)/,$(addsuffix .vpd,$(regression-tests)))

View File

@@ -3,7 +3,7 @@ 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
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.
@@ -13,15 +13,12 @@ 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
.. literalinclude:: ../../generators/example/src/main/scala/RocketConfigs.scala
:language: scala
:start-after: DOC include start: JtagRocket
:end-before: DOC include end: JtagRocket
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.
In this example, the ``WithDTMTop`` 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).
@@ -36,7 +33,7 @@ After creating the config, call the ``make`` command like the following:
# or
cd sims/vcs
make CONFIG=DTMBoomConfig TOP=BoomRocketTopWithDTM MODEL=TestHarnessWithDTM
make CONFIG=DTMBoomConfig TOP=TopWithDTM 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!

View File

@@ -1,8 +1,9 @@
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:
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 ``addResource`` function given by FIRRTL.
An example of its use can be seen in `generators/testchipip/src/main/scala/SerialAdapter.scala <https://github.com/ucb-bar/testchipip/blob/master/src/main/scala/SerialAdapter.scala>`_.
Here is the example inlined:
.. code-block:: scala
@@ -14,13 +15,13 @@ They can be used in the following way:
val exit = Output(Bool())
})
setResource("/testchipip/vsrc/SimSerial.v")
setResource("/testchipip/csrc/SimSerial.cc")
addResource("/testchipip/vsrc/SimSerial.v")
addResource("/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")``.
The ``addResource`` path retrieves resources from the ``src/main/resources`` directory.
So to get an item at ``src/main/resources/fileA.v`` you can use ``addResource("/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``.

View File

@@ -8,12 +8,13 @@ Generators
The Chipyard Framework currently consists of the following RTL generators:
Processor Cores
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Rocket**
**Rocket Core**
An in-order RISC-V core.
See :ref:`Rocket` for more information.
See :ref:`Rocket Core` for more information.
**BOOM (Berkeley Out-of-Order Machine)**
An out-of-order RISC-V core.
@@ -86,12 +87,12 @@ Sims
**verilator (Verilator wrapper)**
Verilator is an open source Verilog simulator.
The ``verilator`` directory provides wrappers which construct Verilator-based simulators from relevant generated RTL, allowing for execution of test RISC-V programs on the simulator (including vcd waveform files).
See :ref:`Verilator` for more information.
See :ref:`Verilator (Open-Source)` for more information.
**vcs (VCS wrapper)**
VCS is a proprietary Verilog simulator.
Assuming the user has valid VCS licenses and installations, the ``vcs`` directory provides wrappers which construct VCS-based simulators from relevant generated RTL, allowing for execution of test RISC-V programs on the simulator (including vcd/vpd waveform files).
See :ref:`VCS` for more information.
See :ref:`Synopsys VCS (License Required)` for more information.
**FireSim**
FireSim is an open-source FPGA-accelerated simulation platform, using Amazon Web Services (AWS) EC2 F1 instances on the public cloud.
@@ -109,4 +110,4 @@ VLSI
The HAMMER flow provide automated scripts which generate relevant tool commands based on a higher level description of physical design constraints.
The HAMMER flow also allows for re-use of process technology knowledge by enabling the construction of process-technology-specific plug-ins, which describe particular constraints relating to that process technology (obsolete standard cells, metal layer routing constraints, etc.).
The HAMMER flow requires access to proprietary EDA tools and process technology libraries.
See :ref:`HAMMER` for more information.
See :ref:`Core HAMMER` for more information.

View File

@@ -8,8 +8,6 @@ In order to use the parameter system correctly, we will use several terms and co
Parameters
--------------------
TODO: Need to explain up, site, field, and other stuff from Henry's thesis.
It is important to note that a significant challenge with the Rocket parameter system is being able to identify the correct parameter to use, and the impact that parameter has on the overall system.
We are still investigating methods to facilitate parameter exploration and discovery.
@@ -21,7 +19,7 @@ Configs are additive, can override each other, and can be composed of other Conf
The naming convention for an additive Config is ``With<YourConfigName>``, while the naming convention for a non-additive Config will be ``<YourConfig>``.
Configs can take arguments which will in-turn set parameters in the design or reference other parameters in the design (see :ref:`Parameters`).
:numref:`basic-config-example` shows a basic additive Config class that takes in zero arguments and instead uses hardcoded values to set the RTL design parameters.
This example shows a basic additive Config class that takes in zero arguments and instead uses hardcoded values to set the RTL design parameters.
In this example, ``MyAcceleratorConfig`` is a Scala case class that defines a set of variables that the generator can use when referencing the ``MyAcceleratorKey`` in the design.
.. _basic-config-example:
@@ -38,7 +36,7 @@ In this example, ``MyAcceleratorConfig`` is a Scala case class that defines a se
someLength = 256)
})
This next example (:numref:`complex-config-example`) shows a "higher-level" additive Config that uses prior parameters that were set to derive other parameters.
This next example shows a "higher-level" additive Config that uses prior parameters that were set to derive other parameters.
.. _complex-config-example:
.. code-block:: scala
@@ -52,7 +50,7 @@ This next example (:numref:`complex-config-example`) shows a "higher-level" addi
hartId = up(RocketTilesKey, site).length)
})
:numref:`top-level-config` shows a non-additive Config that combines the prior two additive Configs using ``++``.
The following example shows a non-additive Config that combines the prior two additive Configs using ``++``.
The additive Configs are applied from the right to left in the list (or bottom to top in the example).
Thus, the order of the parameters being set will first start with the ``DefaultExampleConfig``, then ``WithMyAcceleratorParams``, then ``WithMyMoreComplexAcceleratorConfig``.
@@ -65,13 +63,18 @@ Thus, the order of the parameters being set will first start with the ``DefaultE
new DefaultExampleConfig
)
The ``site``, ``here``, and ``up`` objects in ``WithMyMoreComplexAcceleratorConfig`` are maps from configuration keys to their definitions.
The ``site`` map gives you the definitions as seen from the root of the configuration hierarchy (in this example, ``SomeAdditiveConfig``).
The ``here`` map gives the definitions as seen at the current level of the hierarchy (i.e. in ``WithMyMoreComplexAcceleratorConfig`` itself).
The ``up`` map gives the definitions as seen from the next level up from the current (i.e. from ``WithMyAcceleratorParams``).
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 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.
This example shows a Rocket Chip based SoC that merges multiple system components (BootROM, UART, etc) into a single top-level design.
.. _cake-example:
.. code-block:: scala
@@ -92,7 +95,7 @@ Mix-in
A mix-in is a Scala trait, which sets parameters for specific system components, as well as enabling instantiation and wiring of the relevant system components to system buses.
The naming convention for an additive mix-in is ``Has<YourMixin>``.
This is show in :numref:`cake-example` where things such as ``HasPeripherySerial`` connect a RTL component to a bus and expose signals to the top-level.
This is shown in the MySoC class where things such as ``HasPeripherySerial`` connect a RTL component to a bus and expose signals to the top-level.
Additional References
---------------------------

View File

@@ -20,5 +20,3 @@ Hit next to get started!
Chipyard-Components
Configs-Parameters-Mixins
Initial-Repo-Setup
Running-A-Simulation
Building-A-Chip

View File

@@ -1,6 +1,6 @@
.. _adding-an-accelerator:
Adding An Accelerator/Device
Adding an Accelerator/Device
===============================
Accelerators or custom IO devices can be added to your SoC in several ways:
@@ -61,64 +61,28 @@ 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 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
------------------
The easiest way to create a TileLink peripheral is to use the ``TLRegisterRouter``, which abstracts away the details of handling the TileLink protocol and provides a convenient interface for specifying memory-mapped registers.
To create a RegisterRouter-based peripheral, you will need to specify a parameter case class for the configuration settings, a bundle trait with the extra top-level ports, and a module implementation containing the actual RTL.
In this case we use a submodule ``PWMBase`` to actually perform the pulse-width modulation. The ``PWMModule`` class only creates the registers and hooks them
up using ``regmap``.
.. code-block:: scala
case class PWMParams(address: BigInt, beatBytes: Int)
trait PWMTLBundle extends Bundle {
val pwmout = Output(Bool())
}
trait PWMTLModule {
val io: PWMTLBundle
implicit val p: Parameters
def params: PWMParams
val w = params.beatBytes * 8
val period = Reg(UInt(w.W))
val duty = Reg(UInt(w.W))
val enable = RegInit(false.B)
// ... Use the registers to drive io.pwmout ...
regmap(
0x00 -> Seq(
RegField(w, period)),
0x04 -> Seq(
RegField(w, duty)),
0x08 -> Seq(
RegField(1, enable)))
}
.. literalinclude:: ../../generators/example/src/main/scala/PWM.scala
:language: scala
:start-after: DOC include start: PWM generic traits
:end-before: DOC include end: PWM generic traits
Once you have these classes, you can construct the final peripheral by extending the ``TLRegisterRouter`` and passing the proper arguments.
The first set of arguments determines where the register router will be placed in the global address map and what information will be put in its device tree entry.
The second set of arguments is the IO bundle constructor, which we create by extending ``TLRegBundle`` with our bundle trait.
The final set of arguments is the module constructor, which we create by extends ``TLRegModule`` with our module trait.
.. code-block:: scala
class PWMTL(c: PWMParams)(implicit p: Parameters)
extends TLRegisterRouter(
c.address, "pwm", Seq("ucbbar,pwm"),
beatBytes = c.beatBytes)(
new TLRegBundle(c, _) with PWMTLBundle)(
new TLRegModule(c, _, _) with PWMTLModule)
.. literalinclude:: ../../generators/example/src/main/scala/PWM.scala
:language: scala
:start-after: DOC include start: PWMTL
:end-before: DOC include end: PWMTL
The full module code can be found in ``generators/example/src/main/scala/PWM.scala``.
@@ -130,20 +94,10 @@ In the Rocket Chip cake, there are two kinds of traits: a ``LazyModule`` trait a
The ``LazyModule`` trait runs setup code that must execute before all the hardware gets elaborated.
For a simple memory-mapped peripheral, this just involves connecting the peripheral's TileLink node to the MMIO crossbar.
.. code-block:: scala
trait HasPeripheryPWM extends HasSystemNetworks {
implicit val p: Parameters
private val address = 0x2000
val pwm = LazyModule(new PWMTL(
PWMParams(address, peripheryBusConfig.beatBytes))(p))
pwm.node := TLFragmenter(
peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node)
}
.. literalinclude:: ../../generators/example/src/main/scala/PWM.scala
:language: scala
:start-after: DOC include start: HasPeripheryPWMTL
:end-before: DOC include end: HasPeripheryPWMTL
Note that the ``PWMTL`` class we created from the register router is itself a ``LazyModule``.
Register routers have a TileLink node simply named "node", which we can hook up to the Rocket Chip bus.
@@ -153,77 +107,43 @@ The module implementation trait is where we instantiate our PWM module and conne
Since this module has an extra `pwmout` output, we declare that in this trait, using Chisel's multi-IO functionality.
We then connect the ``PWMTL``'s pwmout to the pwmout we declared.
.. code-block:: scala
trait HasPeripheryPWMModuleImp extends LazyMultiIOModuleImp {
implicit val p: Parameters
val outer: HasPeripheryPWM
val pwmout = IO(Output(Bool()))
pwmout := outer.pwm.module.io.pwmout
}
.. literalinclude:: ../../generators/example/src/main/scala/PWM.scala
:language: scala
:start-after: DOC include start: HasPeripheryPWMTLModuleImp
:end-before: DOC include end: HasPeripheryPWMTLModuleImp
Now we want to mix our traits into the system as a whole.
This code is from ``generators/example/src/main/scala/Top.scala``.
.. code-block:: scala
class ExampleTopWithPWM(q: Parameters) extends ExampleTop(q)
with PeripheryPWM {
override lazy val module = Module(
new ExampleTopWithPWMModule(p, this))
}
class ExampleTopWithPWMModule(l: ExampleTopWithPWM)
extends ExampleTopModule(l) with HasPeripheryPWMModuleImp
.. literalinclude:: ../../generators/example/src/main/scala/Top.scala
:language: scala
:start-after: DOC include start: TopWithPWMTL
:end-before: DOC include end: TopWithPWMTL
Just as we need separate traits for ``LazyModule`` and module implementation, we need two classes to build the system.
The ``ExampleTop`` classes already have the basic peripherals included for us, so we will just extend those.
The ``Top`` classes already have the basic peripherals included for us, so we will just extend those.
The ``ExampleTop`` class includes the pre-elaboration code and also a ``lazy val`` to produce the module implementation (hence ``LazyModule``).
The ``ExampleTopModule`` class is the actual RTL that gets synthesized.
The ``Top`` class includes the pre-elaboration code and also a ``lazy val`` to produce the module implementation (hence ``LazyModule``).
The ``TopModule`` class is the actual RTL that gets synthesized.
Finally, we need to add a configuration class in ``generators/example/src/main/scala/Configs.scala`` that tells the ``TestHarness`` to instantiate ``ExampleTopWithPWM`` instead of the default ``ExampleTop``.
Next, we need to add a configuration mixin in ``generators/example/src/main/scala/ConfigMixins.scala`` that tells the ``TestHarness`` to instantiate ``TopWithPWMTL`` instead of the default ``Top``.
.. code-block:: scala
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
:language: scala
:start-after: DOC include start: WithPWMTop
:end-before: DOC include end: WithPWMTop
class WithPWM extends Config((site, here, up) => {
case BuildTop => (p: Parameters) =>
Module(LazyModule(new ExampleTopWithPWM()(p)).module)
})
class PWMConfig extends Config(new WithPWM ++ new BaseExampleConfig)
And finally, we create a configuration class in ``generators/example/src/main/scala/Configs.scala`` that uses this mixin.
.. literalinclude:: ../../generators/example/src/main/scala/RocketConfigs.scala
:language: scala
:start-after: DOC include start: PWMRocketConfig
:end-before: DOC include end: PWMRocketConfig
Now we can test that the PWM is working. The test program is in ``tests/pwm.c``.
.. code-block:: c
#define PWM_PERIOD 0x2000
#define PWM_DUTY 0x2008
#define PWM_ENABLE 0x2010
static inline void write_reg(unsigned long addr, unsigned long data)
{
volatile unsigned long *ptr = (volatile unsigned long *) addr;
*ptr = data;
}
static inline unsigned long read_reg(unsigned long addr)
{
volatile unsigned long *ptr = (volatile unsigned long *) addr;
return *ptr;
}
int main(void)
{
write_reg(PWM_PERIOD, 20);
write_reg(PWM_DUTY, 5);
write_reg(PWM_ENABLE, 1);
}
.. literalinclude:: ../../tests/pwm.c
:language: c
This just writes out to the registers we defined earlier.
The base of the module's MMIO region is at 0x2000.
@@ -235,9 +155,9 @@ Now with all of that done, we can go ahead and run our simulation.
.. code-block:: shell
cd verilator
make CONFIG=PWMConfig
./simulator-example-PWMConfig ../tests/pwm.riscv
cd sims/verilator
make CONFIG=PWMRocketConfig TOP=TopWithPWMTL
./simulator-example-PWMRocketConfig ../../tests/pwm.riscv
Adding a RoCC Accelerator
----------------------------
@@ -302,47 +222,40 @@ For instance, if we wanted to add the previously defined accelerator and route c
})
class CustomAcceleratorConfig extends Config(
new WithCustomAccelerator ++ new DefaultExampleConfig)
new WithCustomAccelerator ++ new RocketConfig)
To add RoCC instructions in your program, use the RoCC C macros provided in ``tests/rocc.h``. You can find examples in the files ``tests/accum.c`` and ``charcount.c``.
Adding a DMA port
-------------------
IO devices or accelerators (like a disk or network driver), we may want to have the device write directly to the coherent memory system instead.
To add a device like that, you would do the following.
For IO devices or accelerators (like a disk or network driver), instead of
having the CPU poll data from the device, we may want to have the device write
directly to the coherent memory system instead. For example, here is a device
that writes zeros to the memory at a configured address.
.. code-block:: scala
.. literalinclude:: ../../generators/example/src/main/scala/InitZero.scala
:language: scala
class DMADevice(implicit p: Parameters) extends LazyModule {
val node = TLClientNode(TLClientParameters(
name = "dma-device", sourceId = IdRange(0, 1)))
.. literalinclude:: ../../generators/example/src/main/scala/Top.scala
:language: scala
:start-after: DOC include start: TopWithInitZero
:end-before: DOC include end: TopWithInitZero
lazy val module = new DMADeviceModule(this)
}
We use ``TLHelper.makeClientNode`` to create a TileLink client node for us.
We then connect the client node to the memory system through the front bus (fbus).
For more info on creating TileLink client nodes, take a look at :ref:`Client Node`.
class DMADeviceModule(outer: DMADevice) extends LazyModuleImp(outer) {
val io = IO(new Bundle {
val mem = outer.node.bundleOut
val ext = new ExtBundle
})
Once we've created our top-level module including the DMA widget, we can create a configuration for it as we did before.
// ... rest of the code ...
}
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
:language: scala
:start-after: DOC include start: WithInitZero
:end-before: DOC include end: WithInitZero
trait HasPeripheryDMA extends HasSystemNetworks {
implicit val p: Parameters
val dma = LazyModule(new DMADevice)
fsb.node := dma.node
}
trait HasPeripheryDMAModuleImp extends LazyMultiIOModuleImp {
val ext = IO(new ExtBundle)
ext <> outer.dma.module.io.ext
}
.. literalinclude:: ../../generators/example/src/main/scala/RocketConfigs.scala
:language: scala
:start-after: DOC include start: InitZeroRocketConfig
:end-before: DOC include end: InitZeroRocketConfig
The ``ExtBundle`` contains the signals we connect off-chip that we get data from.
The DMADevice also has a Tilelink client port that we connect into the L1-L2 crossbar through the front-side buffer (fsb).
The sourceId variable given in the ``TLClientNode`` instantiation determines the range of ids that can be used in acquire messages from this device.
Since we specified [0, 1) as our range, only the ID 0 can be used.

View File

@@ -0,0 +1,79 @@
Chipyard Boot Process
=======================
This section will describe in detail the process by which a Chipyard-based
SoC boots a Linux kernel and the changes you can make to customize this process.
BootROM and RISC-V Frontend Server
----------------------------------
The BootROM contains both the first instructions to run when the SoC is powered on as well as the
Device Tree Binary (dtb) which details the components of the system.
The assembly for the BootROM code is located in
`generators/testchipip/src/main/resources/testchipip/bootrom/bootrom.S <https://github.com/ucb-bar/testchipip/blob/master/src/main/resources/testchipip/bootrom/bootrom.S>`_.
The BootROM address space starts at ``0x10000`` (determined by the ``BootROMParams`` key in the configuration) and execution starts at address
``0x10040`` (given by the linker script and reset vector in the ``BootROMParams``), which is marked by the ``_hang`` label in the BootROM assembly.
The Chisel generator encodes the assembled instructions into the BootROM
hardware at elaboration time, so if you want to change the BootROM code, you
will need to run ``make`` in the bootrom directory and then regenerate the
verilog. If you don't want to overwrite the existing ``bootrom.S``, you can
also point the generator to a different bootrom image by overriding the
``BootROMParams`` key in the configuration.
.. code-block:: scala
class WithMyBootROM extends Config((site, here, up) => {
case BootROMParams =>
BootROMParams(contentFileName = "/path/to/your/bootrom.img")
})
The default bootloader simply loops on a wait-for-interrupt (WFI) instruction
as the RISC-V frontend-server (FESVR) loads the actual program.
FESVR is a program that runs on the host CPU and can read/write arbitrary
parts of the target system memory using the Tethered Serial Interface (TSI).
FESVR uses TSI to load a baremetal executable or second-stage bootloader into
the SoC memory. In :ref:`Software RTL Simulation`, this will be the binary you
pass to the simulator. Once it is finished loading the program, FESVR will
write to the software interrupt register for CPU 0, which will bring CPU 0
out of its WFI loop. Once it receives the interrupt, CPU 0 will write to
the software interrupt registers for the other CPUs in the system and then
jump to the beginning of DRAM to execute the first instruction of the loaded
executable. The other CPUs will be woken up by the first CPU and also jump
to the beginning of DRAM.
The executable loaded by FESVR should have memory locations designated
as *tohost* and *fromhost*. FESVR uses these memory locations to communicate
with the executable once it is running. The executable uses *tohost* to send
commands to FESVR for things like printing to the console,
proxying system calls, and shutting down the SoC. The *fromhost* register is
used to send back responses for *tohost* commands and for sending console
input.
The Berkeley Boot Loader and RISC-V Linux
-----------------------------------------
For baremetal programs, the story ends here. The loaded executable will run in
machine mode until it sends a command through the *tohost* register telling the
FESVR to power off the SoC.
However, for booting the Linux Kernel, you will need to use a second-stage
bootloader called the Berkeley Boot Loader, or BBL. This program reads the
device tree encoded in the boot ROM and transforms it into a format compatible
with the Linux kernel. It then sets up virtual memory and the interrupt
controller, loads the kernel, which is embedded in the bootloader binary as a
payload, and starts executing the kernel in supervisor mode. The bootloader is
also responsible for servicing machine-mode traps from the kernel and
proxying them over FESVR.
Once BBL jumps into supervisor mode, the Linux kernel takes over and begins
its process. It eventually loads the ``init`` program and runs it in user
mode, thus starting userspace execution.
The easiest way to build a BBL image that boots Linux is to use the FireMarshal
tool that lives in the `firesim-software <https://github.com/firesim/firesim-software>`_
repository. Directions on how to use FireMarshal can be found in the
`FireSim documentation <https://docs.fires.im/en/latest/Advanced-Usage/FireMarshal/index.html>`_.
Using FireMarshal, you can add custom kernel configurations and userspace software
to your workload.

View File

@@ -8,30 +8,23 @@ 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.
Both BOOM and Rocket have mixins labelled ``WithNBoomCores(X)`` and ``WithNBigCores(X)`` that automatically create ``X`` copies of the core/tile [1]_.
When used together you can create a heterogeneous system.
The following example shows a dual core BOOM with a single core Rocket.
.. 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)
.. literalinclude:: ../../generators/example/src/main/scala/HeteroConfigs.scala
:language: scala
:start-after: DOC include start: DualBoomAndRocket
:end-before: DOC include end: DualBoomAndRocket
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.
However, for BOOM, an extra mixin called ``LargeBoomConfig`` 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 ``WithRenumberHarts`` mixin solves this by assigning a unique ``hartId`` to all cores in the system (it can label the Rocket cores first or the BOOM cores first).
The reason this is needed is because by default the ``WithN...Cores(X)`` 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``.
@@ -62,7 +55,7 @@ Then you could use this new mixin like the following.
.. code-block:: scala
class SixCoreConfig extends Config(
new WithNormalBoomRocketTop ++
new WithTop ++
new WithBootROM ++
new WithHeterCoresSetup ++
new freechips.rocketchip.system.BaseConfig)
@@ -75,19 +68,10 @@ 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)
.. literalinclude:: ../../generators/example/src/main/scala/HeteroConfigs.scala
:language: scala
:start-after: DOC include start: BoomAndRocketWithHwacha
:end-before: DOC include end: BoomAndRocketWithHwacha
In this example, Hwachas are added to both BOOM tiles and to the Rocket tile.
All with the same Hwacha parameters.
@@ -100,27 +84,20 @@ Named ``MultiRoCCKey``, this key allows you to attach RoCC accelerators based on
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)
.. literalinclude:: ../../generators/example/src/main/scala/HeteroConfigs.scala
:language: scala
:start-after: DOC include start: DualBoomAndRocketOneHwacha
:end-before: DOC include end: DualBoomAndRocketOneHwacha
In this example, the ``WithRenumberHarts`` relabels the ``hartId``'s of all the BOOM/Rocket cores.
Then after that is applied to the parameters, the ``WithMultiRoCCHwacha(0)`` is used to assign to ``hartId`` zero a Hwacha (in this case ``hartId`` zero is Rocket).
Then after that is applied to the parameters, the ``WithMultiRoCCHwacha`` mixin assigns a Hwacha accelerator to a particular ``hartId`` (in this case, the ``hartId`` of ``2`` corresponds to the Rocket core).
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,...)``).
.. [1] Note, in this section "core" and "tile" are used interchangeably but there is subtle distinction between a "core" and "tile" ("tile" contains a "core", L1D/I$, PTW).
For many places in the documentation, we usually use "core" to mean "tile" (doesn't make a large difference but worth the mention).

View File

@@ -1,4 +1,131 @@
.. _memory-hierarchy:
Memory Hierarchy
===============================
TODO: Talk about SiFive Cache, and integration with L1 and backing main memory models
(maybe even Tilelink)
The L1 Caches
--------------
Each CPU tile has an L1 instruction cache and L1 data cache. The size and
associativity of these caches can be configured. The default ``RocketConfig``
uses 16 KiB, 4-way set-associative instruction and data caches. However,
if you use the ``NMediumCores`` or ``NSmallCores`` configurations, you can
configure 4 KiB direct-mapped caches for L1I and L1D.
.. code-block:: scala
import freechips.rocketchip.subsystem.{WithNMediumCores, WithNSmallCores}
class SmallRocketConfig extends Config(
new WithNSmallCores(1) ++
new RocketConfig)
class MediumRocketConfig extends Config(
new WithNMediumCores(1) ++
new RocketConfig)
If you only want to change the size or associativity, there are configuration
mixins for those too.
.. code-block:: scala
import freechips.rocketchip.subsystem.{WithL1ICacheSets, WithL1DCacheSets, WithL1ICacheWays, WithL1DCacheWays}
class MyL1RocketConfig extends Config(
new WithL1ICacheSets(128) ++
new WithL1ICacheWays(2) ++
new WithL1DCacheSets(128) ++
new WithL1DCacheWays(2) ++
new RocketConfig)
You can also configure the L1 data cache as an data scratchpad instead.
However, there are some limitations on this. If you are using a data scratchpad,
you can only use a single core and you cannot give the design an external DRAM.
.. code-block:: scala
import freechips.rocketchip.subsystem.{WithNoMemPort, WithScratchpadsOnly}
class ScratchpadRocketConfig extends Config(
new WithNoMemPort ++
new WithScratchpadsOnly ++
new SmallRocketConfig)
The SiFive L2 Cache
-------------------
The default RocketConfig provided in the Chipyard example project uses SiFive's
InclusiveCache generator to produce a shared L2 cache. In the default
configuration, the L2 uses a single cache bank with 512 KiB capacity and 8-way
set-associativity. However, you can change these parameters to obtain your
desired cache configuration. The main restriction is that the number of ways
and the number of banks must be powers of 2.
.. code-block:: scala
import freechips.rocketchip.subsystem.WithInclusiveCache
# Create an SoC with 1 MB, 4-way, 4-bank cache
class MyCacheRocketConfig extends Config(
new WithInclusiveCache(
capacityKB = 1024,
nWays = 4,
nBanks = 4) ++
new RocketConfig)
The Broadcast Hub
-----------------
If you do not want to use the L2 cache (say, for a resource-limited embedded
design), you can create a configuration without it. Instead of using the L2
cache, you will instead use RocketChip's TileLink broadcast hub.
To make such a configuration, you can just copy the definition of
``RocketConfig`` but omit the ``WithInclusiveCache`` mixin from the
list of included mixims.
.. code-block:: scala
import freechips.rocketchip.subsystem.{WithNBigCores, BaseConfig}
class CachelessRocketConfig extends Config(
new WithTop ++
new WithBootROM ++
new WithNBigCores(1) ++
new BaseConfig)
If you want to reduce the resources used even further, you can configure
the Broadcast Hub to use a bufferless design.
.. code-block:: scala
import freechips.rocketchip.subsystem.WithBufferlessBroadcastHub
class BufferlessRocketConfig extends Config(
new WithBufferlessBroadcastHub ++
new CachelessRocketConfig)
The Outer Memory System
-----------------------
The L2 coherence agent (either L2 cache or Broadcast Hub) makes requests to
an outer memory system consisting of an AXI4-compatible DRAM controller.
The default configuration uses a single memory channel, but you can configure
the system to use multiple channels. As with the number of L2 banks, the
number of DRAM channels is restricted to powers of two.
.. code-block:: scala
import freechips.rocketchip.subsystem.WithNMemoryChannels
class DualChannelRocketConfig extends Config(
new WithNMemoryChannels(2) ++
new RocketConfig)
In VCS and Verilator simulation, the DRAM is simulated using the
``SimAXIMem`` module, which simply attaches a single-cycle SRAM to each
memory channel.
If you want a more realistic memory simulation, you can use FireSim, which
can simulate the timing of DDR3 controllers. More documentation on FireSim
memory models is available in the `FireSim docs <https://docs.fires.im/en/latest/>`_.

View File

@@ -16,3 +16,4 @@ Hit next to get started!
Heterogeneous-SoCs
Adding-An-Accelerator
Memory-Hierarchy
Boot-Process

View File

@@ -2,7 +2,7 @@ Berkeley Out-of-Order Machine (BOOM)
==============================================
The `Berkeley Out-of-Order Machine (BOOM) <https://boom-core.org/>`__ is a synthesizable and parameterizable open source RV64GC RISC-V core written in the Chisel hardware construction language.
It serves as a drop-in replacement to the Rocket core given by Rocket Chip.
It serves as a drop-in replacement to the Rocket core given by Rocket Chip (replaces the RocketTile with a BoomTile).
BOOM is heavily inspired by the MIPS R10k and the Alpha 21264 out-of-order processors.
Like the R10k and the 21264, BOOM is a unified physical register file design (also known as “explicit register renaming”).
Conceptually, BOOM is broken up into 10 stages: Fetch, Decode, Register Rename, Dispatch, Issue, Register Read, Execute, Memory, Writeback and Commit.

View File

@@ -2,7 +2,14 @@ Hwacha
====================================
The Hwacha project is developing a new vector architecture for future computer systems that are constrained in their power and energy consumption.
Inspired by traditional vector machines from the 70s and 80s, and lessons learned from our previous vector-thread architectures Scale and Maven, we are bringing back elegant, performant, and energy-efficient aspects of vector processing to modern data-parallel architectures.
We propose a new vector-fetch architectural paradigm, which focuses on the following aspects for higher performance, better energy efficiency, and lower complexity.
The Hwacha project is inspired by traditional vector machines from the 70s and 80s, and lessons learned from our previous vector-thread architectures such as Scale and Maven
The Hwacha project includes the Hwacha microarchitecture generator, as well as the ``XHwacha`` non-standard RISC-V extension. Hwacha does not implement the RISC-V standard vector extension proposal.
For more information, please visit the `Hwacha website <http://hwacha.org/>`__.
For more information on the Hwacha project, please visit the `Hwacha website <http://hwacha.org/>`__.
To add the Hwacha vector unit to an SoC, you should add the ``hwacha.DefaultHwachaConfig`` config mixin to the SoC configurations. The Hwacha vector unit uses the RoCC port of a Rocket or BOOM `tile`, and by default connects to the memory system through the `System Bus` (i.e., directly to the L2 cache).
To change the configuration of the Hwacha vector unit, you can write a custom configuration to replace the ``DefaultHwachaConfig``. You can view the ``DefaultHwachaConfig`` under `generators/hwacha/src/main/scala/configs.scala <https://github.com/ucb-bar/hwacha/blob/master/src/main/scala/configs.scala>`__ to see the possible configuration parameters.
Since Hwacha implements a non-standard RISC-V extension, it requires a unique software toolchain to be able to compile and asseble its vector instructions.
To install the Hwacha toolchain, run the ``./scripts/build-toolchains.sh esp-tools`` command within the root Chipyard directory. This may take a while, and it will install the ``esp-tools-install`` directory within your Chipyard root directory. ``esp-tools`` is a fork of ``riscv-tools`` (formerly a collection of relevant software RISC-V tools) that was enhanced with additional non-standard vector instructions. However, due to the upstreaming of the equivalent RISC-V toolchains, ``esp-tools`` may not be up-to-date with the latest mainline version of the tools included in it.

View File

@@ -0,0 +1,72 @@
Rocket Chip
===========
Rocket Chip generator is an SoC generator developed at Berkeley and now supported by
SiFive. Chipyard uses the Rocket Chip generator as the basis for producing a RISC-V SoC.
`Rocket Chip` is distinct from `Rocket core`, the in-order RISC-V CPU generator.
Rocket Chip includes many parts of the SoC besides the CPU. Though Rocket Chip
uses Rocket core CPUs by default, it can also be configured to use the BOOM
out-of-order core generator or some other custom CPU generator instead.
A detailed diagram of a typical Rocket Chip system is shown below.
.. image:: ../_static/images/rocketchip-diagram.png
Tiles
-----
The diagram shows a dual-core ``Rocket`` system. Each ``Rocket`` core is
grouped with a page-table walker, L1 instruction cache, and L1 data cache into
a ``RocketTile``.
The ``Rocket`` core can also be swapped for a ``BOOM`` core. Each tile can
also be configured with a RoCC accelerator that connects to the core as a
coprocessor.
Memory System
-------------
The tiles connect to the ``SystemBus``, which connect it to the L2 cache banks.
The L2 cache banks then connect to the ``MemoryBus``, which connects to the
DRAM controller through a TileLink to AXI converter.
To learn more about the memory hierarchy, see :ref:`Memory Hierarchy`.
MMIO
----
For MMIO peripherals, the ``SystemBus`` connects to the ``ControlBus`` and ``PeripheryBus``.
The ``ControlBus`` attaches standard peripherals like the BootROM, the
Platform-Level Interrupt Controller (PLIC), the core-local interrupts (CLINT),
and the Debug Unit.
The BootROM contains the first stage bootloader, the first instructions to run
when the system comes out of reset. It also contains the Device Tree, which is
used by Linux to determine what other peripherals are attached.
The PLIC aggregates and masks device interrupts and external interrupts.
The core-local interrupts include software interrupts and timer interrupts for
each CPU.
The Debug Unit is used to control the chip externally. It can be used to load
data and instructions to memory or pull data from memory. It can be controlled
through a custom DMI or standard JTAG protocol.
The ``PeripheryBus`` attaches additional peripherals like the NIC and Block Device.
It can also optionally expose an external AXI4 port, which can be attached to
vendor-supplied AXI4 IP.
To learn more about adding MMIO peripherals, check out the :ref:`MMIO Peripheral`
section of :ref:`Adding an Accelerator/Device`.
DMA
---
You can also add DMA devices that read and write directly from the memory
system. These are attached to the ``FrontendBus``. The ``FrontendBus`` can also
connect vendor-supplied AXI4 DMA devices through an AXI4 to TileLink converter.
To learn more about adding DMA devices, see the :ref:`Adding a DMA port` section
of :ref:`Adding an Accelerator/Device`.

View File

@@ -1,8 +1,9 @@
Rocket
Rocket Core
====================================
`Rocket <https://github.com/freechipsproject/rocket-chip>`__ is a 5-stage in-order scalar core generator that is supported by `SiFive <https://www.sifive.com/>`__.
It supports the open source RV64GC RISC-V instruction set and is written in the Chisel hardware construction language.
`Rocket <https://github.com/freechipsproject/rocket-chip>`__ is a 5-stage in-order scalar processor core generator, originally developed at UC Berkeley and currently supported by `SiFive <https://www.sifive.com/>`__. The `Rocket core` is used as a component within the `Rocket Chip SoC generator`. A Rocket core combined with L1 caches (data and instruction caches) form a `Rocket tile`. The `Rocket tile` is the replicable component of the `Rocket Chip SoC generator`.
The Rocket core supports the open-source RV64GC RISC-V instruction set and is written in the Chisel hardware construction language.
It has an MMU that supports page-based virtual memory, a non-blocking data cache, and a front-end with branch prediction.
Branch prediction is configurable and provided by a branch target buffer (BTB), branch history table (BHT), and a return address stack (RAS).
For floating-point, Rocket makes use of Berkeleys Chisel implementations of floating-point units.

80
docs/Generators/SHA3.rst Normal file
View File

@@ -0,0 +1,80 @@
SHA3 RoCC Accelerator
===================================
The SHA3 accelerator is a basic RoCC accelerator for the SHA3 hashing algorithm.
We like using SHA3 in Chipyard tutorial content because it is a self-contained, simple
example of integrating a custom accelerator into Chipyard.
Introduction
-----------------------------------
Secure hashing algorithms represent a class of hashing functions that provide four attributes: ease
of hash computation, inability to generate the message from the hash (one-way property), inability
to change the message and not the hash (weakly collision free property), and inability to find
two messages with the same hash (strongly collision free property). The National Institute of
Standards and Technology (NIST) recently held a competition for a new algorithm to be added to
its set of Secure Hashing Algorithms (SHA). In 2012 the winner was determined to be the Keccak
hashing function and a rough specification for SHA3 was established. The algorithm operates on
variable length messages with a sponge function, and thus alternates between absorbing chunks of
the message into a set of state bits and permuting the state. The absorbing is a simple bitwise
XOR while the permutation is a more complex function composed of several operations, χ, θ, ρ,
π, ι, that all perform various bitwise operations, including rotations, parity calculations, XORs,
etc. The Keccak hashing function is parameterized for different sizes of state and message chunks
but for this accelerator we will only support the Keccak-256 variant with 1600 bits of state and
1088 bit message chunks. A diagram of the SHA3 accelerator is shown below.
.. image:: ../_static/images/sha3.png
Technical Details
------------------------------------
The accelerator is designed around three sub-systems, an
interface with the processor, an interface with memory, and
the actual hashing computation system. The interface
with the processor is designed using the ROCC interface for
coprocessors integrating with the RISC-V Rocket/BOOM
processor. It includes the ability to transfer two 64 bit
words to the co-processor, the request for a return value,
and a small field for the function requested. The accelerator
receives these requests using a ready/valid interface. The
ROCC instruction is parsed and the needed information is
stored into a execution context. The execution context contains
the memory address of the message being hashed, the memory address
to store the resulting hash in, the length of the message, and
several other control fields.
Once the execution context is valid the memory subsystem
then begins to fetch chunks of the message. The memory
subsystem is fully decoupled from the other subsystems
and maintains a single full round memory buffers.
The accelerators memory interface can provide a
maximum of one 64 bit word per cycle which corresponds
to 17 requests needed to fill a buffer (the size is dictated by
the SHA3 algorithm). Memory requests to fill these buffers
are sent out as rapidly as the memory interface can handle,
with a tag field set to allow the different memory buffers
requests to be distinguished, as they may be returned out of
order. Once the memory subsystem has filled a buffer the
control unit absorbs the buffer into the execution
context, at which point the execution context is free to
begin permutation, and the memory buffer is free to send
more memory requests.
After the buffer is absorbed, the hashing computation
subsystem begins the permutation operations. Once
the message is fully hashed, the hash is written to memory
with a simple state machine.
Using a SHA3 Accelerator
------------------------
Since the SHA3 accelerator is designed as a RoCC accelerator,
it can be mixed into a Rocket or BOOM core by overriding the
BuildRoCC key. The configuration mixin is defined in the SHA3
generator. An example configuration highlighting the use of
this mixin is shown here:
.. literalinclude:: ../../generators/example/src/main/scala/RocketConfigs.scala
:language: scala
:start-after: DOC include start: Sha3Rocket
:end-before: DOC include end: Sha3Rocket

View File

@@ -0,0 +1,45 @@
SiFive Generators
==================
Chipyard includes several open-source generators developed and maintained by `SiFive <https://www.sifive.com/>`__.
These are currently organized within two submodules named ``sifive-blocks`` and ``sifive-cache``.
Last-Level Cache Generator
-----------------------------
``sifive-cache`` includes last-level cache geneator. The Chipyard framework uses this last-level cache as an L2 cache. To use this L2 cache, you should add the ``freechips.rocketchip.subsystem.WithInclusiveCache`` mixin to your SoC configuration.
To learn more about configuring this L2 cache, please refer to the :ref:`memory-hierarchy` section.
Peripheral Devices
-------------------
``sifive-blocks`` includes multiple peripheral device generators, such as UART, SPI, PWM, JTAG, GPIO and more.
These peripheral devices usually affect the memory map of the SoC, and its top-level IO as well.
To integrate one of these devices in your SoC, you will need to define a custom mixin with the approriate address for the device using the Rocket Chip parameter system. As an example, for a GPIO device you could add the following mixin to set the GPIO address to ``0x10012000``. This address is the start address for the GPIO configuration registers.
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
:language: scala
:start-after: DOC include start: WithGPIO
:end-before: DOC include end: WithGPIO
Additionally, if the device requires top-level IOs, you will need to define a mixin to change the top-level configuration of your SoC.
When adding a top-level IO, you should also be aware of whether it interacts with the test-harness.
For example, a GPIO device would require a GPIO pin, and therefore we would write a mixin to augment the top level as follows:
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
:language: scala
:start-after: DOC include start: WithGPIOTop
:end-before: DOC include end: WithGPIOTop
This example instantiates a top-level module with include GPIO ports (``TopWithGPIO``), and then ties-off the GPIO port inputs to 0 (``false.B``).
Finally, you add the relevant config mixin to the SoC config. For example:
.. literalinclude:: ../../generators/example/src/main/scala/RocketConfigs.scala
:language: scala
:start-after: DOC include start: GPIORocketConfig
:end-before: DOC include end: GPIORocketConfig
Some of the devices in ``sifive-blocks`` (such as GPIO) may already have pre-defined mixins within the Chipyard example project. You may be able to use these config mixins directly, but you should be aware of their addresses within the SoC address map.

View File

@@ -18,7 +18,9 @@ so changes to the generators themselves will automatically be used when building
:maxdepth: 2
:caption: Generators:
Rocket-Chip
Rocket
BOOM
Hwacha
SiFive-Generators
SHA3

View File

@@ -39,18 +39,18 @@ What's Next?
This depends on what you are planning to do with Chipyard.
* To learn about the structure of Chipyard, see :ref:`chipyard-components`.
* 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.
* To build one of the vanilla Chipyard examples, see :ref:`build-a-chip`.
* If you intend to run a simulation of a custom Chipyard SoC Configuration, go to :ref:`sw-sim-custom` and follow the instructions.
* To add a new accelerator, see :ref:`adding-an-accelerator`.
* If you intend to run a full-system FireSim simulation, go to :ref:`firesim-sim-intro` and follow the instructions.
* To run a simulation of one of the Chipyard examples, see :ref:`sw-rtl-sim-intro`.
* If you intend to add a new accelerator, go to :ref:`adding-an-accelerator` and follow the instructions.
* To run a simulation of a custom Chipyard SoC Configuration, see <>.
* If you want to learn about the structure of Chipyard, go to :ref:`chipyard-components`.
* To run a FPGA-accelerated simulation using FireSim, see :ref:`firesim-sim-intro`.
* If you intend to build one of the vanilla Chipyard examples, go to :ref:`build-a-chip` and follow the instructions.
* To run a VLSI flow using one of the vanilla Chipyard examples, see <>.
* If you intend to run a VLSI flow using one of the vanilla Chipyard examples, go to <> and follow the instructions.
* To change the generators (BOOM, Rocket, &c) themselves, see :ref:`generator-index`.
* If you intend to change the generators (BOOM, Rocket, etc) themselves, see :ref:`generator-index`.

View File

@@ -9,7 +9,7 @@ Software RTL Simulation
------------------------
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`.
For more information on either of these simulators, please refer to :ref:`Verilator (Open-Source)` or :ref:`Synopsys VCS (License Required)`.
The following instructions assume at least one of these simulators is installed.
Verilator/VCS Flows
@@ -39,13 +39,21 @@ In order to construct the simulator with our custom design, we run the following
make SBT_PROJECT=... MODEL=... VLOG_MODEL=... MODEL_PACKAGE=... CONFIG=... CONFIG_PACKAGE=... GENERATOR_PACKAGE=... TB=... TOP=...
Each of these make variables correspond to a particular part of the design/codebase and are needed so that the make system can correctly build and make a RTL simulation.
The ``SBT_PROJECT`` is the ``build.sbt`` project that holds all of the source files and that will be run during the RTL build.
The ``MODEL`` and ``VLOG_MODEL`` are the top-level class names of the design.
Normally, these are the same, but in some cases these can differ (if the Chisel class differs than what is emitted in the Verilog).
The ``MODEL_PACKAGE`` is the Scala package (in the Scala code that says ``package ...``) that holds the ``MODEL`` class.
The ``CONFIG`` is the name of the class used for the parameter Config while the ``CONFIG_PACKAGE`` is the Scala package it resides in.
The ``GENERATOR_PACKAGE`` is the Scala package that holds the Generator class that elaborates the design.
The ``TB`` is the name of the Verilog wrapper that connects the ``TestHarness`` to VCS/Verilator for simulation.
Finally, the ``TOP`` variable is used to distinguish between the top-level of the design and the ``TestHarness`` in our system.
For example, in the normal case, the ``MODEL`` variable specifies the ``TestHarness`` as the top-level of the design.
However, the true top-level design, the SoC being simulated, is pointed to by the ``TOP`` variable.
@@ -58,12 +66,6 @@ Therefore, in order to simulate a simple Rocket-based example system we can use:
make SUB_PROJECT=example
Alternatively, if we would like to simulate a simple BOOM-based example system we can use:
.. code-block:: shell
make SUB_PROJECT=exampleboom
Once the simulator has been constructed, we would like to run RISC-V programs on it.
In the simulation directory, we will find an executable file called ``<...>-<package>-<config>``.
We run this executable with our target RISC-V program as a command line argument in one of two ways.

View File

@@ -0,0 +1,139 @@
.. _sw-rtl-sim-intro:
Software RTL Simulation
===================================
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.
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 VCS simulation, make sure that the VCS simulator is on your ``PATH``.
Choice of Simulator
-------------------------------
First, we will start by entering the Verilator or VCS directory:
For an open-source Verilator simulation, enter the ``sims/verilator`` directory
.. code-block:: shell
# Enter Verilator directory
cd sims/verilator
For a proprietry VCS simulation, enter the ``sims/vcs`` directory
.. code-block:: shell
# Enter VCS directory
cd sims/vcs
.. _sim-default:
Simulating The Default Example
-------------------------------
To compile the example design, run ``make`` in the selected verilator or VCS directory.
This will elaborate the ``RocketConfig`` in the example project.
An executable called ``simulator-example-RocketConfig`` 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-RocketConfig $RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-simple
.. Note:: in a VCS simulator, the simulator name will be ``simv-example-RocketConfig`` ``instead of simulator-example-RocketConfig``.
Alternatively, we can run a pre-packaged suite of RISC-V assembly or benchmark tests, by adding the make target ``run-asm-tests`` or ``run-bmark-tests``.
For example:
.. code-block:: shell
make run-asm-tests
make run-bmark-tests
.. Note:: Before running the pre-packaged suites, you must run the plain ``make`` command, since the elaboration command generates a Makefile fragment that contains the target for the pre-packaged test suites. Otherwise, you will likely encounter a Makefile target error.
.. _sw-sim-custom:
Simulating A Custom Project
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you later create your own project, you can use environment variables to build an alternate configuration.
In order to construct the simulator with our custom design, we run the following command within the simulator directory:
.. code-block:: shell
make SBT_PROJECT=... MODEL=... VLOG_MODEL=... MODEL_PACKAGE=... CONFIG=... CONFIG_PACKAGE=... GENERATOR_PACKAGE=... TB=... TOP=...
Each of these make variables correspond to a particular part of the design/codebase and are needed so that the make system can correctly build and make a RTL simulation.
The ``SBT_PROJECT`` is the ``build.sbt`` project that holds all of the source files and that will be run during the RTL build.
The ``MODEL`` and ``VLOG_MODEL`` are the top-level class names of the design.
Normally, these are the same, but in some cases these can differ (if the Chisel class differs than what is emitted in the Verilog).
The ``MODEL_PACKAGE`` is the Scala package (in the Scala code that says ``package ...``) that holds the ``MODEL`` class.
The ``CONFIG`` is the name of the class used for the parameter Config while the ``CONFIG_PACKAGE`` is the Scala package it resides in.
The ``GENERATOR_PACKAGE`` is the Scala package that holds the Generator class that elaborates the design.
The ``TB`` is the name of the Verilog wrapper that connects the ``TestHarness`` to VCS/Verilator for simulation.
Finally, the ``TOP`` variable is used to distinguish between the top-level of the design and the ``TestHarness`` in our system.
For example, in the normal case, the ``MODEL`` variable specifies the ``TestHarness`` as the top-level of the design.
However, the true top-level design, the SoC being simulated, is pointed to by the ``TOP`` variable.
This separation allows the infrastructure to separate files based on the harness or the SoC top level.
Common configurations of all these variables are packaged using a ``SUB_PROJECT`` make variable.
Therefore, in order to simulate a simple Rocket-based example system we can use:
.. code-block:: shell
make SUB_PROJECT=yourproject
./simulator-<yourproject>-<yourconfig> ...
All `Make` targets that can be applied to the default example, can also be applied to custom project using the custom environment variables. For example, the following code example will run the RISC-V assembly benchmark suite on the Hwacha subproject:
.. code-block:: shell
make SUB_PROJECT=hwacha run-asm-tests
Finally, in the ``generated-src/<...>-<package>-<config>/`` directory resides all of the collateral and Verilog source files for the build/simulation.
Specifically, the SoC top-level (``TOP``) Verilog file is denoted with ``*.top.v`` while the ``TestHarness`` file is denoted with ``*.harness.v``.
Generating Waveforms
-----------------------
If you would like to extract waveforms from the simulation, run the command ``make debug`` instead of just ``make``.
For a Verilator simulation, 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/>`__.
For a VCS simulation, this will generate a vpd file (this is a proprietary waveform representation format used by Synopsys) that can be loaded to vpd-supported waveform viewers.
If you have Synopsys licenses, we recommend using the DVE waveform viewer.

View File

@@ -1,75 +0,0 @@
.. _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,4 +1,4 @@
Simulators
Simulation
=======================
Chipyard supports two classes of simulation:
@@ -12,9 +12,11 @@ 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.
Click next to see how to run a simulation.
.. toctree::
:maxdepth: 2
:caption: Simulators:
:caption: Simulation:
Software-RTL-Simulators
Software-RTL-Simulation
FPGA-Accelerated-Simulators

View File

@@ -0,0 +1,38 @@
Diplomacy Connectors
====================
Nodes in a Diplomacy graph are connected to each other with edges. The Diplomacy
library provides four operators that can be used to form edges between nodes.
:=
--
This is the basic connection operator. It is the same syntax as the Chisel
uni-directional connector, but it is not equivalent. This operator connects
Diplomacy nodes, not Chisel bundles.
The basic connection operator always creates a single edge between the two
nodes.
:=\*
----
This is a "query" type connection operator. It can create multiple edges
between nodes, with the number of edges determined by the client node
(the node on the right side of the operator). This can be useful if you
are connecting a multi-edge client to a nexus node or adapter node.
:\*=
----
This is a "star" type connection operator. It also creates multiple edges,
but the number of edges is determined by the manager (left side of operator),
rather than the client. It's useful for connecting nexus nodes to multi-edge
manager nodes.
:\*=\*
------
This is a "flex" connection operator. It creates multiple edges based on
whichever side of the operator has a known number of edges. This can be used
in generators where the type of node on either side isn't known until runtime.

View File

@@ -0,0 +1,252 @@
TileLink Edge Object Methods
============================
The edge object associated with a TileLink node has several helpful methods
for constructing TileLink messages and retrieving data from them.
Get
---
Constructor for a TLBundleA encoding a ``Get`` message, which requests data
from memory. The D channel response to this message will be an
``AccessAckData``, which may have multiple beats.
**Arguments:**
- ``fromSource: UInt`` - Source ID for this transaction
- ``toAddress: UInt`` - The address to read from
- ``lgSize: UInt`` - Base two logarithm of the number of bytes to be read
**Returns:**
A ``(Bool, TLBundleA)`` tuple. The first item in the pair is a boolean
indicating whether or not the operation is legal for this edge. The second
is the A channel bundle.
Put
---
Constructor for a TLBundleA encoding a ``PutFull`` or ``PutPartial`` message,
which write data to memory. It will be a ``PutPartial`` if the ``mask`` is
specified and a ``PutFull`` if it is omitted. The put may require multiple
beats. If that is the case, only ``data`` and ``mask`` should change for each
beat. All other fields must be the same for all beats in the transaction,
including the address. The manager will respond to this message with a single
``AccessAck``.
**Arguments:**
- ``fromSource: UInt`` - Source ID for this transaction.
- ``toAddress: UInt`` - The address to write to.
- ``lgSize: UInt`` - Base two logarithm of the number of bytes to be written.
- ``data: UInt`` - The data to write on this beat.
- ``mask: UInt`` - (optional) The write mask for this beat.
**Returns:**
A ``(Bool, TLBundleA)`` tuple. The first item in the pair is a boolean
indicating whether or not the operation is legal for this edge. The second
is the A channel bundle.
Arithmetic
----------
Constructor for a TLBundleA encoding an ``Arithmetic`` message, which is an
atomic operation. The possible values for the ``atomic`` field are defined
in the ``TLAtomics`` object. It can be ``MIN``, ``MAX``, ``MINU``, ``MAXU``, or
``ADD``, which correspond to atomic minimum, maximum, unsigned minimum, unsigned
maximum, or addition operations, respectively. The previous value at the
memory location will be returned in the response, which will be in the form
of an ``AccessAckData``.
**Arguments:**
- ``fromSource: UInt`` - Source ID for this transaction.
- ``toAddress: UInt`` - The address to perform an arithmetic operation on.
- ``lgSize: UInt`` - Base two logarithm of the number of bytes to operate on.
- ``data: UInt`` - Right-hand operand of the arithmetic operation
- ``atomic: UInt`` - Arithmetic operation type (from ``TLAtomics``)
**Returns:**
A ``(Bool, TLBundleA)`` tuple. The first item in the pair is a boolean
indicating whether or not the operation is legal for this edge. The second
is the A channel bundle.
Logical
-------
Constructor for a TLBundleA encoding a ``Logical`` message, an atomic operation.
The possible values for the ``atomic`` field are ``XOR``, ``OR``, ``AND``, and
``SWAP``, which correspond to atomic bitwise exclusive or, bitwise inclusive or,
bitwise and, and swap operations, respectively. The previous value at the
memory location will be returned in an ``AccessAckData`` response.
**Arguments:**
- ``fromSource: UInt`` - Source ID for this transaction.
- ``toAddress: UInt`` - The address to perform a logical operation on.
- ``lgSize: UInt`` - Base two logarithm of the number of bytes to operate on.
- ``data: UInt`` - Right-hand operand of the logical operation
- ``atomic: UInt`` - Logical operation type (from ``TLAtomics``)
**Returns:**
A ``(Bool, TLBundleA)`` tuple. The first item in the pair is a boolean
indicating whether or not the operation is legal for this edge. The second
is the A channel bundle.
Hint
----
Constructor for a TLBundleA encoding a ``Hint`` message, which is used to
send prefetch hints to caches. The ``param`` argument determines what kind
of hint it is. The possible values come from the ``TLHints`` object and are
``PREFETCH_READ`` and ``PREFETCH_WRITE``. The first one tells caches to
acquire data in a shared state. The second one tells cache to acquire data
in an exclusive state. If the cache this message reaches is a last-level cache,
there won't be any difference. If the manager this message reaches is not a
cache, it will simply be ignored. In any case, a ``HintAck`` message will be
sent in response.
**Arguments:**
- ``fromSource: UInt`` - Source ID for this transaction.
- ``toAddress: UInt`` - The address to prefetch
- ``lgSize: UInt`` - Base two logarithm of the number of bytes to prefetch
- ``param: UInt`` - Hint type (from TLHints)
**Returns:**
A ``(Bool, TLBundleA)`` tuple. The first item in the pair is a boolean
indicating whether or not the operation is legal for this edge. The second
is the A channel bundle.
AccessAck
---------
Constructor for a TLBundleD encoding an ``AccessAck`` or ``AccessAckData``
message. If the optional ``data`` field is supplied, it will be an
``AccessAckData``. Otherwise, it will be an ``AccessAck``.
**Arguments**
- ``a: TLBundleA`` - The A channel message to acknowledge
- ``data: UInt`` - (optional) The data to send back
**Returns:**
The ``TLBundleD`` for the D channel message.
HintAck
-------
Constructor for a TLBundleD encoding a ``HintAck`` message.
**Arguments**
- ``a: TLBundleA`` - The A channel message to acknowledge
**Returns:**
The ``TLBundleD`` for the D channel message.
first
-----
This method take a decoupled channel (either the A channel or D channel)
and determines whether the current beat is the first beat in the transaction.
**Arguments:**
- ``x: DecoupledIO[TLChannel]`` - The decoupled channel to snoop on.
**Returns:**
A ``Boolean`` which is true if the current beat is the first, or false otherwise.
last
----
This method take a decoupled channel (either the A channel or D channel)
and determines whether the current beat is the last in the transaction.
**Arguments:**
- ``x: DecoupledIO[TLChannel]`` - The decoupled channel to snoop on.
**Returns:**
A ``Boolean`` which is true if the current beat is the last, or false otherwise.
done
----
Equivalent to ``x.fire() && last(x)``.
**Arguments:**
- ``x: DecoupledIO[TLChannel]`` - The decoupled channel to snoop on.
**Returns:**
A ``Boolean`` which is true if the current beat is the last and a beat is
sent on this cycle. False otherwise.
count
-----
This method take a decoupled channel (either the A channel or D channel) and
determines the count (starting from 0) of the current beat in the transaction.
**Arguments:**
- ``x: DecoupledIO[TLChannel]`` - The decoupled channel to snoop on.
**Returns:**
A ``UInt`` indicating the count of the current beat.
numBeats
---------
This method takes in a TileLink bundle and gives the number of beats expected
for the transaction.
**Arguments:**
- ``x: TLChannel`` - The TileLink bundle to get the number of beats from
**Returns:**
A ``UInt`` that is the number of beats in the current transaction.
numBeats1
---------
Similar to ``numBeats`` except it gives the number of beats minus one. If this
is what you need, you should use this instead of doing ``numBeats - 1.U``, as
this is more efficient.
**Arguments:**
- ``x: TLChannel`` - The TileLink bundle to get the number of beats from
**Returns:**
A ``UInt`` that is the number of beats in the current transaction minus one.
hasData
--------
Determines whether the TileLink message contains data or not. This is true
if the message is a PutFull, PutPartial, Arithmetic, Logical, or AccessAckData.
**Arguments:**
- ``x: TLChannel`` - The TileLink bundle to check
**Returns:**
A ``Boolean`` that is true if the current message has data and false otherwise.

View File

@@ -0,0 +1,237 @@
TileLink Node Types
===================
Diplomacy represents the different components of an SoC as nodes of a
directed acyclic graph. TileLink nodes can come in several different types.
Client Node
-----------
TileLink clients are modules that initiate TileLink transactions by sending
requests on the A channel and receive responses on the D channel. If the
client implements TL-C, it will receive probes on the B channel, send releases
on the C channel, and send grant acknowledgements on the E channel.
The L1 caches and DMA devices in RocketChip/Chipyard have client nodes.
You can add a TileLink client node to your LazyModule using the TLHelper
object from testchipip like so:
.. literalinclude:: ../../generators/example/src/main/scala/NodeTypes.scala
:language: scala
:start-after: DOC include start: MyClient
:end-before: DOC include end: MyClient
The ``name`` argument identifies the node in the Diplomacy graph. It is the
only required argument for TLClientParameters.
The ``sourceId`` argument specifies the range of source identifiers that this
client will use. Since we have set the range to [0, 4) here, this client will
be able to send up to four requests in flight at a time. Each request will
have a distinct value in its source field. The default value for this field
is ``IdRange(0, 1)``, which means it would only be able to send a single
request inflight.
The ``requestFifo`` argument is a boolean option which defaults to false.
If it is set to true, the client will request that downstream managers that
support it send responses in FIFO order (that is, in the same order the
corresponding requests were sent).
The ``visibility`` argument specifies the address ranges that the client will
access. By default it is set to include all addresses. In this example, we set
it to contain a single address range ``AddressSet(0x10000, 0xffff)``, which
means that the client will only be able to access addresses from 0x10000 to
0x1ffff. normally do not specify this, but it can help downstream crossbar
generators optimize the hardware by not arbitrating the client to managers with
address ranges that don't overlap with its visibility.
Inside your lazy module implementation, you can call ``node.out`` to get a
list of bundle/edge pairs. If you used the TLHelper, you only specified a
single client edge, so this list will only have one pair.
The ``tl`` bundle is a Chisel hardware bundle that connects to the IO of this
module. It contains two (in the case of TL-UL and TL-UH) or five (in the case
of TL-C) decoupled bundles corresponding to the TileLink channels. This is
what you should connect your hardware logic to in order to actually send/receive
TileLink messages.
The ``edge`` object represents the edge of the Diplomacy graph. It contains
some useful helper functions which will be documented in
:ref:`TileLink Edge Object Methods`.
Manager Node
------------
TileLink managers take requests from clients on the A channel and send
responses back on the D channel. You can create a manager node using the
TLHelper like so:
.. literalinclude:: ../../generators/example/src/main/scala/NodeTypes.scala
:language: scala
:start-after: DOC include start: MyManager
:end-before: DOC include end: MyManager
The ``makeManagerNode`` method takes two arguments. The first is ``beatBytes``,
which is the physical width of the TileLink interface in bytes. The second
is a TLManagerParameters object.
The only required argument for ``TLManagerParameters`` is the ``address``,
which is the set of address ranges that this manager will serve.
This information is used to route requests from the clients. In this example,
the manager will only take requests for addresses from 0x20000 to 0x20fff.
The second argument in ``AddressSet`` is a mask, not a size.
You should generally set it to be one less than a power of two. Otherwise,
the addressing behavior may not be what you expect.
The second argument is ``resources``, which is usually retrieved from a
``Device`` object. In this case, we use a ``SimpleDevice`` object.
This argument is necessary if you want to add an entry to the DeviceTree in
the BootROM so that it can be read by a Linux driver. The two arguments to
``SimpleDevice`` are the name and compatibility list for the device tree
entry. For this manager, then, the device tree entry would look like
.. code-block:: text
L12: my-device@20000 {
compatible = "tutorial,my-device0";
reg = <0x20000 0x1000>;
};
The next argument is ``regionType``, which gives some information about
the caching behavior of the manager. There are seven region types, listed below:
1. ``CACHED`` - An intermediate agent may have cached a copy of the region for you.
2. ``TRACKED`` - The region may have been cached by another master, but coherence is being provided.
3. ``UNCACHED`` - The region has not been cached yet, but should be cached when possible.
4. ``IDEMPOTENT`` - Gets return most recently put content, but content should not be cached.
5. ``VOLATILE`` - Content may change without a put, but puts and gets have no side effects.
6. ``PUT_EFFECTS`` - Puts produce side effects and so must not be combined/delayed.
7. ``GET_EFFECTS`` - Gets produce side effects and so must not be issued speculatively.
Next is the ``executable`` argument, which determines if the CPU is allowed to
fetch instructions from this manager. By default it is false, which is what
most MMIO peripherals should set it to.
The next six arguments start with ``support`` and determine the different
A channel message types that the manager can accept. The definitions of the
message types are explained in :ref:`TileLink Edge Object Methods`.
The ``TransferSizes`` case class specifies the range of logical sizes (in bytes)
that the manager can accept for the particular message type. This is an inclusive
range and all logical sizes must be powers of two. So in this case, the manager
can accept requests with sizes of 1, 2, 4, or 8 bytes.
The final argument shown here is the ``fifoId`` setting, which determines
which FIFO domain (if any) the manager is in. If this argument is set to ``None``
(the default), the manager will not guarantee any ordering of the responses.
If the ``fifoId`` is set, it will share a FIFO domain with all other managers
that specify the same ``fifoId``. This means that client requests sent to
that FIFO domain will see responses in the same order.
Register Node
-------------
While you can directly specify a manager node and write all of the logic
to handle TileLink requests, it is usually much easier to use a register node.
This type of node provides a ``regmap`` method that allows you to specify
control/status registers and automatically generates the logic to handle the
TileLink protocol. More information about how to use register nodes can be
found in :ref:`Register Router`.
Identity Node
-------------
Unlike the previous node types, which had only inputs or only outputs, the
identity node has both. As its name suggests, it simply connects the inputs
to the outputs unchanged. This node is mainly used to combine multiple
nodes into a single node with multiple edges. For instance, say we have two
client lazy modules, each with their own client node.
.. literalinclude:: ../../generators/example/src/main/scala/NodeTypes.scala
:language: scala
:start-after: DOC include start: MyClient1+MyClient2
:end-before: DOC include end: MyClient1+MyClient2
Now we instantiate these two clients in another lazy module and expose their
nodes as a single node.
.. literalinclude:: ../../generators/example/src/main/scala/NodeTypes.scala
:language: scala
:start-after: DOC include start: MyClientGroup
:end-before: DOC include end: MyClientGroup
We can also do the same for managers.
.. literalinclude:: ../../generators/example/src/main/scala/NodeTypes.scala
:language: scala
:start-after: DOC include start: MyManagerGroup
:end-before: DOC include end: MyManagerGroup
If we want to connect the client and manager groups together, we can now do this.
.. literalinclude:: ../../generators/example/src/main/scala/NodeTypes.scala
:language: scala
:start-after: DOC include start: MyClientManagerComplex
:end-before: DOC include end: MyClientManagerComplex
The meaning of the ``:=*`` operator is explained in more detail in the
:ref:`Diplomacy Connectors` section. In summary, it connects two nodes together
using multiple edges. The edges in the identity node are assigned in order,
so in this case ``client1.node`` will eventually connect to ``manager1.node``
and ``client2.node`` will connect to ``manager2.node``.
The number of inputs to an identity node should match the number of outputs.
A mismatch will cause an elaboration error.
Adapter Node
------------
Like the identity node, the adapter node takes some number of inputs and
produces the same number of outputs. However, unlike the identity node, the
adapter node does not simply pass the connections through unchanged.
It can change the logical and physical interfaces between input and output and
rewrite messages going through. RocketChip provides a library of adapters,
which are catalogued in :ref:`Diplomatic Widgets`.
You will rarely need to create an adapter node yourself, but the invocation is
as follows.
.. code-block:: scala
val node = TLAdapterNode(
clientFn = { cp =>
// ..
},
managerFn = { mp =>
// ..
})
The ``clientFn`` is a function that takes the ``TLClientPortParameters`` of
the input as an argument and returns the corresponding parameters for the
output. The ``managerFn`` takes the ``TLManagerPortParameters`` of the output
as an argument and returns the corresponding parameters for the input.
Nexus Node
----------
The nexus node is similar to the adapter node in that it has a different
output interface than input interface. But it can also have a different
number of inputs than it does outputs. This node type is mainly used by
the ``TLXbar`` widget, which provides a TileLink crossbar generator. You will
also likely not need to define this node type manually, but its invocation is
as follows.
.. code-block:: scala
val node = TLNexusNode(
clientFn = { seq =>
// ..
},
managerFn = { seq =>
// ..
})
This has similar arguments as the adapter node's constructor, but instead of
taking single parameters objects as arguments and returning single objects
as results, the functions take and return sequences of parameters. And as you
might expect, the size of the returned sequence need not be the same size as
the input sequence.

View File

@@ -0,0 +1,141 @@
Register Router
===============
Memory-mapped devices generally follow a common pattern. They expose a set
of registers to the CPUs. By writing to a register, the CPU can change the
device's settings or send a command. By reading from a register, the CPU can
query the device's state or retrieve results.
While designers can manually instantiate a manager node and write the logic
for exposing registers themselves, it's much easier to use RocketChip's
``regmap`` interface, which can generate most of the glue logic.
For TileLink devices, you can use the ``regmap`` interface by extending
the ``TLRegisterRouter`` class, as shown in :ref:`Adding An Accelerator/Device`,
or you can create a regular LazyModule and instantiate a ``TLRegisterNode``.
This section will focus on the second method.
Basic Usage
-----------
.. literalinclude:: ../../generators/example/src/main/scala/RegisterNodeExample.scala
:language: scala
:start-after: DOC include start: MyDeviceController
:end-before: DOC include end: MyDeviceController
The code example above shows a simple lazy module that uses the ``TLRegisterNode``
to memory map hardware registers of different sizes. The constructor has
two required arguments: ``address``, which is the base address of the registers,
and ``device``, which is the device tree entry. There are also two optional
arguments. The ``beatBytes`` argument is the interface width in bytes.
The default value is 4 bytes. The ``concurrency`` argument is the size of the
internal queue for TileLink requests. By default, this value is 0, which means
there will be no queue. This value must be greater than 0 if you wish to
decoupled requests and responses for register accesses. This is discussed
in :ref:`Using Functions`.
The main way to interact with the node is to call the ``regmap`` method, which
takes a sequence of pairs. The first element of the pair is an offset from the
base address. The second is a sequence of ``RegField`` objects, each of
which maps a different register. The ``RegField`` constructor takes two
arguments. The first argument is the width of the register in bits.
The second is the register itself.
Since the argument is a sequence, you can associate multiple ``RegField``
objects with an offset. If you do, the registers are read or written in parallel
when the offset is accessed. The registers are in little endian order, so the
first register in the list corresponds to the least significant bits in the
value written. In this example, if the CPU wrote to offset 0x0E with the value
0xAB, ``smallReg0`` will get the value 0xB and ``smallReg1`` would get 0xA.
Decoupled Interfaces
--------------------
Sometimes you may want to do something other than read and write from a hardware
register. The ``RegField`` interface also provides support for reading
and writing ``DecoupledIO`` interfaces. For instance, you can implement a
hardware FIFO like so.
.. literalinclude:: ../../generators/example/src/main/scala/RegisterNodeExample.scala
:language: scala
:start-after: DOC include start: MyQueueRegisters
:end-before: DOC include end: MyQueueRegisters
This variant of the ``RegField`` constructor takes three arguments instead of
two. The first argument is still the bit width. The second is the decoupled
interface to read from. The third is the decoupled interface to write to.
In this example, writing to the "register" will push the data into the queue
and reading from it will pop data from the queue.
You need not specify both read and write for a register. You can also create
read-only or write-only registers. So for the previous example, if you wanted
enqueue and dequeue to use different addresses, you could write the following.
.. literalinclude:: ../../generators/example/src/main/scala/RegisterNodeExample.scala
:language: scala
:start-after: DOC include start: MySeparateQueueRegisters
:end-before: DOC include end: MySeparateQueueRegisters
The read-only register function can also be used to read signals
that aren't registers.
.. code-block:: scala
val constant = 0xf00d.U
node.regmap(
0x00 -> Seq(RegField.r(8, constant)))
Using Functions
---------------
You can also create registers using functions. Say, for instance, that you
want to create a counter that gets incremented on a write and decremented on
a read.
.. literalinclude:: ../../generators/example/src/main/scala/RegisterNodeExample.scala
:language: scala
:start-after: DOC include start: MyCounterRegisters
:end-before: DOC include end: MyCounterRegisters
The functions here are essentially the same as a decoupled interface.
The read function gets passed the ``ready`` signal and returns the
``valid`` and ``bits`` signals. The write function gets passed ``valid` and
``bits`` and returns ``ready``.
You can also pass functions that decouple the read/write request and response.
The request will appear as a decoupled input and the response as a decoupled
output. So for instance, if we wanted to do this for the previous example.
.. literalinclude:: ../../generators/example/src/main/scala/RegisterNodeExample.scala
:language: scala
:start-after: DOC include start: MyCounterReqRespRegisters
:end-before: DOC include end: MyCounterReqRespRegisters
In each function, we set up a state variable ``responding``. The function
is ready to take requests when this is false and is sending a response when
this is true.
In this variant, both read and write take an input valid and return an
output ready. The only different is that bits is an input for read and an
output for write.
In order to use this variant, you need to set ``concurrency`` to a value
larger than 0.
Register Routers for Other Protocols
------------------------------------
One useful feature of the register router interface is that you can easily
change the protocol being used. For instance, in the first example in
:ref:`Basic Usage`, you could simply change the ``TLRegisterNode`` to
and ``AXI4RegisterNode``.
.. literalinclude:: ../../generators/example/src/main/scala/RegisterNodeExample.scala
:language: scala
:start-after: DOC include start: MyAXI4DeviceController
:end-before: DOC include end: MyAXI4DeviceController
Other than the fact that AXI4 nodes don't take a ``device`` argument, and can
only have a single AddressSet instead of multiple, everything else is
unchanged.

View File

@@ -0,0 +1,467 @@
Diplomatic Widgets
==================
RocketChip provides a library of diplomatic TileLink and AXI4 widgets.
The most commonly used widgets are documented here. The TileLink widgets
are available from ``freechips.rocketchip.tilelink`` and the AXI4 widgets
from ``freechips.rocketchip.amba.axi4``.
TLBuffer
--------
A widget for buffering TileLink transactions. It simply instantiates queues
for each of the 2 (or 5 for TL-C) decoupled channels. To configure the queue
for each channel, you pass the constructor a
``freechips.rocketchip.diplomacy.BufferParams`` object. The arguments for
this case class are:
- ``depth: Int`` - The number of entries in the queue
- ``flow: Boolean`` - If true, combinationally couple the valid signals so
that an input can be consumed on the same cycle it is enqueued.
- ``pipe: Boolean`` - If true, combinationally couple the ready signals so
that single-entry queues can run at full rate.
There is an implicit conversion from ``Int`` available. If you pass an
integer instead of a BufferParams object, the queue will be the depth
given in the integer and ``flow`` and ``pipe`` will both be false.
You can also use one of the predefined BufferParams objects.
- ``BufferParams.default`` = ``BufferParams(2, false, false)``
- ``BufferParams.none`` = ``BufferParams(0, false, false)``
- ``BufferParams.flow`` = ``BufferParams(1, true, false)``
- ``BufferParams.pipe`` = ``BufferParams(1, false, true)``
**Arguments:**
There are four constructors available with zero, one, two, or five arguments.
The zero-argument constructor uses ``BufferParams.default`` for all of the
channels.
The single-argument constructor takes a ``BufferParams`` object to use for all
channels.
The arguments for the two-argument constructor are:
- ``ace: BufferParams`` - Parameters to use for the A, C, and E channels.
- ``bd: BufferParams`` - Parameters to use for the B and D channels
The arguments for the five-argument constructor are
- ``a: BufferParams`` - Buffer parameters for the A channel
- ``b: BufferParams`` - Buffer parameters for the B channel
- ``c: BufferParams`` - Buffer parameters for the C channel
- ``d: BufferParams`` - Buffer parameters for the D channel
- ``e: BufferParams`` - Buffer parameters for the E channel
**Example Usage:**
.. code-block:: scala
// Default settings
manager0.node := TLBuffer() := client0.node
// Using implicit conversion to make buffer with 8 queue entries per channel
manager1.node := TLBuffer(8) := client1.node
// Use default on A channel but pipe on D channel
manager2.node := TLBuffer(BufferParams.default, BufferParams.pipe) := client2.node
// Only add queues for the A and D channel
manager3.node := TLBuffer(
BufferParams.default,
BufferParams.none,
BufferParams.none,
BufferParams.default,
BufferParams.none) := client3.node
AXI4Buffer
----------
Similar to the :ref:`TLBuffer`, but for AXI4. It also takes ``BufferParams`` objects
as arguments.
**Arguments:**
Like TLBuffer, AXI4Buffer has zero, one, two, and five-argument constructors.
The zero-argument constructor uses the default BufferParams for all channels.
The one-argument constructor uses the provided BufferParams for all channels.
The two-argument constructor has the following arguments.
- ``aw: BufferParams`` - Buffer parameters for the "ar", "aw", and "w" channels.
- ``br: BufferParams`` - Buffer parameters for the "b", and "r" channels.
The five-argument constructor has the following arguments
- ``aw: BufferParams`` - Buffer parameters for the "ar" channel
- ``w: BufferParams`` - Buffer parameters for the "w" channel
- ``b: BufferParams`` - Buffer parameters for the "b" channel
- ``ar: BufferParams`` - Buffer parameters for the "ar" channel
- ``r: BufferParams`` - Buffer parameters for the "r" channel
**Example Usage:**
.. code-block:: scala
// Default settings
slave0.node := AXI4Buffer() := master0.node
// Using implicit conversion to make buffer with 8 queue entries per channel
slave1.node := AXI4Buffer(8) := master1.node
// Use default on aw/w/ar channel but pipe on b/r channel
slave2.node := AXI4Buffer(BufferParams.default, BufferParams.pipe) := master2.node
// Single-entry queues for aw, b, and ar but two-entry queues for w and r
slave3.node := AXI4Buffer(1, 2, 1, 1, 2) := master3.node
AXI4UserYanker
--------------
This widget takes an AXI4 port that has a user field and turns it into
one without a user field. The values of the user field from input AR and AW
requests is kept in internal queues associated with the ARID/AWID, which is
then used to associate the correct user field to the responses.
**Arguments:**
- ``capMaxFlight: Option[Int]`` - (optional) An option which can hold the
number of requests that can be inflight for each ID. If ``None`` (the default),
the UserYanker will support the maximum number of inflight requests.
**Example Usage:**
.. code-block:: scala
nouser.node := AXI4UserYanker(Some(1)) := hasuser.node
AXI4Deinterleaver
-----------------
Multi-beat AXI4 read responses for different IDs can potentially be interleaved.
This widget reorders read responses from the slave so that all of the beats
for a single transaction are consecutive.
**Arguments:**
- ``maxReadBytes: Int`` - The maximum number of bytes that can be read
in a single transaction.
**Example Usage:**
.. code-block:: scala
interleaved.node := AXI4Deinterleaver() := consecutive.node
TLFragmenter
------------
The TLFragmenter widget shrinks the maximum logical transfer size of the
TileLink interface by breaking larger transactions into multiple smaller
transactions.
**Arguments:**
- ``minSize: Int`` - Minimum size of transfers supported by all outward managers.
- ``maxSize: Int`` - Maximum size of transfers supported after the Fragmenter is applied.
- ``alwaysMin: Boolean`` - (optional) Fragment all requests down to minSize (else fragment to maximum supported by manager). (default: false)
- ``earlyAck: EarlyAck.T`` - (optional) Should a multibeat Put be acknowledged on the first beat or last beat?
Possible values (default: ``EarlyAck.None``):
- ``EarlyAck.AllPuts`` - always acknowledge on first beat.
- ``EarlyAck.PutFulls`` - acknowledge on first beat if PutFull, otherwise acknowledge on last beat.
- ``EarlyAck.None`` - always acknowledge on last beat.
- ``holdFirstDenied: Boolean`` - (optional) Allow the Fragmenter to unsafely combine multibeat Gets by taking the first denied for the whole burst. (default: false)
**Example Usage:**
.. code-block:: scala
val beatBytes = 8
val blockBytes = 64
single.node := TLFragmenter(beatBytes, blockBytes) := multi.node
axi4lite.node := AXI4Fragmenter() := axi4full.node
**Additional Notes**
- TLFragmenter modifies: PutFull, PutPartial, LogicalData, Get, Hint
- TLFragmenter passes: ArithmeticData (truncated to minSize if alwaysMin)
- TLFragmenter cannot modify acquire (could livelock); thus it is unsafe to put caches on both sides
AXI4Fragmenter
--------------
The AXI4Fragmenter is similar to the :ref:`TLFragmenter`, except it can only
break multi-beat AXI4 transactions into single-beat transactions. This
effectively serves as an AXI4 to AXI4-Lite converter. The constructor for this
widget does not take any arguments.
**Example Usage:**
.. code-block:: scala
axi4lite.node := AXI4Fragmenter() := axi4full.node
TLSourceShrinker
----------------
The number of source IDs that a manager sees is usually computed based on the
clients that connect to it. In some cases, you may wish to fix the
number of source IDs. For instance, you might do this if you wish to export
the TileLink port to a Verilog black box. This will pose a problem, however,
if the clients require a larger number of source IDs. In this situation,
you will want to use a TLSourceShrinker.
**Arguments:**
- ``maxInFlight: Int`` - The maximum number of source IDs that will be sent
from the TLSourceShrinker to the manager.
**Example Usage:**
.. code-block:: scala
// client.node may have >16 source IDs
// manager.node will only see 16
manager.node := TLSourceShrinker(16) := client.node
AXI4IdIndexer
-------------
The AXI4 equivalent of :ref:`TLSourceShrinker`. This limits the number of
AWID/ARID bits in the slave AXI4 interface. Useful for connecting to external
or black box AXI4 ports.
**Arguments:**
- ``idBits: Int`` - The number of ID bits on the slave interface.
**Example Usage:**
.. code-block:: scala
// master.node may have >16 unique IDs
// slave.node will only see 4 ID bits
slave.node := AXI4IdIndexer(4) := master.node
**Notes:**
The AXI4IdIndexer will create a ``user`` field on the slave interface, as it
stores the ID of the master requests in this field. If connecting to an AXI4
interface that doesn't have a ``user`` field, you'll need to use the :ref:`AXI4UserYanker`.
TLWidthWidget
-------------
This widget changes the physical width of the TileLink interface. The width
of a TileLink interface is configured by managers, but sometimes you want
the client to see a particular width.
**Arguments:**
- ``innerBeatBytes: Int`` - The physical width (in bytes) seen by the client
**Example Usage:**
.. code-block::
// Assume the manager node sets beatBytes to 8
// With WidthWidget, client sees beatBytes of 4
manager.node := TLWidthWidget(4) := client.node
TLFIFOFixer
-----------
TileLink managers that declare a FIFO domain must ensure that all requests to
that domain from clients which have requested FIFO ordering see responses in
order. However, they can only control the ordering of their own responses, and
do not have control over how those responses interleave with responses from
other managers in the same FIFO domain. Responsibility for ensuring FIFO order
across managers goes to the TLFIFOFixer.
**Arguments:**
- ``policy: TLFIFOFixer.Policy`` - (optional) Which managers will the
TLFIFOFixer enforce ordering on? (default: ``TLFIFOFixer.all``)
The possible values of ``policy`` are:
- ``TLFIFOFixer.all`` - All managers (including those without a FIFO domain)
will have ordering guaranteed
- ``TLFIFOFixer.allFIFO`` - All managers that define a FIFO domain will have
ordering guaranteed
- ``TLFIFOFixer.allVolatile`` - All managers that have a RegionType of
``VOLATILE``, ``PUT_EFFECTS``, or ``GET_EFFECTS`` will have ordering
guaranteed (see :ref:`Manager Node` for explanation of region types).
TLXbar and AXI4Xbar
-------------------
These are crossbar generators for TileLink and AXI4 which will route requests
from TL client / AXI4 master nodes to TL manager / AXI4 slave nodes based on
the addresses defined in the managers / slaves. Normally, these are constructed
without arguments. However, you can change the arbitration policy, which
determines which client ports get precedent in the arbiters. The default policy
is ``TLArbiter.roundRobin``, but you can change it to ``TLArbiter.lowestIndexFirst``
if you want a fixed arbitration precedence.
**Arguments:**
All arguments are optional.
- ``arbitrationPolicy: TLArbiter.Policy`` - The arbitration policy to use.
- ``maxFlightPerId: Int`` - (AXI4 only) The number of transactions with the
same ID that can be inflight at a time. (default: 7)
- ``awQueueDepth: Int`` - (AXI4 only) The depth of the write address queue.
(default: 2)
**Example Usage:**
.. code-block:: scala
// Instantiate the crossbar lazy module
val tlBus = LazyModule(new TLXbar)
// Connect a single input edge
tlBus.node := tlClient0.node
// Connect multiple input edges
tlBus.node :=* tlClient1.node
// Connect a single output edge
tlManager0.node := tlBus.node
// Connect multiple output edges
tlManager1.node :*= tlBus.node
// Instantiate a crossbar with lowestIndexFirst arbitration policy
// Yes, we still use the TLArbiter singleton even though this is AXI4
val axiBus = LazyModule(new AXI4Xbar(TLArbiter.lowestIndexFirst))
// The connections work the same as TL
axiBus.node := axiClient0.node
axiBus.node :=* axiClient1.node
axiManager0.node := axiBus.node
axiManager1.node :*= axiBus.node
TLToAXI4 and AXI4ToTL
---------------------
These are converters between the TileLink and AXI4 protocols. TLToAXI4
takes a TileLink client and connects to an AXI4 slave. AXI4ToTL takes an
AXI4 master and connects to a TileLink manager. Generally you don't want to
override the default arguments of the constructors for these widgets.
**Example Usage:**
.. code-block:: scala
axi4slave.node :=
AXI4UserYanker() :=
AXI4Deinterleaver(64) :=
TLToAXI4() :=
tlclient.node
tlmanager.node :=
AXI4ToTL() :=
AXI4UserYanker() :=
AXI4Fragmenter() :=
axi4master.node
You will need to add an :ref:`AXI4Deinterleaver` after the TLToAXI4 converter
because it cannot deal with interleaved read responses. The TLToAXI4 converter
also uses the AXI4 user field to store some information, so you will need an
:ref:`AXI4UserYanker` if you want to connect to an AXI4 port without user
fields.
Before you connect an AXI4 port to the AXI4ToTL widget, you will need to
add an :ref:`AXI4Fragmenter` and :ref:`AXI4UserYanker` because the converter cannot
deal with multi-beat transactions or user fields.
TLROM
------
The TLROM widget provides a read-only memory that can be accessed using
TileLink. Note: this widget is in the ``freechips.rocketchip.devices.tilelink``
package, not the ``freechips.rocketchip.tilelink`` package like the others.
**Arguments:**
- ``base: BigInt`` - The base address of the memory
- ``size: Int`` - The size of the memory in bytes
- ``contentsDelayed: => Seq[Byte]`` - A function which, when called generates
the byte contents of the ROM.
- ``executable: Boolean`` - (optional) Specify whether the CPU can fetch
instructions from the ROM (default: ``true``).
- ``beatBytes: Int`` - (optional) The width of the interface in bytes.
(default: 4).
- ``resources: Seq[Resource]`` - (optional) Sequence of resources to add to
the device tree.
**Example Usage:**
.. code-block:: scala
val rom = LazyModule(new TLROM(
base = 0x100A0000,
size = 64,
contentsDelayed = Seq.tabulate(64) { i => i.toByte },
beatBytes = 8))
rom.node := TLFragmenter(8, 64) := client.node
**Supported Operations:**
The TLROM only supports single-beat reads. If you want to perform multi-beat
reads, you should attach a TLFragmenter in front of the ROM.
TLRAM and AXI4RAM
-----------------
The TLRAM and AXI4RAM widgets provide read-write memories implemented as SRAMs.
**Arguments:**
- ``address: AddressSet`` - The address range that this RAM will cover.
- ``cacheable: Boolean`` - (optional) Can the contents of this RAM be cached.
(default: ``true``)
- ``executable: Boolean`` - (optional) Can the contents of this RAM be fetched
as instructions. (default: ``true``)
- ``beatBytes: Int`` - (optional) Width of the TL/AXI4 interface in bytes.
(default: 4)
- ``atomics: Boolean`` - (optional, TileLink only) Does the RAM support
atomic operations? (default: ``false``)
**Example Usage:**
.. code-block:: scala
val xbar = LazyModule(new TLXbar)
val tlram = LazyModule(new TLRAM(
address = AddressSet(0x1000, 0xfff)))
val axiram = LazyModule(new AXI4RAM(
address = AddressSet(0x2000, 0xfff)))
tlram.node := xbar.node
axiram := TLToAXI4() := xbar.node
**Supported Operations:**
TLRAM only supports single-beat TL-UL requests. If you set ``atomics`` to true,
it will also support Logical and Arithmetic operations. Use a ``TLFragmenter``
if you want multi-beat reads/writes.
AXI4RAM only supports AXI4-Lite operations, so multi-beat reads/writes and
reads/writes smaller than full-width are not supported. Use an ``AXI4Fragmenter``
if you want to use the full AXI4 protocol.

View File

@@ -0,0 +1,30 @@
TileLink and Diplomacy Reference
================================
TileLink is the cache coherence and memory protocol used by RocketChip and
other Chipyard generators. It is how different modules like caches, memories,
peripherals, and DMA devices communicate with each other.
RocketChip's TileLink implementation is built on top of Diplomacy, a framework
for exchanging configuration information among Chisel generators in a two-phase
elaboration scheme. For a detailed explanation of Diplomacy, see `the paper
by Cook, Terpstra, and Lee <https://carrv.github.io/2017/papers/cook-diplomacy-carrv2017.pdf>`_.
A brief overview of how to connect simple TileLink widgets can be found
in the :ref:`Adding-an-Accelerator` section. This section will provide a
detailed reference for the TileLink and Diplomacy functionality provided by
RocketChip.
A detailed specification of the TileLink 1.7 protocol can be found on the
`SiFive website <https://sifive.cdn.prismic.io/sifive%2F57f93ecf-2c42-46f7-9818-bcdd7d39400a_tilelink-spec-1.7.1.pdf>`_.
.. toctree::
:maxdepth: 2
:caption: Reference
NodeTypes
Diplomacy-Connectors
EdgeFunctions
Register-Router
Widgets

View File

@@ -0,0 +1,6 @@
Chisel Testers
==============================
`Chisel testers <https://github.com/freechipsproject/chisel-testers>`__ is a library for writing tests for Chisel designs.
It provides a Scala API for interacting with a DUT.
It can use multiple backends, including :ref:`Treadle` and Verilator.

15
docs/Tools/Dsptools.rst Normal file
View File

@@ -0,0 +1,15 @@
Dsptools
===============================
`Dsptools <https://github.com/ucb-bar/dsptools/>`__ is a Chisel library for writing custom signal processing hardware.
Additionally, dsptools is useful for integrating custom signal processing hardware into an SoC (especially a Rocket-based SoC).
Some features:
* Complex type
* Typeclasses for writing polymorphic hardware generators
* For example, write one FIR filter generator that works for real or complex inputs
* Extensions to Chisel testers for fixed point and floating point types
* A diplomatic implementation of AXI4-Stream
* Models for verifying APB, AXI-4, and TileLink interfaces with chisel-testers
* DSP building blocks

9
docs/Tools/Treadle.rst Normal file
View File

@@ -0,0 +1,9 @@
Treadle and FIRRTL Interpreter
==============================
`Treadle <https://github.com/freechipsproject/treadle>`__ and
`FIRRTL Interpreter <https://github.com/freechipsproject/firrtl-interpreter>`__
are circuit simulators that directly execute FIRRTL (specifically low-firrtl IR).
Treadle is the replacement for FIRRTL Interpreter but FIRRTL Interpreter is still used within some
projects. Treadle is useful for simulating modules in a larger SoC design. Many projects
use Treadle for interactive debugging and a low-overhead simulator.

View File

@@ -10,5 +10,8 @@ The following pages will introduce them, and how we can use them in order to gen
Chisel
FIRRTL
Treadle
Chisel-Testers
Dsptools
Barstools

View File

@@ -8,4 +8,5 @@ In particular, we aim to support the HAMMER physical design generator flow.
:maxdepth: 2
:caption: VLSI Flow:
Building-A-Chip
HAMMER

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

BIN
docs/_static/images/sha3.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

View File

@@ -12,43 +12,35 @@ New to Chipyard? Jump to the :ref:`Chipyard Basics` page for more info.
.. include:: Quick-Start.rst
Getting Help
------------
If you have a question about Chipyard that isn't answered by the existing
documentation, feel free to ask for help on the
`Chipyard Google Group <https://groups.google.com/forum/#!forum/chipyard>`_.
Table of Contents
-----------------
.. toctree::
:maxdepth: 3
:caption: Contents:
:numbered:
Chipyard-Basics/index
:maxdepth: 3
:caption: Simulation:
:numbered:
Simulation/index
:maxdepth: 3
:caption: Generators:
:numbered:
Generators/index
:maxdepth: 3
:caption: Tools:
:numbered:
Tools/index
:maxdepth: 3
:caption: VLSI Production:
:numbered:
VLSI/index
:maxdepth: 3
:caption: Customization:
:numbered:
Customization/index
:maxdepth: 3
:caption: Advanced Usage:
:numbered:
Advanced-Usage/index
TileLink-Diplomacy-Reference/index
Indices and tables

View File

@@ -3,88 +3,57 @@ 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)
new WithTop ++ // use normal top
new WithBootROM ++ // use testchipip bootrom
new freechips.rocketchip.subsystem.WithInclusiveCache ++ // use SiFive L2 cache
new boom.common.WithSmallBooms ++ // 1-wide BOOM
new boom.common.WithNBoomCores(1) ++ // single-core
new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system
class MediumBoomConfig extends Config(
new WithNormalBoomRocketTop ++
new WithTop ++
new WithBootROM ++
new boom.common.MediumBoomConfig)
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new boom.common.WithMediumBooms ++ // 2-wide BOOM
new boom.common.WithNBoomCores(1) ++
new freechips.rocketchip.system.BaseConfig)
class LargeBoomConfig extends Config(
new WithNormalBoomRocketTop ++
new WithTop ++
new WithBootROM ++
new boom.common.LargeBoomConfig)
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new boom.common.WithLargeBooms ++ // 3-wide BOOM
new boom.common.WithNBoomCores(1) ++
new freechips.rocketchip.system.BaseConfig)
class MegaBoomConfig extends Config(
new WithNormalBoomRocketTop ++
new WithTop ++
new WithBootROM ++
new boom.common.MegaBoomConfig)
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new boom.common.WithMegaBooms ++ // 4-wide BOOM
new boom.common.WithNBoomCores(1) ++
new freechips.rocketchip.system.BaseConfig)
class jtagSmallBoomConfig extends Config(
new WithDTMBoomRocketTop ++
class DualSmallBoomConfig extends Config(
new WithTop ++
new WithBootROM ++
new WithJtagDTM ++
new boom.common.SmallBoomConfig)
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new boom.common.WithSmallBooms ++
new boom.common.WithNBoomCores(2) ++ // dual-core
new freechips.rocketchip.system.BaseConfig)
class jtagMediumBoomConfig extends Config(
new WithDTMBoomRocketTop ++
class SmallRV32BoomConfig extends Config(
new WithTop ++
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)
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new boom.common.WithoutBoomFPU ++ // no fp
new boom.common.WithBoomRV32 ++ // rv32 (32bit)
new boom.common.WithSmallBooms ++
new boom.common.WithNBoomCores(1) ++
new freechips.rocketchip.system.BaseConfig)

View File

@@ -9,7 +9,7 @@ import freechips.rocketchip.diplomacy.{LazyModule, ValName}
import freechips.rocketchip.devices.tilelink.BootROMParams
import freechips.rocketchip.tile.{XLen, BuildRoCC, TileKey, LazyRoCC}
import boom.system.{BoomTilesKey}
import boom.common.{BoomTilesKey}
import testchipip._
@@ -37,6 +37,7 @@ class WithBootROM extends Config((site, here, up) => {
contentFileName = s"./bootrom/bootrom.rv${site(XLen)}.img")
})
// DOC include start: WithGPIO
/**
* Class to add in GPIO
*/
@@ -44,6 +45,7 @@ class WithGPIO extends Config((site, here, up) => {
case PeripheryGPIOKey => List(
GPIOParams(address = 0x10012000, width = 4, includeIOF = false))
})
// DOC include end: WithGPIO
// -----------------------------------------------
// BOOM and/or Rocket Top Level System Parameter Mixins
@@ -52,43 +54,45 @@ class WithGPIO extends Config((site, here, up) => {
/**
* Class to specify a "plain" top level BOOM and/or Rocket system
*/
class WithNormalBoomRocketTop extends Config((site, here, up) => {
case BuildBoomRocketTop => (clock: Clock, reset: Bool, p: Parameters) => {
Module(LazyModule(new BoomRocketTop()(p)).module)
class WithTop extends Config((site, here, up) => {
case BuildTop => (clock: Clock, reset: Bool, p: Parameters) => {
Module(LazyModule(new Top()(p)).module)
}
})
/**
* 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 WithDTMTop extends Config((site, here, up) => {
case BuildTopWithDTM => (clock: Clock, reset: Bool, p: Parameters) => {
Module(LazyModule(new TopWithDTM()(p)).module)
}
})
/**
* Class to specify a top level BOOM and/or Rocket system with PWM
*/
class WithPWMBoomRocketTop extends Config((site, here, up) => {
case BuildBoomRocketTop => (clock: Clock, reset: Bool, p: Parameters) =>
Module(LazyModule(new BoomRocketTopWithPWMTL()(p)).module)
// DOC include start: WithPWMTop
class WithPWMTop extends Config((site, here, up) => {
case BuildTop => (clock: Clock, reset: Bool, p: Parameters) =>
Module(LazyModule(new TopWithPWMTL()(p)).module)
})
// DOC include end: WithPWMTop
/**
* Class to specify a top level BOOM and/or Rocket system with a PWM AXI4
*/
class WithPWMAXI4BoomRocketTop extends Config((site, here, up) => {
case BuildBoomRocketTop => (clock: Clock, reset: Bool, p: Parameters) =>
Module(LazyModule(new BoomRocketTopWithPWMAXI4()(p)).module)
class WithPWMAXI4Top extends Config((site, here, up) => {
case BuildTop => (clock: Clock, reset: Bool, p: Parameters) =>
Module(LazyModule(new TopWithPWMAXI4()(p)).module)
})
/**
* Class to specify a top level BOOM and/or Rocket system with a block device
*/
class WithBlockDeviceModelBoomRocketTop extends Config((site, here, up) => {
case BuildBoomRocketTop => (clock: Clock, reset: Bool, p: Parameters) => {
val top = Module(LazyModule(new BoomRocketTopWithBlockDevice()(p)).module)
class WithBlockDeviceModelTop extends Config((site, here, up) => {
case BuildTop => (clock: Clock, reset: Bool, p: Parameters) => {
val top = Module(LazyModule(new TopWithBlockDevice()(p)).module)
top.connectBlockDeviceModel()
top
}
@@ -97,20 +101,21 @@ class WithBlockDeviceModelBoomRocketTop extends Config((site, here, up) => {
/**
* Class to specify a top level BOOM and/or Rocket system with a simulator block device
*/
class WithSimBlockDeviceBoomRocketTop extends Config((site, here, up) => {
case BuildBoomRocketTop => (clock: Clock, reset: Bool, p: Parameters) => {
val top = Module(LazyModule(new BoomRocketTopWithBlockDevice()(p)).module)
class WithSimBlockDeviceTop extends Config((site, here, up) => {
case BuildTop => (clock: Clock, reset: Bool, p: Parameters) => {
val top = Module(LazyModule(new TopWithBlockDevice()(p)).module)
top.connectSimBlockDevice(clock, reset)
top
}
})
// DOC include start: WithGPIOTop
/**
* Class to specify a top level BOOM and/or Rocket system with GPIO
*/
class WithGPIOBoomRocketTop extends Config((site, here, up) => {
case BuildBoomRocketTop => (clock: Clock, reset: Bool, p: Parameters) => {
val top = Module(LazyModule(new BoomRocketTopWithGPIO()(p)).module)
class WithGPIOTop extends Config((site, here, up) => {
case BuildTop => (clock: Clock, reset: Bool, p: Parameters) => {
val top = Module(LazyModule(new TopWithGPIO()(p)).module)
for (gpio <- top.gpio) {
for (pin <- gpio.pins) {
pin.i.ival := false.B
@@ -119,6 +124,7 @@ class WithGPIOBoomRocketTop extends Config((site, here, up) => {
top
}
})
// DOC include end: WithGPIOTop
// ------------------
// Multi-RoCC Support
@@ -157,3 +163,14 @@ class WithMultiRoCCHwacha(harts: Int*) extends Config((site, here, up) => {
}
}
})
// DOC include start: WithInitZero
class WithInitZero(base: BigInt, size: BigInt) extends Config((site, here, up) => {
case InitZeroKey => InitZeroConfig(base, size)
})
class WithInitZeroTop extends Config((site, here, up) => {
case BuildTop => (clock: Clock, reset: Bool, p: Parameters) =>
Module(LazyModule(new TopWithInitZero()(p)).module)
})
// DOC include end: WithInitZero

View File

@@ -1,266 +0,0 @@
package example
import chisel3._
import freechips.rocketchip.config.{Config}
import freechips.rocketchip.subsystem.{WithRoccExample, WithNMemoryChannels, WithNBigCores, WithRV32, WithExtMemSize, WithNBanks, WithInclusiveCache}
import testchipip._
// --------------
// Rocket Configs
// --------------
class BaseRocketConfig extends Config(
new WithBootROM ++
new freechips.rocketchip.system.DefaultConfig)
class DefaultRocketConfig extends Config(
new WithNormalBoomRocketTop ++
new BaseRocketConfig)
class HwachaConfig extends Config(
new hwacha.DefaultHwachaConfig ++
new DefaultRocketConfig)
class RoccRocketConfig extends Config(
new WithRoccExample ++
new DefaultRocketConfig)
class PWMRocketConfig extends Config(
new WithPWMBoomRocketTop ++
new BaseRocketConfig)
class PWMAXI4RocketConfig extends Config(
new WithPWMAXI4BoomRocketTop ++
new BaseRocketConfig)
class SimBlockDeviceRocketConfig extends Config(
new WithBlockDevice ++
new WithSimBlockDeviceBoomRocketTop ++
new BaseRocketConfig)
class BlockDeviceModelRocketConfig extends Config(
new WithBlockDevice ++
new WithBlockDeviceModelBoomRocketTop ++
new BaseRocketConfig)
class GPIORocketConfig extends Config(
new WithGPIO ++
new WithGPIOBoomRocketTop ++
new BaseRocketConfig)
class DualCoreRocketConfig extends Config(
new WithNBigCores(2) ++
new DefaultRocketConfig)
class RV32RocketConfig extends Config(
new WithRV32 ++
new DefaultRocketConfig)
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.common.LargeBoomConfig)
class SmallBaseBoomConfig extends Config(
new WithBootROM ++
new boom.common.SmallBoomConfig)
class DefaultBoomConfig extends Config(
new WithNormalBoomRocketTop ++
new BaseBoomConfig)
class SmallDefaultBoomConfig extends Config(
new WithNormalBoomRocketTop ++
new SmallBaseBoomConfig)
class HwachaBoomConfig extends Config(
new hwacha.DefaultHwachaConfig ++
new DefaultBoomConfig)
class RoccBoomConfig extends Config(
new WithRoccExample ++
new DefaultBoomConfig)
class PWMBoomConfig extends Config(
new WithPWMBoomRocketTop ++
new BaseBoomConfig)
class PWMAXI4BoomConfig extends Config(
new WithPWMAXI4BoomRocketTop ++
new BaseBoomConfig)
class SimBlockDeviceBoomConfig extends Config(
new WithBlockDevice ++
new WithSimBlockDeviceBoomRocketTop ++
new BaseBoomConfig)
class BlockDeviceModelBoomConfig extends Config(
new WithBlockDevice ++
new WithBlockDeviceModelBoomRocketTop ++
new BaseBoomConfig)
class GPIOBoomConfig extends Config(
new WithGPIO ++
new WithGPIOBoomRocketTop ++
new BaseBoomConfig)
/**
* Slightly different looking configs since we need to override
* the `WithNBoomCores` with the DefaultBoomConfig params
*/
class DualCoreBoomConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new boom.common.WithRVC ++
new boom.common.WithLargeBooms ++
new boom.common.BaseBoomConfig ++
new boom.common.WithNBoomCores(2) ++
new freechips.rocketchip.subsystem.WithoutTLMonitors ++
new freechips.rocketchip.system.BaseConfig)
class DualCoreSmallBoomConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new boom.common.WithRVC ++
new boom.common.WithSmallBooms ++
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.common.SmallRV32UnifiedBoomConfig)
class BoomL2Config extends Config(
new WithInclusiveCache ++
new SmallDefaultBoomConfig)
// ---------------------
// BOOM and Rocket Configs
// ---------------------
class BaseBoomAndRocketConfig extends Config(
new WithBootROM ++
new boom.common.WithRenumberHarts ++
new boom.common.WithRVC ++
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.common.WithRenumberHarts ++
new boom.common.WithRVC ++
new boom.common.WithSmallBooms ++
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 DefaultBoomAndRocketConfig extends Config(
new WithNormalBoomRocketTop ++
new BaseBoomAndRocketConfig)
class SmallDefaultBoomAndRocketConfig extends Config(
new WithNormalBoomRocketTop ++
new SmallBaseBoomAndRocketConfig)
class HwachaBoomAndRocketConfig extends Config(
new hwacha.DefaultHwachaConfig ++
new DefaultBoomAndRocketConfig)
class RoccBoomAndRocketConfig extends Config(
new WithRoccExample ++
new DefaultBoomAndRocketConfig)
class PWMBoomAndRocketConfig extends Config(
new WithPWMBoomRocketTop ++
new BaseBoomAndRocketConfig)
class PWMAXI4BoomAndRocketConfig extends Config(
new WithPWMAXI4BoomRocketTop ++
new BaseBoomAndRocketConfig)
class SimBlockDeviceBoomAndRocketConfig extends Config(
new WithBlockDevice ++
new WithSimBlockDeviceBoomRocketTop ++
new BaseBoomAndRocketConfig)
class BlockDeviceModelBoomAndRocketConfig extends Config(
new WithBlockDevice ++
new WithBlockDeviceModelBoomRocketTop ++
new BaseBoomAndRocketConfig)
class GPIOBoomAndRocketConfig extends Config(
new WithGPIO ++
new WithGPIOBoomRocketTop ++
new BaseBoomAndRocketConfig)
class DualCoreBoomAndOneRocketConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new boom.common.WithRenumberHarts ++
new boom.common.WithRVC ++
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 DualBoomAndOneHwachaRocketConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new WithMultiRoCC ++
new WithMultiRoCCHwacha(0) ++ // put Hwacha just on hart0 which was renumbered to Rocket
new boom.common.WithRenumberHarts(rocketFirst = true) ++
new hwacha.DefaultHwachaConfig ++
new boom.common.WithRVC ++
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 RV32BoomAndRocketConfig extends Config(
new WithNormalBoomRocketTop ++
new WithBootROM ++
new boom.common.WithRenumberHarts ++
new boom.common.WithBoomRV32 ++
new boom.common.WithRVC ++
new boom.common.WithLargeBooms ++
new boom.common.BaseBoomConfig ++
new boom.common.WithNBoomCores(1) ++
new freechips.rocketchip.subsystem.WithoutTLMonitors ++
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

@@ -4,6 +4,7 @@ import chisel3._
import freechips.rocketchip.config.{Parameters}
import freechips.rocketchip.util.{GeneratorApp}
import utilities.TestSuiteHelper
object Generator extends GeneratorApp {
// add unique test suites

View File

@@ -0,0 +1,100 @@
package example
import chisel3._
import freechips.rocketchip.config.{Config}
// ---------------------
// Heterogenous Configs
// ---------------------
class LargeBoomAndRocketConfig extends Config(
new WithTop ++ // default top
new WithBootROM ++ // default bootrom
new freechips.rocketchip.subsystem.WithInclusiveCache ++ // use SiFive l2
new boom.common.WithRenumberHarts ++ // avoid hartid overlap
new boom.common.WithLargeBooms ++ // 3-wide boom
new boom.common.WithNBoomCores(1) ++ // single-core boom
new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // single-core rocket
new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system
class SmallBoomAndRocketConfig extends Config(
new WithTop ++
new WithBootROM ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new boom.common.WithRenumberHarts ++
new boom.common.WithSmallBooms ++ // 1-wide boom
new boom.common.WithNBoomCores(1) ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
// DOC include start: BoomAndRocketWithHwacha
class HwachaLargeBoomAndHwachaRocketConfig extends Config(
new WithTop ++
new WithBootROM ++
new hwacha.DefaultHwachaConfig ++ // add hwacha to all harts
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new boom.common.WithRenumberHarts ++
new boom.common.WithLargeBooms ++
new boom.common.WithNBoomCores(1) ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
// DOC include end: BoomAndRocketWithHwacha
class RoccLargeBoomAndRoccRocketConfig extends Config(
new WithTop ++
new WithBootROM ++
new freechips.rocketchip.subsystem.WithRoccExample ++ // add example rocc accelerator to all harts
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new boom.common.WithRenumberHarts ++
new boom.common.WithLargeBooms ++
new boom.common.WithNBoomCores(1) ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
class DualLargeBoomAndRocketConfig extends Config(
new WithTop ++
new WithBootROM ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new boom.common.WithRenumberHarts ++
new boom.common.WithLargeBooms ++
new boom.common.WithNBoomCores(2) ++ // 2-boom cores
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
// DOC include start: DualBoomAndRocketOneHwacha
class DualLargeBoomAndHwachaRocketConfig extends Config(
new WithTop ++
new WithBootROM ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new WithMultiRoCC ++ // support heterogeneous rocc
new WithMultiRoCCHwacha(2) ++ // put hwacha on hart-2 (rocket)
new boom.common.WithRenumberHarts ++
new boom.common.WithLargeBooms ++
new boom.common.WithNBoomCores(2) ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
// DOC include end: DualBoomAndRocketOneHwacha
class LargeBoomAndRV32RocketConfig extends Config(
new WithTop ++
new WithBootROM ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new boom.common.WithRenumberHarts ++
new boom.common.WithLargeBooms ++
new boom.common.WithNBoomCores(1) ++
new freechips.rocketchip.subsystem.WithRV32 ++ // use 32-bit rocket
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
// DOC include start: DualBoomAndRocket
class DualLargeBoomAndDualRocketConfig extends Config(
new WithTop ++
new WithBootROM ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new boom.common.WithRenumberHarts ++
new boom.common.WithLargeBooms ++
new boom.common.WithNBoomCores(2) ++ // 2 boom cores
new freechips.rocketchip.subsystem.WithNBigCores(2) ++ // 2 rocket cores
new freechips.rocketchip.system.BaseConfig)
// DOC include end: DualBoomAndRocket

View File

@@ -0,0 +1,69 @@
package example
import chisel3._
import chisel3.util._
import freechips.rocketchip.subsystem.{BaseSubsystem, CacheBlockBytes}
import freechips.rocketchip.config.{Parameters, Field}
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, IdRange}
import testchipip.TLHelper
case class InitZeroConfig(base: BigInt, size: BigInt)
case object InitZeroKey extends Field[InitZeroConfig]
class InitZero(implicit p: Parameters) extends LazyModule {
val node = TLHelper.makeClientNode(
name = "init-zero", sourceId = IdRange(0, 1))
lazy val module = new InitZeroModuleImp(this)
}
class InitZeroModuleImp(outer: InitZero) extends LazyModuleImp(outer) {
val config = p(InitZeroKey)
val (mem, edge) = outer.node.out(0)
val addrBits = edge.bundle.addressBits
val blockBytes = p(CacheBlockBytes)
require(config.size % blockBytes == 0)
val s_init :: s_write :: s_resp :: s_done :: Nil = Enum(4)
val state = RegInit(s_init)
val addr = Reg(UInt(addrBits.W))
val bytesLeft = Reg(UInt(log2Ceil(config.size+1).W))
mem.a.valid := state === s_write
mem.a.bits := edge.Put(
fromSource = 0.U,
toAddress = addr,
lgSize = log2Ceil(blockBytes).U,
data = 0.U)._2
mem.d.ready := state === s_resp
when (state === s_init) {
addr := config.base.U
bytesLeft := config.size.U
state := s_write
}
when (edge.done(mem.a)) {
addr := addr + blockBytes.U
bytesLeft := bytesLeft - blockBytes.U
state := s_resp
}
when (mem.d.fire()) {
state := Mux(bytesLeft === 0.U, s_done, s_write)
}
}
trait HasPeripheryInitZero { this: BaseSubsystem =>
implicit val p: Parameters
val initZero = LazyModule(new InitZero()(p))
fbus.fromPort(Some("init-zero"))() := initZero.node
}
trait HasPeripheryInitZeroModuleImp extends LazyModuleImp {
// Don't need anything here
}

View File

@@ -0,0 +1,128 @@
package example
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import testchipip.TLHelper
// These modules are not meant to be synthesized.
// They are used as examples in the documentation and are only here
// to check that they compile.
// DOC include start: MyClient
class MyClient(implicit p: Parameters) extends LazyModule {
val node = TLHelper.makeClientNode(TLClientParameters(
name = "my-client",
sourceId = IdRange(0, 4),
requestFifo = true,
visibility = Seq(AddressSet(0x10000, 0xffff))))
lazy val module = new LazyModuleImp(this) {
val (tl, edge) = node.out(0)
// Rest of code here
}
}
// DOC include end: MyClient
// DOC include start: MyManager
class MyManager(implicit p: Parameters) extends LazyModule {
val device = new SimpleDevice("my-device", Seq("tutorial,my-device0"))
val beatBytes = 8
val node = TLHelper.makeManagerNode(beatBytes, TLManagerParameters(
address = Seq(AddressSet(0x20000, 0xfff)),
resources = device.reg,
regionType = RegionType.UNCACHED,
executable = true,
supportsArithmetic = TransferSizes(1, beatBytes),
supportsLogical = TransferSizes(1, beatBytes),
supportsGet = TransferSizes(1, beatBytes),
supportsPutFull = TransferSizes(1, beatBytes),
supportsPutPartial = TransferSizes(1, beatBytes),
supportsHint = TransferSizes(1, beatBytes),
fifoId = Some(0)))
lazy val module = new LazyModuleImp(this) {
val (tl, edge) = node.in(0)
}
}
// DOC include end: MyManager
// DOC include start: MyClient1+MyClient2
class MyClient1(implicit p: Parameters) extends LazyModule {
val node = TLHelper.makeClientNode("my-client1", IdRange(0, 1))
lazy val module = new LazyModuleImp(this) {
// ...
}
}
class MyClient2(implicit p: Parameters) extends LazyModule {
val node = TLHelper.makeClientNode("my-client2", IdRange(0, 1))
lazy val module = new LazyModuleImp(this) {
// ...
}
}
// DOC include end: MyClient1+MyClient2
// DOC include start: MyClientGroup
class MyClientGroup(implicit p: Parameters) extends LazyModule {
val client1 = LazyModule(new MyClient1)
val client2 = LazyModule(new MyClient2)
val node = TLIdentityNode()
node := client1.node
node := client2.node
lazy val module = new LazyModuleImp(this) {
// Nothing to do here
}
}
// DOC include end: MyClientGroup
// DOC include start: MyManagerGroup
class MyManager1(beatBytes: Int)(implicit p: Parameters) extends LazyModule {
val node = TLHelper.makeManagerNode(beatBytes, TLManagerParameters(
address = Seq(AddressSet(0x0, 0xfff))))
lazy val module = new LazyModuleImp(this) {
// ...
}
}
class MyManager2(beatBytes: Int)(implicit p: Parameters) extends LazyModule {
val node = TLHelper.makeManagerNode(beatBytes, TLManagerParameters(
address = Seq(AddressSet(0x1000, 0xfff))))
lazy val module = new LazyModuleImp(this) {
// ...
}
}
class MyManagerGroup(beatBytes: Int)(implicit p: Parameters) extends LazyModule {
val man1 = LazyModule(new MyManager1(beatBytes))
val man2 = LazyModule(new MyManager2(beatBytes))
val node = TLIdentityNode()
man1.node := node
man2.node := node
lazy val module = new LazyModuleImp(this) {
// Nothing to do here
}
}
// DOC include end: MyManagerGroup
// DOC include start: MyClientManagerComplex
class MyClientManagerComplex(implicit p: Parameters) extends LazyModule {
val client = LazyModule(new MyClientGroup)
val manager = LazyModule(new MyManagerGroup(8))
manager.node :=* client.node
lazy val module = new LazyModuleImp(this) {
// Nothing to do here
}
}
// DOC include end: MyClientManagerComplex

View File

@@ -10,6 +10,7 @@ import freechips.rocketchip.regmapper.{HasRegMap, RegField}
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util.UIntIsOneOf
// DOC include start: PWM generic traits
case class PWMParams(address: BigInt, beatBytes: Int)
class PWMBase(w: Int) extends Module {
@@ -64,19 +65,23 @@ trait PWMModule extends HasRegMap {
0x08 -> Seq(
RegField(1, enable)))
}
// DOC include end: PWM generic traits
// DOC include start: PWMTL
class PWMTL(c: PWMParams)(implicit p: Parameters)
extends TLRegisterRouter(
c.address, "pwm", Seq("ucbbar,pwm"),
beatBytes = c.beatBytes)(
new TLRegBundle(c, _) with PWMBundle)(
new TLRegModule(c, _, _) with PWMModule)
// DOC include end: PWMTL
class PWMAXI4(c: PWMParams)(implicit p: Parameters)
extends AXI4RegisterRouter(c.address, beatBytes = c.beatBytes)(
new AXI4RegBundle(c, _) with PWMBundle)(
new AXI4RegModule(c, _, _) with PWMModule)
// DOC include start: HasPeripheryPWMTL
trait HasPeripheryPWMTL { this: BaseSubsystem =>
implicit val p: Parameters
@@ -88,7 +93,9 @@ trait HasPeripheryPWMTL { this: BaseSubsystem =>
pbus.toVariableWidthSlave(Some(portName)) { pwm.node }
}
// DOC include end: HasPeripheryPWMTL
// DOC include start: HasPeripheryPWMTLModuleImp
trait HasPeripheryPWMTLModuleImp extends LazyModuleImp {
implicit val p: Parameters
val outer: HasPeripheryPWMTL
@@ -97,6 +104,7 @@ trait HasPeripheryPWMTLModuleImp extends LazyModuleImp {
pwmout := outer.pwm.module.io.pwmout
}
// DOC include end: HasPeripheryPWMTLModuleImp
trait HasPeripheryPWMAXI4 { this: BaseSubsystem =>
implicit val p: Parameters

View File

@@ -0,0 +1,181 @@
// DOC include start: MyDeviceController
import chisel3._
import chisel3.util._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.regmapper._
import freechips.rocketchip.tilelink.TLRegisterNode
class MyDeviceController(implicit p: Parameters) extends LazyModule {
val device = new SimpleDevice("my-device", Seq("tutorial,my-device0"))
val node = TLRegisterNode(
address = Seq(AddressSet(0x10028000, 0xfff)),
device = device,
beatBytes = 8,
concurrency = 1)
lazy val module = new LazyModuleImp(this) {
val bigReg = RegInit(0.U(64.W))
val mediumReg = RegInit(0.U(32.W))
val smallReg = RegInit(0.U(16.W))
val tinyReg0 = RegInit(0.U(4.W))
val tinyReg1 = RegInit(0.U(4.W))
node.regmap(
0x00 -> Seq(RegField(64, bigReg)),
0x08 -> Seq(RegField(32, mediumReg)),
0x0C -> Seq(RegField(16, smallReg)),
0x0E -> Seq(
RegField(4, tinyReg0),
RegField(4, tinyReg1)))
}
}
// DOC include end: MyDeviceController
// DOC include start: MyAXI4DeviceController
import freechips.rocketchip.amba.axi4.AXI4RegisterNode
class MyAXI4DeviceController(implicit p: Parameters) extends LazyModule {
val node = AXI4RegisterNode(
address = AddressSet(0x10029000, 0xfff),
beatBytes = 8,
concurrency = 1)
lazy val module = new LazyModuleImp(this) {
val bigReg = RegInit(0.U(64.W))
val mediumReg = RegInit(0.U(32.W))
val smallReg = RegInit(0.U(16.W))
val tinyReg0 = RegInit(0.U(4.W))
val tinyReg1 = RegInit(0.U(4.W))
node.regmap(
0x00 -> Seq(RegField(64, bigReg)),
0x08 -> Seq(RegField(32, mediumReg)),
0x0C -> Seq(RegField(16, smallReg)),
0x0E -> Seq(
RegField(4, tinyReg0),
RegField(4, tinyReg1)))
}
}
// DOC include end: MyAXI4DeviceController
class MyQueueRegisters(implicit p: Parameters) extends LazyModule {
val device = new SimpleDevice("my-queue", Seq("tutorial,my-queue0"))
val node = TLRegisterNode(
address = Seq(AddressSet(0x1002A000, 0xfff)),
device = device,
beatBytes = 8,
concurrency = 1)
lazy val module = new LazyModuleImp(this) {
// DOC include start: MyQueueRegisters
// 4-entry 64-bit queue
val queue = Module(new Queue(UInt(64.W), 4))
node.regmap(
0x00 -> Seq(RegField(64, queue.io.deq, queue.io.enq)))
// DOC include end: MyQueueRegisters
}
}
class MySeparateQueueRegisters(implicit p: Parameters) extends LazyModule {
val device = new SimpleDevice("my-queue", Seq("tutorial,my-queue1"))
val node = TLRegisterNode(
address = Seq(AddressSet(0x1002B000, 0xfff)),
device = device,
beatBytes = 8,
concurrency = 1)
lazy val module = new LazyModuleImp(this) {
val queue = Module(new Queue(UInt(64.W), 4))
// DOC include start: MySeparateQueueRegisters
node.regmap(
0x00 -> Seq(RegField.r(64, queue.io.deq)),
0x08 -> Seq(RegField.w(64, queue.io.enq)))
// DOC include end: MySeparateQueueRegisters
}
}
class MyCounterRegisters(implicit p: Parameters) extends LazyModule {
val device = new SimpleDevice("my-counters", Seq("tutorial,my-counters0"))
val node = TLRegisterNode(
address = Seq(AddressSet(0x1002C000, 0xfff)),
device = device,
beatBytes = 8,
concurrency = 1)
lazy val module = new LazyModuleImp(this) {
// DOC include start: MyCounterRegisters
val counter = RegInit(0.U(64.W))
def readCounter(ready: Bool): (Bool, UInt) = {
when (ready) { counter := counter - 1.U }
// (ready, bits)
(true.B, counter)
}
def writeCounter(valid: Bool, bits: UInt): Bool = {
when (valid) { counter := counter + 1.U }
// Ignore bits
// Return ready
true.B
}
node.regmap(
0x00 -> Seq(RegField.r(64, readCounter(_))),
0x08 -> Seq(RegField.w(64, writeCounter(_, _))))
// DOC include end: MyCounterRegisters
}
}
class MyCounterReqRespRegisters(implicit p: Parameters) extends LazyModule {
val device = new SimpleDevice("my-counters", Seq("tutorial,my-counters1"))
val node = TLRegisterNode(
address = Seq(AddressSet(0x1002D000, 0xfff)),
device = device,
beatBytes = 8,
concurrency = 1)
lazy val module = new LazyModuleImp(this) {
// DOC include start: MyCounterReqRespRegisters
val counter = RegInit(0.U(64.W))
def readCounter(ivalid: Bool, oready: Bool): (Bool, Bool, UInt) = {
val responding = RegInit(false.B)
when (ivalid && !responding) { responding := true.B }
when (responding && oready) {
counter := counter - 1.U
responding := false.B
}
// (iready, ovalid, obits)
(!responding, responding, counter)
}
def writeCounter(ivalid: Bool, oready: Bool, ibits: UInt): (Bool, Bool) = {
val responding = RegInit(false.B)
when (ivalid && !responding) { responding := true.B }
when (responding && oready) {
counter := counter + 1.U
responding := false.B
}
// (iready, ovalid)
(!responding, responding)
}
node.regmap(
0x00 -> Seq(RegField.r(64, readCounter(_, _))),
0x08 -> Seq(RegField.w(64, writeCounter(_, _, _))))
// DOC include end: MyCounterReqRespRegisters
}
}

View File

@@ -0,0 +1,127 @@
package example
import chisel3._
import freechips.rocketchip.config.{Config}
// --------------
// Rocket Configs
// --------------
class RocketConfig extends Config(
new WithTop ++ // use default top
new WithBootROM ++ // use default bootrom
new freechips.rocketchip.subsystem.WithInclusiveCache ++ // use Sifive L2 cache
new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // single rocket-core
new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system
class HwachaRocketConfig extends Config(
new WithTop ++
new WithBootROM ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new hwacha.DefaultHwachaConfig ++ // use Hwacha vector accelerator
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
class RoccRocketConfig extends Config(
new WithTop ++
new WithBootROM ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithRoccExample ++ // use example RoCC-based accelerator
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
// DOC include start: JtagRocket
class jtagRocketConfig extends Config(
new WithDTMTop ++ // use top with dtm
new freechips.rocketchip.subsystem.WithJtagDTM ++ // add jtag/DTM module to coreplex
new WithBootROM ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
// DOC include end: JtagRocket
// DOC include start: PWMRocketConfig
class PWMRocketConfig extends Config(
new WithPWMTop ++ // use top with tilelink-controlled PWM
new WithBootROM ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
// DOC include end: PWMRocketConfig
class PWMAXI4RocketConfig extends Config(
new WithPWMAXI4Top ++ // use top with axi4-controlled PWM
new WithBootROM ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
class SimBlockDeviceRocketConfig extends Config(
new testchipip.WithBlockDevice ++ // add block-device module to peripherybus
new WithSimBlockDeviceTop ++ // use top with block-device IOs and connect to simblockdevice
new WithBootROM ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
class BlockDeviceModelRocketConfig extends Config(
new testchipip.WithBlockDevice ++ // add block-device module to periphery bus
new WithBlockDeviceModelTop ++ // use top with block-device IOs and connect to a blockdevicemodel
new WithBootROM ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
// DOC include start: GPIORocketConfig
class GPIORocketConfig extends Config(
new WithGPIO ++ // add GPIOs to the peripherybus
new WithGPIOTop ++ // use top with GPIOs
new WithBootROM ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
// DOC include end: GPIORocketConfig
class DualCoreRocketConfig extends Config(
new WithTop ++
new WithBootROM ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNBigCores(2) ++ // dual-core (2 RocketTiles)
new freechips.rocketchip.system.BaseConfig)
class RV32RocketConfig extends Config(
new WithTop ++
new WithBootROM ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithRV32 ++ // set RocketTiles to be 32-bit
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
class GB1MemoryRocketConfig extends Config(
new WithTop ++
new WithBootROM ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithExtMemSize((1<<30) * 1L) ++ // use 2GB simulated external memory
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
// DOC include start: Sha3Rocket
class Sha3RocketConfig extends Config(
new WithTop ++
new WithBootROM ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new sha3.WithSha3Accel ++ // add SHA3 rocc accelerator
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
// DOC include end: Sha3Rocket
// DOC include start: InitZeroRocketConfig
class InitZeroRocketConfig extends Config(
new WithInitZero(0x88000000L, 0x1000L) ++
new WithInitZeroTop ++
new WithBootROM ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
// DOC include end: InitZeroRocketConfig

View File

@@ -14,8 +14,8 @@ 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]]
case object BuildTop extends Field[(Clock, Bool, Parameters) => TopModule[Top]]
case object BuildTopWithDTM extends Field[(Clock, Bool, Parameters) => TopWithDTMModule[TopWithDTM]]
/**
* Test harness using TSI to bringup the system
@@ -28,7 +28,7 @@ class TestHarness(implicit val p: Parameters) extends Module {
// force Chisel to rename module
override def desiredName = "TestHarness"
val dut = p(BuildBoomRocketTop)(clock, reset.toBool, p)
val dut = p(BuildTop)(clock, reset.toBool, p)
dut.debug := DontCare
dut.connectSimAXIMem()
@@ -63,7 +63,7 @@ class TestHarnessWithDTM(implicit p: Parameters) extends Module
// force Chisel to rename module
override def desiredName = "TestHarness"
val dut = p(BuildBoomRocketTopWithDTM)(clock, reset.toBool, p)
val dut = p(BuildTopWithDTM)(clock, reset.toBool, p)
dut.reset := reset.asBool | dut.debug.ndreset
dut.connectSimAXIMem()

View File

@@ -10,69 +10,84 @@ import freechips.rocketchip.util.DontTouch
import testchipip._
import utilities.{System, SystemModule}
import sifive.blocks.devices.gpio._
// ------------------------------------
// BOOM and/or Rocket Top Level Systems
// ------------------------------------
class BoomRocketTop(implicit p: Parameters) extends boom.system.BoomRocketSystem
class Top(implicit p: Parameters) extends System
with HasNoDebug
with HasPeripherySerial {
override lazy val module = new BoomRocketTopModule(this)
override lazy val module = new TopModule(this)
}
class BoomRocketTopModule[+L <: BoomRocketTop](l: L) extends boom.system.BoomRocketSystemModule(l)
class TopModule[+L <: Top](l: L) extends SystemModule(l)
with HasNoDebugModuleImp
with HasPeripherySerialModuleImp
with DontTouch
//---------------------------------------------------------------------------------------------------------
// DOC include start: TopWithPWMTL
class BoomRocketTopWithPWMTL(implicit p: Parameters) extends BoomRocketTop
class TopWithPWMTL(implicit p: Parameters) extends Top
with HasPeripheryPWMTL {
override lazy val module = new BoomRocketTopWithPWMTLModule(this)
override lazy val module = new TopWithPWMTLModule(this)
}
class BoomRocketTopWithPWMTLModule(l: BoomRocketTopWithPWMTL) extends BoomRocketTopModule(l)
class TopWithPWMTLModule(l: TopWithPWMTL) extends TopModule(l)
with HasPeripheryPWMTLModuleImp
// DOC include end: TopWithPWMTL
//---------------------------------------------------------------------------------------------------------
class BoomRocketTopWithPWMAXI4(implicit p: Parameters) extends BoomRocketTop
class TopWithPWMAXI4(implicit p: Parameters) extends Top
with HasPeripheryPWMAXI4 {
override lazy val module = new BoomRocketTopWithPWMAXI4Module(this)
override lazy val module = new TopWithPWMAXI4Module(this)
}
class BoomRocketTopWithPWMAXI4Module(l: BoomRocketTopWithPWMAXI4) extends BoomRocketTopModule(l)
class TopWithPWMAXI4Module(l: TopWithPWMAXI4) extends TopModule(l)
with HasPeripheryPWMAXI4ModuleImp
//---------------------------------------------------------------------------------------------------------
class BoomRocketTopWithBlockDevice(implicit p: Parameters) extends BoomRocketTop
class TopWithBlockDevice(implicit p: Parameters) extends Top
with HasPeripheryBlockDevice {
override lazy val module = new BoomRocketTopWithBlockDeviceModule(this)
override lazy val module = new TopWithBlockDeviceModule(this)
}
class BoomRocketTopWithBlockDeviceModule(l: BoomRocketTopWithBlockDevice) extends BoomRocketTopModule(l)
class TopWithBlockDeviceModule(l: TopWithBlockDevice) extends TopModule(l)
with HasPeripheryBlockDeviceModuleImp
//---------------------------------------------------------------------------------------------------------
class BoomRocketTopWithGPIO(implicit p: Parameters) extends BoomRocketTop
with HasPeripheryGPIO {
override lazy val module = new BoomRocketTopWithGPIOModule(this)
class TopWithGPIO(implicit p: Parameters) extends Top
with HasPeripheryGPIO {
override lazy val module = new TopWithGPIOModule(this)
}
class BoomRocketTopWithGPIOModule(l: BoomRocketTopWithGPIO)
extends BoomRocketTopModule(l)
class TopWithGPIOModule(l: TopWithGPIO)
extends TopModule(l)
with HasPeripheryGPIOModuleImp
//---------------------------------------------------------------------------------------------------------
class BoomRocketTopWithDTM(implicit p: Parameters) extends boom.system.BoomRocketSystem
class TopWithDTM(implicit p: Parameters) extends System
{
override lazy val module = new BoomRocketTopWithDTMModule(this)
override lazy val module = new TopWithDTMModule(this)
}
class BoomRocketTopWithDTMModule[+L <: BoomRocketTopWithDTM](l: L) extends boom.system.BoomRocketSystemModule(l)
class TopWithDTMModule[+L <: TopWithDTM](l: L) extends SystemModule(l)
//---------------------------------------------------------------------------------------------------------
// DOC include start: TopWithInitZero
class TopWithInitZero(implicit p: Parameters) extends Top
with HasPeripheryInitZero {
override lazy val module = new TopWithInitZeroModuleImp(this)
}
class TopWithInitZeroModuleImp(l: TopWithInitZero) extends TopModule(l)
with HasPeripheryInitZeroModuleImp
// DOC include end: TopWithInitZero

View File

@@ -16,80 +16,14 @@ 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}
import utilities.TestSuiteHelper
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))
TestSuiteHelper.addRocketTestSuites(params)
TestSuiteHelper.addBoomTestSuites(params)
TestGeneration.addSuite(FastBlockdevTests)
TestGeneration.addSuite(SlowBlockdevTests)
if (!targetName.contains("NoNIC"))

View File

@@ -52,3 +52,7 @@ class FireSimDDR3FRFCFSLLC4MB3ClockDivConfig extends Config(
new FRFCFS16GBQuadRankLLC4MB3Div ++
new FireSimConfig)
class Midas2Config extends Config(
new WithMultiCycleRamModels ++
new FireSimConfig)

View File

@@ -4,14 +4,18 @@ import java.io.File
import chisel3.util.{log2Up}
import freechips.rocketchip.config.{Parameters, Config}
import freechips.rocketchip.groundtest.TraceGenParams
import freechips.rocketchip.tile._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.rocket.DCacheParams
import freechips.rocketchip.subsystem._
import freechips.rocketchip.devices.tilelink.BootROMParams
import freechips.rocketchip.devices.debug.DebugModuleParams
import boom.system.BoomTilesKey
import boom.common.BoomTilesKey
import testchipip.{WithBlockDevice, BlockDeviceKey, BlockDeviceConfig}
import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTParams}
import scala.math.{min, max}
import tracegen.TraceGenKey
import icenet._
class WithBootROM extends Config((site, here, up) => {
@@ -136,8 +140,10 @@ class FireSimBoomConfig extends Config(
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)
new boom.common.WithLargeBooms ++
new boom.common.WithNBoomCores(1) ++
new freechips.rocketchip.system.BaseConfig
)
// A safer implementation than the one in BOOM in that it
// duplicates whatever BOOMTileKey.head is present N times. This prevents
@@ -203,3 +209,69 @@ class SupernodeFireSimRocketChipOctaCoreConfig extends Config(
new WithExtMemSize(0x200000000L) ++ // 8GB
new FireSimRocketChipOctaCoreConfig)
class WithTraceGen(params: Seq[DCacheParams], nReqs: Int = 8192)
extends Config((site, here, up) => {
case TraceGenKey => params.map { dcp => TraceGenParams(
dcache = Some(dcp),
wordBits = site(XLen),
addrBits = 48,
addrBag = {
val nSets = dcp.nSets
val nWays = dcp.nWays
val blockOffset = site(SystemBusKey).blockOffset
val nBeats = min(2, site(SystemBusKey).blockBeats)
val beatBytes = site(SystemBusKey).beatBytes
List.tabulate(2 * nWays) { i =>
Seq.tabulate(nBeats) { j =>
BigInt((j * beatBytes) + ((i * nSets) << blockOffset))
}
}.flatten
},
maxRequests = nReqs,
memStart = site(ExtMem).get.master.base,
numGens = params.size)
}
case MaxHartIdBits => log2Up(params.size)
})
class FireSimTraceGenConfig extends Config(
new WithTraceGen(
List.fill(2) { DCacheParams(nMSHRs = 2, nSets = 16, nWays = 2) }) ++
new FireSimRocketChipConfig)
class WithL2TraceGen(params: Seq[DCacheParams], nReqs: Int = 8192)
extends Config((site, here, up) => {
case TraceGenKey => params.map { dcp => TraceGenParams(
dcache = Some(dcp),
wordBits = site(XLen),
addrBits = 48,
addrBag = {
val sbp = site(SystemBusKey)
val l2p = site(InclusiveCacheKey)
val nSets = max(l2p.sets, dcp.nSets)
val nWays = max(l2p.ways, dcp.nWays)
val nBanks = site(BankedL2Key).nBanks
val blockOffset = sbp.blockOffset
val nBeats = min(2, sbp.blockBeats)
val beatBytes = sbp.beatBytes
List.tabulate(2 * nWays) { i =>
Seq.tabulate(nBeats) { j =>
BigInt((j * beatBytes) + ((i * nSets * nBanks) << blockOffset))
}
}.flatten
},
maxRequests = nReqs,
memStart = site(ExtMem).get.master.base,
numGens = params.size)
}
case MaxHartIdBits => log2Up(params.size)
})
class FireSimTraceGenL2Config extends Config(
new WithL2TraceGen(
List.fill(2) { DCacheParams(nMSHRs = 2, nSets = 16, nWays = 2) }) ++
new WithInclusiveCache(
nBanks = 4,
capacityKB = 1024,
outerLatencyCycles = 50) ++
new FireSimRocketChipConfig)

View File

@@ -1,6 +1,7 @@
package firesim.firesim
import chisel3._
import chisel3.experimental.annotate
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
@@ -12,7 +13,7 @@ import freechips.rocketchip.rocket.TracedInstruction
import firesim.endpoints.{TraceOutputTop, DeclockedTracedInstruction}
import midas.models.AXI4BundleWithEdge
import midas.targetutils.ExcludeInstanceAsserts
import midas.targetutils.{ExcludeInstanceAsserts, MemModelAnnotation}
/** 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
@@ -104,3 +105,23 @@ trait ExcludeInvalidBoomAssertions extends LazyModuleImp {
ExcludeInstanceAsserts(("NonBlockingDCache", "dtlb"))
}
trait CanHaveMultiCycleRegfileImp {
val outer: utilities.HasBoomAndRocketTiles
val boomCores = outer.boomTiles.map(tile => tile.module.core)
boomCores.foreach({ core =>
core.iregfile match {
case irf: boom.exu.RegisterFileSynthesizable => annotate(MemModelAnnotation(irf.regfile))
case _ => Nil
}
if (core.fp_pipeline != null) core.fp_pipeline.fregfile match {
case irf: boom.exu.RegisterFileSynthesizable => annotate(MemModelAnnotation(irf.regfile))
case _ => Nil
}
})
outer.rocketTiles.foreach({ tile =>
annotate(MemModelAnnotation(tile.module.core.rocketImpl.rf.rf))
tile.module.fpuOpt.foreach(fpu => annotate(MemModelAnnotation(fpu.fpuImpl.regfile)))
})
}

View File

@@ -11,10 +11,11 @@ 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 utilities.{Subsystem, SubsystemModuleImp}
import icenet._
import testchipip._
import testchipip.SerialAdapter.SERIAL_IF_WIDTH
import tracegen.{HasTraceGenTiles, HasTraceGenTilesModuleImp}
import sifive.blocks.devices.uart._
import midas.models.AXI4BundleWithEdge
import java.io.File
@@ -30,7 +31,7 @@ import java.io.File
* determine which driver to build.
*******************************************************************************/
class FireSim(implicit p: Parameters) extends RocketSubsystem
class FireSim(implicit p: Parameters) extends Subsystem
with HasHierarchicalBusTopology
with CanHaveFASEDOptimizedMasterAXI4MemPort
with HasPeripheryBootROM
@@ -44,7 +45,7 @@ class FireSim(implicit p: Parameters) extends RocketSubsystem
override lazy val module = new FireSimModuleImp(this)
}
class FireSimModuleImp[+L <: FireSim](l: L) extends RocketSubsystemModuleImp(l)
class FireSimModuleImp[+L <: FireSim](l: L) extends SubsystemModuleImp(l)
with HasRTCModuleImp
with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp
with HasPeripheryBootROMModuleImp
@@ -54,9 +55,10 @@ class FireSimModuleImp[+L <: FireSim](l: L) extends RocketSubsystemModuleImp(l)
with HasPeripheryIceNICModuleImpValidOnly
with HasPeripheryBlockDeviceModuleImp
with HasTraceIOImp
with CanHaveMultiCycleRegfileImp
class FireSimNoNIC(implicit p: Parameters) extends RocketSubsystem
class FireSimNoNIC(implicit p: Parameters) extends Subsystem
with HasHierarchicalBusTopology
with CanHaveFASEDOptimizedMasterAXI4MemPort
with HasPeripheryBootROM
@@ -69,7 +71,7 @@ class FireSimNoNIC(implicit p: Parameters) extends RocketSubsystem
override lazy val module = new FireSimNoNICModuleImp(this)
}
class FireSimNoNICModuleImp[+L <: FireSimNoNIC](l: L) extends RocketSubsystemModuleImp(l)
class FireSimNoNICModuleImp[+L <: FireSimNoNIC](l: L) extends SubsystemModuleImp(l)
with HasRTCModuleImp
with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp
with HasPeripheryBootROMModuleImp
@@ -78,9 +80,10 @@ class FireSimNoNICModuleImp[+L <: FireSimNoNIC](l: L) extends RocketSubsystemMod
with HasPeripheryUARTModuleImp
with HasPeripheryBlockDeviceModuleImp
with HasTraceIOImp
with CanHaveMultiCycleRegfileImp
class FireBoom(implicit p: Parameters) extends BoomRocketSubsystem
class FireBoom(implicit p: Parameters) extends Subsystem
with HasHierarchicalBusTopology
with CanHaveFASEDOptimizedMasterAXI4MemPort
with HasPeripheryBootROM
@@ -94,7 +97,7 @@ class FireBoom(implicit p: Parameters) extends BoomRocketSubsystem
override lazy val module = new FireBoomModuleImp(this)
}
class FireBoomModuleImp[+L <: FireBoom](l: L) extends BoomRocketSubsystemModuleImp(l)
class FireBoomModuleImp[+L <: FireBoom](l: L) extends SubsystemModuleImp(l)
with HasRTCModuleImp
with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp
with HasPeripheryBootROMModuleImp
@@ -105,8 +108,9 @@ class FireBoomModuleImp[+L <: FireBoom](l: L) extends BoomRocketSubsystemModuleI
with HasPeripheryBlockDeviceModuleImp
with HasTraceIOImp
with ExcludeInvalidBoomAssertions
with CanHaveMultiCycleRegfileImp
class FireBoomNoNIC(implicit p: Parameters) extends BoomRocketSubsystem
class FireBoomNoNIC(implicit p: Parameters) extends Subsystem
with HasHierarchicalBusTopology
with CanHaveFASEDOptimizedMasterAXI4MemPort
with HasPeripheryBootROM
@@ -119,7 +123,7 @@ class FireBoomNoNIC(implicit p: Parameters) extends BoomRocketSubsystem
override lazy val module = new FireBoomNoNICModuleImp(this)
}
class FireBoomNoNICModuleImp[+L <: FireBoomNoNIC](l: L) extends BoomRocketSubsystemModuleImp(l)
class FireBoomNoNICModuleImp[+L <: FireBoomNoNIC](l: L) extends SubsystemModuleImp(l)
with HasRTCModuleImp
with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp
with HasPeripheryBootROMModuleImp
@@ -129,6 +133,7 @@ class FireBoomNoNICModuleImp[+L <: FireBoomNoNIC](l: L) extends BoomRocketSubsys
with HasPeripheryBlockDeviceModuleImp
with HasTraceIOImp
with ExcludeInvalidBoomAssertions
with CanHaveMultiCycleRegfileImp
case object NumNodes extends Field[Int]
@@ -174,3 +179,14 @@ class FireSimSupernode(implicit p: Parameters) extends Module {
} }
}
class FireSimTraceGen(implicit p: Parameters) extends BaseSubsystem
with HasHierarchicalBusTopology
with HasTraceGenTiles
with CanHaveFASEDOptimizedMasterAXI4MemPort {
override lazy val module = new FireSimTraceGenModuleImp(this)
}
class FireSimTraceGenModuleImp(outer: FireSimTraceGen)
extends BaseSubsystemModuleImp(outer)
with HasTraceGenTilesModuleImp
with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp

View File

@@ -109,9 +109,9 @@ abstract class FireSimTestSuite(
val lines = Source.fromFile(file).getLines.toList
lines.filter(_.startsWith("TRACEPORT")).drop(dropLines)
}
val resetLength = 50
val resetLength = 51
val verilatedOutput = getLines(new File(outDir, s"/${verilatedLog}"))
val synthPrintOutput = getLines(new File(genDir, s"/TRACEFILE"), resetLength + 1)
val synthPrintOutput = getLines(new File(genDir, s"/TRACEFILE"), resetLength)
assert(verilatedOutput.size == synthPrintOutput.size, "Outputs differ in length")
assert(verilatedOutput.nonEmpty)
for ( (vPrint, sPrint) <- verilatedOutput.zip(synthPrintOutput) ) {
@@ -131,8 +131,9 @@ abstract class FireSimTestSuite(
}
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)
}
class RamModelRocketF1Tests extends FireSimTestSuite("FireSimNoNIC", "FireSimRocketChipDualCoreConfig", "Midas2Config")
class RamModelBoomF1Tests extends FireSimTestSuite("FireBoomNoNIC", "FireSimBoomConfig", "Midas2Config")

1
generators/sha3 Submodule

Submodule generators/sha3 added at 83dd1955a9

View File

@@ -0,0 +1,76 @@
package tracegen
import chisel3._
import chisel3.util.log2Ceil
import freechips.rocketchip.config.{Config, Parameters}
import freechips.rocketchip.groundtest.{TraceGenParams}
import freechips.rocketchip.subsystem.{ExtMem, SystemBusKey, WithInclusiveCache, InclusiveCacheKey}
import freechips.rocketchip.system.BaseConfig
import freechips.rocketchip.rocket.DCacheParams
import freechips.rocketchip.tile.{MaxHartIdBits, XLen}
import scala.math.{max, min}
class WithTraceGen(params: Seq[DCacheParams], nReqs: Int = 8192)
extends Config((site, here, up) => {
case TraceGenKey => params.map { dcp => TraceGenParams(
dcache = Some(dcp),
wordBits = site(XLen),
addrBits = 48,
addrBag = {
val nSets = dcp.nSets
val nWays = dcp.nWays
val blockOffset = site(SystemBusKey).blockOffset
val nBeats = min(2, site(SystemBusKey).blockBeats)
val beatBytes = site(SystemBusKey).beatBytes
List.tabulate(2 * nWays) { i =>
Seq.tabulate(nBeats) { j =>
BigInt((j * beatBytes) + ((i * nSets) << blockOffset))
}
}.flatten
},
maxRequests = nReqs,
memStart = site(ExtMem).get.master.base,
numGens = params.size)
}
case MaxHartIdBits => if (params.size == 1) 1 else log2Ceil(params.size)
})
class TraceGenConfig extends Config(
new WithTraceGen(List.fill(2) { DCacheParams(nMSHRs = 0, nSets = 16, nWays = 2) }) ++
new BaseConfig)
class NonBlockingTraceGenConfig extends Config(
new WithTraceGen(List.fill(2) { DCacheParams(nMSHRs = 2, nSets = 16, nWays = 2) }) ++
new BaseConfig)
class WithL2TraceGen(params: Seq[DCacheParams], nReqs: Int = 8192)
extends Config((site, here, up) => {
case TraceGenKey => params.map { dcp => TraceGenParams(
dcache = Some(dcp),
wordBits = site(XLen),
addrBits = 48,
addrBag = {
val sbp = site(SystemBusKey)
val l2p = site(InclusiveCacheKey)
val nSets = max(l2p.sets, dcp.nSets)
val nWays = max(l2p.ways, dcp.nWays)
val blockOffset = sbp.blockOffset
val nBeats = min(2, sbp.blockBeats)
val beatBytes = sbp.beatBytes
List.tabulate(2 * nWays) { i =>
Seq.tabulate(nBeats) { j =>
BigInt((j * beatBytes) + ((i * nSets) << blockOffset))
}
}.flatten
},
maxRequests = nReqs,
memStart = site(ExtMem).get.master.base,
numGens = params.size)
}
case MaxHartIdBits => if (params.size == 1) 1 else log2Ceil(params.size)
})
class NonBlockingTraceGenL2Config extends Config(
new WithL2TraceGen(List.fill(2)(DCacheParams(nMSHRs = 2, nSets = 16, nWays = 4))) ++
new WithInclusiveCache ++
new BaseConfig)

View File

@@ -0,0 +1,43 @@
package tracegen
import chisel3._
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, BufferParams}
import freechips.rocketchip.groundtest.{DebugCombiner, TraceGenParams}
import freechips.rocketchip.subsystem._
case object TraceGenKey extends Field[Seq[TraceGenParams]]
trait HasTraceGenTiles { this: BaseSubsystem =>
val tiles = p(TraceGenKey).zipWithIndex.map { case (params, i) =>
LazyModule(new TraceGenTile(i, params, p))
}
tiles.foreach { t =>
sbus.fromTile(None, buffer = BufferParams.default) { t.masterNode }
}
}
trait HasTraceGenTilesModuleImp extends LazyModuleImp {
val outer: HasTraceGenTiles
val success = IO(Output(Bool()))
outer.tiles.zipWithIndex.map { case(t, i) =>
t.module.constants.hartid := i.U
}
val status = DebugCombiner(outer.tiles.map(_.module.status))
success := status.finished
}
class TraceGenSystem(implicit p: Parameters) extends BaseSubsystem
with HasTraceGenTiles
with HasHierarchicalBusTopology
with CanHaveMasterAXI4MemPort {
override lazy val module = new TraceGenSystemModuleImp(this)
}
class TraceGenSystemModuleImp(outer: TraceGenSystem)
extends BaseSubsystemModuleImp(outer)
with HasTraceGenTilesModuleImp
with CanHaveMasterAXI4MemPortModuleImp

View File

@@ -0,0 +1,27 @@
package tracegen
import chisel3._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy.LazyModule
import freechips.rocketchip.util.GeneratorApp
class TestHarness(implicit p: Parameters) extends Module {
val io = IO(new Bundle {
val success = Output(Bool())
})
val dut = Module(LazyModule(new TraceGenSystem).module)
io.success := dut.success
dut.connectSimAXIMem()
}
object Generator extends GeneratorApp {
// specify the name that the generator outputs files as
val longName = names.topModuleProject + "." + names.topModuleClass + "." + names.configs
// generate files
generateFirrtl
generateAnno
generateTestSuiteMakefrags
generateArtefacts
}

View File

@@ -0,0 +1,53 @@
package tracegen
import chisel3._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy.{LazyModule, SynchronousCrossing}
import freechips.rocketchip.groundtest.{TraceGenerator, TraceGenParams, DummyPTW, GroundTestStatus}
import freechips.rocketchip.rocket.{DCache, NonBlockingDCache, SimpleHellaCacheIF}
import freechips.rocketchip.tile.{BaseTile, BaseTileModuleImp, HartsWontDeduplicate}
import freechips.rocketchip.tilelink.{TLInwardNode, TLIdentityNode}
import freechips.rocketchip.interrupts._
class TraceGenTile(val id: Int, val params: TraceGenParams, q: Parameters)
extends BaseTile(params, SynchronousCrossing(), HartsWontDeduplicate(params), q) {
val dcache = params.dcache.map { dc => LazyModule(
if (dc.nMSHRs == 0) new DCache(hartId, crossing)
else new NonBlockingDCache(hartId))
}.get
val intInwardNode: IntInwardNode = IntIdentityNode()
val intOutwardNode: IntOutwardNode = IntIdentityNode()
val slaveNode: TLInwardNode = TLIdentityNode()
val ceaseNode: IntOutwardNode = IntIdentityNode()
val haltNode: IntOutwardNode = IntIdentityNode()
val wfiNode: IntOutwardNode = IntIdentityNode()
val masterNode = visibilityNode
masterNode := dcache.node
override lazy val module = new TraceGenTileModuleImp(this)
}
class TraceGenTileModuleImp(outer: TraceGenTile)
extends BaseTileModuleImp(outer) {
val status = IO(new GroundTestStatus)
val halt_and_catch_fire = None
val ptw = Module(new DummyPTW(1))
ptw.io.requestors.head <> outer.dcache.module.io.ptw
val tracegen = Module(new TraceGenerator(outer.params))
tracegen.io.hartid := constants.hartid
val dcacheIF = Module(new SimpleHellaCacheIF())
dcacheIF.io.requestor <> tracegen.io.mem
outer.dcache.module.io.cpu <> dcacheIF.io.cache
status.finished := tracegen.io.finished
status.timeout.valid := tracegen.io.timeout
status.timeout.bits := 0.U
status.error.valid := false.B
assert(!tracegen.io.timeout, s"TraceGen tile ${outer.id}: request timed out")
}

View File

@@ -0,0 +1,108 @@
//******************************************************************************
// Copyright (c) 2019 - 2019, The Regents of the University of California (Regents).
// All Rights Reserved. See LICENSE and LICENSE.SiFive for license details.
//------------------------------------------------------------------------------
package utilities
import chisel3._
import chisel3.internal.sourceinfo.{SourceInfo}
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.devices.debug.{HasPeripheryDebug, HasPeripheryDebugModuleImp}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.diplomaticobjectmodel.model.{OMInterrupt}
import freechips.rocketchip.diplomaticobjectmodel.logicaltree.{RocketTileLogicalTreeNode, LogicalModuleTree}
import freechips.rocketchip.tile._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.interrupts._
import freechips.rocketchip.util._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.amba.axi4._
import boom.common.{BoomTile, BoomTilesKey, BoomCrossingKey}
trait HasBoomAndRocketTiles extends HasTiles
with CanHavePeripheryPLIC
with CanHavePeripheryCLINT
with HasPeripheryDebug
{ this: BaseSubsystem =>
val module: HasBoomAndRocketTilesModuleImp
protected val rocketTileParams = p(RocketTilesKey)
protected val boomTileParams = p(BoomTilesKey)
// crossing can either be per tile or global (aka only 1 crossing specified)
private val rocketCrossings = perTileOrGlobalSetting(p(RocketCrossingKey), rocketTileParams.size)
private val boomCrossings = perTileOrGlobalSetting(p(BoomCrossingKey), boomTileParams.size)
// Make a tile and wire its nodes into the system,
// according to the specified type of clock crossing.
// Note that we also inject new nodes into the tile itself,
// also based on the crossing type.
val rocketTiles = rocketTileParams.zip(rocketCrossings).map { case (tp, crossing) =>
val rocket = LazyModule(new RocketTile(tp, crossing, PriorityMuxHartIdFromSeq(rocketTileParams), logicalTreeNode))
connectMasterPortsToSBus(rocket, crossing)
connectSlavePortsToCBus(rocket, crossing)
def treeNode: RocketTileLogicalTreeNode = new RocketTileLogicalTreeNode(rocket.rocketLogicalTree.getOMInterruptTargets)
LogicalModuleTree.add(logicalTreeNode, rocket.rocketLogicalTree)
rocket
}
val boomTiles = boomTileParams.zip(boomCrossings).map { case (tp, crossing) =>
val boom = LazyModule(new BoomTile(tp, crossing, PriorityMuxHartIdFromSeq(boomTileParams), logicalTreeNode))
connectMasterPortsToSBus(boom, crossing)
connectSlavePortsToCBus(boom, crossing)
def treeNode: RocketTileLogicalTreeNode = new RocketTileLogicalTreeNode(boom.rocketLogicalTree.getOMInterruptTargets)
LogicalModuleTree.add(logicalTreeNode, boom.rocketLogicalTree)
boom
}
// combine tiles and connect interrupts based on the order of harts
val boomAndRocketTiles = (rocketTiles ++ boomTiles).sortWith(_.tileParams.hartId < _.tileParams.hartId).map {
tile => {
connectInterrupts(tile, Some(debug), clintOpt, plicOpt)
tile
}
}
def coreMonitorBundles = (rocketTiles map { t => t.module.core.rocketImpl.coreMonitorBundle}).toList ++
(boomTiles map { t => t.module.core.coreMonitorBundle}).toList
}
trait HasBoomAndRocketTilesModuleImp extends HasTilesModuleImp
with HasPeripheryDebugModuleImp
{
val outer: HasBoomAndRocketTiles
}
class Subsystem(implicit p: Parameters) extends BaseSubsystem
with HasBoomAndRocketTiles
{
val tiles = boomAndRocketTiles
override lazy val module = new SubsystemModuleImp(this)
def getOMInterruptDevice(resourceBindingsMap: ResourceBindingsMap): Seq[OMInterrupt] = Nil
}
class SubsystemModuleImp[+L <: Subsystem](_outer: L) extends BaseSubsystemModuleImp(_outer)
with HasResetVectorWire
with HasBoomAndRocketTilesModuleImp
{
tile_inputs.zip(outer.hartIdList).foreach { case(wire, i) =>
wire.hartid := i.U
wire.reset_vector := global_reset_vector
}
// create file with boom params
ElaborationArtefacts.add("""core.config""", outer.tiles.map(x => x.module.toString).mkString("\n"))
}

View File

@@ -0,0 +1,45 @@
//******************************************************************************
// Copyright (c) 2019 - 2019, The Regents of the University of California (Regents).
// All Rights Reserved. See LICENSE and LICENSE.SiFive for license details.
//------------------------------------------------------------------------------
package utilities
import chisel3._
import freechips.rocketchip.config.{Parameters}
import freechips.rocketchip.subsystem._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.util.{DontTouch}
// ---------------------------------------------------------------------
// Base system that uses the debug test module (dtm) to bringup the core
// ---------------------------------------------------------------------
/**
* Base top with periphery devices and ports, and a BOOM + Rocket subsystem
*/
class System(implicit p: Parameters) extends Subsystem
with HasHierarchicalBusTopology
with HasAsyncExtInterrupts
with CanHaveMasterAXI4MemPort
with CanHaveMasterAXI4MMIOPort
with CanHaveSlaveAXI4Port
with HasPeripheryBootROM
{
override lazy val module = new SystemModule(this)
}
/**
* Base top module implementation with periphery devices and ports, and a BOOM + Rocket subsystem
*/
class SystemModule[+L <: System](_outer: L) extends SubsystemModuleImp(_outer)
with HasRTCModuleImp
with HasExtInterruptsModuleImp
with CanHaveMasterAXI4MemPortModuleImp
with CanHaveMasterAXI4MMIOPortModuleImp
with CanHaveSlaveAXI4PortModuleImp
with HasPeripheryBootROMModuleImp
with DontTouch

View File

@@ -1,4 +1,4 @@
package example
package utilities
import scala.collection.mutable.{LinkedHashSet}
@@ -8,7 +8,7 @@ import freechips.rocketchip.config.{Parameters}
import freechips.rocketchip.util.{GeneratorApp}
import freechips.rocketchip.system.{TestGeneration, RegressionTestSuite}
import boom.system.{BoomTilesKey}
import boom.common.{BoomTilesKey}
/**
* A set of pre-chosen regression tests

View File

@@ -13,5 +13,6 @@ addSbtPlugin("org.scalastyle" %% "scalastyle-sbt-plugin" % "1.0.0")
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.6")
addSbtPlugin("com.simplytyped" % "sbt-antlr4" % "0.8.1")
addSbtPlugin("com.github.gseitz" % "sbt-protobuf" % "0.6.3")
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.4")
libraryDependencies += "com.github.os72" % "protoc-jar" % "3.5.1.1"

5
scripts/add-githooks.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
# adds githooks, expects to be run from base directory
git config core.hooksPath .githooks

View File

@@ -11,7 +11,11 @@ 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
objs=$(make -n -f <(
echo 'include Makefile'
echo '$(info $(value fesvr_objs))'
) | head -n 1)
ar rcs -o libfesvr.a $objs
cp -f libfesvr.a "${RISCV}/lib"

View File

@@ -12,82 +12,82 @@ RDIR=$(pwd)
PRECOMPILED_REPO_HASH=56a40961c98db5e8f904f15dc6efd0870bfefd9e
function usage
{
echo "usage: ./scripts/build-toolchains.sh [riscv-tools] [esp-tools] [ec2fast | --ec2fast] "
usage() {
echo "usage: ${0} [riscv-tools | esp-tools | 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"
exit "$1"
}
error() {
echo "${0##*/}: ${1}" >&2
}
#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.
"$1" --version | awk "NR==1 {if (\$NF>$2) {exit 0} exit 1}" || {
error "${3} requires at least ${1} version ${2}"
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
;;
while getopts 'hH-:' opt ; do
case $opt in
h|H)
usage 3 ;;
-)
case $OPTARG in
help)
usage 3 ;;
ec2fast) # Preserve compatibility
EC2FASTINSTALL=true ;;
*)
error "invalid option: --${OPTARG}"
usage 1 ;;
esac ;;
*)
error "invalid option: -${opt}"
usage 1 ;;
esac
shift
done
shift $((OPTIND - 1))
if [ "$1" = ec2fast ] ; then
EC2FASTINSTALL=true
elif [ -n "$1" ] ; then
TOOLCHAIN="$1"
fi
if [ "$EC2FASTINSTALL" = "true" ]; then
if [ "$TOOLCHAIN" = "riscv-tools" ]; then
cd $RDIR
cd "$RDIR"
git clone https://github.com/firesim/firesim-riscv-tools-prebuilt.git
cd firesim-riscv-tools-prebuilt
git checkout $PRECOMPILED_REPO_HASH
git checkout "$PRECOMPILED_REPO_HASH"
PREBUILTHASH="$(cat HASH)"
git -C $CHIPYARD_DIR submodule update --init toolchains/$TOOLCHAIN
git -C "${CHIPYARD_DIR}" submodule update --init "toolchains/${TOOLCHAIN}"
cd "$CHIPYARD_DIR/toolchains/$TOOLCHAIN"
GITHASH="$(git rev-parse HEAD)"
cd $RDIR
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
error 'error: hash of precompiled toolchain does not match the riscv-tools submodule hash'
exit -1
fi
else
echo "Error: No precompiled toolchain for esp-tools or other non-native riscv-tools."
exit
error "error: unsupported precompiled toolchain: ${TOOLCHAIN}"
exit -1
fi
fi
@@ -104,44 +104,56 @@ if [ "$FASTINSTALL" = true ]; then
mv distrib "$RISCV"
# copy HASH in case user wants it later
cp HASH "$RISCV"
cd $RDIR
cd "$RDIR"
rm -rf firesim-riscv-tools-prebuilt
else
mkdir -p "$RISCV"
git -C $CHIPYARD_DIR submodule update --init --recursive toolchains/$TOOLCHAIN #--jobs 8
git -C "${CHIPYARD_DIR}" submodule update --init --recursive "toolchains/${TOOLCHAIN}" #--jobs 8
cd "$CHIPYARD_DIR/toolchains/$TOOLCHAIN"
export MAKEFLAGS="-j16"
# Scale number of parallel make jobs by hardware thread count
ncpu="$(getconf _NPROCESSORS_ONLN || # GNU
getconf NPROCESSORS_ONLN || # *BSD, Solaris
nproc --all || # Linux
sysctl -n hw.ncpu || # *BSD, OS X
:)" 2>/dev/null
case ${ncpu} in
''|*[^0-9]*) ;; # Ignore non-integer values
*) export MAKEFLAGS="-j ${ncpu}" ;;
esac
#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
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
"${CHIPYARD_DIR}/scripts/build-static-libfesvr.sh"
cd "$RDIR"
# build linux toolchain
cd "$CHIPYARD_DIR/toolchains/$TOOLCHAIN/riscv-gnu-toolchain/build"
make -j16 linux
make linux
echo -e "\\nRISC-V Linux GNU Toolchain installation completed!"
fi
cd $RDIR
cd "$RDIR"
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\${LD_LIBRARY_PATH:+":${LD_LIBRARY_PATH}"}" >> env.sh
{
echo "export CHIPYARD_TOOLCHAIN_SOURCED=1"
echo "export RISCV=$(printf '%q' "$RISCV")"
echo "export PATH=\${RISCV}/bin:\${PATH}"
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.
@@ -153,8 +165,8 @@ if [ "$FASTINSTALL" = "false" ]; then
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
build_project riscv-openocd --prefix="${RISCV}" --enable-remote-bitbang --enable-jtag_vpi --disable-werror
echo -e "\\nRISC-V OpenOCD installation completed!"
cd $RDIR
cd "$RDIR"
fi
fi

23
scripts/check-tracegen.sh Executable file
View File

@@ -0,0 +1,23 @@
#!/bin/bash
set -e
SCRIPT_DIR=$(dirname $0)
AXE_DIR=$(realpath ${SCRIPT_DIR}/../../axe)
ROCKET_DIR=$(realpath ${SCRIPT_DIR}/../generators/rocket-chip)
TO_AXE=${ROCKET_DIR}/scripts/toaxe.py
AXE=${AXE_DIR}/src/axe
AXE_SHRINK=${AXE_DIR}/src/axe-shrink.py
PATH=$PATH:${AXE_DIR}/src
grep '.*:.*#.*@' $1 > /tmp/clean-trace.txt
"$TO_AXE" /tmp/clean-trace.txt > /tmp/trace.axe
result=$("$AXE" check wmo /tmp/trace.axe)
if [ "$result" != OK ]; then
"$AXE_SHRINK" wmo /tmp/trace.axe
else
echo OK
fi

View File

@@ -8,11 +8,11 @@ set -o pipefail
RDIR=$(pwd)
scripts_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
cd $scripts_dir/..
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
./build-setup.sh "$@" --library
cd "$RDIR"

View File

@@ -28,9 +28,9 @@ 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/
cd "${scripts_dir}/../sims"
git submodule update --init firesim
cd firesim/sim
git submodule update --init midas
cd $RDIR
cd "$RDIR"
git config submodule.sims/firesim.update none

View File

@@ -3,11 +3,9 @@
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
git submodule update --init --recursive vlsi/hammer-"$1"-plugin

View File

@@ -90,8 +90,9 @@ $(sim_debug) : $(sim_vsrcs) $(sim_common_files)
#########################################################################################
# create a vcs vpd rule
#########################################################################################
.PRECIOUS: $(output_dir)/%.vpd %.vpd
$(output_dir)/%.vpd: $(output_dir)/% $(sim_debug)
$(sim_debug) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(VERBOSE_FLAGS) +vcdplusfile=$@ $(PERMISSIVE_OFF) $<
(set -o pipefail && $(sim_debug) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(VERBOSE_FLAGS) +vcdplusfile=$@ $(PERMISSIVE_OFF) $< 3>&1 1>&2 2>&3 | spike-dasm > $<.out)
#########################################################################################
# general cleanup rule

View File

@@ -51,7 +51,7 @@ LDFLAGS := $(LDFLAGS) -L$(RISCV)/lib -Wl,-rpath,$(RISCV)/lib -L$(sim_dir) -lfesv
VERILATOR_CC_OPTS = \
-O3 \
-CFLAGS "$(CXXFLAGS) -DTEST_HARNESS=V$(VLOG_MODEL) -DVERILATOR" \
-CFLAGS "-I$(build_dir) -include $(build_dir)/$(long_name).plusArgs" \
-CFLAGS "-I$(build_dir) -include $(build_dir)/$(long_name).plusArgs -include $(build_dir)/verilator.h" \
-LDFLAGS "$(LDFLAGS)"
VERILATOR_NONCC_OPTS = \
@@ -59,7 +59,8 @@ VERILATOR_NONCC_OPTS = \
+define+PRINTF_COND=\$$c\(\"verbose\",\"\&\&\"\,\"done_reset\"\) \
+define+STOP_COND=\$$c\(\"done_reset\"\) \
--assert \
--output-split 20000 \
--output-split 10000 \
--output-split-cfuncs 100 \
$(sim_vsrcs) \
-f $(sim_common_files)
@@ -105,10 +106,11 @@ $(sim_debug): $(model_mk_debug)
#########################################################################################
# create a verilator vpd rule
#########################################################################################
.PRECIOUS: $(output_dir)/%.vpd %.vcd
$(output_dir)/%.vpd: $(output_dir)/% $(sim_debug)
rm -f $@.vcd && mkfifo $@.vcd
vcd2vpd $@.vcd $@ > /dev/null &
$(sim_debug) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(VERBOSE_FLAGS) -v$@.vcd $(PERMISSIVE_OFF) $<
(set -o pipefail && $(sim_debug) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(VERBOSE_FLAGS) -v$@.vcd $(PERMISSIVE_OFF) $< 3>&1 1>&2 2>&3 | spike-dasm > $<.out)
#########################################################################################
# general cleanup rule

View File

@@ -5,7 +5,7 @@
#include "blkdev.h"
#define SECTOR_WORDS (BLKDEV_SECTOR_SIZE / sizeof(uint64_t))
#define TEST_SECTORS 128
#define TEST_SECTORS 16
unsigned long sector_buf[SECTOR_WORDS];

1
tools/chisel-testers Submodule

Submodule tools/chisel-testers added at 41f4eef0d8

1
tools/dsptools Submodule

Submodule tools/dsptools added at 15145ab623

1
tools/treadle Submodule

Submodule tools/treadle added at a03b969af1

View File

@@ -32,11 +32,22 @@ ifeq ($(SUB_PROJECT),example)
MODEL ?= TestHarness
VLOG_MODEL ?= TestHarness
MODEL_PACKAGE ?= $(SBT_PROJECT)
CONFIG ?= DefaultRocketConfig
CONFIG ?= RocketConfig
CONFIG_PACKAGE ?= $(SBT_PROJECT)
GENERATOR_PACKAGE ?= $(SBT_PROJECT)
TB ?= TestDriver
TOP ?= BoomRocketTop
TOP ?= Top
endif
ifeq ($(SUB_PROJECT),tracegen)
SBT_PROJECT ?= tracegen
MODEL ?= TestHarness
VLOG_MODEL ?= $(MODEL)
MODEL_PACKAGE ?= $(SBT_PROJECT)
CONFIG ?= TraceGenConfig
CONFIG_PACKAGE ?= $(SBT_PROJECT)
GENERATOR_PACKAGE ?= $(SBT_PROJECT)
TB ?= TestDriver
TOP ?= TraceGenSystem
endif
# for Rocket-chip developers
ifeq ($(SUB_PROJECT),rocketchip)
@@ -113,15 +124,18 @@ 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
# files that contain lists of files needed for VCS or Verilator simulation
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
# single file that contains all files needed for VCS or Verilator simulation (unique and without .h's)
sim_common_files ?= $(build_dir)/sim_files.common.f
#########################################################################################
# java arguments used in sbt
#########################################################################################
JAVA_ARGS ?= -Xmx8G -Xss8M -XX:MaxPermSize=256M
JAVA_HEAP_SIZE ?= 8G
JAVA_ARGS ?= -Xmx$(JAVA_HEAP_SIZE) -Xss8M -XX:MaxPermSize=256M
#########################################################################################
# default sbt launch command
@@ -142,7 +156,7 @@ output_dir=$(sim_dir)/output/$(long_name)
BINARY ?=
SIM_FLAGS ?=
VERBOSE_FLAGS ?= +verbose
sim_out_name = $(notdir $(basename $(BINARY))).$(long_name)
sim_out_name = $(subst $() $(),_,$(notdir $(basename $(BINARY))).$(long_name))
#########################################################################################
# build output directory for compilation