Merge pull request #367 from ucb-bar/dev

Chipyard 1.1.0 dev to master PR
This commit is contained in:
Sagar Karandikar
2020-01-25 19:14:38 -08:00
committed by GitHub
117 changed files with 2625 additions and 3330 deletions

View File

@@ -23,55 +23,94 @@ status=$(git submodule status)
all_names=()
search_submodule() {
echo "Running check on submodule $submodule in $dir"
hash=$(echo "$status" | grep "$dir.*$submodule " | awk '{print$1}' | grep -o "[[:alnum:]]*")
for branch in "${branches[@]}"
do
echo "Searching for $hash in origin/$branch of $submodule"
(git -C $dir/$submodule branch -r --contains "$hash" | grep "origin/$branch") && true # needs init'ed submodules
if [ $? -eq 0 ]
then
all_names+=("$dir/$submodule $hash 0")
return
fi
done
all_names+=("$dir/$submodule $hash 1")
return
}
search () {
for submodule in "${submodules[@]}"
do
echo "Running check on submodule $submodule in $dir"
hash=$(echo "$status" | grep "$dir.*$submodule " | awk '{print$1}' | grep -o "[[:alnum:]]*")
echo "Searching for $hash in origin/$branch of $submodule"
(git -C $dir/$submodule branch -r --contains "$hash" | grep "origin/$branch") && true # needs init'ed submodules
all_names+=("$dir/$submodule $hash $?")
search_submodule
done
}
submodules=("boom" "hwacha" "icenet" "rocket-chip" "sifive-blocks" "sifive-cache" "testchipip")
submodules=("boom" "hwacha" "icenet" "sha3" "rocket-chip" "sifive-blocks" "sifive-cache" "testchipip" "gemmini")
dir="generators"
branch="master"
if [ "$CIRCLE_BRANCH" == "master" ] || [ "$CIRCLE_BRANCH" == "dev" ]
then
branches=("master")
else
branches=("master" "dev")
fi
search
submodules=("riscv-gnu-toolchain" "riscv-isa-sim" "riscv-pk" "riscv-tests")
dir="toolchains/esp-tools"
branch="master"
branches=("master")
search
submodules=("riscv-gnu-toolchain" "riscv-isa-sim" "riscv-pk" "riscv-tests" "riscv-gnu-toolchain-prebuilt")
submodules=("riscv-gnu-toolchain" "riscv-isa-sim" "riscv-pk" "riscv-tests")
dir="toolchains/riscv-tools"
branch="master"
branches=("master")
search
# riscv-openocd doesn't use its master branch
submodules=("riscv-openocd")
dir="toolchains/riscv-tools"
branch="riscv"
branches=("riscv")
search
submodules=("barstools" "chisel3" "firrtl" "torture")
dir="tools"
branch="master"
submodules=("qemu" "libgloss")
dir="toolchains"
branches=("master")
search
submodules=("spec2017" "coremark")
dir="software"
branches=("master")
search
submodules=("axe" "barstools" "torture" "dsptools" "chisel-testers" "treadle" "firrtl-interpreter")
dir="tools"
if [ "$CIRCLE_BRANCH" == "master" ] || [ "$CIRCLE_BRANCH" == "dev" ]
then
branches=("master")
else
branches=("master" "dev")
fi
search
submodules=("firesim")
dir="sims"
branch="master"
if [ "$CIRCLE_BRANCH" == "master" ] || [ "$CIRCLE_BRANCH" == "dev" ]
then
branches=("master")
else
branches=("master" "dev")
fi
search
submodules=("hammer")
dir="vlsi"
branches=("master")
search
# turn off verbose printing to make this easier to read
set +x
@@ -90,3 +129,4 @@ do
done
echo "Done checking all submodules"

View File

@@ -31,14 +31,14 @@ jobs:
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v2-{{ checksum "../riscv-tools.hash" }}
- riscv-tools-installed-v4-{{ checksum "../riscv-tools.hash" }}
- run:
name: Building riscv-tools toolchain
command: |
.circleci/build-toolchains.sh riscv-tools
no_output_timeout: 120m
- save_cache:
key: riscv-tools-installed-v2-{{ checksum "../riscv-tools.hash" }}
key: riscv-tools-installed-v4-{{ checksum "../riscv-tools.hash" }}
paths:
- "/home/riscvuser/riscv-tools-install"
install-esp-toolchain:
@@ -55,14 +55,14 @@ jobs:
.circleci/create-hash.sh
- restore_cache:
keys:
- esp-tools-installed-v2-{{ checksum "../esp-tools.hash" }}
- esp-tools-installed-v4-{{ checksum "../esp-tools.hash" }}
- run:
name: Building esp-tools toolchain
command: |
.circleci/build-toolchains.sh esp-tools
no_output_timeout: 120m
- save_cache:
key: esp-tools-installed-v2-{{ checksum "../esp-tools.hash" }}
key: esp-tools-installed-v4-{{ checksum "../esp-tools.hash" }}
paths:
- "/home/riscvuser/esp-tools-install"
install-verilator:
@@ -105,7 +105,7 @@ jobs:
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v2-{{ checksum "../riscv-tools.hash" }}
- riscv-tools-installed-v4-{{ checksum "../riscv-tools.hash" }}
- run:
name: Build extra tests
command: .circleci/build-extra-tests.sh
@@ -131,7 +131,7 @@ jobs:
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v2-{{ checksum "../riscv-tools.hash" }}
- riscv-tools-installed-v4-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
@@ -160,7 +160,7 @@ jobs:
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v2-{{ checksum "../riscv-tools.hash" }}
- riscv-tools-installed-v4-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
@@ -189,7 +189,7 @@ jobs:
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v2-{{ checksum "../riscv-tools.hash" }}
- riscv-tools-installed-v4-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
@@ -218,7 +218,7 @@ jobs:
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v2-{{ checksum "../riscv-tools.hash" }}
- riscv-tools-installed-v4-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
@@ -247,7 +247,7 @@ jobs:
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v2-{{ checksum "../riscv-tools.hash" }}
- riscv-tools-installed-v4-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
@@ -276,7 +276,7 @@ jobs:
.circleci/create-hash.sh
- restore_cache:
keys:
- esp-tools-installed-v2-{{ checksum "../esp-tools.hash" }}
- esp-tools-installed-v4-{{ checksum "../esp-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
@@ -288,6 +288,93 @@ jobs:
key: hwacha-{{ .Branch }}-{{ .Revision }}
paths:
- "/home/riscvuser/project"
prepare-gemmini:
docker:
- image: riscvboom/riscvboom-images:0.0.12
environment:
JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
TERM: dumb
steps:
- add_ssh_keys:
fingerprints:
- "3e:c3:02:5b:ed:64:8c:b7:b0:04:43:bc:83:43:73:1e"
- checkout
- run:
name: Create hash of toolchains
command: |
.circleci/create-hash.sh
- restore_cache:
keys:
- esp-tools-installed-v4-{{ checksum "../esp-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Building the gemmini subproject using Verilator
command: .circleci/do-rtl-build.sh gemmini
no_output_timeout: 120m
- save_cache:
key: gemmini-{{ .Branch }}-{{ .Revision }}
paths:
- "/home/riscvuser/project"
prepare-tracegen:
docker:
- image: riscvboom/riscvboom-images:0.0.12
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-v4-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Building the tracegen subproject using Verilator
command: .circleci/do-rtl-build.sh tracegen
no_output_timeout: 120m
- save_cache:
key: tracegen-{{ .Branch }}-{{ .Revision }}
paths:
- "/home/riscvuser/project"
prepare-tracegen-boom:
docker:
- image: riscvboom/riscvboom-images:0.0.12
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-v4-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Building the tracegen-boom subproject using Verilator
command: .circleci/do-rtl-build.sh tracegen-boom
no_output_timeout: 120m
- save_cache:
key: tracegen-boom-{{ .Branch }}-{{ .Revision }}
paths:
- "/home/riscvuser/project"
prepare-firesim:
docker:
- image: riscvboom/riscvboom-images:0.0.12
@@ -305,7 +392,7 @@ jobs:
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v2-{{ checksum "../riscv-tools.hash" }}
- riscv-tools-installed-v4-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
@@ -334,7 +421,7 @@ jobs:
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v2-{{ checksum "../riscv-tools.hash" }}
- riscv-tools-installed-v4-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
@@ -360,7 +447,7 @@ jobs:
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v2-{{ checksum "../riscv-tools.hash" }}
- riscv-tools-installed-v4-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
@@ -381,7 +468,7 @@ jobs:
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v2-{{ checksum "../riscv-tools.hash" }}
- riscv-tools-installed-v4-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- example-{{ .Branch }}-{{ .Revision }}
@@ -405,7 +492,7 @@ jobs:
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v2-{{ checksum "../riscv-tools.hash" }}
- riscv-tools-installed-v4-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- boomrocketexample-{{ .Branch }}-{{ .Revision }}
@@ -429,7 +516,7 @@ jobs:
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v2-{{ checksum "../riscv-tools.hash" }}
- riscv-tools-installed-v4-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- boom-{{ .Branch }}-{{ .Revision }}
@@ -453,7 +540,7 @@ jobs:
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v2-{{ checksum "../riscv-tools.hash" }}
- riscv-tools-installed-v4-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- rocketchip-{{ .Branch }}-{{ .Revision }}
@@ -477,7 +564,7 @@ jobs:
.circleci/create-hash.sh
- restore_cache:
keys:
- esp-tools-installed-v2-{{ checksum "../esp-tools.hash" }}
- esp-tools-installed-v4-{{ checksum "../esp-tools.hash" }}
- restore_cache:
keys:
- hwacha-{{ .Branch }}-{{ .Revision }}
@@ -487,7 +574,55 @@ jobs:
- run:
name: Run hwacha tests
command: .circleci/run-tests.sh hwacha
firesim-run-tests:
gemmini-run-tests:
docker:
- image: riscvboom/riscvboom-images:0.0.12
environment:
JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit
TERM: dumb
steps:
- checkout
- run:
name: Create hash of toolchains
command: |
.circleci/create-hash.sh
- restore_cache:
keys:
- esp-tools-installed-v4-{{ checksum "../esp-tools.hash" }}
- restore_cache:
keys:
- gemmini-{{ .Branch }}-{{ .Revision }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Run gemmini tests
command: .circleci/run-tests.sh gemmini
tracegen-run-tests:
docker:
- image: riscvboom/riscvboom-images:0.0.12
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-v4-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- tracegen-{{ .Branch }}-{{ .Revision }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Run tracegen tests
command: .circleci/run-tests.sh tracegen
tracegen-boom-run-tests:
docker:
- image: riscvboom/riscvboom-images:0.0.12
environment:
@@ -502,6 +637,30 @@ jobs:
- restore_cache:
keys:
- riscv-tools-installed-v2-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- tracegen-boom-{{ .Branch }}-{{ .Revision }}
- restore_cache:
keys:
- verilator-installed-v3-{{ checksum "sims/verilator/verilator.mk" }}
- run:
name: Run tracegen-boom tests
command: .circleci/run-tests.sh tracegen-boom
firesim-run-tests:
docker:
- image: riscvboom/riscvboom-images:0.0.12
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-v4-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- firesim-{{ .Branch }}-{{ .Revision }}
@@ -528,7 +687,7 @@ jobs:
.circleci/create-hash.sh
- restore_cache:
keys:
- riscv-tools-installed-v2-{{ checksum "../riscv-tools.hash" }}
- riscv-tools-installed-v4-{{ checksum "../riscv-tools.hash" }}
- restore_cache:
keys:
- fireboom-{{ .Branch }}-{{ .Revision }}
@@ -569,6 +728,8 @@ workflows:
# Build verilator
- install-verilator
- commit-on-master-check
# Build extra tests
- build-extra-tests:
requires:
@@ -605,6 +766,21 @@ workflows:
- install-esp-toolchain
- install-verilator
- prepare-gemmini:
requires:
- install-esp-toolchain
- install-verilator
- prepare-tracegen:
requires:
- install-riscv-toolchain
- install-verilator
- prepare-tracegen-boom:
requires:
- install-riscv-toolchain
- install-verilator
- prepare-firesim:
requires:
- install-riscv-toolchain
@@ -644,6 +820,18 @@ workflows:
requires:
- prepare-hwacha
- gemmini-run-tests:
requires:
- prepare-gemmini
- tracegen-run-tests:
requires:
- prepare-tracegen
- tracegen-boom-run-tests:
requires:
- prepare-tracegen-boom
# Run the firesim tests
- firesim-run-tests:
requires:

View File

@@ -15,7 +15,8 @@ cd $LOCAL_CHIPYARD_DIR
# Use normalized output of git-submodule status as hashfile
for tools in 'riscv-tools' 'esp-tools' ; do
git submodule status "toolchains/${tools}" "toolchains/qemu" | while read -r line ; do
git submodule status "toolchains/${tools}" 'toolchains/libgloss' 'toolchains/qemu' |
while read -r line ; do
echo "${line#[!0-9a-f]}"
done > "${HOME}/${tools}.hash"
done

View File

@@ -45,7 +45,10 @@ mapping["example"]="SUB_PROJECT=example"
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=SimBlockDeviceRocketConfig TOP=TopWithBlockDevice"
mapping["hwacha"]="SUB_PROJECT=example CONFIG=HwachaRocketConfig GENERATOR_PACKAGE=hwacha"
mapping["blockdevrocketchip"]="SUB_PROJECT=example CONFIG=SimBlockDeviceRocketConfig"
mapping["hwacha"]="SUB_PROJECT=example CONFIG=HwachaRocketConfig"
mapping["gemmini"]="SUB_PROJECT=example CONFIG=GemminiRocketConfig"
mapping["tracegen"]="SUB_PROJECT=tracegen CONFIG=NonBlockingTraceGenL2Config"
mapping["tracegen-boom"]="SUB_PROJECT=tracegen CONFIG=BoomTraceGenConfig"
mapping["firesim"]="DESIGN=FireSim TARGET_CONFIG=DDR3FRFCFSLLC4MB_FireSimRocketChipConfig PLATFORM_CONFIG=BaseF1Config"
mapping["fireboom"]="DESIGN=FireSim TARGET_CONFIG=DDR3FRFCFSLLC4MB_FireSimBoomConfig PLATFORM_CONFIG=BaseF1Config"

View File

@@ -15,7 +15,6 @@ 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\""
@@ -35,7 +34,7 @@ TOOLS_DIR=$REMOTE_RISCV_DIR
LD_LIB_DIR=$REMOTE_RISCV_DIR/lib
VERILATOR_BIN_DIR=$REMOTE_VERILATOR_DIR/install/bin
if [ $1 = "hwacha" ]; then
if [ $1 = "hwacha" ] || [ $1 = "gemmini" ]; then
TOOLS_DIR=$REMOTE_ESP_DIR
LD_LIB_DIR=$REMOTE_ESP_DIR/lib
run "mkdir -p $REMOTE_ESP_DIR"

View File

@@ -32,7 +32,7 @@ run "cp -r ~/.sbt $REMOTE_WORK_DIR"
TOOLS_DIR=$REMOTE_RISCV_DIR
LD_LIB_DIR=$REMOTE_RISCV_DIR/lib
if [ $1 = "hwacha" ]; then
if [ $1 = "hwacha" ] || [ $1 = "gemmini" ]; then
TOOLS_DIR=$REMOTE_ESP_DIR
LD_LIB_DIR=$REMOTE_ESP_DIR/lib
run "mkdir -p $REMOTE_ESP_DIR"

View File

@@ -12,7 +12,7 @@ trap clean EXIT
cd $LOCAL_CHIPYARD_DIR
./scripts/init-submodules-no-riscv-tools.sh
cd sims/firesim/sim/midas && git submodule update --init
cd sims/firesim/sim/midas
# set stricthostkeychecking to no (must happen before rsync)
run "echo \"Ping $SERVER\""

View File

@@ -24,6 +24,10 @@ run_both () {
run_asm $@
}
run_tracegen () {
make tracegen -C $LOCAL_SIM_DIR VERILATOR_INSTALL_DIR=$LOCAL_VERILATOR_DIR $@
}
case $1 in
example)
run_bmark ${mapping[$1]}
@@ -46,6 +50,24 @@ case $1 in
export PATH=$RISCV/bin:$PATH
make run-rv64uv-p-asm-tests -j$NPROC -C $LOCAL_SIM_DIR VERILATOR_INSTALL_DIR=$LOCAL_VERILATOR_DIR ${mapping[$1]}
;;
gemmini)
export RISCV=$LOCAL_ESP_DIR
export LD_LIBRARY_PATH=$LOCAL_ESP_DIR/lib
export PATH=$RISCV/bin:$PATH
GEMMINI_SOFTWARE_DIR=$LOCAL_SIM_DIR/../../generators/gemmini/software/gemmini-rocc-tests
cd $GEMMINI_SOFTWARE_DIR
./build.sh
cd $LOCAL_SIM_DIR
$LOCAL_SIM_DIR/simulator-example-GemminiRocketConfig $GEMMINI_SOFTWARE_DIR/build/bareMetalC/aligned-baremetal
$LOCAL_SIM_DIR/simulator-example-GemminiRocketConfig $GEMMINI_SOFTWARE_DIR/build/bareMetalC/raw_hazard-baremetal
$LOCAL_SIM_DIR/simulator-example-GemminiRocketConfig $GEMMINI_SOFTWARE_DIR/build/bareMetalC/mvin_mvout-baremetal
;;
tracegen)
run_tracegen ${mapping[$1]}
;;
tracegen-boom)
run_tracegen ${mapping[$1]}
;;
*)
echo "No set of tests for $1. Did you spell it right?"
exit 1

View File

@@ -1 +1,3 @@
*/target
sims
toolchains

23
.github/ISSUE_TEMPLATE/bug-report.md vendored Normal file
View File

@@ -0,0 +1,23 @@
---
name: Bug Report
about: Report a problem with Chipyard
labels: bug
---
<!-- choose one -->
**Impact**: rtl | software | unknown | other
**What is the current behavior?**
**What is the expected behavior?**
**Please tell us about your environment:**
<!-- (examples)
- version: `chipyard git commit hash`
- os: `Linux knight 4.4.0-92-generic #115-Ubuntu SMP Thu Aug 10 09:04:33 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux`
- other: `prior steps taken/documentation followed/...`
-->
**Other information**
<!-- include detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, ... -->

View File

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

6
.github/ISSUE_TEMPLATE/other.md vendored Normal file
View File

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

13
.github/ISSUE_TEMPLATE/question.md vendored Normal file
View File

@@ -0,0 +1,13 @@
---
name: Question
about: Ask a question
labels: question
---
<!-- have you looked at the Chipyard documentation? -->
<!-- have you looked at the subproject documentation/githubs? -->
<!-- for example: -->
<!-- rocketchip: https://github.com/chipsalliance/rocket-chip/issues -->
<!-- boom: https://github.com/riscv-boom/riscv-boom/issues -->
<!-- firesim: https://github.com/firesim/firesim/issues -->

10
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,10 @@
**Related issue**: <!-- if applicable -->
<!-- choose one -->
**Type of change**: bug fix | new feature | other enhancement
<!-- choose one -->
**Impact**: rtl change | software change | unknown | other
**Release Notes**
<!-- Text from here to the end of the body will be considered for inclusion in the release notes for the version containing this pull request. -->

15
.gitmodules vendored
View File

@@ -65,6 +65,9 @@
[submodule "toolchains/esp-tools/riscv-tests"]
path = toolchains/esp-tools/riscv-tests
url = https://github.com/ucb-bar/esp-tests.git
[submodule "toolchains/libgloss"]
path = toolchains/libgloss
url = https://github.com/ucb-bar/libgloss-htif.git
[submodule "vlsi/hammer"]
path = vlsi/hammer
url = https://github.com/ucb-bar/hammer.git
@@ -95,3 +98,15 @@
[submodule "toolchains/qemu"]
path = toolchains/qemu
url = https://github.com/qemu/qemu.git
[submodule "tools/axe"]
path = tools/axe
url = https://github.com/CTSRD-CHERI/axe.git
[submodule "software/spec2017"]
path = software/spec2017
url = https://github.com/ucb-bar/spec2017-workload.git
[submodule "software/coremark"]
path = software/coremark
url = https://github.com/ucb-bar/coremark-workload.git
[submodule "generators/gemmini"]
path = generators/gemmini
url = https://github.com/ucb-bar/gemmini

View File

@@ -1,3 +1,52 @@
[1.0.0] - 2019-10-11
Added
This repository used to be "project-template", a template for Chisel-based projects. Through tighter integration of multiple projects from the Berkeley Architecture Research group at UC Berkeley, this repository is re-released as Chipyard - a framework for agile hardware development of RISC-V based Systems-on-Chip.
# Changelog
This changelog follows the format defined here: https://keepachangelog.com/en/1.0.0/
## [1.1.0] - 2020-01-25
A more detailed account of everything included is included in the dev to master PR for this release: https://github.com/ucb-bar/chipyard/pull/367
### Added
* Gemmini generator and config (PR #356 )
* Coremark + SPEC2017 benchmarks (PR #326, #338, #344)
* Add Hwacha tests to CI (PR #284)
* Add Hwacha tests to benchmark and assembly test suites (PR #284)
* Added Hwacha + Large Boom Config (PR #315)
* Add multi-core config with a small Rocket core attached on the side (PR #361 )
* Add UART and Test Harness UART Adapter to all configurations (PR #348)
* User can specify $RISCV directory in build-toolchains.sh (PR #334)
* Checksum offload in IceNet (PR #364)
### Changed
* Rocketchip bumped to commit [4f0cdea](https://github.com/chipsalliance/rocket-chip/tree/4f0cdea85c8a2b849fd582ccc8497892001d06b0), for chisel version 3.2.0 which includes Async reset support
* FireSim release 1.8.0
* FireMarshal release 1.8.0
* BOOM release 2.2.3 (PR #397)
* baremetal software toolchains, using libgloss and newlib instead of in-house syscalls.
* Add toolchain specific `env.sh` (PR #304)
* `run-binary`-like interface now dumps `.log` (stdout) and `.out` (stderr) files (PR #308)
* Split the VLSI build dir on type of design (PR #331)
* Reduce Ctags runtime and only look at scala, C, C++, and Python files (PR #346)
* Top/Top-level-traits now behave as a configurable generator (PR #347)
* Test suite makefrag generator includes Hwacha test suites (PR #342)
### Fixed
* Fix VLSI makefile requirements for SRAM generation (PR #318)
* Only filter header files from common simulation files (PR #322)
* Bump MacroCompiler for bugfixes (PR #332)
* commit-on-master check has specific behavior based on source branch (PR #345)
* Makefile filtering of blackbox resource files only omits .h files (PR #322)
* Parallel make fixed (PR #386 #392)
### Deprecated
* No longer need to specify `WithXTop`, default `Top` is a generator for all `Top`s (PR #347)
### Removed
* N/A
## [1.0.0] - 2019-10-19
### Added
* This repository used to be "project-template", a template for Chisel-based projects. Through tighter integration of multiple projects from the Berkeley Architecture Research group at UC Berkeley, this repository is re-released as Chipyard - a framework for agile hardware development of RISC-V based Systems-on-Chip.

39
LICENSE
View File

@@ -1,27 +1,30 @@
Copyright (c) 2017-2019, The Regents of the University of California (Regents).
BSD 3-Clause License
Copyright (c) 2017-2020, The Regents of the University of California (Regents)
All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the Regents nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

View File

@@ -1,4 +1,4 @@
![CHIPYARD](https://github.com/ucb-bar/chipyard/raw/alon-docs-dev/docs/_static/images/chipyard-logo-full.png)
![CHIPYARD](https://github.com/ucb-bar/chipyard/raw/master/docs/_static/images/chipyard-logo-full.png)
# Chipyard Framework [![CircleCI](https://circleci.com/gh/ucb-bar/chipyard/tree/master.svg?style=svg)](https://circleci.com/gh/ucb-bar/chipyard/tree/master)
@@ -29,6 +29,29 @@ Chipyard is actively developed in the [Berkeley Architecture Research Group][ucb
* See [CONTRIBUTING.md](/CONTRIBUTING.md)
## Chipyard-related Publications
These publications cover many of the internal components used in Chipyard. However, for the most up-to-date details, users should refer to the Chipyard docs.
* **Generators**
* **Rocket Chip**: K. Asanovic, et al., *UCB EECS TR*. [PDF](http://www2.eecs.berkeley.edu/Pubs/TechRpts/2016/EECS-2016-17.pdf).
* **BOOM**: C. Celio, et al., *Hot Chips 30*. [PDF](https://www.hotchips.org/hc30/1conf/1.03_Berkeley_BROOM_HC30.Berkeley.Celio.v02.pdf).
* **Hwacha**: Y. Lee, et al., *ESSCIRC'14*. [PDF](http://hwacha.org/papers/riscv-esscirc2014.pdf).
* **Gemmini**: H. Genc, et al., *arXiv*. [PDF](https://arxiv.org/pdf/1911.09925).
* **Sims**
* **FireSim**: S. Karandikar, et al., *ISCA'18*. [PDF](https://sagark.org/assets/pubs/firesim-isca2018.pdf).
* **FireSim Micro Top Picks**: S. Karandikar, et al., *IEEE Micro, Top Picks 2018*. [PDF](https://sagark.org/assets/pubs/firesim-micro-top-picks2018.pdf).
* **FASED**: D. Biancolin, et al., *FPGA'19*. [PDF](https://people.eecs.berkeley.edu/~biancolin/papers/fased-fpga19.pdf).
* **Golden Gate**: A. Magyar, et al., *ICCAD'19*. [PDF](https://davidbiancolin.github.io/papers/goldengate-iccad19.pdf).
* **FirePerf**: S. Karandikar, et al., *ASPLOS'20*. [PDF](https://sagark.org/assets/pubs/fireperf-asplos2020.pdf).
* **Tools**
* **Chisel**: J. Bachrach, et al., *DAC'12*. [PDF](https://people.eecs.berkeley.edu/~krste/papers/chisel-dac2012.pdf).
* **FIRRTL**: A. Izraelevitz, et al., *ICCAD'17*. [PDF](https://ieeexplore.ieee.org/document/8203780).
* **Chisel DSP**: A. Wang, et al., *DAC'18*. [PDF](https://ieeexplore.ieee.org/document/8465790).
* **VLSI**
* **Hammer**: E. Wang, et al., *ISQED'20*. [PDF](https://www.isqed.org/English/Archives/2020/Technical_Sessions/113.html).
[hwacha]:http://hwacha.org
[hammer]:https://github.com/ucb-bar/hammer

View File

@@ -7,14 +7,14 @@ lazy val chipyardRoot = RootProject(file("."))
lazy val commonSettings = Seq(
organization := "edu.berkeley.cs",
version := "1.0",
scalaVersion := "2.12.4",
scalaVersion := "2.12.10",
traceLevel := 15,
test in assembly := {},
assemblyMergeStrategy in assembly := { _ match {
case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard
case _ => MergeStrategy.first}},
scalacOptions ++= Seq("-deprecation","-unchecked","-Xsource:2.11"),
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % "test",
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.8" % "test",
libraryDependencies += "org.json4s" %% "json4s-jackson" % "3.6.1",
libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value,
libraryDependencies += "com.github.scopt" %% "scopt" % "3.7.0",
@@ -35,7 +35,7 @@ lazy val firesimAsLibrary = sys.env.get("FIRESIM_STANDALONE") == None
lazy val firesimDir = if (firesimAsLibrary) {
file("sims/firesim/sim/")
} else {
file("../../")
file("../../sim")
}
// Checks for -DROCKET_USE_MAVEN.
@@ -111,20 +111,23 @@ lazy val hardfloat = (project in rocketChipDir / "hardfloat")
lazy val rocketMacros = (project in rocketChipDir / "macros")
.settings(commonSettings)
lazy val rocketConfig = (project in rocketChipDir / "api-config-chipsalliance/build-rules/sbt")
.settings(commonSettings)
lazy val rocketchip = freshProject("rocketchip", rocketChipDir)
.settings(commonSettings)
.dependsOn(chisel, hardfloat, rocketMacros)
.dependsOn(chisel, hardfloat, rocketMacros, rocketConfig)
lazy val testchipip = (project in file("generators/testchipip"))
.dependsOn(rocketchip)
.dependsOn(rocketchip, sifive_blocks)
.settings(commonSettings)
lazy val example = conditionalDependsOn(project in file("generators/example"))
.dependsOn(boom, hwacha, sifive_blocks, sifive_cache, utilities, sha3)
.dependsOn(boom, hwacha, sifive_blocks, sifive_cache, utilities, sha3, gemmini, icenet)
.settings(commonSettings)
lazy val tracegen = conditionalDependsOn(project in file("generators/tracegen"))
.dependsOn(rocketchip, sifive_cache)
.dependsOn(rocketchip, sifive_cache, boom)
.settings(commonSettings)
lazy val utilities = conditionalDependsOn(project in file("generators/utilities"))
@@ -147,6 +150,10 @@ lazy val sha3 = (project in file("generators/sha3"))
.dependsOn(rocketchip, chisel_testers, midasTargetUtils)
.settings(commonSettings)
lazy val gemmini = (project in file("generators/gemmini"))
.dependsOn(rocketchip, chisel_testers, testchipip)
.settings(commonSettings)
lazy val tapeout = conditionalDependsOn(project in file("./tools/barstools/tapeout/"))
.dependsOn(chisel_testers, example)
.settings(commonSettings)
@@ -181,7 +188,7 @@ lazy val sifive_blocks = (project in file("generators/sifive-blocks"))
lazy val sifive_cache = (project in file("generators/sifive-cache")).settings(
commonSettings,
scalaSource in Compile := baseDirectory.value / "craft"
scalaSource in Compile := baseDirectory.value / "design/craft"
).dependsOn(rocketchip)
// Library components of FireSim
@@ -189,7 +196,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, sha3, utilities, tracegen, midasTargetUtils, midas, firesimLib % "test->test;compile->compile")
.dependsOn(boom, hwacha, example, icenet, testchipip, sifive_blocks, sifive_cache, sha3, utilities, tracegen, midasTargetUtils, midas, firesimLib % "test->test;compile->compile")
.settings(
commonSettings,
testGrouping in Test := isolateAllTests( (definedTests in Test).value )

View File

@@ -40,10 +40,15 @@ $(sim_files): $(call lookup_scala_srcs,$(base_dir)/generators/utilities/src/main
#########################################################################################
.INTERMEDIATE: generator_temp
$(FIRRTL_FILE) $(ANNO_FILE): generator_temp
@echo "" > /dev/null
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)"
.PHONY: firrtl
firrtl: $(FIRRTL_FILE)
#########################################################################################
# create verilog files rules and variables
#########################################################################################
@@ -54,30 +59,37 @@ TOP_TARGETS = $(TOP_FILE) $(TOP_SMEMS_CONF) $(TOP_ANNO) $(TOP_FIR) $(sim_top_bla
HARNESS_TARGETS = $(HARNESS_FILE) $(HARNESS_SMEMS_CONF) $(HARNESS_ANNO) $(HARNESS_FIR) $(sim_harness_blackboxes)
# DOC include start: FirrtlCompiler
# NOTE: These *_temp intermediate targets will get removed in favor of make 4.3 grouped targets (&: operator)
.INTERMEDIATE: firrtl_temp
$(TOP_TARGETS) $(HARNESS_TARGETS): firrtl_temp
@echo "" > /dev/null
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)"
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)" && touch $(sim_top_blackboxes) $(sim_harness_blackboxes)
# DOC include end: FirrtlCompiler
# This file is for simulation only. VLSI flows should replace this file with one containing hard SRAMs
MACROCOMPILER_MODE ?= --mode synflops
.INTERMEDIATE: top_macro_temp
$(TOP_SMEMS_FILE) $(TOP_SMEMS_FIR): top_macro_temp
@echo "" > /dev/null
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
.INTERMEDIATE: harness_macro_temp
$(HARNESS_SMEMS_FILE) $(HARNESS_SMEMS_FIR): harness_macro_temp
harness_macro_temp: $(HARNESS_SMEMS_CONF)
@echo "" > /dev/null
harness_macro_temp: $(HARNESS_SMEMS_CONF) | top_macro_temp
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 and headers in list of simulation file inputs
########################################################################################
$(sim_common_files): $(sim_files) $(sim_top_blackboxes) $(sim_harness_blackboxes)
awk '{print $1;}' $^ | sort -u | grep -v '.*\.h' > $@
awk '{print $1;}' $^ | sort -u | grep -v '.*\.h$$' > $@
#########################################################################################
# helper rule to just make verilog files
@@ -90,19 +102,19 @@ verilog: $(sim_vsrcs)
#########################################################################################
.PHONY: run-binary run-binary-fast run-binary-debug run-fast
run-binary: $(sim)
(set -o pipefail && $(sim) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(VERBOSE_FLAGS) $(PERMISSIVE_OFF) $(BINARY) 3>&1 1>&2 2>&3 | spike-dasm > $(sim_out_name).out)
(set -o pipefail && $(sim) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(VERBOSE_FLAGS) $(PERMISSIVE_OFF) $(BINARY) 2> >(spike-dasm > $(sim_out_name).out) | tee $(sim_out_name).log)
#########################################################################################
# helper rules to run simulator as fast as possible
#########################################################################################
run-binary-fast: $(sim)
(set -o pipefail && $(sim) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(PERMISSIVE_OFF) $(BINARY) 3>&1 1>&2 2>&3 | spike-dasm > $(sim_out_name).out)
(set -o pipefail && $(sim) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(PERMISSIVE_OFF) $(BINARY) | tee $(sim_out_name).log)
#########################################################################################
# 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_FLAGS) $(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) 2> >(spike-dasm > $(sim_out_name).out) | tee $(sim_out_name).log)
run-fast: run-asm-tests-fast run-bmark-tests-fast
@@ -114,10 +126,10 @@ $(output_dir)/%: $(RISCV)/riscv64-unknown-elf/share/riscv-tests/isa/%
ln -sf $< $@
$(output_dir)/%.run: $(output_dir)/% $(sim)
$(sim) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(PERMISSIVE_OFF) $< && touch $@
(set -o pipefail && $(sim) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(PERMISSIVE_OFF) $< | tee $<.log) && touch $@
$(output_dir)/%.out: $(output_dir)/% $(sim)
(set -o pipefail && $(sim) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(VERBOSE_FLAGS) $(PERMISSIVE_OFF) $< 3>&1 1>&2 2>&3 | spike-dasm > $@)
(set -o pipefail && $(sim) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(VERBOSE_FLAGS) $(PERMISSIVE_OFF) $< 2> >(spike-dasm > $@) | tee $<.log)
#########################################################################################
# include build/project specific makefrags made from the generator
@@ -125,3 +137,23 @@ $(output_dir)/%.out: $(output_dir)/% $(sim)
ifneq ($(filter run% %.run %.out %.vpd %.vcd,$(MAKECMDGOALS)),)
-include $(build_dir)/$(long_name).d
endif
#################################################
# Rules for running and checking tracegen tests #
#################################################
AXE_DIR=$(base_dir)/tools/axe/src
AXE=$(AXE_DIR)/axe
$(AXE): $(wildcard $(AXE_DIR)/*.[ch]) $(AXE_DIR)/make.sh
cd $(AXE_DIR) && ./make.sh
$(output_dir)/tracegen.out: $(sim)
mkdir -p $(output_dir) && $(sim) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(VERBOSE_FLAGS) $(PERMISSIVE_OFF) none 2> $@
$(output_dir)/tracegen.result: $(output_dir)/tracegen.out $(AXE)
$(base_dir)/scripts/check-tracegen.sh $< > $@
tracegen: $(output_dir)/tracegen.result
.PHONY: tracegen

View File

@@ -0,0 +1,111 @@
.. _cdes:
Context-Dependent-Environments
========================================
Readers may notice that the parameterization system frequently uses ``(site, here, up)``.
This construct is an artifact of the "context-dependent-environment" system which Chipyard and Rocket Chip both leverage for powerful composable hardware configuration.
The CDE parameterization system provides different "Views" of a single global parameterization. The syntax for accessing a ``Field`` within a ``View`` is ``my_view(MyKey, site_view)``, where ``site_view`` is a "global" view that will be passed recursively into various functions and key-lookups in the call-stack of ``my_view(MyKey, site_view)``.
.. note::
Rocket Chip based designs will frequently use ``val p: Parameters`` and ``p(SomeKey)`` to lookup the value of a key. ``Parameters`` is just a subclass of the ``View`` abstract class, and ``p(SomeKey)`` really expands into ``p(SomeKey, p)``. This is because we consider the call ``p(SomeKey)`` to be the "site", or "source" of the original key query, so we need to pass in the view of the configuration provided by ``p`` recursively to future calls through the ``site`` argument.
Consider the following example using CDEs.
.. code:: scala
case object SomeKeyX extends Field[Boolean](false) // default is false
case object SomeKeyY extends Field[Boolean](false) // default is false
case object SomeKeyZ extends Field[Boolean](false) // default is false
class WithX(b: Boolean) extends Config((site, here, up) => {
case SomeKeyX => b
}
class WithY(b: Boolean) extends Config((site, here, up) => {
case SomeKeyY => b
}
When forming a query based on a ``Parameters`` object, like ``p(SomeKeyX)``, the configuration system traverses the "chain" of mixins until it finds a partial function which is defined at the key, and then returns that value.
.. code:: scala
val params = Config(new WithX(true) ++ new WithY(true)) // "chain" together mixins
params(SomeKeyX) // evaluates to true
params(SomeKeyY) // evaluates to true
params(SomeKeyZ) // evaluates to false
In this example, the evaluation of ``params(SomeKeyX)`` will terminate in the partial function defined in ``WithX(true)``, while the evaluation of ``params(SomeKeyY)`` will terminate in the partial function defined in ``WithY(true)``. Note that when no partial functions match, the evaluation will return the default value for that parameter.
The real power of CDEs arises from the ``(site, here, up)`` parameters to the partial functions, which provide useful "views" into the global parameterization that the partial functions may access to determine a parameterization.
.. note::
Additional information on the motivations for CDEs can be found in Chapter 2 of `Henry Cook's Thesis <https://www2.eecs.berkeley.edu/Pubs/TechRpts/2016/EECS-2016-89.pdf>`_ .
Site
~~~~
``site`` provides a ``View`` of the "source" of the original parameter query.
.. code:: scala
class WithXEqualsYSite extends Config((site, here, up) => {
case SomeKeyX => site(SomeKeyY) // expands to site(SomeKeyY, site)
}
val params_1 = Config(new WithXEqualsYSite ++ new WithY(true))
val params_2 = Config(new WithY(true) ++ new WithXEqualsYSite)
params_1(SomeKeyX) // evaluates to true
params_2(SomeKeyX) // evaluates to true
In this example, the partial function in ``WithXEqualsYSite`` will look up the value of ``SomeKeyY`` in the original ``params_N`` object, which becomes ``site`` in each call in the recursive traversal.
Here
~~~~
``here`` provides a ``View`` of the locally defined Config, which typically just contains some partial function.
.. code:: scala
class WithXEqualsYHere extends Config((site, here, up) => {
case SomeKeyY => false
case SomeKeyX => here(SomeKeyY, site)
}
val params_1 = Config(new WithXEqualsYHere ++ new WithY(true))
val params_2 = Config(new WithY(true) ++ new WithXEqualsYHere)
params_1(SomeKeyX) // evaluates to false
params_2(SomeKeyX) // evaluates to false
In this example, note that although our final parameterization in ``params_2`` has ``SomeKeyY`` set to ``true``, the call to ``here(SomeKeyY, site)`` only looks in the local partial function defined in ``WithXEqualsYHere``. Note that we pass ``site`` to ``here`` since ``site`` may be used in the recursive call.
Up
~~~~
``up`` provides a ``View`` of the previously defined set of partial functions in the "chain" of partial functions. This is useful when we want to lookup a previously set value for some key, but not the final value for that key.
.. code:: scala
class WithXEqualsYUp extends Config((site, here, up) => {
case SomeKeyX => up(SomeKeyY, site)
}
val params_1 = Config(new WithXEqualsYUp ++ new WithY(true))
val params_2 = Config(new WithY(true) ++ new WithXEqualsYUp)
params_1(SomeKeyX) // evaluates to true
params_2(SomeKeyX) // evaluates to false
In this example, note how ``up(SomeKeyY, site)`` in ``WithXEqualsYUp`` will refer to *either* the the partial function defining ``SomeKeyY`` in ``WithY(true)`` *or* the default value for ``SomeKeyY`` provided in the original ``case object SomeKeyY`` definition, *depending on the order in which the mixins were used*. Since the order of mixins affects the the order of the ``View`` traversal, ``up`` provides a different ``View`` of the parameterization in ``params_1`` and ``params_2``.
Also note that again, ``site`` must be recursively passed through the call to ``up``.

View File

@@ -48,8 +48,8 @@ By default, Chipyard uses the Tethered Serial Interface (TSI) to communicate wit
TSI protocol is an implementation of HTIF that is used to send commands to the
RISC-V DUT. These TSI commands are simple R/W commands
that are able to probe the DUT's memory space. During simulation, the host sends TSI commands to a
simulation stub called ``SimSerial`` (C++ class) that resides in a ``SimSerial`` verilog module
(both are located in the ``generators/testchipip`` project). This ``SimSerial`` verilog module then
simulation stub called ``SimSerial`` (C++ class) that resides in a ``SimSerial`` Verilog module
(both are located in the ``generators/testchipip`` project). This ``SimSerial`` Verilog module then
sends the TSI command recieved by the simulation stub into the DUT which then converts the TSI
command into a TileLink request. This conversion is done by the ``SerialAdapter`` module
(located in the ``generators/testchipip`` project). In simulation, FESVR
@@ -60,11 +60,19 @@ mechanism to communicate with the DUT in simulation.
In the case of a chip tapeout bringup, TSI commands can be sent over a custom communication
medium to communicate with the chip. For example, some Berkeley tapeouts have a FPGA
with a RISC-V soft-core that runs FESVR. The FESVR on the soft-core sends TSI commands
to a TSI-to-TileLink converter living on the FPGA (i.e. ``SerialAdapter``). Then this converter
sends the converted TileLink commands over a serial link to the chip. The following image shows this flow:
to a TSI-to-TileLink converter living on the FPGA (i.e. ``SerialAdapter``). After the transaction is
converted to TileLink, the ``TLSerdesser`` (located in ``generators/testchipip``) serializes the
transaction and sends it to the chip (this ``TLSerdesser`` is sometimes also referred to as a
serial-link or serdes). Once the serialized transaction is received on the
chip, it is deserialized and masters a bus on the chip. The following image shows this flow:
.. image:: ../_static/images/chip-bringup.png
.. note::
The ``TLSerdesser`` can also be used as a slave (client), so it can sink memory requests from the chip
and connect to off-chip backing memory. Or in other words, ``TLSerdesser`` creates a bi-directional TileLink
interface.
Using the Debug Module Interface (DMI)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -75,8 +83,8 @@ The DTM is given in the `RISC-V Debug Specification <https://riscv.org/specifica
and is responsible for managing communication between the DUT and whatever lives on the other side of the DMI (in this case FESVR).
This is implemented in the Rocket Chip ``Subsystem`` by having the ``HasPeripheryDebug`` and ``HasPeripheryDebugModuleImp`` mixins.
During simulation, the host sends DMI commands to a
simulation stub called ``SimDTM`` (C++ class) that resides in a ``SimDTM`` verilog module
(both are located in the ``generators/rocket-chip`` project). This ``SimDTM`` verilog module then
simulation stub called ``SimDTM`` (C++ class) that resides in a ``SimDTM`` Verilog module
(both are located in the ``generators/rocket-chip`` project). This ``SimDTM`` Verilog module then
sends the DMI command recieved by the simulation stub into the DUT which then converts the DMI
command into a TileLink request. This conversion is done by the DTM named ``DebugModule`` in the ``generators/rocket-chip`` project.
When the DTM receives the program to load, it starts to write the binary byte-wise into memory.
@@ -109,7 +117,7 @@ top-level system with the DTM (``TopWithDTM``), a test-harness to connect to the
:start-after: DOC include start: DmiRocket
:end-before: DOC include end: DmiRocket
In this example, the ``WithDTMTop`` mixin specifies that the top-level SoC will instantiate a DTM (that by default is setup to use DMI).
In this example, the ``WithDTM`` mixin specifies that the top-level SoC will instantiate a DTM (that by default is setup to use DMI).
The rest of the mixins specify the rest of the system (cores, accelerators, etc).
Then you can run simulations with the new DMI-enabled top-level and test-harness.
@@ -119,7 +127,7 @@ Then you can run simulations with the new DMI-enabled top-level and test-harness
# or
cd sims/vcs
make CONFIG=dmiRocketConfig TOP=TopWithDTM MODEL=TestHarnessWithDTM run-asm-tests
make CONFIG=dmiRocketConfig run-asm-tests
Using the JTAG Interface
------------------------
@@ -132,8 +140,7 @@ Creating a DTM+JTAG Config
First, a DTM config must be created for the system that you want to create.
This step is similar to the DMI simulation section within the :ref:`Starting the TSI or DMI Simulation` section.
First, you must make a top-level system (``TopWithDTM``) and test-harness (``TestHarnessWithDTM``) that instantiates
and connects the DTM correctly. The configuration is very similar to a DMI-based configuration. The main difference
The configuration is very similar to a DMI-based configuration. The main difference
is the addition of the ``WithJtagDTM`` mixin that configures the instantiated DTM to use the JTAG protocol as the
bringup method.
@@ -153,7 +160,7 @@ After creating the config, call the ``make`` command like the following to build
# or
cd sims/vcs
make CONFIG=jtagRocketConfig TOP=TopWithDTM MODEL=TestHarnessWithDTM
make CONFIG=jtagRocketConfig
In this example, the simulation 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

View File

@@ -40,14 +40,18 @@ make variable to set additional simulator flags:
make CONFIG=CustomConfig run-binary-debug BINARY=linux.riscv SIM_FLAGS=+vpdfilesize=1024
.. note::
In some cases where there is multiple simulator flags, you can write the ``SIM_FLAGS``
like the following: ``SIM_FLAGS="+vpdfilesize=XYZ +some_other_flag=ABC"``.
Print Output
---------------------------
Both Rocket and BOOM can be configured with varying levels of print output.
For information see the Rocket core source code, or the BOOM `documentation
<https://docs.boom-core.org/en/latest/>`__ .website. In addition, developers
may insert arbitrary printfs at arbitrary conditions within the Chisel g
enerators. See the Chisel documentation for information on this.
For information see the Rocket core source code, or the BOOM `documentation
<https://docs.boom-core.org/en/latest/>`__ website. In addition, developers
may insert arbitrary printfs at arbitrary conditions within the Chisel generators.
See the Chisel documentation for information on this.
Once the cores have been configured with the desired print statements, the
``+verbose`` flag will cause the simulator to print the statements. The following
@@ -56,6 +60,7 @@ commands will all generate desired print statements:
.. code-block:: shell
make CONFIG=CustomConfig run-binary-debug BINARY=helloworld.riscv
# The below command does the same thing
./simv-CustomConfig-debug +verbose helloworld.riscv

View File

@@ -4,7 +4,7 @@ Tops, Test-Harnesses, and the Test-Driver
The three highest levels of hierarchy in a Chipyard
SoC are the Top (DUT), ``TestHarness``, and the ``TestDriver``.
The Top and ``TestHarness`` are both emitted by Chisel generators.
The ``TestDriver`` serves as our testbench, and is a verilog
The ``TestDriver`` serves as our testbench, and is a Verilog
file in Rocket Chip.
@@ -45,22 +45,13 @@ System
Tops
^^^^^^^^^^^^^^^^^^^^^^^^^
A SoC Top then extends the ``System`` class with any config-specific components. There are two "classes" of Tops in Chipyard that enable different bringup methods.
A SoC Top then extends the ``System`` class with any config-specific components.
In Chipyard, this includes things like adding a NIC, UART, and GPIO as well as setting up the hardware for the bringup method.
Please refer to :ref:`Communicating with the DUT` for more information on these bringup methods.
- ``Top`` is the default setup. These top modules instantiate a serial module which interfaces with the ``TestHarness``. In addition, the Debug Transfer Module (DTM) is removed and replaced with a TSI-based bringup flow. All other example "Tops" (except the ``TopWithDTM``) extend this Top as the "base" top-level system.
- ``TopWithDTM`` does not include the TSI-based bringup flow. Instead it keeps the Debug Transfer Module (DTM) within the design so that you can use a DMI-based or JTAG-based bringup.
For a custom Top a mixed-in trait adds the additional modules or IOs (an example of this is ``TopWithGPIO``).
TestHarness
-------------------------
There are two variants of ``TestHarness`` generators in Chipyard, both located in
`generators/example/src/main/scala/TestHarness.scala <https://github.com/ucb-bar/chipyard/blob/master/generators/example/src/main/scala/TestHarness.scala>`__.
One is designed for TSI-based bringup, while the other performs DTM-based bringup.
See :ref:`Communicating with the DUT` for more information on these two methodologies.
The wiring between the ``TestHarness`` and the Top are performed in methods defined in mixins added to the Top.
When these methods are called from the ``TestHarness``, they may instantiate modules within the scope of the harness,
and then connect them to the DUT. For example, the ``connectSimAXIMem`` method defined in the
@@ -70,21 +61,9 @@ and connect them to the correct IOs of the top.
While this roundabout way of attaching to the IOs of the top may seem to be unnecessarily complex, it allows the designer to compose
custom traits together without having to worry about the details of the implementation of any particular trait.
Specifying a Top
^^^^^^^^^^^^^^^^^^^^^^^^^
To see why the Top connection method is useful, consider the case where we want to use a custom Top with additional GPIO pins.
In `generators/example/src/main/scala/Top.scala <https://github.com/ucb-bar/chipyard/blob/master/generators/example/src/main/scala/Top.scala>`__,
we can see how the ``TopWithGPIO`` class adds the ``HasPeripheryGPIO`` trait. This trait adds IOs to the Top module,
instantiates a TileLink GPIO node, and connects it to the proper buses.
If we look at the ``WithGPIOTop`` mixin in the ``ConfigMixins.scala`` file, we see that adding this mixin to the top-level Config overrides the
``BuildTop`` key with a custom function that both instantiates the custom Top, and drives all the GPIO pins.
When the ``TestHarness`` looks up the ``BuildTop`` key, this function will run and perform the specified wiring, and then return the Top module.
TestDriver
-------------------------
The ``TestDriver`` is defined in ``generators/rocketchip/src/main/resources/vsrc/TestDriver.v``.
This verilog file executes a simulation by instantiating the ``TestHarness``, driving the clock and reset signals, and interpreting the success output.
This file is compiled with the generated verilog for the ``TestHarness`` and the Top to produce a simulator.
This Verilog file executes a simulation by instantiating the ``TestHarness``, driving the clock and reset signals, and interpreting the success output.
This file is compiled with the generated Verilog for the ``TestHarness`` and the Top to produce a simulator.

View File

@@ -12,3 +12,5 @@ They expect you to know about Chisel, Parameters, Configs, etc.
Chip-Communication
Debugging-RTL
Resources
CDEs

View File

@@ -10,6 +10,19 @@ Chipyard is developed and tested on Linux-based systems.
.. Warning:: Working under Windows is not recommended.
In CentOS-based platforms, we recommend installing the following dependencies:
.. include:: /../scripts/centos-req.sh
:code: bash
In Ubuntu/Debian-based platforms (Ubuntu), we recommend installing the following dependencies:
.. include:: /../scripts/ubuntu-req.sh
:code: bash
.. Note:: When running on an Amazon Web Services EC2 FPGA-development instance (for FireSim), FireSim includes a machine setup script that will install all of the aforementioned dependencies (and some additional ones).
Checking out the sources
------------------------
@@ -21,6 +34,8 @@ After cloning this repo, you will need to initialize all of the submodules.
cd chipyard
./scripts/init-submodules-no-riscv-tools.sh
.. _build-toolchains:
Building a Toolchain
------------------------

View File

@@ -16,6 +16,7 @@ Hit next to get started!
:caption: Chipyard Basics:
Chipyard-Components
Development-Ecosystem
Configs-Parameters-Mixins
Initial-Repo-Setup

View File

@@ -1,261 +0,0 @@
.. _adding-an-accelerator:
Adding an Accelerator/Device
===============================
Accelerators or custom IO devices can be added to your SoC in several ways:
* MMIO Peripheral (a.k.a TileLink-Attached Accelerator)
* Tightly-Coupled RoCC Accelerator
These approaches differ in the method of the communication between the processor and the custom block.
With the TileLink-Attached approach, the processor communicates with MMIO peripherals through memory-mapped registers.
In contrast, the processor communicates with a RoCC accelerators through a custom protocol and custom non-standard ISA instructions reserved in the RISC-V ISA encoding space.
Each core can have up to four accelerators that are controlled by custom instructions and share resources with the CPU.
RoCC coprocessor instructions have the following form.
.. code-block:: none
customX rd, rs1, rs2, funct
The X will be a number 0-3, and determines the opcode of the instruction, which controls which accelerator an instruction will be routed to.
The ``rd``, ``rs1``, and ``rs2`` fields are the register numbers of the destination register and two source registers.
The ``funct`` field is a 7-bit integer that the accelerator can use to distinguish different instructions from each other.
Note that communication through a RoCC interface requires a custom software toolchain, whereas MMIO peripherals can use that standard toolchain with appropriate driver support.
Integrating into the Generator Build System
-------------------------------------------
While developing, you want to include Chisel code in a submodule so that it can be shared by different projects.
To add a submodule to the Chipyard framework, make sure that your project is organized as follows.
.. code-block:: none
yourproject/
build.sbt
src/main/scala/
YourFile.scala
Put this in a git repository and make it accessible.
Then add it as a submodule to under the following directory hierarchy: ``generators/yourproject``.
.. code-block:: shell
cd generators/
git submodule add https://git-repository.com/yourproject.git
Then add ``yourproject`` to the Chipyard top-level build.sbt file.
.. code-block:: scala
lazy val yourproject = (project in file("generators/yourproject")).settings(commonSettings).dependsOn(rocketchip)
You can then import the classes defined in the submodule in a new project if
you add it as a dependency. For instance, if you want to use this code in
the ``example`` project, change the final line in build.sbt to the following.
.. code-block:: scala
lazy val example = (project in file(".")).settings(commonSettings).dependsOn(testchipip, yourproject)
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``.
.. 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.
.. 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``.
After creating the module, we need to hook it up to our SoC.
Rocket Chip accomplishes this using the cake pattern.
This basically involves placing code inside traits.
In the Rocket Chip cake, there are two kinds of traits: a ``LazyModule`` trait and a module implementation trait.
The ``LazyModule`` trait runs setup code that must execute before all the hardware gets elaborated.
For a simple memory-mapped peripheral, this just involves connecting the peripheral's TileLink node to the MMIO crossbar.
.. 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.
This will automatically add address map and device tree entries for the peripheral.
The module implementation trait is where we instantiate our PWM module and connect it to the rest of the SoC.
Since this module has an extra `pwmout` output, we declare that in this trait, using Chisel's multi-IO functionality.
We then connect the ``PWMTL``'s pwmout to the pwmout we declared.
.. 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``.
.. 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 ``Top`` classes already have the basic peripherals included for us, so we will just extend those.
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.
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``.
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
:language: scala
:start-after: DOC include start: WithPWMTop
:end-before: DOC include end: WithPWMTop
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``.
.. 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.
This will be printed out in the address map portion when you generated the verilog code.
Compiling this program with make produces a ``pwm.riscv`` executable.
Now with all of that done, we can go ahead and run our simulation.
.. code-block:: shell
cd sims/verilator
make CONFIG=PWMRocketConfig TOP=TopWithPWMTL
./simulator-example-PWMRocketConfig ../../tests/pwm.riscv
Adding a RoCC Accelerator
----------------------------
RoCC accelerators are lazy modules that extend the ``LazyRoCC`` class.
Their implementation should extends the ``LazyRoCCModule`` class.
.. code-block:: scala
class CustomAccelerator(opcodes: OpcodeSet)
(implicit p: Parameters) extends LazyRoCC(opcodes) {
override lazy val module = new CustomAcceleratorModule(this)
}
class CustomAcceleratorModule(outer: CustomAccelerator)
extends LazyRoCCModuleImp(outer) {
val cmd = Queue(io.cmd)
// The parts of the command are as follows
// inst - the parts of the instruction itself
// opcode
// rd - destination register number
// rs1 - first source register number
// rs2 - second source register number
// funct
// xd - is the destination register being used?
// xs1 - is the first source register being used?
// xs2 - is the second source register being used?
// rs1 - the value of source register 1
// rs2 - the value of source register 2
...
}
The ``opcodes`` parameter for ``LazyRoCC`` is the set of custom opcodes that will map to this accelerator.
More on this in the next subsection.
The ``LazyRoCC`` class contains two TLOutputNode instances, ``atlNode`` and ``tlNode``.
The former connects into a tile-local arbiter along with the backside of the L1 instruction cache.
The latter connects directly to the L1-L2 crossbar.
The corresponding Tilelink ports in the module implementation's IO bundle are ``atl`` and ``tl``, respectively.
The other interfaces available to the accelerator are ``mem``, which provides access to the L1 cache;
``ptw`` which provides access to the page-table walker;
the ``busy`` signal, which indicates when the accelerator is still handling an instruction;
and the ``interrupt`` signal, which can be used to interrupt the CPU.
Look at the examples in ``generators/rocket-chip/src/main/scala/tile/LazyRocc.scala`` for detailed information on the different IOs.
Adding RoCC accelerator to Config
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RoCC accelerators can be added to a core by overriding the ``BuildRoCC`` parameter in the configuration.
This takes a sequence of functions producing ``LazyRoCC`` objects, one for each accelerator you wish to add.
For instance, if we wanted to add the previously defined accelerator and route custom0 and custom1 instructions to it, we could do the following.
.. code-block:: scala
class WithCustomAccelerator extends Config((site, here, up) => {
case BuildRoCC => Seq((p: Parameters) => LazyModule(
new CustomAccelerator(OpcodeSet.custom0 | OpcodeSet.custom1)(p)))
})
class CustomAcceleratorConfig extends Config(
new WithCustomAccelerator ++ new 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
-------------------
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.
.. literalinclude:: ../../generators/example/src/main/scala/InitZero.scala
:language: scala
.. literalinclude:: ../../generators/example/src/main/scala/Top.scala
:language: scala
:start-after: DOC include start: TopWithInitZero
:end-before: DOC include end: TopWithInitZero
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`.
Once we've created our top-level module including the DMA widget, we can create a configuration for it as we did before.
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
:language: scala
:start-after: DOC include start: WithInitZero
:end-before: DOC include end: WithInitZero
.. literalinclude:: ../../generators/example/src/main/scala/RocketConfigs.scala
:language: scala
:start-after: DOC include start: InitZeroRocketConfig
:end-before: DOC include end: InitZeroRocketConfig

View File

@@ -17,7 +17,7 @@ The BootROM address space starts at ``0x10000`` (determined by the ``BootROMPara
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
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.

View File

@@ -0,0 +1,59 @@
.. _custom_chisel:
Integrating Custom Chisel Projects into the Generator Build System
==================================================================
.. warning::
This section assumes integration of custom Chisel through git submodules.
While it is possible to directly commit custom Chisel into the Chipyard framework,
we heavily recommend managing custom code through git submodules. Using submodules decouples
development of custom features from development on the Chipyard framework.
While developing, you want to include Chisel code in a submodule so that it can be shared by different projects.
To add a submodule to the Chipyard framework, make sure that your project is organized as follows.
.. code-block:: none
yourproject/
build.sbt
src/main/scala/
YourFile.scala
Put this in a git repository and make it accessible.
Then add it as a submodule to under the following directory hierarchy: ``generators/yourproject``.
The ``build.sbt`` is a minimal file which describes metadata for a Chisel project.
For a simple project, the ``build.sbt`` can even be empty, but below we provide an example
build.sbt.
.. code-block:: scala
organization := "edu.berkeley.cs"
version := "1.0"
name := "yourproject"
scalaVersion := "2.12.4"
.. code-block:: shell
cd generators/
git submodule add https://git-repository.com/yourproject.git
Then add ``yourproject`` to the Chipyard top-level build.sbt file.
.. code-block:: scala
lazy val yourproject = (project in file("generators/yourproject")).settings(commonSettings).dependsOn(rocketchip)
You can then import the classes defined in the submodule in a new project if
you add it as a dependency. For instance, if you want to use this code in
the ``example`` project, change the final line in build.sbt to the following.
.. code-block:: scala
lazy val example = (project in file(".")).settings(commonSettings).dependsOn(testchipip, yourproject)

View File

@@ -0,0 +1,39 @@
.. _dma-devices:
Adding a DMA Device
===================
DMA devices are Tilelink widgets which act as masters. In other words,
DMA devices can send their own read and write requests to the chip's memory
system.
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.
.. literalinclude:: ../../generators/example/src/main/scala/InitZero.scala
:language: scala
.. literalinclude:: ../../generators/example/src/main/scala/Top.scala
:language: scala
:start-after: DOC include start: Top
:end-before: DOC include end: Top
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`.
Once we've created our top-level module including the DMA widget, we can create a configuration for it as we did before.
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
:language: scala
:start-after: DOC include start: WithInitZero
:end-before: DOC include end: WithInitZero
.. literalinclude:: ../../generators/example/src/main/scala/RocketConfigs.scala
:language: scala
:start-after: DOC include start: InitZeroRocketConfig
:end-before: DOC include end: InitZeroRocketConfig

View File

@@ -19,7 +19,7 @@ The following example shows a dual core BOOM with a single core Rocket.
: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 ``LargeBoomConfig`` is added to override the default parameters with a different set of more common default parameters.
However, for BOOM, an extra mixin called ``WithLargeBooms`` 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.
@@ -55,8 +55,12 @@ Then you could use this new mixin like the following.
.. code-block:: scala
class SixCoreConfig extends Config(
new WithTop ++
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new WithHeterCoresSetup ++
new freechips.rocketchip.system.BaseConfig)

View File

@@ -8,8 +8,7 @@ design flows. Fortunately, both Chisel and Chipyard provide extensive
support for Verilog integration.
Here, we will examine the process of incorporating an MMIO peripheral
(similar to the PWM example from the previous section) that uses a
Verilog implementation of Greatest Common Denominator (GCD)
that uses a Verilog implementation of Greatest Common Denominator (GCD)
algorithm. There are a few steps to adding a Verilog peripheral:
* Adding a Verilog resource file to the project
@@ -58,11 +57,11 @@ and Verilog sources follow the prescribed directory layout.
build.sbt
src/main/
scala/
GCDMMIOBlackBox.scala
GCD.scala
resources/
vsrc/
GCDMMIOBlackBox.v
Defining a Chisel BlackBox
--------------------------
@@ -79,17 +78,17 @@ Of particular interest is the fact that parameterized Verilog modules
can be passed the full space of possible parameter values. These
values may depend on elaboration-time values in the Chisel generator,
as the bitwidth of the GCD calculation does in this example.
**Verilog GCD port list and parameters**
.. literalinclude:: ../../generators/example/src/main/resources/vsrc/GCDMMIOBlackBox.v
:language: verilog
:language: Verilog
:start-after: DOC include start: GCD portlist
:end-before: DOC include end: GCD portlist
**Chisel BlackBox Definition**
.. literalinclude:: ../../generators/example/src/main/scala/GCDMMIOBlackBox.scala
.. literalinclude:: ../../generators/example/src/main/scala/GCD.scala
:language: scala
:start-after: DOC include start: GCD blackbox
:end-before: DOC include end: GCD blackbox
@@ -102,54 +101,32 @@ diplomatic memory mapping on the system bus, we still have to
integrate the peripheral at the Chisel level by mixing
peripheral-specific traits into a ``TLRegisterRouter``. The ``params``
member and ``HasRegMap`` base trait should look familiar from the
previous memory-mapped PWM device example.
previous memory-mapped GCD device example.
.. literalinclude:: ../../generators/example/src/main/scala/GCDMMIOBlackBox.scala
.. literalinclude:: ../../generators/example/src/main/scala/GCD.scala
:language: scala
:start-after: DOC include start: GCD instance regmap
:end-before: DOC include end: GCD instance regmap
Advanced Features of RegField Entries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
One significant difference from the PWM example is in the peripheral's
memory map. ``RegField`` exposes polymorphic ``r`` and ``w`` methods
that allow read- and write-only memory-mapped registers to be
interfaced to hardware in multiple ways.
* ``RegField.r(2, status)`` is used to create a 2-bit, read-only register that captures the current value of the ``status`` signal when read.
* ``RegField.r(params.width, gcd)`` "connects" the decoupled handshaking interface ``gcd`` to a read-only memory-mapped register. When this register is read via MMIO, the ``ready`` signal is asserted. This is in turn connected to ``output_ready`` on the Verilog blackbox through the glue logic.
* ``RegField.w(params.width, x)`` exposes a plain register (much like those in the PWM example) via MMIO, but makes it write-only.
* ``RegField.w(params.width, y)`` associates the decoupled interface signal ``y`` with a write-only memory-mapped register, causing ``y.valid`` to be asserted when the register is written.
Since the ready/valid signals of ``y`` are connected to the
``input_ready`` and ``input_valid`` signals of the blackbox,
respectively, this register map and glue logic has the effect of
triggering the GCD algorithm when ``y`` is written. Therefore, the
algorithm is set up by first writing ``x`` and then performing a
triggering write to ``y``. Polling can be used for status checks.
Defining a Chip with a GCD Peripheral
Defining a Chip with a BlackBox
---------------------------------------
As with the PWM example, a few more pieces are needed to tie the system together.
Since we've parameterized the GCD instantiation to choose between the
Chisel and the Verilog module, creating a config is easy.
**Composing traits into a complete cake pattern peripheral**
.. literalinclude:: ../../generators/example/src/main/scala/GCDMMIOBlackBox.scala
.. literalinclude:: ../../generators/example/src/main/scala/RocketConfigs.scala
:language: scala
:start-after: DOC include start: GCD cake
:end-before: DOC include end: GCD cake
:start-after: DOC include start: GCDAXI4BlackBoxRocketConfig
:end-before: DOC include end: GCDAXI4BlackBoxRocketConfig
Note the differences arising due to the fact that this peripheral has
no top-level IO. To build a complete system, a new ``Top`` and new
``Config`` objects are added in a manner exactly analogous to the PWM
example.
You can play with the parameterization of the mixin to choose a TL/AXI4, BlackBox/Chisel
version of the GCD.
Software Testing
----------------
The GCD module has a slightly more complex interface, so polling is
The GCD module has a more complex interface, so polling is
used to check the status of the device before each triggering read or
write.

View File

@@ -0,0 +1,106 @@
.. _keys-traits-configs:
Keys, Traits, and Configs
=========================
You have probably seen snippets of Chisel referencing Keys, Traits, and Configs by this point.
This section aims to elucidate the interactions between these Chisel/Scala components, and provide
best practices for how these should be used to create a parameterized design and configure it.
We will continue to use the GCD example.
Keys
----
Keys specify some parameter which controls some custom widget. Keys should typically be implemented as **Option types**, with a default value of ``None`` that means no change in the system. In other words, the default behavior when the user does not explicitly set the key should be a no-op.
Keys should be defined and documented in sub-projects, since they generally deal with some specific block, and not system-level integration. (We make an exception for the example GCD widget).
.. literalinclude:: ../../generators/example/src/main/scala/GCD.scala
:language: scala
:start-after: DOC include start: GCD key
:end-before: DOC include end: GCD key
The object within a key is typically a ``case class XXXParams``, which defines a set of parameters which some block accepts. For example, the GCD widget's ``GCDParams`` parameterizes its address, operand widths, whether the widget should be connected by Tilelink or AXI4, and whether the widget should use the blackbox-Verilog implementation, or the Chisel implementation.
.. literalinclude:: ../../generators/example/src/main/scala/GCD.scala
:language: scala
:start-after: DOC include start: GCD params
:end-before: DOC include end: GCD params
Accessing the value stored in the key is easy in Chisel, as long as the ``implicit p: Parameters`` object is being passed through to the relevant module. For example, ``p(GCDKey).get.address`` returns the address field of ``GCDParams``. Note this only works if ``GCDKey`` was not set to ``None``, so your Chisel should check for that case!
Traits
------
Typically, most custom blocks will need to modify the behavior of some pre-existing block. For example, the GCD widget needs the ``Top`` module to instantiate and connect the widget via Tilelink, generate a top-level ``gcd_busy`` port, and connect that to the module as well. Traits let us do this without modifying the existing code for the ``Top``, and enables compartmentalization of code for different custom blocks.
Top-level traits specify that the ``Top`` has been parameterized to read some custom Key and optionally instantiate and connect a widget defined by that Key. Traits **should not** mandate the instantiation of custom logic. In other words, traits should be written with ``CanHave`` semantics, where the default behavior when the Key is unset is a no-op.
Top-level traits should be defined and documented in subprojects, alongside their corresponding Keys. The traits should then be added to the ``Top`` being used by Chipyard.
Below we see the traits for the GCD example. The Lazy trait connects the GCD module to the Diplomacy graph, while the Implementation trait causes the ``Top`` to instantiate an additional port and concretely connect it to the GCD module.
.. literalinclude:: ../../generators/example/src/main/scala/GCD.scala
:language: scala
:start-after: DOC include start: GCD lazy trait
:end-before: DOC include end: GCD imp trait
These traits are added to the default ``Top`` in Chipyard.
.. literalinclude:: ../../generators/example/src/main/scala/Top.scala
:language: scala
:start-after: DOC include start: Top
:end-before: DOC include end: Top
Mixins
------
Mixins set the keys to a non-default value. Together, the collection of Mixins which define a configuration generate the values for all the keys used by the generator.
For example, the ``WithGCDMixin`` is parameterized by the type of GCD widget you want to instantiate. When this mixin is added to a config, the ``GCDKey`` is set to a instance of ``GCDParams``, informing the previously mentioned traits to instantiate and connect the GCD widget appropriately.
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
:language: scala
:start-after: DOC include start: GCD mixin
:end-before: DOC include end: GCD mixin
We can use this mixin when composing our configs.
.. literalinclude:: ../../generators/example/src/main/scala/RocketConfigs.scala
:language: scala
:start-after: DOC include start: GCDTLRocketConfig
:end-before: DOC include end: GCDTLRocketConfig
BuildTop
--------
The ``BuildTop`` key is special, because sometimes, we need to instantiate ``TestHarness`` modules to interface with a custom widget. The ``BuildTop`` key provides a function which can call some method of the Top to instantiate these ``TestHarness`` modules. Since the ``BuildTop`` key is called from the ``TestHarness``, these modules will appear in the ``TestHarness``. The config system also lets the ``BuildTop`` key look recursively into previous definitions of itself. This enables composability of the ``Top`` configurations.
For example, conside a config that contains the mixins ``WithGPIO ++ WithTSI``. We need to instantiate the TSI serial adapter, and connect it to the ``success`` signal of our ``TestHarness``. We also need to instantiate the GPIO pins, and tie their inputs to 0 in the ``TestHarness``, since we currently cannot drive the GPIOs in simulation.
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
:language: scala
:start-after: DOC include start: tsi mixin
:end-before: DOC include end: tsi mixin
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
:language: scala
:start-after: DOC include start: gpio mixin
:end-before: DOC include end: gpio mixin
When ``WithGPIO ++ WithTSI`` is evaluated right to left, the call to ``up(BuildTop, site)`` in ``WithGPIO`` will reference the function defined in the ``BuildTop`` key of ``WithTSI``. Thus, at elaboration time, when the ``BuildTop`` function is called by the ``TestHarness``, first the ``BuildTop`` function in ``WithTSI`` will be evaluated. This connects the ``success`` signal of the ``TestHarness`` to the ``SerialAdapter`` enabled by ``WithTSI``. Then, the rest of the code in the ``BuildTop`` function of ``WithGPIO`` will execute, tieing off the top-level GPIO input pins. Thus the evaluation of the ``BuildTop`` functions in a completed config is "right-to-left", matching how the evaluation of the mixins at compile-time is also "right-to-left".
.. warning::
In some cases, the ordering and duplication of mixins which extend ``BuildTop`` will have unintended consequences.
For example, ``WithTSI ++ WithTSI`` will attempt to generate and connect two ``SimSerial`` widgets in the ``TestHarness``,
which will likely break the simulation.
In general, you should avoid attaching multiple mixins which interface to the same top-level ports.
.. note::
Readers who want more information on the configuration system may be interested in reading :ref:`cdes`.

View File

@@ -0,0 +1,142 @@
.. _mmio-accelerators:
MMIO Peripherals
==================
The easiest way to create a MMIO peripheral is to use the ``TLRegisterRouter`` or ``AXI4RegisterRouter`` widgets, which abstracts away the details of handling the interconnect protocols and provides a convenient interface for specifying memory-mapped registers. Since Chipyard and Rocket Chip SoCs primarily use Tilelink as the on-chip interconnect protocol, this section will primarily focus on designing Tilelink-based peripherals. However, see ``generators/example/src/main/scala/GCD.scala`` for how an example AXI4 based peripheral is defined and connected to the Tilelink graph through converters.
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.
For this example, we will show how to connect a MMIO peripheral which computes the GCD.
The full code can be found in ``generators/example/src/main/scala/GCD.scala``.
In this case we use a submodule ``GCDMMIOChiselModule`` to actually perform the GCD. The ``GCDModule`` class only creates the registers and hooks them up using ``regmap``.
.. literalinclude:: ../../generators/example/src/main/scala/GCD.scala
:language: scala
:start-after: DOC include start: GCD chisel
:end-before: DOC include end: GCD chisel
.. literalinclude:: ../../generators/example/src/main/scala/GCD.scala
:language: scala
:start-after: DOC include start: GCD instance regmap
:end-before: DOC include end: GCD instance regmap
Advanced Features of RegField Entries
-------------------------------------
``RegField`` exposes polymorphic ``r`` and ``w`` methods
that allow read- and write-only memory-mapped registers to be
interfaced to hardware in multiple ways.
* ``RegField.r(2, status)`` is used to create a 2-bit, read-only register that captures the current value of the ``status`` signal when read.
* ``RegField.r(params.width, gcd)`` "connects" the decoupled handshaking interface ``gcd`` to a read-only memory-mapped register. When this register is read via MMIO, the ``ready`` signal is asserted. This is in turn connected to ``output_ready`` on the GCD module through the glue logic.
* ``RegField.w(params.width, x)`` exposes a plain register via MMIO, but makes it write-only.
* ``RegField.w(params.width, y)`` associates the decoupled interface signal ``y`` with a write-only memory-mapped register, causing ``y.valid`` to be asserted when the register is written.
Since the ready/valid signals of ``y`` are connected to the
``input_ready`` and ``input_valid`` signals of the GCD module,
respectively, this register map and glue logic has the effect of
triggering the GCD algorithm when ``y`` is written. Therefore, the
algorithm is set up by first writing ``x`` and then performing a
triggering write to ``y``. Polling can be used for status checks.
Connecting by TileLink
----------------------
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.
Notice how we can create an analogous AXI4 version of our peripheral.
.. literalinclude:: ../../generators/example/src/main/scala/GCD.scala
:language: scala
:start-after: DOC include start: GCD router
:end-before: DOC include end: GCD router
Top-level Traits
----------------
After creating the module, we need to hook it up to our SoC.
Rocket Chip accomplishes this using the cake pattern.
This basically involves placing code inside traits.
In the Rocket Chip cake, there are two kinds of traits: a ``LazyModule`` trait and a module implementation trait.
The ``LazyModule`` trait runs setup code that must execute before all the hardware gets elaborated.
For a simple memory-mapped peripheral, this just involves connecting the peripheral's TileLink node to the MMIO crossbar.
.. literalinclude:: ../../generators/example/src/main/scala/GCD.scala
:language: scala
:start-after: DOC include start: GCD lazy trait
:end-before: DOC include end: GCD lazy trait
Note that the ``GCDTL`` 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.
This will automatically add address map and device tree entries for the peripheral.
Also observe how we have to place additional AXI4 buffers and converters for the AXI4 version of this peripheral.
For peripherals which instantiate a concrete module, or which need to be connected to concrete IOs or wires, a matching concrete trait is necessary. We will make our GCD example output a ``gcd_busy`` signal as a top-level port to demonstrate. In the concrete module implementation trait, we instantiate the top level IO (a concrete object) and wire it to the IO of our lazy module.
.. literalinclude:: ../../generators/example/src/main/scala/GCD.scala
:language: scala
:start-after: DOC include start: GCD imp trait
:end-before: DOC include end: GCD imp trait
Constructing the Top and Config
-------------------------------
Now we want to mix our traits into the system as a whole.
This code is from ``generators/example/src/main/scala/Top.scala``.
.. literalinclude:: ../../generators/example/src/main/scala/Top.scala
:language: scala
:start-after: DOC include start: Top
:end-before: DOC include end: Top
Just as we need separate traits for ``LazyModule`` and module implementation, we need two classes to build the system.
The ``Top`` class contains the set of traits which parameterize and define the ``Top``. Typically these traits will optionally add IOs or peripherals to the ``Top``.
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.
And finally, we create a configuration class in ``generators/example/src/main/scala/Configs.scala`` that uses the ``WithGCD`` mixin defined earlier.
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
:language: scala
:start-after: DOC include start: GCD mixin
:end-before: DOC include end: GCD mixin
.. literalinclude:: ../../generators/example/src/main/scala/RocketConfigs.scala
:language: scala
:start-after: DOC include start: GCDTLRocketConfig
:end-before: DOC include end: GCDTLRocketConfig
Testing
-------
Now we can test that the GCD is working. The test program is in ``tests/gcd.c``.
.. literalinclude:: ../../tests/gcd.c
:language: c
This just writes out to the registers we defined earlier.
The base of the module's MMIO region is at 0x2000 by default.
This will be printed out in the address map portion when you generate the Verilog code.
You can also see how this changes the emitted ``.json`` addressmap files in ``generated-src``.
Compiling this program with ``make`` produces a ``gcd.riscv`` executable.
Now with all of that done, we can go ahead and run our simulation.
.. code-block:: shell
cd sims/verilator
make CONFIG=GCDTLRocketConfig BINARY=../../tests/gcd.riscv run-binary

View File

@@ -9,20 +9,30 @@ 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
if you use the ``NMedCores`` 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)
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithNSmallCores(1) ++ // small rocket cores
new freechips.rocketchip.system.BaseConfig)
class MediumRocketConfig extends Config(
new WithNMediumCores(1) ++
new RocketConfig)
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithNMedCores(1) ++ // medium rocket cores
new freechips.rocketchip.system.BaseConfig)
If you only want to change the size or associativity, there are configuration
mixins for those too.
@@ -32,24 +42,45 @@ mixins for those too.
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)
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new WithL1ICacheSets(128) ++ // change rocket I$
new WithL1ICacheWays(2) ++ // change rocket I$
new WithL1DCacheSets(128) ++ // change rocket D$
new WithL1DCacheWays(2) ++ // change rocket D$
new freechips.rocketchip.subsystem.WithNSmallCores(1) ++
new freechips.rocketchip.system.BaseConfig)
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.
Note that these configurations fully remove the L2 cache and mbus.
.. code-block:: scala
import freechips.rocketchip.subsystem.{WithNoMemPort, WithScratchpadsOnly}
class SmallRocketConfigNoL2 extends Config(
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithNSmallCores(1) ++
new freechips.rocketchip.system.BaseConfig)
class ScratchpadRocketConfig extends Config(
new WithNoMemPort ++
new WithScratchpadsOnly ++
new SmallRocketConfig)
new freechips.rocketchip.subsystem.WithNoMemPort ++
new freechips.rocketchip.subsystem.WithNMemoryChannels(0) ++
new freechips.rocketchip.subsystem.WithNBanks(0) ++
new freechips.rocketchip.subsystem.WithScratchpadsOnly ++
new SmallRocketConfigNoL2)
This configuration fully removes the L2 cache and memory bus by setting the
number of channels and number of banks to 0.
The SiFive L2 Cache
-------------------
@@ -65,13 +96,19 @@ and the number of banks must be powers of 2.
import freechips.rocketchip.subsystem.WithInclusiveCache
# Create an SoC with 1 MB, 4-way, 4-bank cache
class MyCacheRocketConfig extends Config(
new WithInclusiveCache(
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new WithInclusiveCache( // add 1MB, 4-way, 4-bank cache
capacityKB = 1024,
nWays = 4,
nBanks = 4) ++
new RocketConfig)
new freechips.rocketchip.subsystem.WithNSmallCores(1) ++
new freechips.rocketchip.system.BaseConfig)
The Broadcast Hub
-----------------
@@ -85,13 +122,15 @@ list of included mixims.
.. code-block:: scala
import freechips.rocketchip.subsystem.{WithNBigCores, BaseConfig}
class CachelessRocketConfig extends Config(
new WithTop ++
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithNBigCores(1) ++
new BaseConfig)
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
If you want to reduce the resources used even further, you can configure
the Broadcast Hub to use a bufferless design.
@@ -119,8 +158,15 @@ number of DRAM channels is restricted to powers of two.
import freechips.rocketchip.subsystem.WithNMemoryChannels
class DualChannelRocketConfig extends Config(
new WithNMemoryChannels(2) ++
new RocketConfig)
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new WithNMemoryChannels(2) ++ // multi-channel outer mem
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
In VCS and Verilator simulation, the DRAM is simulated using the
``SimAXIMem`` module, which simply attaches a single-cycle SRAM to each

View File

@@ -0,0 +1,70 @@
.. _rocc-accelerators:
Adding a RoCC Accelerator
----------------------------
RoCC accelerators are lazy modules that extend the ``LazyRoCC`` class.
Their implementation should extends the ``LazyRoCCModule`` class.
.. code-block:: scala
class CustomAccelerator(opcodes: OpcodeSet)
(implicit p: Parameters) extends LazyRoCC(opcodes) {
override lazy val module = new CustomAcceleratorModule(this)
}
class CustomAcceleratorModule(outer: CustomAccelerator)
extends LazyRoCCModuleImp(outer) {
val cmd = Queue(io.cmd)
// The parts of the command are as follows
// inst - the parts of the instruction itself
// opcode
// rd - destination register number
// rs1 - first source register number
// rs2 - second source register number
// funct
// xd - is the destination register being used?
// xs1 - is the first source register being used?
// xs2 - is the second source register being used?
// rs1 - the value of source register 1
// rs2 - the value of source register 2
...
}
The ``opcodes`` parameter for ``LazyRoCC`` is the set of custom opcodes that will map to this accelerator.
More on this in the next subsection.
The ``LazyRoCC`` class contains two TLOutputNode instances, ``atlNode`` and ``tlNode``.
The former connects into a tile-local arbiter along with the backside of the L1 instruction cache.
The latter connects directly to the L1-L2 crossbar.
The corresponding Tilelink ports in the module implementation's IO bundle are ``atl`` and ``tl``, respectively.
The other interfaces available to the accelerator are ``mem``, which provides access to the L1 cache;
``ptw`` which provides access to the page-table walker;
the ``busy`` signal, which indicates when the accelerator is still handling an instruction;
and the ``interrupt`` signal, which can be used to interrupt the CPU.
Look at the examples in ``generators/rocket-chip/src/main/scala/tile/LazyRocc.scala`` for detailed information on the different IOs.
Adding RoCC accelerator to Config
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RoCC accelerators can be added to a core by overriding the ``BuildRoCC`` parameter in the configuration.
This takes a sequence of functions producing ``LazyRoCC`` objects, one for each accelerator you wish to add.
For instance, if we wanted to add the previously defined accelerator and route custom0 and custom1 instructions to it, we could do the following.
.. code-block:: scala
class WithCustomAccelerator extends Config((site, here, up) => {
case BuildRoCC => Seq((p: Parameters) => LazyModule(
new CustomAccelerator(OpcodeSet.custom0 | OpcodeSet.custom1)(p)))
})
class CustomAcceleratorConfig extends Config(
new WithCustomAccelerator ++
new 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``.

View File

@@ -0,0 +1,27 @@
.. _rocc-vs-mmio:
RoCC vs MMIO
------------
Accelerators or custom IO devices can be added to your SoC in several ways:
* MMIO Peripheral (a.k.a TileLink-Attached Accelerator)
* Tightly-Coupled RoCC Accelerator
These approaches differ in the method of the communication between the processor and the custom block.
With the TileLink-Attached approach, the processor communicates with MMIO peripherals through memory-mapped registers.
In contrast, the processor communicates with a RoCC accelerators through a custom protocol and custom non-standard ISA instructions reserved in the RISC-V ISA encoding space.
Each core can have up to four accelerators that are controlled by custom instructions and share resources with the CPU.
RoCC coprocessor instructions have the following form.
.. code-block:: none
customX rd, rs1, rs2, funct
The X will be a number 0-3, and determines the opcode of the instruction, which controls which accelerator an instruction will be routed to.
The ``rd``, ``rs1``, and ``rs2`` fields are the register numbers of the destination register and two source registers.
The ``funct`` field is a 7-bit integer that the accelerator can use to distinguish different instructions from each other.
Note that communication through a RoCC interface requires a custom software toolchain, whereas MMIO peripherals can use that standard toolchain with appropriate driver support.

View File

@@ -3,18 +3,41 @@ Customization
These guides will walk you through customization of your system-on-chip:
- Contructing heterogenous systems-on-chip using the Chipyard generators and configuration system.
- Contructing heterogenous systems-on-chip using the existing Chipyard generators and configuration system.
- Adding custom accelerators to your system-on-chip.
- How to include your custom Chisel sources in the Chipyard build system
Hit next to get started!
- Adding custom RoCC accelerators to an existing Chipyard core (BOOM or Rocket)
- Adding custom MMIO widgets to the Chipyard memory system by Tilelink or AXI4, with custom Top-level IOs
- Standard practices for using Keys, Traits, and Configs to parameterize your design
- Customizing the memory hierarchy
- Connect widgets which act as TileLink masters
- Adding custom blackboxed Verilog to a Chipyard design
We also provide information on:
- The boot process for Chipyard SoCs
- Examples of FIRRTL transforms used in Chipyard, and where they are specified
We recommend reading all these pages in order. Hit next to get started!
.. toctree::
:maxdepth: 2
:caption: Customization:
Heterogeneous-SoCs
Adding-An-Accelerator
Custom-Chisel
RoCC-or-MMIO
RoCC-Accelerators
MMIO-Peripherals
Keys-Traits-Configs
DMA-Devices
Incorporating-Verilog-Blocks
Memory-Hierarchy
Boot-Process

View File

@@ -0,0 +1,90 @@
Gemmini
====================================
The Gemmini project is developing a systolic-array based matrix multiplication unit generator for the investigation of software/hardware implications of such integrated SoC accelerators. It is inspired by recent trends in machine learning accelerators for edge and mobile SoCs.
Gemmini is implemented as a RoCC accelerator with non-standard RISC-V custom instructions. The Gemmini unit uses the RoCC port of a Rocket or BOOM `tile`, and by default connects to the memory system through the System Bus (i.e., directly to the L2 cache).
To add a Gemmini unit to an SoC, you should add the ``gemmini.DefaultGemminiConfig`` config mixin to the SoC configurations. To change the configuration of the Gemmini accelerator unit, you can write a custom configuration to replace the ``DefaultGemminiConfig``, which you can view under `generators/gemmini/src/main/scala/configs.scala <https://github.com/ucb-bar/gemmini/blob/master/src/main/scala/gemmini/configs.scala>`__ to see the possible configuration parameters.
The example Chipyard config includes the following example SoC configuration which includes Gemmini:
.. literalinclude:: ../../generators/example/src/main/scala/RocketConfigs.scala
:language: scala
:start-after: DOC include start: GemminiRocketConfig
:end-before: DOC include end: GemminiRocketConfig
To build a simulation of this example Chipyard config, run the following commands:
.. code-block:: shell
cd sims/verilator # or "cd sims/vcs"
make CONFIG=GemminiRocketConfig
.. image:: ../_static/images/gemmini-system.png
Generator Parameters
--------------------------
Major parameters of interest include:
* Systolic array dimensions (``tileRows``, ``tileColumns``, ``meshRows``, ``meshColumns``): The systolic array is composed of a 2-level hierarchy, in which each tile is fully combinational, while a mesh of tiles has pipeline registers between each tile.
.. image:: ../_static/images/gemmini-systolic-array.png
* Dataflow parameters (``dataflow``): Determine whether the systolic array in Gemmini is output-stationary or weight-stationary, or whether it supports both dataflows so that programmers may choose between them at runtime.
* Scratchpad and accumulator memory parameters (``sp_banks``, ``sp_capacity``, ``acc_capacity``): Determine the properties of the Gemmini scratchpad memory: overall capacity of the scratchpad or accumulators (in KiB), and the number of banks the scratchpad is divided into.
* Type parameters (``inputType``, ``outputType``, ``accType``): Determine the data-types flowing through different parts of a Gemmini accelerator. For example, ``inputType`` may be an 8-bit fixed-point number, while ``accType``, which determines the type of partial accumulations in a matrix multiplication, may be a 32-bit integer. ``outputType`` only determines the type of the data passed between two processing elements (PEs); for example, an 8-bit multiplication may produce a 16-bit result which must be shared between PEs in a systolic array.
* Access-execute queue parameters (``ld_queue_length``, ``st_queue_length``, ``ex_queue_length``, ``rob_entries``): To implement access-execute decoupling, a Gemmini accelerator has a load instruction queue, a store instruction queue, and an execute instruction queue. The relative sizes of these queue determine the level of access-execute decoupling. Gemmini also implements a reorder buffer (ROB) - the number of entries in the ROB determines possible dependency management limitations.
* DMA parameters (``dma_maxbytes``, ``dma_buswidth``, ``mem_pipeline``): Gemmini implements a DMA to move data from main memory to the Gemmini scratchpad, and from the Gemmini accumulators to main memory. The size of these DMA transactions is determined by the DMA parameters. These DMA parameters are tightly coupled with Rocket Chip SoC system parameters: in particular ``dma_buswidth`` is associated with the ``SystemBusKey`` ``beatBytes`` parameter, and ``dma_maxbytes`` is associated with ``cacheblockbytes`` Rocket Chip parameters.
Software
------------------
The Gemmini non-standard ISA extension is specified in the `Gemmini repository <https://github.com/ucb-bar/gemmini/blob/master/README.md>`__.
The ISA includes configuration instructions, data movement instructions (from main memory to the Gemmini scratchpad, and from the Gemmini accumulators to main memory), and matrix multiplication execution instructions.
Since Gemmini instructions are not exposed through the GNU binutils assembler, several C macros are provided in order to construct the instruction encodings to call these instructions.
The Gemmini generator includes a C matrix multiplication library which wraps the calls to the custom Gemmini instructions.
The ``software`` directory of the generator includes the aforementioned library and macros, as well as bare-metal tests, and some FireMarshal workloads to run the tests in a Linux environment. In particular, the matrix multiplication C library can be found in the ``software/gemmini-rocc-tests/include/gemmini.h`` file.
The Gemmini generator generates a C header file based on the generator parameters. This header files gets compiled together with the matrix multiplication library to tune library performance. The generated header file can be found under ``software/gemmini-rocc-tests/include/gemmini_params.h``
Build and Run Gemmini Tests
^^^^^^^^^^^^^^^^^^^^^^^^^^^
To build Gemmini tests:
.. code-block:: shell
cd generators/gemmini/software/gemmini-rocc-tests/
./build.sh
Afterwards, the test binaries will be found in ``generators/gemmini/software/gemmini-rocc-tests/build``. Binaries whose names end in ``-baremetal`` are meant to be run in a bare-metal environment, while binaries whose names end in ``-linux`` are meant to run in a Linux environment. You can run the tests either on a cycle-accurate RTL simulator, or on a (much faster) functional ISA simulator called Spike.
The Gemmini generator implements a custom non-standard version of Spike. This implementation is found within the ``esp-tools`` Spike implementation, together with the Hwacha vector accelerator non-standard ISA-extension. In order to use this version of Spike, please make sure to build the ``esp-tools`` software toolchain, as described in :ref:`build-toolchains`.
In order to run Spike with the gemmini functional model, you will need to use the ``--extension=gemmini`` flag. For example:
.. code-block:: shell
spike --extension=gemmini <some/gemmini/baremetal/test>
Spike is built by default without a commit log. However, if you would like to add detailed functional log of gemmini operation to the spike model, you can rebuild spike manually (based on the instructions in the ``esp-tools/riscv-isa-sim/README`` file), with the ``--enable-gemminicommitlog`` option added to the ``configure`` step.
Alternative SoC Configs
--------------------------
The Gemmini generator includes additional alternative SoC configs (configs that are not in the Chipyard example project).
If you would like to build one of these alternative SoC configurations which are defined in within the Gemmini project repository, you can run the following commands. These commands are similar to the one required when building a simulation from the example project, but they specify that the location of the configs are in the Gemmini subproject, as opposed to the Chipyard example project:
.. code-block:: shell
cd sims/verilator # or "cd sims/vcs"
make CONFIG=GemminiAcceleratorConfig CONFIG_PACKAGE=gemmini MODEL_PACKAGE=freechips.rocketchip.system GENERATOR_PACKAGE=freechips.rocketchip.system TOP=ExampleRocketSystem

View File

@@ -11,5 +11,5 @@ To add the Hwacha vector unit to an SoC, you should add the ``hwacha.DefaultHwac
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.
Since Hwacha implements a non-standard RISC-V extension, it requires a unique software toolchain to be able to compile and assemble 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

@@ -77,4 +77,7 @@ this mixin is shown here:
:start-after: DOC include start: Sha3Rocket
:end-before: DOC include end: Sha3Rocket
The SHA3 example baremetal and Linux tests are located in the SHA3 repository.
Please refer to its `README.md <https://github.com/ucb-bar/sha3/blob/master/README.md>`_ for more information on how to run/build the tests.

View File

@@ -20,17 +20,11 @@ To integrate one of these devices in your SoC, you will need to define a custom
.. literalinclude:: ../../generators/example/src/main/scala/ConfigMixins.scala
:language: scala
:start-after: DOC include start: WithGPIO
:end-before: DOC include end: WithGPIO
:start-after: DOC include start: gpio mixin
:end-before: DOC include end: gpio mixin
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``).

View File

@@ -3,13 +3,13 @@ Test Chip IP
Chipyard includes a Test Chip IP library which provides various hardware
widgets that may be useful when designing SoCs. This includes a :ref:`Serial Adapter`,
:ref:`Block Device Controller`, :ref:`TileLink SERDES`, and :ref:`TileLink Switcher`.
:ref:`Block Device Controller`, :ref:`TileLink SERDES`, :ref:`TileLink Switcher`, and :ref:`UART Adapter`.
Serial Adapter
--------------
The serial adapter is used by tethered test chips to communicate with the host
processor. An instance of RISC-V frontend server running on the host CPU
processor. An instance of RISC-V frontend server running on the host CPU
can send commands to the serial adapter to read and write data from the memory
system. The frontend server uses this functionality to load the test program
into memory and to poll for completion of the program. More information on
@@ -61,3 +61,15 @@ the select signal once TileLink messages have begun sending.
For an example of how to use the switcher, take a look at the ``SwitcherTest``
unit test in the `Test Chip IP unit tests <https://github.com/ucb-bar/testchipip/blob/master/src/main/scala/Unittests.scala>`_.
UART Adapter
------------
The UART Adapter is a device that lives in the TestHarness and connects to the
UART port of the DUT to simulate communication over UART (ex. printing out to UART
during Linux boot). In addition to working with ``stdin/stdout`` of the host, it is able to
output a UART log to a particular file using ``+uartlog=<NAME_OF_FILE>`` during simulation.
By default, this UART Adapter is added to all systems within Chipyard by adding the
``CanHavePeripheryUARTWithAdapter`` and ``CanHavePeripheryUARTWithAdapterImp`` traits to the ``Top`` system.
These traits add a SiFive UART to the system as well as add the UART Adapter to the TestHarness.

View File

@@ -22,6 +22,7 @@ so changes to the generators themselves will automatically be used when building
Rocket
BOOM
Hwacha
Gemmini
IceNet
TestChipIP
SiFive-Generators

View File

@@ -54,7 +54,7 @@ This depends on what you are planning to do with Chipyard.
* If you intend to run a full-system FireSim simulation, go to :ref:`firesim-sim-intro` and follow the instructions.
* If you intend to add a new accelerator, go to :ref:`adding-an-accelerator` and follow the instructions.
* If you intend to add a new accelerator, go to :ref:`customization` and follow the instructions.
* If you want to learn about the structure of Chipyard, go to :ref:`chipyard-components`.

View File

@@ -5,11 +5,11 @@ Advanced Usage
Alternative RTL Flows
---------------------
The Make-based build system provided supports using Hammer without using RTL generated by Chipyard. To push a custom verilog module through, one only needs to append the following environment variables to the ``make buildfile`` command (or edit them directly in the Makefile).
The Make-based build system provided supports using Hammer without using RTL generated by Chipyard. To push a custom Verilog module through, one only needs to append the following environment variables to the ``make buildfile`` command (or edit them directly in the Makefile).
.. code-block:: shell
CUSTOM_VLOG=<your verilog files>
CUSTOM_VLOG=<your Verilog files>
VLSI_TOP=<your top module>
``CUSTOM_VLOG`` breaks the dependency on the rest of the Chipyard infrastructure and does not start any Chisel/FIRRTL elaboration. ``VLSI_TOP`` selects the top module from your custom Verilog files.
@@ -32,7 +32,7 @@ For ``make par``:
./example-vlsi -e /path/to/env.yml -p /path/to/syn-output-full.json -o /path/to/par-input.json --obj_dir /path/to/build syn-to-par
./example-vlsi -e /path/to/env.yml -p /path/to/par-input.json --obj_dir /path/to/build par
A ``syn-to-par`` action translates the synthesis output configuration into an input configuration given by ``-o``. Then, this is passed to the ``par`` action.
For more information about all the options that can be passed to the Hammer command-line driver, please see the Hammer documentation.

View File

@@ -64,7 +64,7 @@ In the Chipyard root, run:
.. code-block:: shell
``./scripts/init-vlsi.sh asap7``
./scripts/init-vlsi.sh asap7
to pull the Hammer & plugin submodules. Note that for technologies other than ``asap7``, the tech submodule must be added in the ``vlsi`` folder first.
@@ -84,7 +84,7 @@ To elaborate the ``Sha3RocketConfig`` (Rocket Chip w/ the accelerator) and set u
make buildfile MACROCOMPILER_MODE='--mode synflops' CONFIG=Sha3RocketConfig VLSI_TOP=Sha3AccelwBB
The ``MACROCOMPILER_MODE='--mode synflops'`` is needed because the ASAP7 process does not yet have a memory compiler, so flip-flop arrays are used instead. This will dramatically increase the synthesis runtime if your design has a lot of memory state (e.g. large caches).
The ``MACROCOMPILER_MODE='--mode synflops'`` is needed because the ASAP7 process does not yet have a memory compiler, so flip-flop arrays are used instead. This will dramatically increase the synthesis runtime if your design has a lot of memory state (e.g. large caches). This change is automatically inferred by the makefile but is included here for completeness.
The ``CONFIG=Sha3RocketConfig`` selects the target generator config in the same manner as the rest of the Chipyard framework. This elaborates a Rocket Chip with the Sha3Accel module.
@@ -111,7 +111,7 @@ Synthesis
^^^^^^^^^
.. code-block:: shell
``make syn``
make syn
Post-synthesis logs and collateral are in ``build/syn-rundir``. The raw QoR data is available at ``build/syn-rundir/reports``, and methods to extract this information for design space exploration are a WIP.
@@ -119,7 +119,7 @@ Place-and-Route
^^^^^^^^^^^^^^^
.. code-block:: shell
``make par``
make par
After completion, the final database can be opened in an interactive Innovus session via ``./build/par-rundir/generated-scripts/open_chip``.
@@ -131,7 +131,7 @@ Timing reports are found in ``build/par-rundir/timingReports``. They are gzipped
.. code-block:: shell
``python3 view_gds.py build/par-rundir/Sha3AccelwBB.gds``
python3 view_gds.py build/par-rundir/Sha3AccelwBB.gds
By default, this script only shows the M2 thru M4 routing. Layers can be toggled in the layout viewer's side pane and ``view_gds.py`` has a mapping of layer numbers to layer names.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

BIN
docs/_static/images/gemmini-system.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

View File

@@ -10,7 +10,8 @@ module GCDMMIOBlackBox
input [WIDTH-1:0] y,
input output_ready,
output output_valid,
output reg [WIDTH-1:0] gcd
output reg [WIDTH-1:0] gcd,
output busy
);
// DOC include end: GCD portlist
@@ -21,6 +22,7 @@ module GCDMMIOBlackBox
assign input_ready = state == S_IDLE;
assign output_valid = state == S_DONE;
assign busy = state != S_IDLE;
always @(posedge clock) begin
if (reset)

View File

@@ -9,51 +9,103 @@ import freechips.rocketchip.config.{Config}
// ---------------------
class SmallBoomConfig extends Config(
new WithTop ++ // use normal top
new WithTSI ++ // use testchipip serial offchip link
new WithNoGPIO ++ // no top-level GPIO pins (overrides default set in sifive-blocks)
new WithBootROM ++ // use testchipip bootrom
new WithUART ++ // add a UART
new freechips.rocketchip.subsystem.WithNoMMIOPort ++ // no top-level mmio master port (overrides default set in rocketchip)
new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level mmio slave port (overrides default set in rocketchip)
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 WithTop ++
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
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 WithTop ++
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
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 WithTop ++
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new boom.common.WithMegaBooms ++ // 4-wide BOOM
new boom.common.WithNBoomCores(1) ++
new freechips.rocketchip.system.BaseConfig)
class DualSmallBoomConfig extends Config(
new WithTop ++
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new boom.common.WithSmallBooms ++
new boom.common.WithNBoomCores(2) ++ // dual-core
new freechips.rocketchip.system.BaseConfig)
class SmallRV32BoomConfig extends Config(
new WithTop ++
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
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)
class HwachaLargeBoomConfig extends Config(
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new hwacha.DefaultHwachaConfig ++ // use Hwacha vector accelerator
new boom.common.WithLargeBooms ++ // 3-wide BOOM
new boom.common.WithNBoomCores(1) ++
new freechips.rocketchip.system.BaseConfig)
class LoopbackNICBoomConfig extends Config(
new WithTSI ++
new WithNoGPIO ++
new WithLoopbackNIC ++ // loopback the NIC
new WithIceNIC ++ // add IceNIC
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new boom.common.WithLargeBooms ++
new boom.common.WithNBoomCores(1) ++
new freechips.rocketchip.system.BaseConfig)

View File

@@ -4,10 +4,13 @@ import chisel3._
import chisel3.util.{log2Up}
import freechips.rocketchip.config.{Field, Parameters, Config}
import freechips.rocketchip.subsystem.{RocketTilesKey, WithRoccExample, WithNMemoryChannels, WithNBigCores, WithRV32}
import freechips.rocketchip.subsystem.{SystemBusKey, RocketTilesKey, WithRoccExample, WithNMemoryChannels, WithNBigCores, WithRV32, CacheBlockBytes}
import freechips.rocketchip.diplomacy.{LazyModule, ValName}
import freechips.rocketchip.devices.tilelink.BootROMParams
import freechips.rocketchip.tile.{XLen, BuildRoCC, TileKey, LazyRoCC}
import freechips.rocketchip.devices.debug.{Debug}
import freechips.rocketchip.tile.{XLen, BuildRoCC, TileKey, LazyRoCC, RocketTileParams, MaxHartIdBits}
import freechips.rocketchip.rocket.{RocketCoreParams, MulDivParams, DCacheParams, ICacheParams}
import freechips.rocketchip.util.{AsyncResetReg}
import boom.common.{BoomTilesKey}
@@ -16,6 +19,9 @@ import testchipip._
import hwacha.{Hwacha}
import sifive.blocks.devices.gpio._
import sifive.blocks.devices.uart._
import icenet.{NICKey, NICConfig}
/**
* TODO: Why do we need this?
@@ -30,100 +36,26 @@ import ConfigValName._
// -----------------------
/**
* Class to specify where the BootRom file is (from `rebar` top)
* Mixin to add the Chipyard bootrom
*/
class WithBootROM extends Config((site, here, up) => {
case BootROMParams => BootROMParams(
contentFileName = s"./bootrom/bootrom.rv${site(XLen)}.img")
})
// DOC include start: WithGPIO
// DOC include start: gpio mixin
/**
* Class to add in GPIO
* Mixin to add GPIOs and tie them off outside the DUT
*/
class WithGPIO extends Config((site, here, up) => {
case PeripheryGPIOKey => List(
case PeripheryGPIOKey => Seq(
GPIOParams(address = 0x10012000, width = 4, includeIOF = false))
})
// DOC include end: WithGPIO
// -----------------------------------------------
// BOOM and/or Rocket Top Level System Parameter Mixins
// -----------------------------------------------
/**
* Class to specify a "plain" top level BOOM and/or Rocket system
*/
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 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
*/
// 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 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 TL-attached GCD device
*/
class WithGCDTop extends Config((site, here, up) => {
case BuildTop => (clock: Clock, reset: Bool, p: Parameters) =>
Module(LazyModule(new TopWithGCD()(p)).module)
})
/**
* Class to specify a top level BOOM and/or Rocket system with a block device
*/
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
}
})
/**
* Class to specify a top level BOOM and/or Rocket system with a simulator block device
*/
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 WithGPIOTop extends Config((site, here, up) => {
case BuildTop => (clock: Clock, reset: Bool, p: Parameters) => {
val top = Module(LazyModule(new TopWithGPIO()(p)).module)
case BuildTop => (clock: Clock, reset: Bool, p: Parameters, success: Bool) => {
val top = up(BuildTop, site)(clock, reset, p, success)
// TODO: Currently FIRRTL will error if the GPIO input
// pins are unconnected, so tie them to 0.
// In future IO cell blackboxes will replace this with
// more correct functionality
for (gpio <- top.gpio) {
for (pin <- gpio.pins) {
pin.i.ival := false.B
@@ -132,7 +64,88 @@ class WithGPIOTop extends Config((site, here, up) => {
top
}
})
// DOC include end: WithGPIOTop
// DOC include end: gpio mixin
/**
* Mixin to add in UART
*/
class WithUART extends Config((site, here, up) => {
case PeripheryUARTKey => Seq(
UARTParams(address = 0x54000000L, nTxEntries = 256, nRxEntries = 256))
})
/**
* Mixin to remove any GPIOs
*/
class WithNoGPIO extends Config((site, here, up) => {
case PeripheryGPIOKey => Seq()
})
// DOC include start: tsi mixin
/**
* Mixin to add an offchip TSI link (used for backing memory)
*/
class WithTSI extends Config((site, here, up) => {
case SerialKey => true
case BuildTop => (clock: Clock, reset: Bool, p: Parameters, success: Bool) => {
val top = up(BuildTop, site)(clock, reset, p, success)
success := top.connectSimSerial()
top
}
})
// DOC include end: tsi mixin
/**
* Mixin to add an DTM (used for dmi or jtag bringup)
*/
class WithDTM extends Config((site, here, up) => {
case BuildTop => (clock: Clock, reset: Bool, p: Parameters, success: Bool) => {
val top = up(BuildTop, site)(clock, reset, p, success)
top.reset := reset.asBool | top.debug.map { debug => AsyncResetReg(debug.ndreset) }.getOrElse(false.B)
Debug.connectDebug(top.debug, top.psd, clock, reset.asBool, success)(p)
top
}
})
// DOC include start: GCD mixin
/**
* Mixin to add a GCD peripheral
*/
class WithGCD(useAXI4: Boolean, useBlackBox: Boolean) extends Config((site, here, up) => {
case GCDKey => Some(GCDParams(useAXI4 = useAXI4, useBlackBox = useBlackBox))
})
// DOC include end: GCD mixin
/**
* Mixin to add a RTL block device model
*/
class WithBlockDeviceModel extends Config((site, here, up) => {
case BuildTop => (clock: Clock, reset: Bool, p: Parameters, success: Bool) => {
val top = up(BuildTop, site)(clock, reset, p, success)
top.connectBlockDeviceModel()
top
}
})
/**
* Mixin to add a simulated block device model
*/
class WithSimBlockDevice extends Config((site, here, up) => {
case BuildTop => (clock: Clock, reset: Bool, p: Parameters, success: Bool) => {
val top = up(BuildTop, site)(clock, reset, p, success)
top.connectSimBlockDevice(clock, reset)
top
}
})
// DOC include start: WithInitZero
/**
* Mixin to add a peripheral that clears memory
*/
class WithInitZero(base: BigInt, size: BigInt) extends Config((site, here, up) => {
case InitZeroKey => Some(InitZeroConfig(base, size))
})
// DOC include end: WithInitZero
// ------------------
// Multi-RoCC Support
@@ -172,13 +185,62 @@ 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)
/**
* Mixin to add a small Rocket core to the system as a "control" core.
* Used as an example of a PMU core.
*/
class WithControlCore extends Config((site, here, up) => {
case RocketTilesKey => up(RocketTilesKey, site) :+
RocketTileParams(
core = RocketCoreParams(
useVM = false,
fpu = None,
mulDiv = Some(MulDivParams(mulUnroll = 8))),
btb = None,
dcache = Some(DCacheParams(
rowBits = site(SystemBusKey).beatBits,
nSets = 64,
nWays = 1,
nTLBEntries = 4,
nMSHRs = 0,
blockBytes = site(CacheBlockBytes))),
icache = Some(ICacheParams(
rowBits = site(SystemBusKey).beatBits,
nSets = 64,
nWays = 1,
nTLBEntries = 4,
blockBytes = site(CacheBlockBytes))),
hartId = up(RocketTilesKey, site).size + up(BoomTilesKey, site).size
)
case MaxHartIdBits => log2Up(up(RocketTilesKey, site).size + up(BoomTilesKey, site).size + 1)
})
class WithInitZeroTop extends Config((site, here, up) => {
case BuildTop => (clock: Clock, reset: Bool, p: Parameters) =>
Module(LazyModule(new TopWithInitZero()(p)).module)
/**
* Mixin to add an IceNIC
*/
class WithIceNIC(inBufFlits: Int = 1800, usePauser: Boolean = false)
extends Config((site, here, up) => {
case NICKey => Some(NICConfig(
inBufFlits = inBufFlits,
usePauser = usePauser,
checksumOffload = true))
})
/**
* Mixin to loopback the IceNIC
*/
class WithLoopbackNIC extends Config((site, here, up) => {
case BuildTop => (clock: Clock, reset: Bool, p: Parameters, success: Bool) => {
val top = up(BuildTop, site)(clock, reset, p, success)
top.connectNicLoopback()
top
}
})
/**
* Mixin to add a backing scratchpad (default size 4MB)
*/
class WithBackingScratchpad(base: BigInt = 0x80000000L, mask: BigInt = ((4 << 20) - 1)) extends Config((site, here, up) => {
case BackingScratchpadKey => Some(BackingScratchpadParams(base, mask))
})
// DOC include end: WithInitZero

View File

@@ -0,0 +1,200 @@
package example
import chisel3._
import chisel3.util._
import chisel3.experimental.{IntParam, BaseModule}
import freechips.rocketchip.amba.axi4._
import freechips.rocketchip.subsystem.BaseSubsystem
import freechips.rocketchip.config.{Parameters, Field}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.regmapper.{HasRegMap, RegField}
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util.UIntIsOneOf
// DOC include start: GCD params
case class GCDParams(
address: BigInt = 0x2000,
width: Int = 32,
useAXI4: Boolean = false,
useBlackBox: Boolean = true)
// DOC include end: GCD params
// DOC include start: GCD key
case object GCDKey extends Field[Option[GCDParams]](None)
// DOC include end: GCD key
class GCDIO(val w: Int) extends Bundle {
val clock = Input(Clock())
val reset = Input(Bool())
val input_ready = Output(Bool())
val input_valid = Input(Bool())
val x = Input(UInt(w.W))
val y = Input(UInt(w.W))
val output_ready = Input(Bool())
val output_valid = Output(Bool())
val gcd = Output(UInt(w.W))
val busy = Output(Bool())
}
trait GCDTopIO extends Bundle {
val gcd_busy = Output(Bool())
}
trait HasGCDIO extends BaseModule {
val w: Int
val io = IO(new GCDIO(w))
}
// DOC include start: GCD blackbox
class GCDMMIOBlackBox(val w: Int) extends BlackBox(Map("WIDTH" -> IntParam(w))) with HasBlackBoxResource
with HasGCDIO
{
addResource("/vsrc/GCDMMIOBlackBox.v")
}
// DOC include end: GCD blackbox
// DOC include start: GCD chisel
class GCDMMIOChiselModule(val w: Int) extends Module
with HasGCDIO
{
val s_idle :: s_run :: s_done :: Nil = Enum(3)
val state = RegInit(s_idle)
val tmp = Reg(UInt(w.W))
val gcd = Reg(UInt(w.W))
io.input_ready := state === s_idle
io.output_valid := state === s_done
io.gcd := gcd
when (state === s_idle && io.input_valid) {
state := s_run
} .elsewhen (state === s_run && tmp === 0.U) {
state := s_done
} .elsewhen (state === s_done && io.output_ready) {
state := s_idle
}
when (state === s_idle && io.input_valid) {
gcd := io.x
tmp := io.y
} .elsewhen (state === s_run) {
when (gcd > tmp) {
gcd := gcd - tmp
} .otherwise {
tmp := tmp - gcd
}
}
io.busy := state =/= s_idle
}
// DOC include end: GCD chisel
// DOC include start: GCD instance regmap
trait GCDModule extends HasRegMap {
val io: GCDTopIO
implicit val p: Parameters
def params: GCDParams
val clock: Clock
val reset: Reset
// How many clock cycles in a PWM cycle?
val x = Reg(UInt(params.width.W))
val y = Wire(new DecoupledIO(UInt(params.width.W)))
val gcd = Wire(new DecoupledIO(UInt(params.width.W)))
val status = Wire(UInt(2.W))
val impl = if (params.useBlackBox) {
Module(new GCDMMIOBlackBox(params.width))
} else {
Module(new GCDMMIOChiselModule(params.width))
}
impl.io.clock := clock
impl.io.reset := reset.asBool
impl.io.x := x
impl.io.y := y.bits
impl.io.input_valid := y.valid
y.ready := impl.io.input_ready
gcd.bits := impl.io.gcd
gcd.valid := impl.io.output_valid
impl.io.output_ready := gcd.ready
status := Cat(impl.io.input_ready, impl.io.output_ready)
io.gcd_busy := impl.io.busy
regmap(
0x00 -> Seq(
RegField.r(2, status)), // a read-only register capturing current status
0x04 -> Seq(
RegField.w(params.width, x)), // a plain, write-only register
0x08 -> Seq(
RegField.w(params.width, y)), // write-only, y.valid is set on write
0x0C -> Seq(
RegField.r(params.width, gcd))) // read-only, gcd.ready is set on read
}
// DOC include end: GCD instance regmap
// DOC include start: GCD router
class GCDTL(params: GCDParams, beatBytes: Int)(implicit p: Parameters)
extends TLRegisterRouter(
params.address, "gcd", Seq("ucbbar,gcd"),
beatBytes = beatBytes)(
new TLRegBundle(params, _) with GCDTopIO)(
new TLRegModule(params, _, _) with GCDModule)
class GCDAXI4(params: GCDParams, beatBytes: Int)(implicit p: Parameters)
extends AXI4RegisterRouter(
params.address,
beatBytes=beatBytes)(
new AXI4RegBundle(params, _) with GCDTopIO)(
new AXI4RegModule(params, _, _) with GCDModule)
// DOC include end: GCD router
// DOC include start: GCD lazy trait
trait CanHavePeripheryGCD { this: BaseSubsystem =>
private val portName = "gcd"
// Only build if we are using the TL (nonAXI4) version
val gcd = p(GCDKey) match {
case Some(params) => {
if (params.useAXI4) {
val gcd = LazyModule(new GCDAXI4(params, pbus.beatBytes)(p))
pbus.toSlave(Some(portName)) {
gcd.node :=
AXI4Buffer () :=
TLToAXI4 () :=
// toVariableWidthSlave doesn't use holdFirstDeny, which TLToAXI4() needsx
TLFragmenter(pbus.beatBytes, pbus.blockBytes, holdFirstDeny = true)
}
Some(gcd)
} else {
val gcd = LazyModule(new GCDTL(params, pbus.beatBytes)(p))
pbus.toVariableWidthSlave(Some(portName)) { gcd.node }
Some(gcd)
}
}
case None => None
}
}
// DOC include end: GCD lazy trait
// DOC include start: GCD imp trait
trait CanHavePeripheryGCDModuleImp extends LazyModuleImp {
val outer: CanHavePeripheryGCD
val gcd_busy = outer.gcd match {
case Some(gcd) => {
val busy = IO(Output(Bool()))
busy := gcd.module.io.gcd_busy
Some(busy)
}
case None => None
}
}
// DOC include end: GCD imp trait

View File

@@ -1,98 +0,0 @@
package example
import chisel3._
import chisel3.util._
import chisel3.core.{IntParam, Reset}
import freechips.rocketchip.amba.axi4._
import freechips.rocketchip.subsystem.BaseSubsystem
import freechips.rocketchip.config.{Parameters, Field}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.regmapper.{HasRegMap, RegField}
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util.UIntIsOneOf
// DOC include start: GCD blackbox
class GCDMMIOBlackBox(w: Int) extends BlackBox(Map("WIDTH" -> IntParam(w))) with HasBlackBoxResource {
val io = IO(new Bundle {
val clock = Input(Clock())
val reset = Input(Bool())
val input_ready = Output(Bool())
val input_valid = Input(Bool())
val x = Input(UInt(w.W))
val y = Input(UInt(w.W))
val output_ready = Input(Bool())
val output_valid = Output(Bool())
val gcd = Output(UInt(w.W))
})
addResource("/vsrc/GCDMMIOBlackBox.v")
}
// DOC include end: GCD blackbox
// DOC include start: GCD instance regmap
case class GCDParams(address: BigInt, beatBytes: Int, width: Int)
trait GCDModule extends HasRegMap {
implicit val p: Parameters
def params: GCDParams
val clock: Clock
val reset: Reset
val impl = Module(new GCDMMIOBlackBox(params.width))
// How many clock cycles in a PWM cycle?
val x = Reg(UInt(params.width.W))
val y = Wire(new DecoupledIO(impl.io.y))
val gcd = Wire(new DecoupledIO(impl.io.gcd))
val status = Cat(impl.io.input_ready, impl.io.output_valid)
impl.io.clock := clock
impl.io.reset := reset.asBool
impl.io.x := x
impl.io.y := y.bits
impl.io.input_valid := y.valid
y.ready := impl.io.input_ready
gcd.bits := impl.io.gcd
gcd.valid := impl.io.output_valid
impl.io.output_ready := gcd.ready
regmap(
0x00 -> Seq(
RegField.r(2, status)), // a read-only register capturing current status
0x04 -> Seq(
RegField.w(params.width, x)), // a plain, write-only register
0x08 -> Seq(
RegField.w(params.width, y)), // write-only, y.valid is set on write
0x0C -> Seq(
RegField.r(params.width, gcd))) // read-only, gcd.ready is set on read
}
// DOC include end: GCD instance regmap
// DOC include start: GCD cake
class GCD(c: GCDParams)(implicit p: Parameters)
extends TLRegisterRouter(
c.address, "gcd", Seq("ucbbar,gcd"),
beatBytes = c.beatBytes)(
new TLRegBundle(c, _))(
new TLRegModule(c, _, _) with GCDModule)
trait HasPeripheryGCD { this: BaseSubsystem =>
implicit val p: Parameters
private val address = 0x2000
private val portName = "gcd"
private val gcdWidth = 32
val gcd = LazyModule(new GCD(
GCDParams(address, pbus.beatBytes, gcdWidth))(p))
pbus.toVariableWidthSlave(Some(portName)) { gcd.node }
}
trait HasPeripheryGCDModuleImp extends LazyModuleImp {
implicit val p: Parameters
val outer: HasPeripheryGCD
}
// DOC include end: GCD cake

View File

@@ -1,10 +1,14 @@
package example
import scala.util.Try
import chisel3._
import freechips.rocketchip.config.{Parameters}
import freechips.rocketchip.util.{GeneratorApp}
import utilities.TestSuiteHelper
import freechips.rocketchip.system.{TestGeneration}
import utilities.{TestSuiteHelper}
object Generator extends GeneratorApp {
// add unique test suites
@@ -12,10 +16,22 @@ object Generator extends GeneratorApp {
implicit val p: Parameters = params
TestSuiteHelper.addRocketTestSuites
TestSuiteHelper.addBoomTestSuites
// if hwacha parameter exists then generate its tests
// TODO: find a more elegant way to do this. either through
// trying to disambiguate BuildRoCC, having a AccelParamsKey,
// or having the Accelerator/Tile add its own tests
import hwacha.HwachaTestSuites._
if (Try(p(hwacha.HwachaNLanes)).getOrElse(0) > 0) {
TestGeneration.addSuites(rv64uv.map(_("p")))
TestGeneration.addSuites(rv64uv.map(_("vp")))
TestGeneration.addSuite(rv64sv("p"))
TestGeneration.addSuite(hwachaBmarks)
}
}
// specify the name that the generator outputs files as
val longName = names.topModuleProject + "." + names.topModuleClass + "." + names.configs
override lazy val longName = names.topModuleProject + "." + names.topModuleClass + "." + names.configs
// generate files
generateFirrtl

View File

@@ -9,9 +9,13 @@ import freechips.rocketchip.config.{Config}
// ---------------------
class LargeBoomAndRocketConfig extends Config(
new WithTop ++ // default top
new WithTSI ++ // use testchipip serial offchip link
new WithNoGPIO ++ // no top-level GPIO pins (overrides default set in sifive-blocks)
new WithBootROM ++ // default bootrom
new WithUART ++ // add a UART
new freechips.rocketchip.subsystem.WithInclusiveCache ++ // use SiFive l2
new freechips.rocketchip.subsystem.WithNoMMIOPort ++ // no top-level MMIO master port (overrides default set in rocketchip)
new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level MMIO slave port (overrides default set in rocketchip)
new boom.common.WithRenumberHarts ++ // avoid hartid overlap
new boom.common.WithLargeBooms ++ // 3-wide boom
new boom.common.WithNBoomCores(1) ++ // single-core boom
@@ -19,9 +23,13 @@ class LargeBoomAndRocketConfig extends Config(
new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system
class SmallBoomAndRocketConfig extends Config(
new WithTop ++
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new boom.common.WithRenumberHarts ++
new boom.common.WithSmallBooms ++ // 1-wide boom
new boom.common.WithNBoomCores(1) ++
@@ -30,10 +38,14 @@ class SmallBoomAndRocketConfig extends Config(
// DOC include start: BoomAndRocketWithHwacha
class HwachaLargeBoomAndHwachaRocketConfig extends Config(
new WithTop ++
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new hwacha.DefaultHwachaConfig ++ // add hwacha to all harts
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new boom.common.WithRenumberHarts ++
new boom.common.WithLargeBooms ++
new boom.common.WithNBoomCores(1) ++
@@ -42,9 +54,13 @@ class HwachaLargeBoomAndHwachaRocketConfig extends Config(
// DOC include end: BoomAndRocketWithHwacha
class RoccLargeBoomAndRoccRocketConfig extends Config(
new WithTop ++
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithRoccExample ++ // add example rocc accelerator to all harts
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new boom.common.WithRenumberHarts ++
new boom.common.WithLargeBooms ++
@@ -53,8 +69,12 @@ class RoccLargeBoomAndRoccRocketConfig extends Config(
new freechips.rocketchip.system.BaseConfig)
class DualLargeBoomAndRocketConfig extends Config(
new WithTop ++
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new boom.common.WithRenumberHarts ++
new boom.common.WithLargeBooms ++
@@ -64,9 +84,13 @@ class DualLargeBoomAndRocketConfig extends Config(
// DOC include start: DualBoomAndRocketOneHwacha
class DualLargeBoomAndHwachaRocketConfig extends Config(
new WithTop ++
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new WithMultiRoCC ++ // support heterogeneous rocc
new WithMultiRoCCHwacha(2) ++ // put hwacha on hart-2 (rocket)
new boom.common.WithRenumberHarts ++
@@ -77,9 +101,13 @@ class DualLargeBoomAndHwachaRocketConfig extends Config(
// DOC include end: DualBoomAndRocketOneHwacha
class LargeBoomAndRV32RocketConfig extends Config(
new WithTop ++
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new boom.common.WithRenumberHarts ++
new boom.common.WithLargeBooms ++
new boom.common.WithNBoomCores(1) ++
@@ -89,12 +117,31 @@ class LargeBoomAndRV32RocketConfig extends Config(
// DOC include start: DualBoomAndRocket
class DualLargeBoomAndDualRocketConfig extends Config(
new WithTop ++
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
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
class MultiCoreWithControlCoreConfig extends Config(
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new WithControlCore ++ // add small control core (last hartid)
new boom.common.WithRenumberHarts ++
new boom.common.WithLargeBooms ++
new boom.common.WithNBoomCores(2) ++ // 2 normal boom cores
new freechips.rocketchip.subsystem.WithNBigCores(2) ++ // 2 normal rocket cores
new freechips.rocketchip.system.BaseConfig)

View File

@@ -8,7 +8,7 @@ import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, IdRange}
import testchipip.TLHelper
case class InitZeroConfig(base: BigInt, size: BigInt)
case object InitZeroKey extends Field[InitZeroConfig]
case object InitZeroKey extends Field[Option[InitZeroConfig]](None)
class InitZero(implicit p: Parameters) extends LazyModule {
val node = TLHelper.makeClientNode(
@@ -18,7 +18,7 @@ class InitZero(implicit p: Parameters) extends LazyModule {
}
class InitZeroModuleImp(outer: InitZero) extends LazyModuleImp(outer) {
val config = p(InitZeroKey)
val config = p(InitZeroKey).get
val (mem, edge) = outer.node.out(0)
val addrBits = edge.bundle.addressBits
@@ -57,13 +57,11 @@ class InitZeroModuleImp(outer: InitZero) extends LazyModuleImp(outer) {
}
}
trait HasPeripheryInitZero { this: BaseSubsystem =>
trait CanHavePeripheryInitZero { 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
p(InitZeroKey) .map { k =>
val initZero = LazyModule(new InitZero()(p))
fbus.fromPort(Some("init-zero"))() := initZero.node
}
}

View File

@@ -1,134 +0,0 @@
package example
import chisel3._
import chisel3.util._
import freechips.rocketchip.amba.axi4._
import freechips.rocketchip.subsystem.BaseSubsystem
import freechips.rocketchip.config.{Parameters, Field}
import freechips.rocketchip.diplomacy._
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 {
val io = IO(new Bundle {
val pwmout = Output(Bool())
val period = Input(UInt(w.W))
val duty = Input(UInt(w.W))
val enable = Input(Bool())
})
// The counter should count up until period is reached
val counter = Reg(UInt(w.W))
when (counter >= (io.period - 1.U)) {
counter := 0.U
} .otherwise {
counter := counter + 1.U
}
// If PWM is enabled, pwmout is high when counter < duty
// If PWM is not enabled, it will always be low
io.pwmout := io.enable && (counter < io.duty)
}
trait PWMBundle extends Bundle {
val pwmout = Output(Bool())
}
trait PWMModule extends HasRegMap {
val io: PWMBundle
implicit val p: Parameters
def params: PWMParams
// How many clock cycles in a PWM cycle?
val period = Reg(UInt(32.W))
// For how many cycles should the clock be high?
val duty = Reg(UInt(32.W))
// Is the PWM even running at all?
val enable = RegInit(false.B)
val base = Module(new PWMBase(32))
io.pwmout := base.io.pwmout
base.io.period := period
base.io.duty := duty
base.io.enable := enable
regmap(
0x00 -> Seq(
RegField(32, period)),
0x04 -> Seq(
RegField(32, duty)),
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
private val address = 0x2000
private val portName = "pwm"
val pwm = LazyModule(new PWMTL(
PWMParams(address, pbus.beatBytes))(p))
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
val pwmout = IO(Output(Bool()))
pwmout := outer.pwm.module.io.pwmout
}
// DOC include end: HasPeripheryPWMTLModuleImp
trait HasPeripheryPWMAXI4 { this: BaseSubsystem =>
implicit val p: Parameters
private val address = 0x2000
private val portName = "pwm"
val pwm = LazyModule(new PWMAXI4(
PWMParams(address, pbus.beatBytes))(p))
pbus.toSlave(Some(portName)) {
pwm.node :=
AXI4Buffer () :=
TLToAXI4() :=
// toVariableWidthSlave doesn't use holdFirstDeny, which TLToAXI4() needs
TLFragmenter(pbus.beatBytes, pbus.blockBytes, holdFirstDeny = true)
}
}
trait HasPeripheryPWMAXI4ModuleImp extends LazyModuleImp {
implicit val p: Parameters
val outer: HasPeripheryPWMAXI4
val pwmout = IO(Output(Bool()))
pwmout := outer.pwm.module.io.pwmout
}

View File

@@ -9,23 +9,49 @@ import freechips.rocketchip.config.{Config}
// --------------
class RocketConfig extends Config(
new WithTop ++ // use default top
new WithTSI ++ // use testchipip serial offchip link
new WithNoGPIO ++ // no top-level GPIO pins (overrides default set in sifive-blocks)
new WithBootROM ++ // use default bootrom
new WithUART ++ // add a UART
new freechips.rocketchip.subsystem.WithNoMMIOPort ++ // no top-level MMIO master port (overrides default set in rocketchip)
new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level MMIO slave port (overrides default set in rocketchip)
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 WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
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 ++
// DOC include start: GemminiRocketConfig
class GemminiRocketConfig extends Config(
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new gemmini.DefaultGemminiConfig ++ // use Gemmini systolic array GEMM accelerator
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
// DOC include end: GemminiRocketConfig
class RoccRocketConfig extends Config(
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithRoccExample ++ // use example RoCC-based accelerator
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
@@ -33,9 +59,13 @@ class RoccRocketConfig extends Config(
// 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 WithDTM ++ // use top with dtm
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithJtagDTM ++ // enable communicating with the DTM using jtag
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
@@ -43,89 +73,127 @@ class jtagRocketConfig extends Config(
// DOC include start: DmiRocket
class dmiRocketConfig extends Config(
new WithDTMTop ++ // use top with dtm
new WithDTM ++ // use top with dtm
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
// DOC include end: DmiRocket
// DOC include start: PWMRocketConfig
class PWMRocketConfig extends Config(
new WithPWMTop ++ // use top with tilelink-controlled PWM
// DOC include start: GCDTLRocketConfig
class GCDTLRocketConfig extends Config(
new WithTSI ++
new WithNoGPIO ++
new WithUART ++
new WithGCD(useAXI4=false, useBlackBox=false) ++ // Use GCD Chisel, connect Tilelink
new WithBootROM ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
// DOC include end: PWMRocketConfig
// DOC include end: GCDTLRocketConfig
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 GCDRocketConfig extends Config( // add MMIO GCD module
new WithGCDTop ++
// DOC include start: GCDAXI4BlackBoxRocketConfig
class GCDAXI4BlackBoxRocketConfig extends Config(
new WithTSI ++
new WithUART ++
new WithNoGPIO ++
new WithGCD(useAXI4=true, useBlackBox=true) ++ // Use GCD blackboxed verilog, connect by AXI4->Tilelink
new WithBootROM ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
// DOC include end: GCDAXI4BlackBoxRocketConfig
class SimBlockDeviceRocketConfig extends Config(
new WithTSI ++
new WithNoGPIO ++
new testchipip.WithBlockDevice ++ // add block-device module to peripherybus
new WithSimBlockDeviceTop ++ // use top with block-device IOs and connect to simblockdevice
new WithSimBlockDevice ++ // use top with block-device IOs and connect to simblockdevice
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
class BlockDeviceModelRocketConfig extends Config(
new WithTSI ++
new WithNoGPIO ++
new testchipip.WithBlockDevice ++ // add block-device module to periphery bus
new WithBlockDeviceModelTop ++ // use top with block-device IOs and connect to a blockdevicemodel
new WithBlockDeviceModel ++ // use top with block-device IOs and connect to a blockdevicemodel
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
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 WithTSI ++
new WithGPIO ++ // add GPIOs to the peripherybus
new WithGPIOTop ++ // use top with GPIOs
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
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 WithTSI ++
new WithBootROM ++
new WithUART ++
new WithNoGPIO ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
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 WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
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 WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithExtMemSize((1<<30) * 1L) ++ // use 2GB simulated external memory
new freechips.rocketchip.subsystem.WithExtMemSize((1<<30) * 1L) ++ // use 1GB 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 WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new sha3.WithSha3Accel ++ // add SHA3 rocc accelerator
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
@@ -134,10 +202,40 @@ class Sha3RocketConfig extends Config(
// DOC include start: InitZeroRocketConfig
class InitZeroRocketConfig extends Config(
new WithInitZero(0x88000000L, 0x1000L) ++
new WithInitZeroTop ++
new WithInitZero(0x88000000L, 0x1000L) ++ // add InitZero
new WithNoGPIO ++
new WithTSI ++
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
// DOC include end: InitZeroRocketConfig
class LoopbackNICRocketConfig extends Config(
new WithTSI ++
new WithIceNIC ++ // add an IceNIC
new WithNoGPIO ++
new WithLoopbackNIC ++ // loopback the IceNIC
new WithBootROM ++
new WithUART ++
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)
class ScratchpadRocketConfig extends Config(
new WithTSI ++
new WithNoGPIO ++
new WithBootROM ++
new WithUART ++
new WithBackingScratchpad ++ // add backing scratchpad
new freechips.rocketchip.subsystem.WithNoMemPort ++ // remove offchip mem port
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
new freechips.rocketchip.subsystem.WithNoSlavePort ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new freechips.rocketchip.system.BaseConfig)

View File

@@ -10,12 +10,22 @@ import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.util.GeneratorApp
import freechips.rocketchip.devices.debug.{Debug}
/**
* TODO: Why do we need this?
*/
import ConfigValName._
// -------------------------------
// BOOM and/or Rocket Test Harness
// -------------------------------
case object BuildTop extends Field[(Clock, Bool, Parameters) => TopModule[Top]]
case object BuildTopWithDTM extends Field[(Clock, Bool, Parameters) => TopWithDTMModule[TopWithDTM]]
case object BuildTop extends Field[(Clock, Bool, Parameters, Bool) => TopModule[Top]](
(clock: Clock, reset: Bool, p: Parameters, success: Bool) => {
val top = Module(LazyModule(new Top()(p)).suggestName("top").module)
top.debug.map { debug => debug := DontCare }
top
}
)
/**
* Test harness using TSI to bringup the system
@@ -25,12 +35,8 @@ class TestHarness(implicit val p: Parameters) extends Module {
val success = Output(Bool())
})
// force Chisel to rename module
override def desiredName = "TestHarness"
val dut = p(BuildTop)(clock, reset.toBool, p)
dut.debug := DontCare
val dut = p(BuildTop)(clock, reset.toBool, p, io.success)
dut.connectSimUARTs()
dut.connectSimAXIMem()
dut.connectSimAXIMMIO()
dut.dontTouchPorts()
@@ -48,40 +54,4 @@ class TestHarness(implicit val p: Parameters) extends Module {
}
})
io.success := dut.connectSimSerial()
}
/**
* Test harness using the Debug Test Module (DTM) to bringup the system
*/
class TestHarnessWithDTM(implicit p: Parameters) extends Module
{
val io = IO(new Bundle {
val success = Output(Bool())
})
// force Chisel to rename module
override def desiredName = "TestHarness"
val dut = p(BuildTopWithDTM)(clock, reset.toBool, p)
dut.reset := reset.asBool | dut.debug.ndreset
dut.connectSimAXIMem()
dut.connectSimAXIMMIO()
dut.dontTouchPorts()
dut.tieOffInterrupts()
dut.l2_frontend_bus_axi4.foreach(axi => {
axi.tieoff()
experimental.DataMirror.directionOf(axi.ar.ready) match {
case core.ActualDirection.Input =>
axi.r.bits := DontCare
axi.b.bits := DontCare
case core.ActualDirection.Output =>
axi.aw.bits := DontCare
axi.ar.bits := DontCare
axi.w.bits := DontCare
}
})
Debug.connectDebug(dut.debug, clock, reset.asBool, io.success)
}

View File

@@ -13,91 +13,36 @@ import testchipip._
import utilities.{System, SystemModule}
import sifive.blocks.devices.gpio._
import sifive.blocks.devices.uart._
import icenet.{CanHavePeripheryIceNIC, CanHavePeripheryIceNICModuleImp}
// ------------------------------------
// BOOM and/or Rocket Top Level Systems
// ------------------------------------
// DOC include start: Top
class Top(implicit p: Parameters) extends System
with HasNoDebug
with HasPeripherySerial {
with CanHavePeripheryUARTAdapter // Enables optionally adding the UART print adapter
with HasPeripheryUART // Enables optionally adding the sifive UART
with HasPeripheryGPIO // Enables optionally adding the sifive GPIOs
with CanHavePeripheryBlockDevice // Enables optionally adding the block device
with CanHavePeripheryInitZero // Enables optionally adding the initzero example widget
with CanHavePeripheryGCD // Enables optionally adding the GCD example widget
with CanHavePeripherySerial // Enables optionally adding the TSI serial-adapter and port
with CanHavePeripheryIceNIC // Enables optionally adding the IceNIC for FireSim
with CanHaveBackingScratchpad // Enables optionally adding a backing scratchpad
{
override lazy val module = new TopModule(this)
}
class TopModule[+L <: Top](l: L) extends SystemModule(l)
with HasNoDebugModuleImp
with HasPeripherySerialModuleImp
with DontTouch
//---------------------------------------------------------------------------------------------------------
// DOC include start: TopWithPWMTL
class TopWithPWMTL(implicit p: Parameters) extends Top
with HasPeripheryPWMTL {
override lazy val module = new TopWithPWMTLModule(this)
}
class TopWithPWMTLModule(l: TopWithPWMTL) extends TopModule(l)
with HasPeripheryPWMTLModuleImp
// DOC include end: TopWithPWMTL
//---------------------------------------------------------------------------------------------------------
class TopWithPWMAXI4(implicit p: Parameters) extends Top
with HasPeripheryPWMAXI4 {
override lazy val module = new TopWithPWMAXI4Module(this)
}
class TopWithPWMAXI4Module(l: TopWithPWMAXI4) extends TopModule(l)
with HasPeripheryPWMAXI4ModuleImp
//---------------------------------------------------------------------------------------------------------
class TopWithGCD(implicit p: Parameters) extends Top
with HasPeripheryGCD {
override lazy val module = new TopWithGCDModule(this)
}
class TopWithGCDModule(l: TopWithGCD) extends TopModule(l)
with HasPeripheryGCDModuleImp
//---------------------------------------------------------------------------------------------------------
class TopWithBlockDevice(implicit p: Parameters) extends Top
with HasPeripheryBlockDevice {
override lazy val module = new TopWithBlockDeviceModule(this)
}
class TopWithBlockDeviceModule(l: TopWithBlockDevice) extends TopModule(l)
with HasPeripheryBlockDeviceModuleImp
//---------------------------------------------------------------------------------------------------------
class TopWithGPIO(implicit p: Parameters) extends Top
with HasPeripheryGPIO {
override lazy val module = new TopWithGPIOModule(this)
}
class TopWithGPIOModule(l: TopWithGPIO)
extends TopModule(l)
with HasPeripheryGPIOModuleImp
//---------------------------------------------------------------------------------------------------------
class TopWithDTM(implicit p: Parameters) extends System
{
override lazy val module = new TopWithDTMModule(this)
}
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
with HasPeripheryUARTModuleImp
with CanHavePeripheryBlockDeviceModuleImp
with CanHavePeripheryGCDModuleImp
with CanHavePeripherySerialModuleImp
with CanHavePeripheryIceNICModuleImp
with CanHavePeripheryUARTAdapterModuleImp
with DontTouch
// DOC include end: Top

View File

@@ -0,0 +1,27 @@
package example
import chisel3._
import freechips.rocketchip.subsystem.BaseSubsystem
import freechips.rocketchip.config.{Field}
import freechips.rocketchip.diplomacy.{LazyModule, AddressSet}
import freechips.rocketchip.tilelink.{TLRAM}
case class BackingScratchpadParams(
base: BigInt,
mask: BigInt)
case object BackingScratchpadKey extends Field[Option[BackingScratchpadParams]](None)
/**
* Trait to add a scratchpad on the mbus
*/
trait CanHaveBackingScratchpad { this: BaseSubsystem =>
private val portName = "Backing-Scratchpad"
val spadOpt = p(BackingScratchpadKey).map { param =>
val spad = LazyModule(new TLRAM(address=AddressSet(param.base, param.mask), beatBytes=mbus.beatBytes))
mbus.toVariableWidthSlave(Some(portName)) { spad.node }
spad
}
}

View File

@@ -10,7 +10,7 @@ import freechips.rocketchip.devices.debug.HasPeripheryDebugModuleImp
import freechips.rocketchip.subsystem.{CanHaveMasterAXI4MemPortModuleImp}
import sifive.blocks.devices.uart.HasPeripheryUARTModuleImp
import testchipip.{HasPeripherySerialModuleImp, HasPeripheryBlockDeviceModuleImp}
import testchipip.{CanHavePeripherySerialModuleImp, CanHavePeripheryBlockDeviceModuleImp}
import icenet.HasPeripheryIceNICModuleImpValidOnly
import junctions.{NastiKey, NastiParameters}
@@ -18,32 +18,33 @@ import midas.models.{FASEDBridge, AXI4EdgeSummary, CompleteConfig}
import firesim.bridges._
import firesim.configs.MemModelKey
import firesim.util.RegisterBridgeBinder
import tracegen.HasTraceGenTilesModuleImp
class WithTiedOffDebug extends RegisterBridgeBinder({ case target: HasPeripheryDebugModuleImp =>
target.debug.clockeddmi.foreach({ cdmi =>
target.debug.foreach(_.clockeddmi.foreach({ cdmi =>
cdmi.dmi.req.valid := false.B
cdmi.dmi.req.bits := DontCare
cdmi.dmi.resp.ready := false.B
cdmi.dmiClock := false.B.asClock
cdmi.dmiReset := false.B
})
}))
Seq()
})
class WithSerialBridge extends RegisterBridgeBinder({
case target: HasPeripherySerialModuleImp => Seq(SerialBridge(target.serial)(target.p))
case target: CanHavePeripherySerialModuleImp => Seq(SerialBridge(target.serial.get)(target.p))
})
class WithNICBridge extends RegisterBridgeBinder({
case target: HasPeripheryIceNICModuleImpValidOnly => Seq(NICBridge(target.net)(target.p))
case target: HasPeripheryIceNICModuleImpValidOnly => Seq(NICBridge(target.net)(target.p))
})
class WithUARTBridge extends RegisterBridgeBinder({
case target: HasPeripheryUARTModuleImp => target.uart.map(u => UARTBridge(u)(target.p))
case target: HasPeripheryUARTModuleImp => target.uart.map(u => UARTBridge(u)(target.p))
})
class WithBlockDeviceBridge extends RegisterBridgeBinder({
case target: HasPeripheryBlockDeviceModuleImp => Seq(BlockDevBridge(target.bdev, target.reset.toBool)(target.p))
case target: CanHavePeripheryBlockDeviceModuleImp => Seq(BlockDevBridge(target.bdev.get, target.reset.toBool)(target.p))
})
class WithFASEDBridge extends RegisterBridgeBinder({
@@ -64,6 +65,11 @@ class WithTracerVBridge extends RegisterBridgeBinder({
case target: HasTraceIOImp => TracerVBridge(target.traceIO)(target.p)
})
class WithTraceGenBridge extends RegisterBridgeBinder({
case target: HasTraceGenTilesModuleImp =>
Seq(GroundTestBridge(target.success)(target.p))
})
// Shorthand to register all of the provided bridges above
class WithDefaultFireSimBridges extends Config(
new WithTiedOffDebug ++

View File

@@ -4,7 +4,7 @@ package firesim.firesim
import java.io.{File, FileWriter}
import chisel3.experimental.RawModule
import chisel3.RawModule
import chisel3.internal.firrtl.{Circuit, Port}
import freechips.rocketchip.diplomacy.{ValName, AutoBundle}
@@ -18,6 +18,8 @@ import freechips.rocketchip.tile.XLen
import firesim.util.{GeneratorArgs, HasTargetAgnosticUtilites, HasFireSimGeneratorUtilities}
import scala.util.Try
import utilities.TestSuiteHelper
trait HasTestSuites {
@@ -28,6 +30,14 @@ trait HasTestSuites {
TestGeneration.addSuite(SlowBlockdevTests)
if (!targetName.contains("NoNIC"))
TestGeneration.addSuite(NICLoopbackTests)
import hwacha.HwachaTestSuites._
if (Try(params(hwacha.HwachaNLanes)).getOrElse(0) > 0) {
TestGeneration.addSuites(rv64uv.map(_("p")))
TestGeneration.addSuites(rv64uv.map(_("vp")))
TestGeneration.addSuite(rv64sv("p"))
TestGeneration.addSuite(hwachaBmarks)
}
}
}
@@ -48,7 +58,7 @@ trait IsFireSimGeneratorLike extends HasFireSimGeneratorUtilities with HasTestSu
}
object FireSimGenerator extends App with IsFireSimGeneratorLike {
val longName = names.topModuleProject + "." + names.topModuleClass + "." + names.configs
override lazy val longName = names.topModuleProject + "." + names.topModuleClass + "." + names.configs
lazy val generatorArgs = GeneratorArgs(args)
lazy val genDir = new File(names.targetDir)
// The only reason this is not generateFirrtl; generateAnno is that we need to use a different
@@ -60,7 +70,7 @@ object FireSimGenerator extends App with IsFireSimGeneratorLike {
// For now, provide a separate generator app when not specifically building for FireSim
object Generator extends freechips.rocketchip.util.GeneratorApp with HasTestSuites {
val longName = names.topModuleProject + "." + names.topModuleClass + "." + names.configs
override lazy val longName = names.topModuleProject + "." + names.topModuleClass + "." + names.configs
generateFirrtl
generateAnno
generateTestSuiteMakefrags

View File

@@ -10,9 +10,9 @@ 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 freechips.rocketchip.devices.debug.{DebugModuleParams, DebugModuleKey}
import boom.common.BoomTilesKey
import testchipip.{BlockDeviceKey, BlockDeviceConfig}
import testchipip.{BlockDeviceKey, BlockDeviceConfig, SerialKey}
import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTParams}
import scala.math.{min, max}
import tracegen.TraceGenKey
@@ -47,12 +47,17 @@ class WithUARTKey extends Config((site, here, up) => {
nRxEntries = 256))
})
class WithSerial extends Config((site, here, up) => {
case SerialKey => true
})
class WithBlockDevice extends Config(new testchipip.WithBlockDevice)
class WithNICKey extends Config((site, here, up) => {
case NICKey => NICConfig(
case NICKey => Some(NICConfig(
inBufFlits = 8192,
ctrlQueueDepth = 64)
ctrlQueueDepth = 64,
checksumOffload = true))
})
class WithRocketL2TLBs(entries: Int) extends Config((site, here, up) => {
@@ -77,7 +82,7 @@ class WithBoomL2TLBs(entries: Int) extends Config((site, here, up) => {
// Disables clock-gating; doesn't play nice with our FAME-1 pass
class WithoutClockGating extends Config((site, here, up) => {
case DebugModuleParams => up(DebugModuleParams, site).copy(clockGate = false)
case DebugModuleKey => up(DebugModuleKey, site).map(_.copy(clockGate = false))
})
// Testing configurations
@@ -88,6 +93,7 @@ class WithScalaTestFeatures extends Config((site, here, up) => {
// FASED Config Aliases. This to enable config generation via "_" concatenation
// which requires that all config classes be defined in the same package
class DDR3FRFCFS extends FRFCFS16GBQuadRank
class DDR3FRFCFSLLC4MB extends FRFCFS16GBQuadRankLLC4MB
// L2 Config Aliases. For use with "_" concatenation
@@ -110,6 +116,7 @@ class FireSimRocketChipConfig extends Config(
new WithoutTLMonitors ++
new WithUARTKey ++
new WithNICKey ++
new WithSerial ++
new WithBlockDevice ++
new WithRocketL2TLBs(1024) ++
new WithPerfCounters ++
@@ -167,6 +174,7 @@ class FireSimBoomConfig extends Config(
new WithoutTLMonitors ++
new WithUARTKey ++
new WithNICKey ++
new WithSerial ++
new WithBlockDevice ++
new WithBoomL2TLBs(1024) ++
new WithoutClockGating ++
@@ -207,6 +215,18 @@ class FireSimRocketBoomConfig extends Config(
new FireSimBoomConfig
)
//**********************************************************************************
//* Gemmini Configurations
//*********************************************************************************/
// Gemmini systolic accelerator default config
class FireSimRocketChipGemminiL2Config extends Config(
new WithInclusiveCache ++
new gemmini.DefaultGemminiConfig ++
new WithNBigCores(1) ++
new FireSimRocketChipConfig)
//**********************************************************************************
//* Supernode Configurations
//*********************************************************************************/
@@ -279,6 +299,7 @@ class WithTraceGen(params: Seq[DCacheParams], nReqs: Int = 8192)
class FireSimTraceGenConfig extends Config(
new WithTraceGen(
List.fill(2) { DCacheParams(nMSHRs = 2, nSets = 16, nWays = 2) }) ++
new WithTraceGenBridge ++
new FireSimRocketChipConfig)
class WithL2TraceGen(params: Seq[DCacheParams], nReqs: Int = 8192)
@@ -316,4 +337,5 @@ class FireSimTraceGenL2Config extends Config(
nBanks = 4,
capacityKB = 1024,
outerLatencyCycles = 50) ++
new WithTraceGenBridge ++
new FireSimRocketChipConfig)

View File

@@ -42,10 +42,10 @@ class FireSimDUT(implicit p: Parameters) extends Subsystem
with HasHierarchicalBusTopology
with CanHaveMasterAXI4MemPort
with HasPeripheryBootROM
with HasPeripherySerial
with CanHavePeripherySerial
with HasPeripheryUART
with HasPeripheryIceNIC
with HasPeripheryBlockDevice
with CanHavePeripheryIceNIC
with CanHavePeripheryBlockDevice
with HasTraceIO
{
override lazy val module = new FireSimModuleImp(this)
@@ -55,10 +55,10 @@ class FireSimModuleImp[+L <: FireSimDUT](l: L) extends SubsystemModuleImp(l)
with HasRTCModuleImp
with CanHaveMasterAXI4MemPortModuleImp
with HasPeripheryBootROMModuleImp
with HasPeripherySerialModuleImp
with CanHavePeripherySerialModuleImp
with HasPeripheryUARTModuleImp
with HasPeripheryIceNICModuleImpValidOnly
with HasPeripheryBlockDeviceModuleImp
with CanHavePeripheryBlockDeviceModuleImp
with HasTraceIOImp
with CanHaveMultiCycleRegfileImp
@@ -68,9 +68,9 @@ class FireSimNoNICDUT(implicit p: Parameters) extends Subsystem
with HasHierarchicalBusTopology
with CanHaveMasterAXI4MemPort
with HasPeripheryBootROM
with HasPeripherySerial
with CanHavePeripherySerial
with HasPeripheryUART
with HasPeripheryBlockDevice
with CanHavePeripheryBlockDevice
with HasTraceIO
{
override lazy val module = new FireSimNoNICModuleImp(this)
@@ -80,24 +80,38 @@ class FireSimNoNICModuleImp[+L <: FireSimNoNICDUT](l: L) extends SubsystemModule
with HasRTCModuleImp
with CanHaveMasterAXI4MemPortModuleImp
with HasPeripheryBootROMModuleImp
with HasPeripherySerialModuleImp
with CanHavePeripherySerialModuleImp
with HasPeripheryUARTModuleImp
with HasPeripheryBlockDeviceModuleImp
with CanHavePeripheryBlockDeviceModuleImp
with HasTraceIOImp
with CanHaveMultiCycleRegfileImp
class FireSimNoNIC(implicit p: Parameters) extends DefaultFireSimHarness(() => new FireSimNoNICDUT)
class FireSimTraceGen(implicit p: Parameters) extends BaseSubsystem
class FireSimTraceGenDUT(implicit p: Parameters) extends BaseSubsystem
with HasHierarchicalBusTopology
with HasTraceGenTiles
with CanHaveMasterAXI4MemPort {
override lazy val module = new FireSimTraceGenModuleImp(this)
}
class FireSimTraceGenModuleImp(outer: FireSimTraceGen) extends BaseSubsystemModuleImp(outer)
class FireSimTraceGenModuleImp(outer: FireSimTraceGenDUT) extends BaseSubsystemModuleImp(outer)
with HasTraceGenTilesModuleImp
with CanHaveMasterAXI4MemPortModuleImp
class FireSimTraceGen(implicit p: Parameters) extends DefaultFireSimHarness(
() => new FireSimTraceGenDUT)
// Supernoded-ness comes from setting p(NumNodes) (see DefaultFiresimHarness) to something > 1
class FireSimSupernode(implicit p: Parameters) extends DefaultFireSimHarness(() => new FireSimDUT)
// Verilog blackbox integration demo
class FireSimVerilogGCDDUT(implicit p: Parameters) extends FireSimDUT
with example.CanHavePeripheryGCD
{
override lazy val module = new FireSimVerilogGCDModuleImp(this)
}
class FireSimVerilogGCDModuleImp[+L <: FireSimVerilogGCDDUT](l: L) extends FireSimModuleImp(l)
class FireSimVerilogGCD(implicit p: Parameters) extends DefaultFireSimHarness(() => new FireSimVerilogGCDDUT)

View File

@@ -138,3 +138,38 @@ class RocketNICF1Tests extends FireSimTestSuite("FireSim", "DDR3FRFCFSLLC4MB_Fir
}
class RamModelRocketF1Tests extends FireSimTestSuite("FireSimNoNIC", "FireSimRocketChipDualCoreConfig", "BaseF1Config_MCRams")
class RamModelBoomF1Tests extends FireSimTestSuite("FireSimNoNIC", "FireSimBoomConfig", "BaseF1Config_MCRams")
abstract class FireSimTraceGenTest(targetConfig: String, platformConfig: String)
extends firesim.TestSuiteCommon with IsFireSimGeneratorLike {
val longName = names.topModuleProject + "." + names.topModuleClass + "." + names.configs
lazy val generatorArgs = GeneratorArgs(
midasFlowKind = "midas",
targetDir = "generated-src",
topModuleProject = "firesim.firesim",
topModuleClass = "FireSimTraceGen",
targetConfigProject = "firesim.firesim",
targetConfigs = targetConfig ++ "_WithScalaTestFeatures",
platformConfigProject = "firesim.firesim",
platformConfigs = platformConfig)
// From HasFireSimGeneratorUtilities
// For the firesim utilities to use the same directory as the test suite
override lazy val testDir = genDir
// From TestSuiteCommon
val targetTuple = generatorArgs.tupleName
val commonMakeArgs = Seq(s"DESIGN=${generatorArgs.topModuleClass}",
s"TARGET_CONFIG=${generatorArgs.targetConfigs}",
s"PLATFORM_CONFIG=${generatorArgs.platformConfigs}")
it should "pass" in {
assert(make("fsim-tracegen") == 0)
}
}
class FireSimLLCTraceGenTest extends FireSimTraceGenTest(
"DDR3FRFCFSLLC4MB_FireSimTraceGenConfig", "BaseF1Config")
class FireSimL2TraceGenTest extends FireSimTraceGenTest(
"DDR3FRFCFS_FireSimTraceGenL2Config", "BaseF1Config")

1
generators/gemmini Submodule

Submodule generators/gemmini added at 6602434b34

View File

@@ -32,9 +32,35 @@ class WithTraceGen(params: Seq[DCacheParams], nReqs: Int = 8192)
memStart = site(ExtMem).get.master.base,
numGens = params.size)
}
case MaxHartIdBits => if (params.size == 1) 1 else log2Ceil(params.size)
case MaxHartIdBits => log2Ceil(params.size + up(BoomTraceGenKey, site).length) max 1
})
class WithBoomTraceGen(params: Seq[DCacheParams], nReqs: Int = 8192)
extends Config((site, here, up) => {
case BoomTraceGenKey => 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 => log2Ceil(params.size + up(TraceGenKey, site).length) max 1
})
class TraceGenConfig extends Config(
new WithTraceGen(List.fill(2) { DCacheParams(nMSHRs = 0, nSets = 16, nWays = 2) }) ++
new BaseConfig)
@@ -43,6 +69,10 @@ class NonBlockingTraceGenConfig extends Config(
new WithTraceGen(List.fill(2) { DCacheParams(nMSHRs = 2, nSets = 16, nWays = 2) }) ++
new BaseConfig)
class BoomTraceGenConfig extends Config(
new WithBoomTraceGen(List.fill(2) { DCacheParams(nMSHRs = 8, 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(

View File

@@ -6,12 +6,18 @@ import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, BufferParams}
import freechips.rocketchip.groundtest.{DebugCombiner, TraceGenParams}
import freechips.rocketchip.subsystem._
case object TraceGenKey extends Field[Seq[TraceGenParams]]
case object BoomTraceGenKey extends Field[Seq[TraceGenParams]](Nil)
case object TraceGenKey extends Field[Seq[TraceGenParams]](Nil)
trait HasTraceGenTiles { this: BaseSubsystem =>
val tiles = p(TraceGenKey).zipWithIndex.map { case (params, i) =>
val rocket_tiles = p(TraceGenKey).zipWithIndex.map { case (params, i) =>
LazyModule(new TraceGenTile(i, params, p))
}
val boom_tiles = p(BoomTraceGenKey).zipWithIndex.map { case (params, i) =>
LazyModule(new BoomTraceGenTile(i, params, p))
}
val tiles = rocket_tiles ++ boom_tiles
tiles.foreach { t =>
sbus.fromTile(None, buffer = BufferParams.default) { t.masterNode }
@@ -26,7 +32,10 @@ trait HasTraceGenTilesModuleImp extends LazyModuleImp {
t.module.constants.hartid := i.U
}
val status = DebugCombiner(outer.tiles.map(_.module.status))
val status = DebugCombiner(
outer.rocket_tiles.map(_.module.status) ++
outer.boom_tiles.map(_.module.status)
)
success := status.finished
}

View File

@@ -17,7 +17,7 @@ class TestHarness(implicit p: Parameters) extends Module {
object Generator extends GeneratorApp {
// specify the name that the generator outputs files as
val longName = names.topModuleProject + "." + names.topModuleClass + "." + names.configs
override lazy val longName = names.topModuleProject + "." + names.topModuleClass + "." + names.configs
// generate files
generateFirrtl

View File

@@ -1,14 +1,19 @@
package tracegen
import chisel3._
import chisel3.util._
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.rocket.{DCache, NonBlockingDCache, SimpleHellaCacheIF, HellaCacheExceptions, HellaCacheReq, HellaCacheIO}
import freechips.rocketchip.rocket.constants.{MemoryOpConstants}
import freechips.rocketchip.tile.{BaseTile, BaseTileModuleImp, HartsWontDeduplicate, TileKey}
import freechips.rocketchip.tilelink.{TLInwardNode, TLIdentityNode}
import freechips.rocketchip.interrupts._
import boom.lsu.{BoomNonBlockingDCache, LSU, LSUCoreIO}
import boom.common.{BoomTileParams, MicroOp, BoomCoreParams, BoomModule}
class TraceGenTile(val id: Int, val params: TraceGenParams, q: Parameters)
extends BaseTile(params, SynchronousCrossing(), HartsWontDeduplicate(params), q) {
val dcache = params.dcache.map { dc => LazyModule(
@@ -29,6 +34,190 @@ class TraceGenTile(val id: Int, val params: TraceGenParams, q: Parameters)
override lazy val module = new TraceGenTileModuleImp(this)
}
class BoomLSUShim(implicit p: Parameters) extends BoomModule()(p)
with MemoryOpConstants {
val io = IO(new Bundle {
val lsu = Flipped(new LSUCoreIO)
val tracegen = Flipped(new HellaCacheIO)
})
io.lsu.tsc_reg := 0.U(1.W)
val rob_sz = numRobEntries
val rob = Reg(Vec(rob_sz, new HellaCacheReq))
val rob_respd = RegInit(VecInit((~(0.U(rob_sz.W))).asBools))
val rob_uop = Reg(Vec(rob_sz, new MicroOp))
val rob_bsy = RegInit(VecInit(0.U(rob_sz.W).asBools))
val rob_head = RegInit(0.U(log2Up(rob_sz).W))
val rob_tail = RegInit(0.U(log2Up(rob_sz).W))
val rob_wait_till_empty = RegInit(false.B)
val ready_for_amo = rob_tail === rob_head && io.lsu.fencei_rdy
when (ready_for_amo) {
rob_wait_till_empty := false.B
}
def WrapInc(idx: UInt, max: Int): UInt = {
Mux(idx === (max-1).U, 0.U, idx + 1.U)
}
io.tracegen.req.ready := (!rob_bsy(rob_tail) &&
!rob_wait_till_empty &&
(ready_for_amo || !(isAMO(io.tracegen.req.bits.cmd) || io.tracegen.req.bits.cmd === M_XLR || io.tracegen.req.bits.cmd === M_XSC)) &&
(WrapInc(rob_tail, rob_sz) =/= rob_head) &&
!(io.lsu.ldq_full(0) && isRead(io.tracegen.req.bits.cmd)) &&
!(io.lsu.stq_full(0) && isWrite(io.tracegen.req.bits.cmd))
)
val tracegen_uop = WireInit((0.U).asTypeOf(new MicroOp))
tracegen_uop.uses_ldq := isRead(io.tracegen.req.bits.cmd) && !isWrite(io.tracegen.req.bits.cmd)
tracegen_uop.uses_stq := isWrite(io.tracegen.req.bits.cmd)
tracegen_uop.rob_idx := rob_tail
tracegen_uop.uopc := io.tracegen.req.bits.tag
tracegen_uop.mem_size := io.tracegen.req.bits.size
tracegen_uop.mem_cmd := io.tracegen.req.bits.cmd
tracegen_uop.mem_signed := io.tracegen.req.bits.signed
tracegen_uop.ldq_idx := io.lsu.dis_ldq_idx(0)
tracegen_uop.stq_idx := io.lsu.dis_stq_idx(0)
tracegen_uop.is_amo := isAMO(io.tracegen.req.bits.cmd) || io.tracegen.req.bits.cmd === M_XSC
tracegen_uop.ctrl.is_load := isRead(io.tracegen.req.bits.cmd) && !isWrite(io.tracegen.req.bits.cmd)
tracegen_uop.ctrl.is_sta := isWrite(io.tracegen.req.bits.cmd)
tracegen_uop.ctrl.is_std := isWrite(io.tracegen.req.bits.cmd)
io.lsu.dis_uops(0).valid := io.tracegen.req.fire()
io.lsu.dis_uops(0).bits := tracegen_uop
when (io.tracegen.req.fire()) {
rob_tail := WrapInc(rob_tail, rob_sz)
rob_bsy(rob_tail) := true.B
rob_uop(rob_tail) := tracegen_uop
rob_respd(rob_tail) := false.B
rob(rob_tail) := io.tracegen.req.bits
when (
isAMO(io.tracegen.req.bits.cmd) ||
io.tracegen.req.bits.cmd === M_XLR ||
io.tracegen.req.bits.cmd === M_XSC
) {
rob_wait_till_empty := true.B
}
}
io.lsu.fp_stdata.valid := false.B
io.lsu.fp_stdata.bits := DontCare
io.lsu.commit.valids(0) := (!rob_bsy(rob_head) && rob_head =/= rob_tail && rob_respd(rob_head))
io.lsu.commit.uops(0) := rob_uop(rob_head)
io.lsu.commit.rbk_valids(0) := false.B
io.lsu.commit.rollback := false.B
io.lsu.commit.fflags := DontCare
when (io.lsu.commit.valids(0)) {
rob_head := WrapInc(rob_head, rob_sz)
}
when (io.lsu.clr_bsy(0).valid) {
rob_bsy(io.lsu.clr_bsy(0).bits) := false.B
}
when (io.lsu.clr_unsafe(0).valid && rob(io.lsu.clr_unsafe(0).bits).cmd =/= M_XLR) {
rob_bsy(io.lsu.clr_unsafe(0).bits) := false.B
}
when (io.lsu.exe(0).iresp.valid) {
rob_bsy(io.lsu.exe(0).iresp.bits.uop.rob_idx) := false.B
}
assert(!io.lsu.lxcpt.valid)
io.lsu.exe(0).req.valid := RegNext(io.tracegen.req.fire())
io.lsu.exe(0).req.bits := DontCare
io.lsu.exe(0).req.bits.uop := RegNext(tracegen_uop)
io.lsu.exe(0).req.bits.addr := RegNext(io.tracegen.req.bits.addr)
io.lsu.exe(0).req.bits.data := RegNext(io.tracegen.req.bits.data)
io.tracegen.resp.valid := io.lsu.exe(0).iresp.valid
io.tracegen.resp.bits := DontCare
io.tracegen.resp.bits.tag := io.lsu.exe(0).iresp.bits.uop.uopc
io.tracegen.resp.bits.size := io.lsu.exe(0).iresp.bits.uop.mem_size
io.tracegen.resp.bits.data := io.lsu.exe(0).iresp.bits.data
val store_resp_idx = PriorityEncoder((0 until rob_sz) map {i =>
!rob_respd(i) && isWrite(rob(i).cmd)
})
val can_do_store_resp = ~rob_respd(store_resp_idx) && isWrite(rob(store_resp_idx).cmd) && !isRead(rob(store_resp_idx).cmd)
when (can_do_store_resp && !io.lsu.exe(0).iresp.valid) {
rob_respd(store_resp_idx) := true.B
io.tracegen.resp.valid := true.B
io.tracegen.resp.bits.tag := rob(store_resp_idx).tag
}
when (io.lsu.exe(0).iresp.valid) {
rob_respd(io.lsu.exe(0).iresp.bits.uop.rob_idx) := true.B
}
io.lsu.exe(0).fresp.ready := true.B
io.lsu.exe(0).iresp.ready := true.B
io.lsu.exception := false.B
io.lsu.fence_dmem := false.B
io.lsu.rob_pnr_idx := rob_tail
io.lsu.commit_load_at_rob_head := false.B
io.lsu.brinfo := DontCare
io.lsu.brinfo.valid := false.B
io.lsu.rob_head_idx := rob_head
}
class BoomTraceGenTile(val id: Int, val params: TraceGenParams, q: Parameters)
extends BaseTile(params, SynchronousCrossing(), HartsWontDeduplicate(params), q) {
val boom_params = p.alterMap(Map(TileKey -> BoomTileParams(
dcache=params.dcache,
core=BoomCoreParams(nPMPs=0, numLdqEntries=32, numStqEntries=32, useVM=false))))
val dcache = LazyModule(new BoomNonBlockingDCache(hartId)(boom_params))
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 BoomTraceGenTileModuleImp(this)
}
class BoomTraceGenTileModuleImp(outer: BoomTraceGenTile)
extends BaseTileModuleImp(outer){
val status = IO(new GroundTestStatus)
val tracegen = Module(new TraceGenerator(outer.params))
tracegen.io.hartid := constants.hartid
val ptw = Module(new DummyPTW(1))
val lsu = Module(new LSU()(outer.boom_params, outer.dcache.module.edge))
val boom_shim = Module(new BoomLSUShim()(outer.boom_params))
ptw.io.requestors.head <> lsu.io.ptw
outer.dcache.module.io.lsu <> lsu.io.dmem
boom_shim.io.tracegen <> tracegen.io.mem
boom_shim.io.lsu <> lsu.io.core
// Normally the PTW would use this port
lsu.io.hellacache := DontCare
lsu.io.hellacache.req.valid := false.B
status.finished := tracegen.io.finished
status.timeout.valid := tracegen.io.timeout
status.timeout.bits := 0.U
status.error.valid := false.B
}
class TraceGenTileModuleImp(outer: TraceGenTile)
extends BaseTileModuleImp(outer) {
val status = IO(new GroundTestStatus)

View File

@@ -66,7 +66,7 @@ trait HasBoomAndRocketTiles extends HasTiles
def treeNode: RocketTileLogicalTreeNode = new RocketTileLogicalTreeNode(rocketLogicalTree.getOMInterruptTargets)
LogicalModuleTree.add(logicalTreeNode, rocketLogicalTree)
connectInterrupts(tile, Some(debug), clintOpt, plicOpt)
connectInterrupts(tile, debugOpt, clintOpt, plicOpt)
tile
}

View File

@@ -10,10 +10,17 @@ RDIR=$(pwd)
CHIPYARD_DIR="${CHIPYARD_DIR:-$(git rev-parse --show-toplevel)}"
usage() {
echo "usage: ${0} [riscv-tools | esp-tools | ec2fast]"
echo "usage: ${0} [OPTIONS] [riscv-tools | esp-tools | ec2fast]"
echo ""
echo "Installation Types"
echo " riscv-tools: if set, builds the riscv toolchain (this is also the default)"
echo " esp-tools: if set, builds esp-tools toolchain used for the hwacha vector accelerator"
echo " ec2fast: if set, pulls in a pre-compiled RISC-V toolchain for an EC2 manager instance"
echo ""
echo "Options"
echo " --prefix PREFIX : Install destination. If unset, defaults to $(pwd)/riscv-tools-install"
echo " or $(pwd)/esp-tools-install"
echo " --help -h : Display this message"
exit "$1"
}
@@ -27,38 +34,34 @@ die() {
TOOLCHAIN="riscv-tools"
EC2FASTINSTALL="false"
RISCV=""
while getopts 'hH-:' opt ; do
case $opt in
h|H)
usage 3 ;;
-)
case $OPTARG in
help)
# getopts does not support long options, and is inflexible
while [ "$1" != "" ];
do
case $1 in
-h | --help | help )
usage 3 ;;
ec2fast) # Preserve compatibility
EC2FASTINSTALL=true ;;
*)
error "invalid option: --${OPTARG}"
-p | --prefix )
shift
RISCV=$(realpath $1) ;;
riscv-tools | esp-tools)
TOOLCHAIN=$1 ;;
ec2fast )
EC2FASTINSTALL="true" ;;
* )
error "invalid option $1"
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"
if [ -z "$RISCV" ] ; then
INSTALL_DIR="$TOOLCHAIN-install"
RISCV="$(pwd)/$INSTALL_DIR"
fi
INSTALL_DIR="$TOOLCHAIN-install"
RISCV="$(pwd)/$INSTALL_DIR"
echo "Installing toolchain to $RISCV"
# install risc-v tools
export RISCV="$RISCV"
@@ -107,7 +110,7 @@ else
esac; ) || die 'obsolete make version; need GNU make 4.x or later'
module_prepare riscv-gnu-toolchain qemu
module_build riscv-gnu-toolchain --prefix="${RISCV}"
module_build riscv-gnu-toolchain --prefix="${RISCV}" --with-cmodel=medany
echo '==> Building GNU/Linux toolchain'
module_make riscv-gnu-toolchain linux
fi
@@ -122,14 +125,21 @@ CC= CXX= module_all riscv-pk --prefix="${RISCV}" --host=riscv64-unknown-elf
module_all riscv-tests --prefix="${RISCV}/riscv64-unknown-elf"
# Common tools (not in any particular toolchain dir)
SRCDIR="$(pwd)/toolchains" module_all libgloss --prefix="${RISCV}/riscv64-unknown-elf" --host=riscv64-unknown-elf
SRCDIR="$(pwd)/toolchains" module_all qemu --prefix="${RISCV}" --target-list=riscv64-softmmu
cd "$RDIR"
# create specific 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
} > env-$TOOLCHAIN.sh
# create general env.sh
ln -sf env-$TOOLCHAIN.sh env.sh
echo "Toolchain Build Complete!"

18
scripts/centos-req.sh Executable file
View File

@@ -0,0 +1,18 @@
#!/bin/bash
sudo yum groupinstall -y "Development tools"
sudo yum install -y gmp-devel mpfr-devel libmpc-devel zlib-devel vim git java java-devel
curl https://bintray.com/sbt/rpm/rpm | sudo tee /etc/yum.repos.d/bintray-sbt-rpm.repo
sudo yum install -y sbt texinfo gengetopt
sudo yum install -y expat-devel libusb1-devel ncurses-devel cmake "perl(ExtUtils::MakeMaker)"
# deps for poky
sudo yum install -y python36 patch diffstat texi2html texinfo subversion chrpath git wget
# deps for qemu
sudo yum install -y gtk3-devel
# deps for firemarshal
sudo yum install -y python36-pip python36-devel rsync libguestfs-tools makeinfo expat ctags
# Install GNU make 4.x (needed to cross-compile glibc 2.28+)
sudo yum install -y centos-release-scl
sudo yum install -y devtoolset-8-make
# install DTC
sudo yum install -y dtc

View File

@@ -3,7 +3,7 @@
set -e
SCRIPT_DIR=$(dirname $0)
AXE_DIR=$(realpath ${SCRIPT_DIR}/../../axe)
AXE_DIR=$(realpath ${SCRIPT_DIR}/../tools/axe)
ROCKET_DIR=$(realpath ${SCRIPT_DIR}/../generators/rocket-chip)
TO_AXE=${ROCKET_DIR}/scripts/toaxe.py

View File

@@ -14,4 +14,4 @@
# * tags file in the directory that this was called in
# ctags wrapper
ctags -R --exclude=@.ctagsignore --links=no
ctags -R --exclude=@.ctagsignore --links=no --languages=scala,C,C++,python

View File

@@ -6,32 +6,17 @@ set -o pipefail
RDIR=$(git rev-parse --show-toplevel)
_usage() {
echo "usage: ${0} [--no-firesim]" >&2
exit 1
}
NO_FIRESIM=false
while getopts 'h-:' opt ; do
case ${opt} in
-)
case ${OPTARG} in
no-firesim) NO_FIRESIM=true ;;
*) echo "invalid option: --${OPTARG}" >&2 ; _usage ;;
esac ;;
h) _usage ;;
*) echo "invalid option: -${opt}" >&2 ; _usage ;;
esac
done
shift $((OPTIND - 1))
# Ignore toolchain submodules
cd "$RDIR"
for name in toolchains/*/*/ ; do
for name in toolchains/*-tools/*/ ; do
git config submodule."${name%/}".update none
done
git config submodule.toolchains/libgloss.update none
git config submodule.toolchains/qemu.update none
# Don't automatically initialize generators with big submodules (e.g. linux source)
git config submodule.generators/sha3.update none
# Disable updates to the FireSim submodule until explicitly requested
git config submodule.sims/firesim.update none
# Disable updates to the hammer tool plugins repos
@@ -39,23 +24,30 @@ git config submodule.vlsi/hammer-cadence-plugins.update none
git config submodule.vlsi/hammer-synopsys-plugins.update none
git config submodule.vlsi/hammer-mentor-plugins.update none
git submodule update --init --recursive #--jobs 8
# Un-ignore toolchain submodules
for name in toolchains/*/*/ ; do
for name in toolchains/*-tools/*/ ; do
git config --unset submodule."${name%/}".update
done
git config --unset submodule.toolchains/libgloss.update
git config --unset submodule.toolchains/qemu.update
git config --unset submodule.vlsi/hammer-cadence-plugins.update
git config --unset submodule.vlsi/hammer-synopsys-plugins.update
git config --unset submodule.vlsi/hammer-mentor-plugins.update
if [ $NO_FIRESIM = false ]; then
echo "initializing firesim"
# 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
git submodule update --init sims/firesim
git -C sims/firesim submodule update --init sim/midas
git -C sims/firesim submodule update --init --recursive sw/firesim-software
git config submodule.sims/firesim.update none
fi
git config --unset submodule.generators/sha3.update
# Non-recursive clone to exclude riscv-linux
git submodule update --init generators/sha3
git config --unset submodule.sims/firesim.update
# Minimal non-recursive clone to initialize sbt dependencies
git submodule update --init sims/firesim
(
cd sims/firesim
# Initialize dependencies for MIDAS-level RTL simulation
git submodule update --init sim/midas
# Exclude riscv-linux
git submodule update --init sw/firesim-software
)
git config submodule.sims/firesim.update none

19
scripts/ubuntu-req.sh Executable file
View File

@@ -0,0 +1,19 @@
#!/bin/bash
sudo apt-get install -y build-essential bison flex
sudo apt-get install -y libgmp-dev libmpfr-dev libmpc-dev zlib1g-dev vim git default-jdk default-jre
# install sbt: https://www.scala-sbt.org/release/docs/Installing-sbt-on-Linux.html
echo "deb https://dl.bintray.com/sbt/debian /" | sudo tee -a /etc/apt/sources.list.d/sbt.list
curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | sudo apt-key add
sudo apt-get update
sudo apt-get install -y sbt
sudo apt-get install -y texinfo gengetopt
sudo apt-get install -y libxpat1-dev libusb-dev libncurses5-dev cmake
# deps for poky
sudo apt-get install -y python3.6 patch diffstat texi2html texinfo subversion chrpath git wget
# deps for qemu
sudo apt-get install -y libgtk-3-dev
# deps for firemarshal
sudo apt-get install -y python3-pip python3.6-dev rsync libguestfs-tools expat ctags
# install DTC
sudo apt-get install -y device-tree-compiler

View File

@@ -91,7 +91,7 @@ $(sim_debug) : $(sim_vsrcs) $(sim_common_files)
#########################################################################################
.PRECIOUS: $(output_dir)/%.vpd %.vpd
$(output_dir)/%.vpd: $(output_dir)/% $(sim_debug)
(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)
(set -o pipefail && $(sim_debug) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(VERBOSE_FLAGS) +vcdplusfile=$@ $(PERMISSIVE_OFF) $< 2> >(spike-dasm > $<.out) | tee $<.log)
#########################################################################################
# general cleanup rule

View File

@@ -110,7 +110,7 @@ $(sim_debug): $(model_mk_debug)
$(output_dir)/%.vpd: $(output_dir)/% $(sim_debug)
rm -f $@.vcd && mkfifo $@.vcd
vcd2vpd $@.vcd $@ > /dev/null &
(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)
(set -o pipefail && $(sim_debug) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(VERBOSE_FLAGS) -v$@.vcd $(PERMISSIVE_OFF) $< 2> >(spike-dasm > $<.out) | tee $<.log)
#########################################################################################
# general cleanup rule

1
software/coremark Submodule

Submodule software/coremark added at cf8b8f7d82

1
software/spec2017 Submodule

Submodule software/spec2017 added at b864313643

1
tests/.gitignore vendored
View File

@@ -1,3 +1,4 @@
*.o
*.riscv
*.dump
libgloss/

View File

@@ -1,12 +1,18 @@
GCC=riscv64-unknown-elf-gcc
OBJDUMP=riscv64-unknown-elf-objdump
CFLAGS=-mcmodel=medany -std=gnu99 -O2 -fno-common -fno-builtin-printf -Wall
LDFLAGS=-static -nostdlib -nostartfiles -lgcc
CFLAGS= -std=gnu99 -O2 -fno-common -fno-builtin-printf -Wall
LDFLAGS= -static
include libgloss.mk
PROGRAMS = pwm blkdev accum charcount nic-loopback big-blkdev pingd
.DEFAULT_GOAL := default
.PHONY: default
default: $(addsuffix .riscv,$(PROGRAMS))
.PHONY: dumps
dumps: $(addsuffix .dump,$(PROGRAMS))
%.o: %.S
@@ -15,11 +21,14 @@ dumps: $(addsuffix .dump,$(PROGRAMS))
%.o: %.c mmio.h
$(GCC) $(CFLAGS) -c $< -o $@
%.riscv: %.o crt.o syscalls.o link.ld
$(GCC) -T link.ld $(LDFLAGS) $< crt.o syscalls.o -o $@
%.riscv: %.o $(libgloss)
$(GCC) $(LDFLAGS) $< -o $@
%.dump: %.riscv
$(OBJDUMP) -D $< > $@
.PHONY: clean
clean:
rm -f *.riscv *.o *.dump
$(if $(libgloss),rm -rf $(libgloss_builddir)/)

View File

@@ -1,237 +0,0 @@
# See LICENSE for license details.
#include "encoding.h"
#if __riscv_xlen == 64
# define LREG ld
# define SREG sd
# define REGBYTES 8
#else
# define LREG lw
# define SREG sw
# define REGBYTES 4
#endif
.section ".text.init"
.globl _start
_start:
li x1, 0
li x2, 0
li x3, 0
li x4, 0
li x5, 0
li x6, 0
li x7, 0
li x8, 0
li x9, 0
li x10,0
li x11,0
li x12,0
li x13,0
li x14,0
li x15,0
li x16,0
li x17,0
li x18,0
li x19,0
li x20,0
li x21,0
li x22,0
li x23,0
li x24,0
li x25,0
li x26,0
li x27,0
li x28,0
li x29,0
li x30,0
li x31,0
# enable FPU and accelerator if present
li t0, MSTATUS_FS | MSTATUS_XS
csrs mstatus, t0
# make sure XLEN agrees with compilation choice
li t0, 1
slli t0, t0, 31
#if __riscv_xlen == 64
bgez t0, 1f
#else
bltz t0, 1f
#endif
2:
li a0, 1
sw a0, tohost, t0
j 2b
1:
#ifdef __riscv_flen
# initialize FPU if we have one
la t0, 1f
csrw mtvec, t0
fssr x0
fmv.s.x f0, x0
fmv.s.x f1, x0
fmv.s.x f2, x0
fmv.s.x f3, x0
fmv.s.x f4, x0
fmv.s.x f5, x0
fmv.s.x f6, x0
fmv.s.x f7, x0
fmv.s.x f8, x0
fmv.s.x f9, x0
fmv.s.x f10,x0
fmv.s.x f11,x0
fmv.s.x f12,x0
fmv.s.x f13,x0
fmv.s.x f14,x0
fmv.s.x f15,x0
fmv.s.x f16,x0
fmv.s.x f17,x0
fmv.s.x f18,x0
fmv.s.x f19,x0
fmv.s.x f20,x0
fmv.s.x f21,x0
fmv.s.x f22,x0
fmv.s.x f23,x0
fmv.s.x f24,x0
fmv.s.x f25,x0
fmv.s.x f26,x0
fmv.s.x f27,x0
fmv.s.x f28,x0
fmv.s.x f29,x0
fmv.s.x f30,x0
fmv.s.x f31,x0
1:
#endif
# initialize trap vector
la t0, trap_entry
csrw mtvec, t0
# initialize global pointer
.option push
.option norelax
la gp, __global_pointer$
.option pop
la tp, _end + 63
and tp, tp, -64
# get core id
csrr a0, mhartid
# for now, assume only 1 core
li a1, 1
1:bgeu a0, a1, 1b
# give each core 128KB of stack + TLS
#define STKSHIFT 17
sll a2, a0, STKSHIFT
add tp, tp, a2
add sp, a0, 1
sll sp, sp, STKSHIFT
add sp, sp, tp
j _init
.align 2
trap_entry:
addi sp, sp, -272
SREG x1, 1*REGBYTES(sp)
SREG x2, 2*REGBYTES(sp)
SREG x3, 3*REGBYTES(sp)
SREG x4, 4*REGBYTES(sp)
SREG x5, 5*REGBYTES(sp)
SREG x6, 6*REGBYTES(sp)
SREG x7, 7*REGBYTES(sp)
SREG x8, 8*REGBYTES(sp)
SREG x9, 9*REGBYTES(sp)
SREG x10, 10*REGBYTES(sp)
SREG x11, 11*REGBYTES(sp)
SREG x12, 12*REGBYTES(sp)
SREG x13, 13*REGBYTES(sp)
SREG x14, 14*REGBYTES(sp)
SREG x15, 15*REGBYTES(sp)
SREG x16, 16*REGBYTES(sp)
SREG x17, 17*REGBYTES(sp)
SREG x18, 18*REGBYTES(sp)
SREG x19, 19*REGBYTES(sp)
SREG x20, 20*REGBYTES(sp)
SREG x21, 21*REGBYTES(sp)
SREG x22, 22*REGBYTES(sp)
SREG x23, 23*REGBYTES(sp)
SREG x24, 24*REGBYTES(sp)
SREG x25, 25*REGBYTES(sp)
SREG x26, 26*REGBYTES(sp)
SREG x27, 27*REGBYTES(sp)
SREG x28, 28*REGBYTES(sp)
SREG x29, 29*REGBYTES(sp)
SREG x30, 30*REGBYTES(sp)
SREG x31, 31*REGBYTES(sp)
csrr a0, mcause
csrr a1, mepc
mv a2, sp
jal handle_trap
csrw mepc, a0
# Remain in M-mode after eret
li t0, MSTATUS_MPP
csrs mstatus, t0
LREG x1, 1*REGBYTES(sp)
LREG x2, 2*REGBYTES(sp)
LREG x3, 3*REGBYTES(sp)
LREG x4, 4*REGBYTES(sp)
LREG x5, 5*REGBYTES(sp)
LREG x6, 6*REGBYTES(sp)
LREG x7, 7*REGBYTES(sp)
LREG x8, 8*REGBYTES(sp)
LREG x9, 9*REGBYTES(sp)
LREG x10, 10*REGBYTES(sp)
LREG x11, 11*REGBYTES(sp)
LREG x12, 12*REGBYTES(sp)
LREG x13, 13*REGBYTES(sp)
LREG x14, 14*REGBYTES(sp)
LREG x15, 15*REGBYTES(sp)
LREG x16, 16*REGBYTES(sp)
LREG x17, 17*REGBYTES(sp)
LREG x18, 18*REGBYTES(sp)
LREG x19, 19*REGBYTES(sp)
LREG x20, 20*REGBYTES(sp)
LREG x21, 21*REGBYTES(sp)
LREG x22, 22*REGBYTES(sp)
LREG x23, 23*REGBYTES(sp)
LREG x24, 24*REGBYTES(sp)
LREG x25, 25*REGBYTES(sp)
LREG x26, 26*REGBYTES(sp)
LREG x27, 27*REGBYTES(sp)
LREG x28, 28*REGBYTES(sp)
LREG x29, 29*REGBYTES(sp)
LREG x30, 30*REGBYTES(sp)
LREG x31, 31*REGBYTES(sp)
addi sp, sp, 272
mret
.section ".tdata.begin"
.globl _tdata_begin
_tdata_begin:
.section ".tdata.end"
.globl _tdata_end
_tdata_end:
.section ".tbss.end"
.globl _tbss_end
_tbss_end:
.section ".tohost","aw",@progbits
.align 6
.globl tohost
tohost: .dword 0
.align 6
.globl fromhost
fromhost: .dword 0

File diff suppressed because it is too large Load Diff

1
tests/htif.ld Symbolic link
View File

@@ -0,0 +1 @@
../toolchains/libgloss/util/htif.ld

50
tests/libgloss.mk Normal file
View File

@@ -0,0 +1,50 @@
# Handle libgloss-htif dependency
ifndef libgloss
ifndef GCC
$(error GCC is not defined)
endif
libgloss_specs := htif_nano.specs
# Test whether libgloss-htif is globally installed and usable
# Define BUILD_LIBGLOSS=1 to unconditionally force a local build
BUILD_LIBGLOSS ?= $(shell { echo 'int main(void) { return 0; }' | \
$(GCC) -xc -specs=$(libgloss_specs) -o /dev/null - 2> /dev/null ; } || \
echo "$$?")
ifneq ($(BUILD_LIBGLOSS),)
$(info libgloss-htif: Using local build)
libgloss_srcdir := ../toolchains/libgloss
libgloss_builddir := libgloss
libgloss_specs := $(libgloss_srcdir)/util/$(libgloss_specs)
libgloss_lib := $(libgloss_builddir)/libgloss_htif.a
libgloss := $(libgloss_lib) $(libgloss_specs) htif.ld
LDFLAGS += -L libgloss
$(libgloss_builddir)/Makefile: $(libgloss_srcdir)/configure
mkdir -p $(dir $@)
cd $(dir $@) && $(realpath $<) \
--prefix=$(shell $(GCC) -print-sysroot) \
--host=$(TARGET) \
--disable-multilib
$(libgloss_lib): $(libgloss_builddir)/Makefile
$(MAKE) -C $(dir $^)
.PHONY: libgloss
libgloss: $(libgloss)
else
$(info libgloss-htif: Using global install)
libgloss := # No additional prerequisites
endif
CFLAGS += -specs=$(libgloss_specs)
LDFLAGS += -specs=$(libgloss_specs)
endif # libgloss

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