diff --git a/.circleci/check-commit.sh b/.circleci/check-commit.sh index ad7be185..3c57d64c 100755 --- a/.circleci/check-commit.sh +++ b/.circleci/check-commit.sh @@ -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" + diff --git a/.circleci/config.yml b/.circleci/config.yml index e1738732..9fbb2958 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -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: diff --git a/.circleci/create-hash.sh b/.circleci/create-hash.sh index 939eeb31..7a8915a5 100755 --- a/.circleci/create-hash.sh +++ b/.circleci/create-hash.sh @@ -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 diff --git a/.circleci/defaults.sh b/.circleci/defaults.sh index 884592f1..08c4222c 100755 --- a/.circleci/defaults.sh +++ b/.circleci/defaults.sh @@ -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" diff --git a/.circleci/do-firesim-build.sh b/.circleci/do-firesim-build.sh index ecb965b2..8114355f 100755 --- a/.circleci/do-firesim-build.sh +++ b/.circleci/do-firesim-build.sh @@ -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" diff --git a/.circleci/do-rtl-build.sh b/.circleci/do-rtl-build.sh index 50f9ce94..dd667dfb 100755 --- a/.circleci/do-rtl-build.sh +++ b/.circleci/do-rtl-build.sh @@ -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" diff --git a/.circleci/run-midasexamples-tests.sh b/.circleci/run-midasexamples-tests.sh index 383a75ff..7d31ac11 100755 --- a/.circleci/run-midasexamples-tests.sh +++ b/.circleci/run-midasexamples-tests.sh @@ -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\"" diff --git a/.circleci/run-tests.sh b/.circleci/run-tests.sh index 4a6d9e7b..6d01d182 100755 --- a/.circleci/run-tests.sh +++ b/.circleci/run-tests.sh @@ -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 diff --git a/.ctagsignore b/.ctagsignore index c910d58a..c1b3fb23 100644 --- a/.ctagsignore +++ b/.ctagsignore @@ -1 +1,3 @@ */target +sims +toolchains diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md new file mode 100644 index 00000000..4da4667e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -0,0 +1,23 @@ +--- +name: Bug Report +about: Report a problem with Chipyard +labels: bug + +--- + + +**Impact**: rtl | software | unknown | other + +**What is the current behavior?** + +**What is the expected behavior?** + +**Please tell us about your environment:** + + +**Other information** + diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md new file mode 100644 index 00000000..70e2081d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -0,0 +1,13 @@ +--- +name: Feature Request +about: Propose a change to Chipyard + +--- + + +**Impact**: rtl | software | unknown | other + +**Description** + + +**What is a motivating example for changing the behavior?** diff --git a/.github/ISSUE_TEMPLATE/other.md b/.github/ISSUE_TEMPLATE/other.md new file mode 100644 index 00000000..b41a5e5c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/other.md @@ -0,0 +1,6 @@ +--- +name: Other +about: Something else! + +--- + diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md new file mode 100644 index 00000000..b8c3f482 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/question.md @@ -0,0 +1,13 @@ +--- +name: Question +about: Ask a question +labels: question + +--- + + + + + + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..4949e777 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,10 @@ +**Related issue**: + + +**Type of change**: bug fix | new feature | other enhancement + + +**Impact**: rtl change | software change | unknown | other + +**Release Notes** + diff --git a/.gitmodules b/.gitmodules index 6843547b..d514a4e9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 diff --git a/CHANGELOG.md b/CHANGELOG.md index 935c72f6..31fb2250 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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. diff --git a/LICENSE b/LICENSE index c6092e14..946eca94 100644 --- a/LICENSE +++ b/LICENSE @@ -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. diff --git a/README.md b/README.md index 79a6b533..26f32cf5 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/build.sbt b/build.sbt index 9fa5352e..2fd83c55 100644 --- a/build.sbt +++ b/build.sbt @@ -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 ) diff --git a/common.mk b/common.mk index 112285c2..2259bb40 100644 --- a/common.mk +++ b/common.mk @@ -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 diff --git a/docs/Advanced-Concepts/CDEs.rst b/docs/Advanced-Concepts/CDEs.rst new file mode 100644 index 00000000..b8e130e6 --- /dev/null +++ b/docs/Advanced-Concepts/CDEs.rst @@ -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 `_ . + + +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``. + + diff --git a/docs/Advanced-Concepts/Chip-Communication.rst b/docs/Advanced-Concepts/Chip-Communication.rst index 92efd17c..29979900 100644 --- a/docs/Advanced-Concepts/Chip-Communication.rst +++ b/docs/Advanced-Concepts/Chip-Communication.rst @@ -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 `__ .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 +`__ 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 diff --git a/docs/Advanced-Concepts/Top-Testharness.rst b/docs/Advanced-Concepts/Top-Testharness.rst index 1256ea59..3d22e54a 100644 --- a/docs/Advanced-Concepts/Top-Testharness.rst +++ b/docs/Advanced-Concepts/Top-Testharness.rst @@ -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 `__. -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 `__, -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. diff --git a/docs/Advanced-Concepts/index.rst b/docs/Advanced-Concepts/index.rst index 8194fe1f..af23525a 100644 --- a/docs/Advanced-Concepts/index.rst +++ b/docs/Advanced-Concepts/index.rst @@ -12,3 +12,5 @@ They expect you to know about Chisel, Parameters, Configs, etc. Chip-Communication Debugging-RTL Resources + CDEs + diff --git a/docs/Chipyard-Basics/Initial-Repo-Setup.rst b/docs/Chipyard-Basics/Initial-Repo-Setup.rst index ad5f1abd..931da013 100644 --- a/docs/Chipyard-Basics/Initial-Repo-Setup.rst +++ b/docs/Chipyard-Basics/Initial-Repo-Setup.rst @@ -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 ------------------------ diff --git a/docs/Chipyard-Basics/index.rst b/docs/Chipyard-Basics/index.rst index 28a08700..9a306c4f 100644 --- a/docs/Chipyard-Basics/index.rst +++ b/docs/Chipyard-Basics/index.rst @@ -16,6 +16,7 @@ Hit next to get started! :caption: Chipyard Basics: Chipyard-Components + Development-Ecosystem Configs-Parameters-Mixins Initial-Repo-Setup diff --git a/docs/Customization/Adding-An-Accelerator.rst b/docs/Customization/Adding-An-Accelerator.rst deleted file mode 100644 index 3c0ea4eb..00000000 --- a/docs/Customization/Adding-An-Accelerator.rst +++ /dev/null @@ -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 - - diff --git a/docs/Customization/Boot-Process.rst b/docs/Customization/Boot-Process.rst index d23fae85..b6b5e8a3 100644 --- a/docs/Customization/Boot-Process.rst +++ b/docs/Customization/Boot-Process.rst @@ -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. diff --git a/docs/Customization/Custom-Chisel.rst b/docs/Customization/Custom-Chisel.rst new file mode 100644 index 00000000..feec3141 --- /dev/null +++ b/docs/Customization/Custom-Chisel.rst @@ -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) diff --git a/docs/Customization/DMA-Devices.rst b/docs/Customization/DMA-Devices.rst new file mode 100644 index 00000000..f2e95e52 --- /dev/null +++ b/docs/Customization/DMA-Devices.rst @@ -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 + + diff --git a/docs/Customization/Heterogeneous-SoCs.rst b/docs/Customization/Heterogeneous-SoCs.rst index 116d4ae9..e1d58c6a 100644 --- a/docs/Customization/Heterogeneous-SoCs.rst +++ b/docs/Customization/Heterogeneous-SoCs.rst @@ -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) diff --git a/docs/Customization/Incorporating-Verilog-Blocks.rst b/docs/Customization/Incorporating-Verilog-Blocks.rst index 64f064f8..fc1b8d7d 100644 --- a/docs/Customization/Incorporating-Verilog-Blocks.rst +++ b/docs/Customization/Incorporating-Verilog-Blocks.rst @@ -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. diff --git a/docs/Customization/Keys-Traits-Configs.rst b/docs/Customization/Keys-Traits-Configs.rst new file mode 100644 index 00000000..e7705f44 --- /dev/null +++ b/docs/Customization/Keys-Traits-Configs.rst @@ -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`. + + diff --git a/docs/Customization/MMIO-Peripherals.rst b/docs/Customization/MMIO-Peripherals.rst new file mode 100644 index 00000000..23fddca4 --- /dev/null +++ b/docs/Customization/MMIO-Peripherals.rst @@ -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 + + diff --git a/docs/Customization/Memory-Hierarchy.rst b/docs/Customization/Memory-Hierarchy.rst index 207e0775..6266e435 100644 --- a/docs/Customization/Memory-Hierarchy.rst +++ b/docs/Customization/Memory-Hierarchy.rst @@ -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 diff --git a/docs/Customization/RoCC-Accelerators.rst b/docs/Customization/RoCC-Accelerators.rst new file mode 100644 index 00000000..7a3f4447 --- /dev/null +++ b/docs/Customization/RoCC-Accelerators.rst @@ -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``. + diff --git a/docs/Customization/RoCC-or-MMIO.rst b/docs/Customization/RoCC-or-MMIO.rst new file mode 100644 index 00000000..dd1ed81c --- /dev/null +++ b/docs/Customization/RoCC-or-MMIO.rst @@ -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. diff --git a/docs/Customization/index.rst b/docs/Customization/index.rst index cd52a499..c5ec5778 100644 --- a/docs/Customization/index.rst +++ b/docs/Customization/index.rst @@ -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 diff --git a/docs/Generators/Gemmini.rst b/docs/Generators/Gemmini.rst new file mode 100644 index 00000000..66f8e017 --- /dev/null +++ b/docs/Generators/Gemmini.rst @@ -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 `__ 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 `__. +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 + +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 + diff --git a/docs/Generators/Hwacha.rst b/docs/Generators/Hwacha.rst index 240d6fc9..ac4f4fdf 100644 --- a/docs/Generators/Hwacha.rst +++ b/docs/Generators/Hwacha.rst @@ -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 `__ 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. diff --git a/docs/Generators/SHA3.rst b/docs/Generators/SHA3.rst index 96b5744a..a9b87108 100644 --- a/docs/Generators/SHA3.rst +++ b/docs/Generators/SHA3.rst @@ -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 `_ for more information on how to run/build the tests. + diff --git a/docs/Generators/SiFive-Generators.rst b/docs/Generators/SiFive-Generators.rst index 8f2202b0..19360162 100644 --- a/docs/Generators/SiFive-Generators.rst +++ b/docs/Generators/SiFive-Generators.rst @@ -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``). diff --git a/docs/Generators/TestChipIP.rst b/docs/Generators/TestChipIP.rst index 7d490c5f..13b516e3 100644 --- a/docs/Generators/TestChipIP.rst +++ b/docs/Generators/TestChipIP.rst @@ -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 `_. + +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=`` 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. diff --git a/docs/Generators/index.rst b/docs/Generators/index.rst index 5aa097b6..5bb5d491 100644 --- a/docs/Generators/index.rst +++ b/docs/Generators/index.rst @@ -22,6 +22,7 @@ so changes to the generators themselves will automatically be used when building Rocket BOOM Hwacha + Gemmini IceNet TestChipIP SiFive-Generators diff --git a/docs/Quick-Start.rst b/docs/Quick-Start.rst index d1d7ed93..cc650bd6 100644 --- a/docs/Quick-Start.rst +++ b/docs/Quick-Start.rst @@ -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`. diff --git a/docs/VLSI/Advanced-Usage.rst b/docs/VLSI/Advanced-Usage.rst index c7e1bae2..6ab44c02 100644 --- a/docs/VLSI/Advanced-Usage.rst +++ b/docs/VLSI/Advanced-Usage.rst @@ -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= + CUSTOM_VLOG= VLSI_TOP= ``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. diff --git a/docs/VLSI/Tutorial.rst b/docs/VLSI/Tutorial.rst index 66a2f220..406cee46 100644 --- a/docs/VLSI/Tutorial.rst +++ b/docs/VLSI/Tutorial.rst @@ -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. diff --git a/docs/_static/images/chip-bringup.png b/docs/_static/images/chip-bringup.png index b7ed0226..4e8d0602 100644 Binary files a/docs/_static/images/chip-bringup.png and b/docs/_static/images/chip-bringup.png differ diff --git a/docs/_static/images/gemmini-system.png b/docs/_static/images/gemmini-system.png new file mode 100644 index 00000000..df44708f Binary files /dev/null and b/docs/_static/images/gemmini-system.png differ diff --git a/docs/_static/images/gemmini-systolic-array.png b/docs/_static/images/gemmini-systolic-array.png new file mode 100644 index 00000000..6586065a Binary files /dev/null and b/docs/_static/images/gemmini-systolic-array.png differ diff --git a/generators/boom b/generators/boom index 2a0ea2e7..a88fe70c 160000 --- a/generators/boom +++ b/generators/boom @@ -1 +1 @@ -Subproject commit 2a0ea2e7acfd4605eed513e15062848e4e5be309 +Subproject commit a88fe70c81c33fb4773d52a529633029fa6eb9af diff --git a/generators/example/src/main/resources/vsrc/GCDMMIOBlackBox.v b/generators/example/src/main/resources/vsrc/GCDMMIOBlackBox.v index 9104ae87..46acd5c8 100644 --- a/generators/example/src/main/resources/vsrc/GCDMMIOBlackBox.v +++ b/generators/example/src/main/resources/vsrc/GCDMMIOBlackBox.v @@ -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) diff --git a/generators/example/src/main/scala/BoomConfigs.scala b/generators/example/src/main/scala/BoomConfigs.scala index 9b073907..a6a0adb4 100644 --- a/generators/example/src/main/scala/BoomConfigs.scala +++ b/generators/example/src/main/scala/BoomConfigs.scala @@ -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) + diff --git a/generators/example/src/main/scala/ConfigMixins.scala b/generators/example/src/main/scala/ConfigMixins.scala index 7d7e74af..acd1001e 100644 --- a/generators/example/src/main/scala/ConfigMixins.scala +++ b/generators/example/src/main/scala/ConfigMixins.scala @@ -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 diff --git a/generators/example/src/main/scala/GCD.scala b/generators/example/src/main/scala/GCD.scala new file mode 100644 index 00000000..f41e78db --- /dev/null +++ b/generators/example/src/main/scala/GCD.scala @@ -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 diff --git a/generators/example/src/main/scala/GCDMMIOBlackBox.scala b/generators/example/src/main/scala/GCDMMIOBlackBox.scala deleted file mode 100644 index 891fe1c9..00000000 --- a/generators/example/src/main/scala/GCDMMIOBlackBox.scala +++ /dev/null @@ -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 diff --git a/generators/example/src/main/scala/Generator.scala b/generators/example/src/main/scala/Generator.scala index f164b481..9beb094c 100644 --- a/generators/example/src/main/scala/Generator.scala +++ b/generators/example/src/main/scala/Generator.scala @@ -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 diff --git a/generators/example/src/main/scala/HeteroConfigs.scala b/generators/example/src/main/scala/HeteroConfigs.scala index a9443c2e..d68532ad 100644 --- a/generators/example/src/main/scala/HeteroConfigs.scala +++ b/generators/example/src/main/scala/HeteroConfigs.scala @@ -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) diff --git a/generators/example/src/main/scala/InitZero.scala b/generators/example/src/main/scala/InitZero.scala index 3a90bfcc..4c7f3bbb 100644 --- a/generators/example/src/main/scala/InitZero.scala +++ b/generators/example/src/main/scala/InitZero.scala @@ -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 + } } diff --git a/generators/example/src/main/scala/PWM.scala b/generators/example/src/main/scala/PWM.scala deleted file mode 100644 index bd6056f4..00000000 --- a/generators/example/src/main/scala/PWM.scala +++ /dev/null @@ -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 -} diff --git a/generators/example/src/main/scala/RocketConfigs.scala b/generators/example/src/main/scala/RocketConfigs.scala index 615111df..7cc43a4d 100644 --- a/generators/example/src/main/scala/RocketConfigs.scala +++ b/generators/example/src/main/scala/RocketConfigs.scala @@ -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) diff --git a/generators/example/src/main/scala/TestHarness.scala b/generators/example/src/main/scala/TestHarness.scala index 61807f2e..50c872f2 100644 --- a/generators/example/src/main/scala/TestHarness.scala +++ b/generators/example/src/main/scala/TestHarness.scala @@ -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) } diff --git a/generators/example/src/main/scala/Top.scala b/generators/example/src/main/scala/Top.scala index b7f1a500..47ab1c28 100644 --- a/generators/example/src/main/scala/Top.scala +++ b/generators/example/src/main/scala/Top.scala @@ -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 diff --git a/generators/example/src/main/scala/TopCakes.scala b/generators/example/src/main/scala/TopCakes.scala new file mode 100644 index 00000000..30f13e48 --- /dev/null +++ b/generators/example/src/main/scala/TopCakes.scala @@ -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 + } +} diff --git a/generators/firechip/src/main/scala/BridgeBinders.scala b/generators/firechip/src/main/scala/BridgeBinders.scala index c2bed0e5..f0c9c664 100644 --- a/generators/firechip/src/main/scala/BridgeBinders.scala +++ b/generators/firechip/src/main/scala/BridgeBinders.scala @@ -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 ++ diff --git a/generators/firechip/src/main/scala/Generator.scala b/generators/firechip/src/main/scala/Generator.scala index 0c5b4909..dd5b432d 100644 --- a/generators/firechip/src/main/scala/Generator.scala +++ b/generators/firechip/src/main/scala/Generator.scala @@ -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 diff --git a/generators/firechip/src/main/scala/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index 9839c14f..17ac06e6 100644 --- a/generators/firechip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/src/main/scala/TargetConfigs.scala @@ -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) diff --git a/generators/firechip/src/main/scala/Targets.scala b/generators/firechip/src/main/scala/Targets.scala index dc259c23..b608e67b 100644 --- a/generators/firechip/src/main/scala/Targets.scala +++ b/generators/firechip/src/main/scala/Targets.scala @@ -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) diff --git a/generators/firechip/src/test/scala/ScalaTestSuite.scala b/generators/firechip/src/test/scala/ScalaTestSuite.scala index 06018ae1..f4f55cd9 100644 --- a/generators/firechip/src/test/scala/ScalaTestSuite.scala +++ b/generators/firechip/src/test/scala/ScalaTestSuite.scala @@ -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") diff --git a/generators/gemmini b/generators/gemmini new file mode 160000 index 00000000..6602434b --- /dev/null +++ b/generators/gemmini @@ -0,0 +1 @@ +Subproject commit 6602434b34fb33d005af50cd5e7bf8534f82ebf7 diff --git a/generators/hwacha b/generators/hwacha index ff4605f5..ef5e5196 160000 --- a/generators/hwacha +++ b/generators/hwacha @@ -1 +1 @@ -Subproject commit ff4605f5d10d91b7ae8c4a006b965d4706009a06 +Subproject commit ef5e5196b685536890396a08a9f5024eb8b7928e diff --git a/generators/icenet b/generators/icenet index baa40ed8..49b6dfb6 160000 --- a/generators/icenet +++ b/generators/icenet @@ -1 +1 @@ -Subproject commit baa40ed85d7425ef5ce206d52fb8b2759c6f6827 +Subproject commit 49b6dfb6341bf128e95c549e42f881ad16dd45a5 diff --git a/generators/rocket-chip b/generators/rocket-chip index 50de8a34..4f0cdea8 160000 --- a/generators/rocket-chip +++ b/generators/rocket-chip @@ -1 +1 @@ -Subproject commit 50de8a34c19c12de5066cd7ada50ebb5f5b2ea26 +Subproject commit 4f0cdea85c8a2b849fd582ccc8497892001d06b0 diff --git a/generators/sha3 b/generators/sha3 index 60ddfe7c..543adb4f 160000 --- a/generators/sha3 +++ b/generators/sha3 @@ -1 +1 @@ -Subproject commit 60ddfe7c5b2c1640d91e7d9a35c65011c1600810 +Subproject commit 543adb4ff1ac8b4f21f8d3ac5f7e865f8d109731 diff --git a/generators/sifive-blocks b/generators/sifive-blocks index 24dd5378..1bc0ef18 160000 --- a/generators/sifive-blocks +++ b/generators/sifive-blocks @@ -1 +1 @@ -Subproject commit 24dd537894379dc160ed9e15d33444439822ab5b +Subproject commit 1bc0ef18d6653f1133cb9293e8ee8620f9417c78 diff --git a/generators/sifive-cache b/generators/sifive-cache index 13d0c2f1..f5a09e28 160000 --- a/generators/sifive-cache +++ b/generators/sifive-cache @@ -1 +1 @@ -Subproject commit 13d0c2f17853a658ae86eae793718c71ac82dddf +Subproject commit f5a09e289b92e53039d74114140d0380032ad8b4 diff --git a/generators/testchipip b/generators/testchipip index aa13f6cc..c11549ba 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit aa13f6ccc1a05a20e52a1600b6c8c796d306f1cd +Subproject commit c11549ba30483ee3c0d331fb893c45814bdb6b63 diff --git a/generators/tracegen/src/main/scala/Configs.scala b/generators/tracegen/src/main/scala/Configs.scala index e3536e6a..dd195296 100644 --- a/generators/tracegen/src/main/scala/Configs.scala +++ b/generators/tracegen/src/main/scala/Configs.scala @@ -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( diff --git a/generators/tracegen/src/main/scala/System.scala b/generators/tracegen/src/main/scala/System.scala index 57d048a3..18307678 100644 --- a/generators/tracegen/src/main/scala/System.scala +++ b/generators/tracegen/src/main/scala/System.scala @@ -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 } diff --git a/generators/tracegen/src/main/scala/TestHarness.scala b/generators/tracegen/src/main/scala/TestHarness.scala index 93da430b..5e07909f 100644 --- a/generators/tracegen/src/main/scala/TestHarness.scala +++ b/generators/tracegen/src/main/scala/TestHarness.scala @@ -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 diff --git a/generators/tracegen/src/main/scala/Tile.scala b/generators/tracegen/src/main/scala/Tile.scala index 1897224d..28974e1b 100644 --- a/generators/tracegen/src/main/scala/Tile.scala +++ b/generators/tracegen/src/main/scala/Tile.scala @@ -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) diff --git a/generators/utilities/src/main/scala/Subsystem.scala b/generators/utilities/src/main/scala/Subsystem.scala index 560caa4c..d5354946 100644 --- a/generators/utilities/src/main/scala/Subsystem.scala +++ b/generators/utilities/src/main/scala/Subsystem.scala @@ -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 } diff --git a/scripts/build-toolchains.sh b/scripts/build-toolchains.sh index b3195add..d5d181e7 100755 --- a/scripts/build-toolchains.sh +++ b/scripts/build-toolchains.sh @@ -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!" diff --git a/scripts/centos-req.sh b/scripts/centos-req.sh new file mode 100755 index 00000000..8fac61af --- /dev/null +++ b/scripts/centos-req.sh @@ -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 diff --git a/scripts/check-tracegen.sh b/scripts/check-tracegen.sh index bc82f572..3ba63067 100755 --- a/scripts/check-tracegen.sh +++ b/scripts/check-tracegen.sh @@ -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 diff --git a/scripts/gen-tags.sh b/scripts/gen-tags.sh index afc7e228..80d0365f 100755 --- a/scripts/gen-tags.sh +++ b/scripts/gen-tags.sh @@ -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 diff --git a/scripts/init-submodules-no-riscv-tools.sh b/scripts/init-submodules-no-riscv-tools.sh index d8842050..67e74e99 100755 --- a/scripts/init-submodules-no-riscv-tools.sh +++ b/scripts/init-submodules-no-riscv-tools.sh @@ -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 diff --git a/scripts/ubuntu-req.sh b/scripts/ubuntu-req.sh new file mode 100755 index 00000000..1858c3a4 --- /dev/null +++ b/scripts/ubuntu-req.sh @@ -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 diff --git a/sims/firesim b/sims/firesim index afad1b6a..b4951f25 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit afad1b6accfaba5efbc0cfeea66372abae5ab2eb +Subproject commit b4951f2589114e3849c77c798982afd10fc11b3e diff --git a/sims/vcs/Makefile b/sims/vcs/Makefile index aeda8a1b..f9bb8ca9 100644 --- a/sims/vcs/Makefile +++ b/sims/vcs/Makefile @@ -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 diff --git a/sims/verilator/Makefile b/sims/verilator/Makefile index b3185ade..364d68fd 100644 --- a/sims/verilator/Makefile +++ b/sims/verilator/Makefile @@ -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 diff --git a/software/coremark b/software/coremark new file mode 160000 index 00000000..cf8b8f7d --- /dev/null +++ b/software/coremark @@ -0,0 +1 @@ +Subproject commit cf8b8f7d82e085b3ecb31865fa40fb3dd62554f2 diff --git a/software/spec2017 b/software/spec2017 new file mode 160000 index 00000000..b8643136 --- /dev/null +++ b/software/spec2017 @@ -0,0 +1 @@ +Subproject commit b86431364360a9e64487e5dec2962c48bafb67ff diff --git a/tests/.gitignore b/tests/.gitignore index 8efed223..b8212fd8 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,3 +1,4 @@ *.o *.riscv *.dump +libgloss/ diff --git a/tests/Makefile b/tests/Makefile index 80142ad7..6f247e70 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -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)/) diff --git a/tests/crt.S b/tests/crt.S deleted file mode 100644 index d75e81e0..00000000 --- a/tests/crt.S +++ /dev/null @@ -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 diff --git a/tests/encoding.h b/tests/encoding.h deleted file mode 100644 index 35e0f9fe..00000000 --- a/tests/encoding.h +++ /dev/null @@ -1,1313 +0,0 @@ -// See LICENSE for license details. - -#ifndef RISCV_CSR_ENCODING_H -#define RISCV_CSR_ENCODING_H - -#define MSTATUS_UIE 0x00000001 -#define MSTATUS_SIE 0x00000002 -#define MSTATUS_HIE 0x00000004 -#define MSTATUS_MIE 0x00000008 -#define MSTATUS_UPIE 0x00000010 -#define MSTATUS_SPIE 0x00000020 -#define MSTATUS_HPIE 0x00000040 -#define MSTATUS_MPIE 0x00000080 -#define MSTATUS_SPP 0x00000100 -#define MSTATUS_HPP 0x00000600 -#define MSTATUS_MPP 0x00001800 -#define MSTATUS_FS 0x00006000 -#define MSTATUS_XS 0x00018000 -#define MSTATUS_MPRV 0x00020000 -#define MSTATUS_PUM 0x00040000 -#define MSTATUS_MXR 0x00080000 -#define MSTATUS_VM 0x1F000000 -#define MSTATUS32_SD 0x80000000 -#define MSTATUS64_SD 0x8000000000000000 - -#define SSTATUS_UIE 0x00000001 -#define SSTATUS_SIE 0x00000002 -#define SSTATUS_UPIE 0x00000010 -#define SSTATUS_SPIE 0x00000020 -#define SSTATUS_SPP 0x00000100 -#define SSTATUS_FS 0x00006000 -#define SSTATUS_XS 0x00018000 -#define SSTATUS_PUM 0x00040000 -#define SSTATUS32_SD 0x80000000 -#define SSTATUS64_SD 0x8000000000000000 - -#define DCSR_XDEBUGVER (3U<<30) -#define DCSR_NDRESET (1<<29) -#define DCSR_FULLRESET (1<<28) -#define DCSR_EBREAKM (1<<15) -#define DCSR_EBREAKH (1<<14) -#define DCSR_EBREAKS (1<<13) -#define DCSR_EBREAKU (1<<12) -#define DCSR_STOPCYCLE (1<<10) -#define DCSR_STOPTIME (1<<9) -#define DCSR_CAUSE (7<<6) -#define DCSR_DEBUGINT (1<<5) -#define DCSR_HALT (1<<3) -#define DCSR_STEP (1<<2) -#define DCSR_PRV (3<<0) - -#define DCSR_CAUSE_NONE 0 -#define DCSR_CAUSE_SWBP 1 -#define DCSR_CAUSE_HWBP 2 -#define DCSR_CAUSE_DEBUGINT 3 -#define DCSR_CAUSE_STEP 4 -#define DCSR_CAUSE_HALT 5 - -#define MCONTROL_TYPE(xlen) (0xfULL<<((xlen)-4)) -#define MCONTROL_DMODE(xlen) (1ULL<<((xlen)-5)) -#define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11)) - -#define MCONTROL_SELECT (1<<19) -#define MCONTROL_TIMING (1<<18) -#define MCONTROL_ACTION (0x3f<<12) -#define MCONTROL_CHAIN (1<<11) -#define MCONTROL_MATCH (0xf<<7) -#define MCONTROL_M (1<<6) -#define MCONTROL_H (1<<5) -#define MCONTROL_S (1<<4) -#define MCONTROL_U (1<<3) -#define MCONTROL_EXECUTE (1<<2) -#define MCONTROL_STORE (1<<1) -#define MCONTROL_LOAD (1<<0) - -#define MCONTROL_TYPE_NONE 0 -#define MCONTROL_TYPE_MATCH 2 - -#define MCONTROL_ACTION_DEBUG_EXCEPTION 0 -#define MCONTROL_ACTION_DEBUG_MODE 1 -#define MCONTROL_ACTION_TRACE_START 2 -#define MCONTROL_ACTION_TRACE_STOP 3 -#define MCONTROL_ACTION_TRACE_EMIT 4 - -#define MCONTROL_MATCH_EQUAL 0 -#define MCONTROL_MATCH_NAPOT 1 -#define MCONTROL_MATCH_GE 2 -#define MCONTROL_MATCH_LT 3 -#define MCONTROL_MATCH_MASK_LOW 4 -#define MCONTROL_MATCH_MASK_HIGH 5 - -#define MIP_SSIP (1 << IRQ_S_SOFT) -#define MIP_HSIP (1 << IRQ_H_SOFT) -#define MIP_MSIP (1 << IRQ_M_SOFT) -#define MIP_STIP (1 << IRQ_S_TIMER) -#define MIP_HTIP (1 << IRQ_H_TIMER) -#define MIP_MTIP (1 << IRQ_M_TIMER) -#define MIP_SEIP (1 << IRQ_S_EXT) -#define MIP_HEIP (1 << IRQ_H_EXT) -#define MIP_MEIP (1 << IRQ_M_EXT) - -#define SIP_SSIP MIP_SSIP -#define SIP_STIP MIP_STIP - -#define PRV_U 0 -#define PRV_S 1 -#define PRV_H 2 -#define PRV_M 3 - -#define VM_MBARE 0 -#define VM_MBB 1 -#define VM_MBBID 2 -#define VM_SV32 8 -#define VM_SV39 9 -#define VM_SV48 10 - -#define IRQ_S_SOFT 1 -#define IRQ_H_SOFT 2 -#define IRQ_M_SOFT 3 -#define IRQ_S_TIMER 5 -#define IRQ_H_TIMER 6 -#define IRQ_M_TIMER 7 -#define IRQ_S_EXT 9 -#define IRQ_H_EXT 10 -#define IRQ_M_EXT 11 -#define IRQ_COP 12 -#define IRQ_HOST 13 - -#define DEFAULT_RSTVEC 0x00001000 -#define DEFAULT_NMIVEC 0x00001004 -#define DEFAULT_MTVEC 0x00001010 -#define CONFIG_STRING_ADDR 0x0000100C -#define EXT_IO_BASE 0x40000000 -#define DRAM_BASE 0x80000000 - -// page table entry (PTE) fields -#define PTE_V 0x001 // Valid -#define PTE_R 0x002 // Read -#define PTE_W 0x004 // Write -#define PTE_X 0x008 // Execute -#define PTE_U 0x010 // User -#define PTE_G 0x020 // Global -#define PTE_A 0x040 // Accessed -#define PTE_D 0x080 // Dirty -#define PTE_SOFT 0x300 // Reserved for Software - -#define PTE_PPN_SHIFT 10 - -#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V) - -#ifdef __riscv - -#ifdef __riscv64 -# define MSTATUS_SD MSTATUS64_SD -# define SSTATUS_SD SSTATUS64_SD -# define RISCV_PGLEVEL_BITS 9 -#else -# define MSTATUS_SD MSTATUS32_SD -# define SSTATUS_SD SSTATUS32_SD -# define RISCV_PGLEVEL_BITS 10 -#endif -#define RISCV_PGSHIFT 12 -#define RISCV_PGSIZE (1 << RISCV_PGSHIFT) - -#ifndef __ASSEMBLER__ - -#ifdef __GNUC__ - -#define read_csr(reg) ({ unsigned long __tmp; \ - asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ - __tmp; }) - -#define write_csr(reg, val) ({ \ - if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ - asm volatile ("csrw " #reg ", %0" :: "i"(val)); \ - else \ - asm volatile ("csrw " #reg ", %0" :: "r"(val)); }) - -#define swap_csr(reg, val) ({ unsigned long __tmp; \ - if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ - asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "i"(val)); \ - else \ - asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \ - __tmp; }) - -#define set_csr(reg, bit) ({ unsigned long __tmp; \ - if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ - asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \ - else \ - asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \ - __tmp; }) - -#define clear_csr(reg, bit) ({ unsigned long __tmp; \ - if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ - asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \ - else \ - asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \ - __tmp; }) - -#define rdtime() read_csr(time) -#define rdcycle() read_csr(cycle) -#define rdinstret() read_csr(instret) - -#endif - -#endif - -#endif - -#endif -/* Automatically generated by parse-opcodes */ -#ifndef RISCV_ENCODING_H -#define RISCV_ENCODING_H -#define MATCH_BEQ 0x63 -#define MASK_BEQ 0x707f -#define MATCH_BNE 0x1063 -#define MASK_BNE 0x707f -#define MATCH_BLT 0x4063 -#define MASK_BLT 0x707f -#define MATCH_BGE 0x5063 -#define MASK_BGE 0x707f -#define MATCH_BLTU 0x6063 -#define MASK_BLTU 0x707f -#define MATCH_BGEU 0x7063 -#define MASK_BGEU 0x707f -#define MATCH_JALR 0x67 -#define MASK_JALR 0x707f -#define MATCH_JAL 0x6f -#define MASK_JAL 0x7f -#define MATCH_LUI 0x37 -#define MASK_LUI 0x7f -#define MATCH_AUIPC 0x17 -#define MASK_AUIPC 0x7f -#define MATCH_ADDI 0x13 -#define MASK_ADDI 0x707f -#define MATCH_SLLI 0x1013 -#define MASK_SLLI 0xfc00707f -#define MATCH_SLTI 0x2013 -#define MASK_SLTI 0x707f -#define MATCH_SLTIU 0x3013 -#define MASK_SLTIU 0x707f -#define MATCH_XORI 0x4013 -#define MASK_XORI 0x707f -#define MATCH_SRLI 0x5013 -#define MASK_SRLI 0xfc00707f -#define MATCH_SRAI 0x40005013 -#define MASK_SRAI 0xfc00707f -#define MATCH_ORI 0x6013 -#define MASK_ORI 0x707f -#define MATCH_ANDI 0x7013 -#define MASK_ANDI 0x707f -#define MATCH_ADD 0x33 -#define MASK_ADD 0xfe00707f -#define MATCH_SUB 0x40000033 -#define MASK_SUB 0xfe00707f -#define MATCH_SLL 0x1033 -#define MASK_SLL 0xfe00707f -#define MATCH_SLT 0x2033 -#define MASK_SLT 0xfe00707f -#define MATCH_SLTU 0x3033 -#define MASK_SLTU 0xfe00707f -#define MATCH_XOR 0x4033 -#define MASK_XOR 0xfe00707f -#define MATCH_SRL 0x5033 -#define MASK_SRL 0xfe00707f -#define MATCH_SRA 0x40005033 -#define MASK_SRA 0xfe00707f -#define MATCH_OR 0x6033 -#define MASK_OR 0xfe00707f -#define MATCH_AND 0x7033 -#define MASK_AND 0xfe00707f -#define MATCH_ADDIW 0x1b -#define MASK_ADDIW 0x707f -#define MATCH_SLLIW 0x101b -#define MASK_SLLIW 0xfe00707f -#define MATCH_SRLIW 0x501b -#define MASK_SRLIW 0xfe00707f -#define MATCH_SRAIW 0x4000501b -#define MASK_SRAIW 0xfe00707f -#define MATCH_ADDW 0x3b -#define MASK_ADDW 0xfe00707f -#define MATCH_SUBW 0x4000003b -#define MASK_SUBW 0xfe00707f -#define MATCH_SLLW 0x103b -#define MASK_SLLW 0xfe00707f -#define MATCH_SRLW 0x503b -#define MASK_SRLW 0xfe00707f -#define MATCH_SRAW 0x4000503b -#define MASK_SRAW 0xfe00707f -#define MATCH_LB 0x3 -#define MASK_LB 0x707f -#define MATCH_LH 0x1003 -#define MASK_LH 0x707f -#define MATCH_LW 0x2003 -#define MASK_LW 0x707f -#define MATCH_LD 0x3003 -#define MASK_LD 0x707f -#define MATCH_LBU 0x4003 -#define MASK_LBU 0x707f -#define MATCH_LHU 0x5003 -#define MASK_LHU 0x707f -#define MATCH_LWU 0x6003 -#define MASK_LWU 0x707f -#define MATCH_SB 0x23 -#define MASK_SB 0x707f -#define MATCH_SH 0x1023 -#define MASK_SH 0x707f -#define MATCH_SW 0x2023 -#define MASK_SW 0x707f -#define MATCH_SD 0x3023 -#define MASK_SD 0x707f -#define MATCH_FENCE 0xf -#define MASK_FENCE 0x707f -#define MATCH_FENCE_I 0x100f -#define MASK_FENCE_I 0x707f -#define MATCH_MUL 0x2000033 -#define MASK_MUL 0xfe00707f -#define MATCH_MULH 0x2001033 -#define MASK_MULH 0xfe00707f -#define MATCH_MULHSU 0x2002033 -#define MASK_MULHSU 0xfe00707f -#define MATCH_MULHU 0x2003033 -#define MASK_MULHU 0xfe00707f -#define MATCH_DIV 0x2004033 -#define MASK_DIV 0xfe00707f -#define MATCH_DIVU 0x2005033 -#define MASK_DIVU 0xfe00707f -#define MATCH_REM 0x2006033 -#define MASK_REM 0xfe00707f -#define MATCH_REMU 0x2007033 -#define MASK_REMU 0xfe00707f -#define MATCH_MULW 0x200003b -#define MASK_MULW 0xfe00707f -#define MATCH_DIVW 0x200403b -#define MASK_DIVW 0xfe00707f -#define MATCH_DIVUW 0x200503b -#define MASK_DIVUW 0xfe00707f -#define MATCH_REMW 0x200603b -#define MASK_REMW 0xfe00707f -#define MATCH_REMUW 0x200703b -#define MASK_REMUW 0xfe00707f -#define MATCH_AMOADD_W 0x202f -#define MASK_AMOADD_W 0xf800707f -#define MATCH_AMOXOR_W 0x2000202f -#define MASK_AMOXOR_W 0xf800707f -#define MATCH_AMOOR_W 0x4000202f -#define MASK_AMOOR_W 0xf800707f -#define MATCH_AMOAND_W 0x6000202f -#define MASK_AMOAND_W 0xf800707f -#define MATCH_AMOMIN_W 0x8000202f -#define MASK_AMOMIN_W 0xf800707f -#define MATCH_AMOMAX_W 0xa000202f -#define MASK_AMOMAX_W 0xf800707f -#define MATCH_AMOMINU_W 0xc000202f -#define MASK_AMOMINU_W 0xf800707f -#define MATCH_AMOMAXU_W 0xe000202f -#define MASK_AMOMAXU_W 0xf800707f -#define MATCH_AMOSWAP_W 0x800202f -#define MASK_AMOSWAP_W 0xf800707f -#define MATCH_LR_W 0x1000202f -#define MASK_LR_W 0xf9f0707f -#define MATCH_SC_W 0x1800202f -#define MASK_SC_W 0xf800707f -#define MATCH_AMOADD_D 0x302f -#define MASK_AMOADD_D 0xf800707f -#define MATCH_AMOXOR_D 0x2000302f -#define MASK_AMOXOR_D 0xf800707f -#define MATCH_AMOOR_D 0x4000302f -#define MASK_AMOOR_D 0xf800707f -#define MATCH_AMOAND_D 0x6000302f -#define MASK_AMOAND_D 0xf800707f -#define MATCH_AMOMIN_D 0x8000302f -#define MASK_AMOMIN_D 0xf800707f -#define MATCH_AMOMAX_D 0xa000302f -#define MASK_AMOMAX_D 0xf800707f -#define MATCH_AMOMINU_D 0xc000302f -#define MASK_AMOMINU_D 0xf800707f -#define MATCH_AMOMAXU_D 0xe000302f -#define MASK_AMOMAXU_D 0xf800707f -#define MATCH_AMOSWAP_D 0x800302f -#define MASK_AMOSWAP_D 0xf800707f -#define MATCH_LR_D 0x1000302f -#define MASK_LR_D 0xf9f0707f -#define MATCH_SC_D 0x1800302f -#define MASK_SC_D 0xf800707f -#define MATCH_ECALL 0x73 -#define MASK_ECALL 0xffffffff -#define MATCH_EBREAK 0x100073 -#define MASK_EBREAK 0xffffffff -#define MATCH_URET 0x200073 -#define MASK_URET 0xffffffff -#define MATCH_SRET 0x10200073 -#define MASK_SRET 0xffffffff -#define MATCH_HRET 0x20200073 -#define MASK_HRET 0xffffffff -#define MATCH_MRET 0x30200073 -#define MASK_MRET 0xffffffff -#define MATCH_DRET 0x7b200073 -#define MASK_DRET 0xffffffff -#define MATCH_SFENCE_VM 0x10400073 -#define MASK_SFENCE_VM 0xfff07fff -#define MATCH_WFI 0x10500073 -#define MASK_WFI 0xffffffff -#define MATCH_CSRRW 0x1073 -#define MASK_CSRRW 0x707f -#define MATCH_CSRRS 0x2073 -#define MASK_CSRRS 0x707f -#define MATCH_CSRRC 0x3073 -#define MASK_CSRRC 0x707f -#define MATCH_CSRRWI 0x5073 -#define MASK_CSRRWI 0x707f -#define MATCH_CSRRSI 0x6073 -#define MASK_CSRRSI 0x707f -#define MATCH_CSRRCI 0x7073 -#define MASK_CSRRCI 0x707f -#define MATCH_FADD_S 0x53 -#define MASK_FADD_S 0xfe00007f -#define MATCH_FSUB_S 0x8000053 -#define MASK_FSUB_S 0xfe00007f -#define MATCH_FMUL_S 0x10000053 -#define MASK_FMUL_S 0xfe00007f -#define MATCH_FDIV_S 0x18000053 -#define MASK_FDIV_S 0xfe00007f -#define MATCH_FSGNJ_S 0x20000053 -#define MASK_FSGNJ_S 0xfe00707f -#define MATCH_FSGNJN_S 0x20001053 -#define MASK_FSGNJN_S 0xfe00707f -#define MATCH_FSGNJX_S 0x20002053 -#define MASK_FSGNJX_S 0xfe00707f -#define MATCH_FMIN_S 0x28000053 -#define MASK_FMIN_S 0xfe00707f -#define MATCH_FMAX_S 0x28001053 -#define MASK_FMAX_S 0xfe00707f -#define MATCH_FSQRT_S 0x58000053 -#define MASK_FSQRT_S 0xfff0007f -#define MATCH_FADD_D 0x2000053 -#define MASK_FADD_D 0xfe00007f -#define MATCH_FSUB_D 0xa000053 -#define MASK_FSUB_D 0xfe00007f -#define MATCH_FMUL_D 0x12000053 -#define MASK_FMUL_D 0xfe00007f -#define MATCH_FDIV_D 0x1a000053 -#define MASK_FDIV_D 0xfe00007f -#define MATCH_FSGNJ_D 0x22000053 -#define MASK_FSGNJ_D 0xfe00707f -#define MATCH_FSGNJN_D 0x22001053 -#define MASK_FSGNJN_D 0xfe00707f -#define MATCH_FSGNJX_D 0x22002053 -#define MASK_FSGNJX_D 0xfe00707f -#define MATCH_FMIN_D 0x2a000053 -#define MASK_FMIN_D 0xfe00707f -#define MATCH_FMAX_D 0x2a001053 -#define MASK_FMAX_D 0xfe00707f -#define MATCH_FCVT_S_D 0x40100053 -#define MASK_FCVT_S_D 0xfff0007f -#define MATCH_FCVT_D_S 0x42000053 -#define MASK_FCVT_D_S 0xfff0007f -#define MATCH_FSQRT_D 0x5a000053 -#define MASK_FSQRT_D 0xfff0007f -#define MATCH_FLE_S 0xa0000053 -#define MASK_FLE_S 0xfe00707f -#define MATCH_FLT_S 0xa0001053 -#define MASK_FLT_S 0xfe00707f -#define MATCH_FEQ_S 0xa0002053 -#define MASK_FEQ_S 0xfe00707f -#define MATCH_FLE_D 0xa2000053 -#define MASK_FLE_D 0xfe00707f -#define MATCH_FLT_D 0xa2001053 -#define MASK_FLT_D 0xfe00707f -#define MATCH_FEQ_D 0xa2002053 -#define MASK_FEQ_D 0xfe00707f -#define MATCH_FCVT_W_S 0xc0000053 -#define MASK_FCVT_W_S 0xfff0007f -#define MATCH_FCVT_WU_S 0xc0100053 -#define MASK_FCVT_WU_S 0xfff0007f -#define MATCH_FCVT_L_S 0xc0200053 -#define MASK_FCVT_L_S 0xfff0007f -#define MATCH_FCVT_LU_S 0xc0300053 -#define MASK_FCVT_LU_S 0xfff0007f -#define MATCH_FMV_X_S 0xe0000053 -#define MASK_FMV_X_S 0xfff0707f -#define MATCH_FCLASS_S 0xe0001053 -#define MASK_FCLASS_S 0xfff0707f -#define MATCH_FCVT_W_D 0xc2000053 -#define MASK_FCVT_W_D 0xfff0007f -#define MATCH_FCVT_WU_D 0xc2100053 -#define MASK_FCVT_WU_D 0xfff0007f -#define MATCH_FCVT_L_D 0xc2200053 -#define MASK_FCVT_L_D 0xfff0007f -#define MATCH_FCVT_LU_D 0xc2300053 -#define MASK_FCVT_LU_D 0xfff0007f -#define MATCH_FMV_X_D 0xe2000053 -#define MASK_FMV_X_D 0xfff0707f -#define MATCH_FCLASS_D 0xe2001053 -#define MASK_FCLASS_D 0xfff0707f -#define MATCH_FCVT_S_W 0xd0000053 -#define MASK_FCVT_S_W 0xfff0007f -#define MATCH_FCVT_S_WU 0xd0100053 -#define MASK_FCVT_S_WU 0xfff0007f -#define MATCH_FCVT_S_L 0xd0200053 -#define MASK_FCVT_S_L 0xfff0007f -#define MATCH_FCVT_S_LU 0xd0300053 -#define MASK_FCVT_S_LU 0xfff0007f -#define MATCH_FMV_S_X 0xf0000053 -#define MASK_FMV_S_X 0xfff0707f -#define MATCH_FCVT_D_W 0xd2000053 -#define MASK_FCVT_D_W 0xfff0007f -#define MATCH_FCVT_D_WU 0xd2100053 -#define MASK_FCVT_D_WU 0xfff0007f -#define MATCH_FCVT_D_L 0xd2200053 -#define MASK_FCVT_D_L 0xfff0007f -#define MATCH_FCVT_D_LU 0xd2300053 -#define MASK_FCVT_D_LU 0xfff0007f -#define MATCH_FMV_D_X 0xf2000053 -#define MASK_FMV_D_X 0xfff0707f -#define MATCH_FLW 0x2007 -#define MASK_FLW 0x707f -#define MATCH_FLD 0x3007 -#define MASK_FLD 0x707f -#define MATCH_FSW 0x2027 -#define MASK_FSW 0x707f -#define MATCH_FSD 0x3027 -#define MASK_FSD 0x707f -#define MATCH_FMADD_S 0x43 -#define MASK_FMADD_S 0x600007f -#define MATCH_FMSUB_S 0x47 -#define MASK_FMSUB_S 0x600007f -#define MATCH_FNMSUB_S 0x4b -#define MASK_FNMSUB_S 0x600007f -#define MATCH_FNMADD_S 0x4f -#define MASK_FNMADD_S 0x600007f -#define MATCH_FMADD_D 0x2000043 -#define MASK_FMADD_D 0x600007f -#define MATCH_FMSUB_D 0x2000047 -#define MASK_FMSUB_D 0x600007f -#define MATCH_FNMSUB_D 0x200004b -#define MASK_FNMSUB_D 0x600007f -#define MATCH_FNMADD_D 0x200004f -#define MASK_FNMADD_D 0x600007f -#define MATCH_C_NOP 0x1 -#define MASK_C_NOP 0xffff -#define MATCH_C_ADDI16SP 0x6101 -#define MASK_C_ADDI16SP 0xef83 -#define MATCH_C_JR 0x8002 -#define MASK_C_JR 0xf07f -#define MATCH_C_JALR 0x9002 -#define MASK_C_JALR 0xf07f -#define MATCH_C_EBREAK 0x9002 -#define MASK_C_EBREAK 0xffff -#define MATCH_C_LD 0x6000 -#define MASK_C_LD 0xe003 -#define MATCH_C_SD 0xe000 -#define MASK_C_SD 0xe003 -#define MATCH_C_ADDIW 0x2001 -#define MASK_C_ADDIW 0xe003 -#define MATCH_C_LDSP 0x6002 -#define MASK_C_LDSP 0xe003 -#define MATCH_C_SDSP 0xe002 -#define MASK_C_SDSP 0xe003 -#define MATCH_C_ADDI4SPN 0x0 -#define MASK_C_ADDI4SPN 0xe003 -#define MATCH_C_FLD 0x2000 -#define MASK_C_FLD 0xe003 -#define MATCH_C_LW 0x4000 -#define MASK_C_LW 0xe003 -#define MATCH_C_FLW 0x6000 -#define MASK_C_FLW 0xe003 -#define MATCH_C_FSD 0xa000 -#define MASK_C_FSD 0xe003 -#define MATCH_C_SW 0xc000 -#define MASK_C_SW 0xe003 -#define MATCH_C_FSW 0xe000 -#define MASK_C_FSW 0xe003 -#define MATCH_C_ADDI 0x1 -#define MASK_C_ADDI 0xe003 -#define MATCH_C_JAL 0x2001 -#define MASK_C_JAL 0xe003 -#define MATCH_C_LI 0x4001 -#define MASK_C_LI 0xe003 -#define MATCH_C_LUI 0x6001 -#define MASK_C_LUI 0xe003 -#define MATCH_C_SRLI 0x8001 -#define MASK_C_SRLI 0xec03 -#define MATCH_C_SRAI 0x8401 -#define MASK_C_SRAI 0xec03 -#define MATCH_C_ANDI 0x8801 -#define MASK_C_ANDI 0xec03 -#define MATCH_C_SUB 0x8c01 -#define MASK_C_SUB 0xfc63 -#define MATCH_C_XOR 0x8c21 -#define MASK_C_XOR 0xfc63 -#define MATCH_C_OR 0x8c41 -#define MASK_C_OR 0xfc63 -#define MATCH_C_AND 0x8c61 -#define MASK_C_AND 0xfc63 -#define MATCH_C_SUBW 0x9c01 -#define MASK_C_SUBW 0xfc63 -#define MATCH_C_ADDW 0x9c21 -#define MASK_C_ADDW 0xfc63 -#define MATCH_C_J 0xa001 -#define MASK_C_J 0xe003 -#define MATCH_C_BEQZ 0xc001 -#define MASK_C_BEQZ 0xe003 -#define MATCH_C_BNEZ 0xe001 -#define MASK_C_BNEZ 0xe003 -#define MATCH_C_SLLI 0x2 -#define MASK_C_SLLI 0xe003 -#define MATCH_C_FLDSP 0x2002 -#define MASK_C_FLDSP 0xe003 -#define MATCH_C_LWSP 0x4002 -#define MASK_C_LWSP 0xe003 -#define MATCH_C_FLWSP 0x6002 -#define MASK_C_FLWSP 0xe003 -#define MATCH_C_MV 0x8002 -#define MASK_C_MV 0xf003 -#define MATCH_C_ADD 0x9002 -#define MASK_C_ADD 0xf003 -#define MATCH_C_FSDSP 0xa002 -#define MASK_C_FSDSP 0xe003 -#define MATCH_C_SWSP 0xc002 -#define MASK_C_SWSP 0xe003 -#define MATCH_C_FSWSP 0xe002 -#define MASK_C_FSWSP 0xe003 -#define MATCH_CUSTOM0 0xb -#define MASK_CUSTOM0 0x707f -#define MATCH_CUSTOM0_RS1 0x200b -#define MASK_CUSTOM0_RS1 0x707f -#define MATCH_CUSTOM0_RS1_RS2 0x300b -#define MASK_CUSTOM0_RS1_RS2 0x707f -#define MATCH_CUSTOM0_RD 0x400b -#define MASK_CUSTOM0_RD 0x707f -#define MATCH_CUSTOM0_RD_RS1 0x600b -#define MASK_CUSTOM0_RD_RS1 0x707f -#define MATCH_CUSTOM0_RD_RS1_RS2 0x700b -#define MASK_CUSTOM0_RD_RS1_RS2 0x707f -#define MATCH_CUSTOM1 0x2b -#define MASK_CUSTOM1 0x707f -#define MATCH_CUSTOM1_RS1 0x202b -#define MASK_CUSTOM1_RS1 0x707f -#define MATCH_CUSTOM1_RS1_RS2 0x302b -#define MASK_CUSTOM1_RS1_RS2 0x707f -#define MATCH_CUSTOM1_RD 0x402b -#define MASK_CUSTOM1_RD 0x707f -#define MATCH_CUSTOM1_RD_RS1 0x602b -#define MASK_CUSTOM1_RD_RS1 0x707f -#define MATCH_CUSTOM1_RD_RS1_RS2 0x702b -#define MASK_CUSTOM1_RD_RS1_RS2 0x707f -#define MATCH_CUSTOM2 0x5b -#define MASK_CUSTOM2 0x707f -#define MATCH_CUSTOM2_RS1 0x205b -#define MASK_CUSTOM2_RS1 0x707f -#define MATCH_CUSTOM2_RS1_RS2 0x305b -#define MASK_CUSTOM2_RS1_RS2 0x707f -#define MATCH_CUSTOM2_RD 0x405b -#define MASK_CUSTOM2_RD 0x707f -#define MATCH_CUSTOM2_RD_RS1 0x605b -#define MASK_CUSTOM2_RD_RS1 0x707f -#define MATCH_CUSTOM2_RD_RS1_RS2 0x705b -#define MASK_CUSTOM2_RD_RS1_RS2 0x707f -#define MATCH_CUSTOM3 0x7b -#define MASK_CUSTOM3 0x707f -#define MATCH_CUSTOM3_RS1 0x207b -#define MASK_CUSTOM3_RS1 0x707f -#define MATCH_CUSTOM3_RS1_RS2 0x307b -#define MASK_CUSTOM3_RS1_RS2 0x707f -#define MATCH_CUSTOM3_RD 0x407b -#define MASK_CUSTOM3_RD 0x707f -#define MATCH_CUSTOM3_RD_RS1 0x607b -#define MASK_CUSTOM3_RD_RS1 0x707f -#define MATCH_CUSTOM3_RD_RS1_RS2 0x707b -#define MASK_CUSTOM3_RD_RS1_RS2 0x707f -#define CSR_FFLAGS 0x1 -#define CSR_FRM 0x2 -#define CSR_FCSR 0x3 -#define CSR_CYCLE 0xc00 -#define CSR_TIME 0xc01 -#define CSR_INSTRET 0xc02 -#define CSR_HPMCOUNTER3 0xc03 -#define CSR_HPMCOUNTER4 0xc04 -#define CSR_HPMCOUNTER5 0xc05 -#define CSR_HPMCOUNTER6 0xc06 -#define CSR_HPMCOUNTER7 0xc07 -#define CSR_HPMCOUNTER8 0xc08 -#define CSR_HPMCOUNTER9 0xc09 -#define CSR_HPMCOUNTER10 0xc0a -#define CSR_HPMCOUNTER11 0xc0b -#define CSR_HPMCOUNTER12 0xc0c -#define CSR_HPMCOUNTER13 0xc0d -#define CSR_HPMCOUNTER14 0xc0e -#define CSR_HPMCOUNTER15 0xc0f -#define CSR_HPMCOUNTER16 0xc10 -#define CSR_HPMCOUNTER17 0xc11 -#define CSR_HPMCOUNTER18 0xc12 -#define CSR_HPMCOUNTER19 0xc13 -#define CSR_HPMCOUNTER20 0xc14 -#define CSR_HPMCOUNTER21 0xc15 -#define CSR_HPMCOUNTER22 0xc16 -#define CSR_HPMCOUNTER23 0xc17 -#define CSR_HPMCOUNTER24 0xc18 -#define CSR_HPMCOUNTER25 0xc19 -#define CSR_HPMCOUNTER26 0xc1a -#define CSR_HPMCOUNTER27 0xc1b -#define CSR_HPMCOUNTER28 0xc1c -#define CSR_HPMCOUNTER29 0xc1d -#define CSR_HPMCOUNTER30 0xc1e -#define CSR_HPMCOUNTER31 0xc1f -#define CSR_SSTATUS 0x100 -#define CSR_SIE 0x104 -#define CSR_STVEC 0x105 -#define CSR_SSCRATCH 0x140 -#define CSR_SEPC 0x141 -#define CSR_SCAUSE 0x142 -#define CSR_SBADADDR 0x143 -#define CSR_SIP 0x144 -#define CSR_SPTBR 0x180 -#define CSR_MSTATUS 0x300 -#define CSR_MISA 0x301 -#define CSR_MEDELEG 0x302 -#define CSR_MIDELEG 0x303 -#define CSR_MIE 0x304 -#define CSR_MTVEC 0x305 -#define CSR_MSCRATCH 0x340 -#define CSR_MEPC 0x341 -#define CSR_MCAUSE 0x342 -#define CSR_MBADADDR 0x343 -#define CSR_MIP 0x344 -#define CSR_TSELECT 0x7a0 -#define CSR_TDATA1 0x7a1 -#define CSR_TDATA2 0x7a2 -#define CSR_TDATA3 0x7a3 -#define CSR_DCSR 0x7b0 -#define CSR_DPC 0x7b1 -#define CSR_DSCRATCH 0x7b2 -#define CSR_MCYCLE 0xb00 -#define CSR_MINSTRET 0xb02 -#define CSR_MHPMCOUNTER3 0xb03 -#define CSR_MHPMCOUNTER4 0xb04 -#define CSR_MHPMCOUNTER5 0xb05 -#define CSR_MHPMCOUNTER6 0xb06 -#define CSR_MHPMCOUNTER7 0xb07 -#define CSR_MHPMCOUNTER8 0xb08 -#define CSR_MHPMCOUNTER9 0xb09 -#define CSR_MHPMCOUNTER10 0xb0a -#define CSR_MHPMCOUNTER11 0xb0b -#define CSR_MHPMCOUNTER12 0xb0c -#define CSR_MHPMCOUNTER13 0xb0d -#define CSR_MHPMCOUNTER14 0xb0e -#define CSR_MHPMCOUNTER15 0xb0f -#define CSR_MHPMCOUNTER16 0xb10 -#define CSR_MHPMCOUNTER17 0xb11 -#define CSR_MHPMCOUNTER18 0xb12 -#define CSR_MHPMCOUNTER19 0xb13 -#define CSR_MHPMCOUNTER20 0xb14 -#define CSR_MHPMCOUNTER21 0xb15 -#define CSR_MHPMCOUNTER22 0xb16 -#define CSR_MHPMCOUNTER23 0xb17 -#define CSR_MHPMCOUNTER24 0xb18 -#define CSR_MHPMCOUNTER25 0xb19 -#define CSR_MHPMCOUNTER26 0xb1a -#define CSR_MHPMCOUNTER27 0xb1b -#define CSR_MHPMCOUNTER28 0xb1c -#define CSR_MHPMCOUNTER29 0xb1d -#define CSR_MHPMCOUNTER30 0xb1e -#define CSR_MHPMCOUNTER31 0xb1f -#define CSR_MUCOUNTEREN 0x320 -#define CSR_MSCOUNTEREN 0x321 -#define CSR_MHPMEVENT3 0x323 -#define CSR_MHPMEVENT4 0x324 -#define CSR_MHPMEVENT5 0x325 -#define CSR_MHPMEVENT6 0x326 -#define CSR_MHPMEVENT7 0x327 -#define CSR_MHPMEVENT8 0x328 -#define CSR_MHPMEVENT9 0x329 -#define CSR_MHPMEVENT10 0x32a -#define CSR_MHPMEVENT11 0x32b -#define CSR_MHPMEVENT12 0x32c -#define CSR_MHPMEVENT13 0x32d -#define CSR_MHPMEVENT14 0x32e -#define CSR_MHPMEVENT15 0x32f -#define CSR_MHPMEVENT16 0x330 -#define CSR_MHPMEVENT17 0x331 -#define CSR_MHPMEVENT18 0x332 -#define CSR_MHPMEVENT19 0x333 -#define CSR_MHPMEVENT20 0x334 -#define CSR_MHPMEVENT21 0x335 -#define CSR_MHPMEVENT22 0x336 -#define CSR_MHPMEVENT23 0x337 -#define CSR_MHPMEVENT24 0x338 -#define CSR_MHPMEVENT25 0x339 -#define CSR_MHPMEVENT26 0x33a -#define CSR_MHPMEVENT27 0x33b -#define CSR_MHPMEVENT28 0x33c -#define CSR_MHPMEVENT29 0x33d -#define CSR_MHPMEVENT30 0x33e -#define CSR_MHPMEVENT31 0x33f -#define CSR_MVENDORID 0xf11 -#define CSR_MARCHID 0xf12 -#define CSR_MIMPID 0xf13 -#define CSR_MHARTID 0xf14 -#define CSR_CYCLEH 0xc80 -#define CSR_TIMEH 0xc81 -#define CSR_INSTRETH 0xc82 -#define CSR_HPMCOUNTER3H 0xc83 -#define CSR_HPMCOUNTER4H 0xc84 -#define CSR_HPMCOUNTER5H 0xc85 -#define CSR_HPMCOUNTER6H 0xc86 -#define CSR_HPMCOUNTER7H 0xc87 -#define CSR_HPMCOUNTER8H 0xc88 -#define CSR_HPMCOUNTER9H 0xc89 -#define CSR_HPMCOUNTER10H 0xc8a -#define CSR_HPMCOUNTER11H 0xc8b -#define CSR_HPMCOUNTER12H 0xc8c -#define CSR_HPMCOUNTER13H 0xc8d -#define CSR_HPMCOUNTER14H 0xc8e -#define CSR_HPMCOUNTER15H 0xc8f -#define CSR_HPMCOUNTER16H 0xc90 -#define CSR_HPMCOUNTER17H 0xc91 -#define CSR_HPMCOUNTER18H 0xc92 -#define CSR_HPMCOUNTER19H 0xc93 -#define CSR_HPMCOUNTER20H 0xc94 -#define CSR_HPMCOUNTER21H 0xc95 -#define CSR_HPMCOUNTER22H 0xc96 -#define CSR_HPMCOUNTER23H 0xc97 -#define CSR_HPMCOUNTER24H 0xc98 -#define CSR_HPMCOUNTER25H 0xc99 -#define CSR_HPMCOUNTER26H 0xc9a -#define CSR_HPMCOUNTER27H 0xc9b -#define CSR_HPMCOUNTER28H 0xc9c -#define CSR_HPMCOUNTER29H 0xc9d -#define CSR_HPMCOUNTER30H 0xc9e -#define CSR_HPMCOUNTER31H 0xc9f -#define CSR_MCYCLEH 0xb80 -#define CSR_MINSTRETH 0xb82 -#define CSR_MHPMCOUNTER3H 0xb83 -#define CSR_MHPMCOUNTER4H 0xb84 -#define CSR_MHPMCOUNTER5H 0xb85 -#define CSR_MHPMCOUNTER6H 0xb86 -#define CSR_MHPMCOUNTER7H 0xb87 -#define CSR_MHPMCOUNTER8H 0xb88 -#define CSR_MHPMCOUNTER9H 0xb89 -#define CSR_MHPMCOUNTER10H 0xb8a -#define CSR_MHPMCOUNTER11H 0xb8b -#define CSR_MHPMCOUNTER12H 0xb8c -#define CSR_MHPMCOUNTER13H 0xb8d -#define CSR_MHPMCOUNTER14H 0xb8e -#define CSR_MHPMCOUNTER15H 0xb8f -#define CSR_MHPMCOUNTER16H 0xb90 -#define CSR_MHPMCOUNTER17H 0xb91 -#define CSR_MHPMCOUNTER18H 0xb92 -#define CSR_MHPMCOUNTER19H 0xb93 -#define CSR_MHPMCOUNTER20H 0xb94 -#define CSR_MHPMCOUNTER21H 0xb95 -#define CSR_MHPMCOUNTER22H 0xb96 -#define CSR_MHPMCOUNTER23H 0xb97 -#define CSR_MHPMCOUNTER24H 0xb98 -#define CSR_MHPMCOUNTER25H 0xb99 -#define CSR_MHPMCOUNTER26H 0xb9a -#define CSR_MHPMCOUNTER27H 0xb9b -#define CSR_MHPMCOUNTER28H 0xb9c -#define CSR_MHPMCOUNTER29H 0xb9d -#define CSR_MHPMCOUNTER30H 0xb9e -#define CSR_MHPMCOUNTER31H 0xb9f -#define CAUSE_MISALIGNED_FETCH 0x0 -#define CAUSE_FAULT_FETCH 0x1 -#define CAUSE_ILLEGAL_INSTRUCTION 0x2 -#define CAUSE_BREAKPOINT 0x3 -#define CAUSE_MISALIGNED_LOAD 0x4 -#define CAUSE_FAULT_LOAD 0x5 -#define CAUSE_MISALIGNED_STORE 0x6 -#define CAUSE_FAULT_STORE 0x7 -#define CAUSE_USER_ECALL 0x8 -#define CAUSE_SUPERVISOR_ECALL 0x9 -#define CAUSE_HYPERVISOR_ECALL 0xa -#define CAUSE_MACHINE_ECALL 0xb -#endif -#ifdef DECLARE_INSN -DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ) -DECLARE_INSN(bne, MATCH_BNE, MASK_BNE) -DECLARE_INSN(blt, MATCH_BLT, MASK_BLT) -DECLARE_INSN(bge, MATCH_BGE, MASK_BGE) -DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU) -DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU) -DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR) -DECLARE_INSN(jal, MATCH_JAL, MASK_JAL) -DECLARE_INSN(lui, MATCH_LUI, MASK_LUI) -DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC) -DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI) -DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI) -DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI) -DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU) -DECLARE_INSN(xori, MATCH_XORI, MASK_XORI) -DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI) -DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI) -DECLARE_INSN(ori, MATCH_ORI, MASK_ORI) -DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI) -DECLARE_INSN(add, MATCH_ADD, MASK_ADD) -DECLARE_INSN(sub, MATCH_SUB, MASK_SUB) -DECLARE_INSN(sll, MATCH_SLL, MASK_SLL) -DECLARE_INSN(slt, MATCH_SLT, MASK_SLT) -DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU) -DECLARE_INSN(xor, MATCH_XOR, MASK_XOR) -DECLARE_INSN(srl, MATCH_SRL, MASK_SRL) -DECLARE_INSN(sra, MATCH_SRA, MASK_SRA) -DECLARE_INSN(or, MATCH_OR, MASK_OR) -DECLARE_INSN(and, MATCH_AND, MASK_AND) -DECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW) -DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW) -DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW) -DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW) -DECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW) -DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW) -DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW) -DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW) -DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW) -DECLARE_INSN(lb, MATCH_LB, MASK_LB) -DECLARE_INSN(lh, MATCH_LH, MASK_LH) -DECLARE_INSN(lw, MATCH_LW, MASK_LW) -DECLARE_INSN(ld, MATCH_LD, MASK_LD) -DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU) -DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU) -DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU) -DECLARE_INSN(sb, MATCH_SB, MASK_SB) -DECLARE_INSN(sh, MATCH_SH, MASK_SH) -DECLARE_INSN(sw, MATCH_SW, MASK_SW) -DECLARE_INSN(sd, MATCH_SD, MASK_SD) -DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE) -DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I) -DECLARE_INSN(mul, MATCH_MUL, MASK_MUL) -DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH) -DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU) -DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU) -DECLARE_INSN(div, MATCH_DIV, MASK_DIV) -DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU) -DECLARE_INSN(rem, MATCH_REM, MASK_REM) -DECLARE_INSN(remu, MATCH_REMU, MASK_REMU) -DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW) -DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW) -DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW) -DECLARE_INSN(remw, MATCH_REMW, MASK_REMW) -DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW) -DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W) -DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W) -DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W) -DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W) -DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W) -DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W) -DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W) -DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W) -DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W) -DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W) -DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W) -DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D) -DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D) -DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D) -DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D) -DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D) -DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D) -DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D) -DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D) -DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D) -DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D) -DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D) -DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL) -DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK) -DECLARE_INSN(uret, MATCH_URET, MASK_URET) -DECLARE_INSN(sret, MATCH_SRET, MASK_SRET) -DECLARE_INSN(hret, MATCH_HRET, MASK_HRET) -DECLARE_INSN(mret, MATCH_MRET, MASK_MRET) -DECLARE_INSN(dret, MATCH_DRET, MASK_DRET) -DECLARE_INSN(sfence_vm, MATCH_SFENCE_VM, MASK_SFENCE_VM) -DECLARE_INSN(wfi, MATCH_WFI, MASK_WFI) -DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW) -DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS) -DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC) -DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI) -DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI) -DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI) -DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S) -DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S) -DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S) -DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S) -DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S) -DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S) -DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S) -DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S) -DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S) -DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S) -DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D) -DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D) -DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D) -DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D) -DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D) -DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D) -DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D) -DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D) -DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D) -DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D) -DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S) -DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D) -DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S) -DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S) -DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S) -DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D) -DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D) -DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D) -DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S) -DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S) -DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S) -DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S) -DECLARE_INSN(fmv_x_s, MATCH_FMV_X_S, MASK_FMV_X_S) -DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S) -DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D) -DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D) -DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D) -DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D) -DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D) -DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D) -DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W) -DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU) -DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L) -DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU) -DECLARE_INSN(fmv_s_x, MATCH_FMV_S_X, MASK_FMV_S_X) -DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W) -DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU) -DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L) -DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU) -DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X) -DECLARE_INSN(flw, MATCH_FLW, MASK_FLW) -DECLARE_INSN(fld, MATCH_FLD, MASK_FLD) -DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW) -DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD) -DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S) -DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S) -DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S) -DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S) -DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D) -DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D) -DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D) -DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D) -DECLARE_INSN(c_nop, MATCH_C_NOP, MASK_C_NOP) -DECLARE_INSN(c_addi16sp, MATCH_C_ADDI16SP, MASK_C_ADDI16SP) -DECLARE_INSN(c_jr, MATCH_C_JR, MASK_C_JR) -DECLARE_INSN(c_jalr, MATCH_C_JALR, MASK_C_JALR) -DECLARE_INSN(c_ebreak, MATCH_C_EBREAK, MASK_C_EBREAK) -DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD) -DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD) -DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW) -DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP) -DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP) -DECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN) -DECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD) -DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW) -DECLARE_INSN(c_flw, MATCH_C_FLW, MASK_C_FLW) -DECLARE_INSN(c_fsd, MATCH_C_FSD, MASK_C_FSD) -DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW) -DECLARE_INSN(c_fsw, MATCH_C_FSW, MASK_C_FSW) -DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI) -DECLARE_INSN(c_jal, MATCH_C_JAL, MASK_C_JAL) -DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI) -DECLARE_INSN(c_lui, MATCH_C_LUI, MASK_C_LUI) -DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI) -DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI) -DECLARE_INSN(c_andi, MATCH_C_ANDI, MASK_C_ANDI) -DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB) -DECLARE_INSN(c_xor, MATCH_C_XOR, MASK_C_XOR) -DECLARE_INSN(c_or, MATCH_C_OR, MASK_C_OR) -DECLARE_INSN(c_and, MATCH_C_AND, MASK_C_AND) -DECLARE_INSN(c_subw, MATCH_C_SUBW, MASK_C_SUBW) -DECLARE_INSN(c_addw, MATCH_C_ADDW, MASK_C_ADDW) -DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J) -DECLARE_INSN(c_beqz, MATCH_C_BEQZ, MASK_C_BEQZ) -DECLARE_INSN(c_bnez, MATCH_C_BNEZ, MASK_C_BNEZ) -DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI) -DECLARE_INSN(c_fldsp, MATCH_C_FLDSP, MASK_C_FLDSP) -DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP) -DECLARE_INSN(c_flwsp, MATCH_C_FLWSP, MASK_C_FLWSP) -DECLARE_INSN(c_mv, MATCH_C_MV, MASK_C_MV) -DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD) -DECLARE_INSN(c_fsdsp, MATCH_C_FSDSP, MASK_C_FSDSP) -DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP) -DECLARE_INSN(c_fswsp, MATCH_C_FSWSP, MASK_C_FSWSP) -DECLARE_INSN(custom0, MATCH_CUSTOM0, MASK_CUSTOM0) -DECLARE_INSN(custom0_rs1, MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1) -DECLARE_INSN(custom0_rs1_rs2, MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2) -DECLARE_INSN(custom0_rd, MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD) -DECLARE_INSN(custom0_rd_rs1, MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1) -DECLARE_INSN(custom0_rd_rs1_rs2, MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2) -DECLARE_INSN(custom1, MATCH_CUSTOM1, MASK_CUSTOM1) -DECLARE_INSN(custom1_rs1, MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1) -DECLARE_INSN(custom1_rs1_rs2, MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2) -DECLARE_INSN(custom1_rd, MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD) -DECLARE_INSN(custom1_rd_rs1, MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1) -DECLARE_INSN(custom1_rd_rs1_rs2, MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2) -DECLARE_INSN(custom2, MATCH_CUSTOM2, MASK_CUSTOM2) -DECLARE_INSN(custom2_rs1, MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1) -DECLARE_INSN(custom2_rs1_rs2, MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2) -DECLARE_INSN(custom2_rd, MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD) -DECLARE_INSN(custom2_rd_rs1, MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1) -DECLARE_INSN(custom2_rd_rs1_rs2, MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2) -DECLARE_INSN(custom3, MATCH_CUSTOM3, MASK_CUSTOM3) -DECLARE_INSN(custom3_rs1, MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1) -DECLARE_INSN(custom3_rs1_rs2, MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2) -DECLARE_INSN(custom3_rd, MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD) -DECLARE_INSN(custom3_rd_rs1, MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1) -DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2) -#endif -#ifdef DECLARE_CSR -DECLARE_CSR(fflags, CSR_FFLAGS) -DECLARE_CSR(frm, CSR_FRM) -DECLARE_CSR(fcsr, CSR_FCSR) -DECLARE_CSR(cycle, CSR_CYCLE) -DECLARE_CSR(time, CSR_TIME) -DECLARE_CSR(instret, CSR_INSTRET) -DECLARE_CSR(hpmcounter3, CSR_HPMCOUNTER3) -DECLARE_CSR(hpmcounter4, CSR_HPMCOUNTER4) -DECLARE_CSR(hpmcounter5, CSR_HPMCOUNTER5) -DECLARE_CSR(hpmcounter6, CSR_HPMCOUNTER6) -DECLARE_CSR(hpmcounter7, CSR_HPMCOUNTER7) -DECLARE_CSR(hpmcounter8, CSR_HPMCOUNTER8) -DECLARE_CSR(hpmcounter9, CSR_HPMCOUNTER9) -DECLARE_CSR(hpmcounter10, CSR_HPMCOUNTER10) -DECLARE_CSR(hpmcounter11, CSR_HPMCOUNTER11) -DECLARE_CSR(hpmcounter12, CSR_HPMCOUNTER12) -DECLARE_CSR(hpmcounter13, CSR_HPMCOUNTER13) -DECLARE_CSR(hpmcounter14, CSR_HPMCOUNTER14) -DECLARE_CSR(hpmcounter15, CSR_HPMCOUNTER15) -DECLARE_CSR(hpmcounter16, CSR_HPMCOUNTER16) -DECLARE_CSR(hpmcounter17, CSR_HPMCOUNTER17) -DECLARE_CSR(hpmcounter18, CSR_HPMCOUNTER18) -DECLARE_CSR(hpmcounter19, CSR_HPMCOUNTER19) -DECLARE_CSR(hpmcounter20, CSR_HPMCOUNTER20) -DECLARE_CSR(hpmcounter21, CSR_HPMCOUNTER21) -DECLARE_CSR(hpmcounter22, CSR_HPMCOUNTER22) -DECLARE_CSR(hpmcounter23, CSR_HPMCOUNTER23) -DECLARE_CSR(hpmcounter24, CSR_HPMCOUNTER24) -DECLARE_CSR(hpmcounter25, CSR_HPMCOUNTER25) -DECLARE_CSR(hpmcounter26, CSR_HPMCOUNTER26) -DECLARE_CSR(hpmcounter27, CSR_HPMCOUNTER27) -DECLARE_CSR(hpmcounter28, CSR_HPMCOUNTER28) -DECLARE_CSR(hpmcounter29, CSR_HPMCOUNTER29) -DECLARE_CSR(hpmcounter30, CSR_HPMCOUNTER30) -DECLARE_CSR(hpmcounter31, CSR_HPMCOUNTER31) -DECLARE_CSR(sstatus, CSR_SSTATUS) -DECLARE_CSR(sie, CSR_SIE) -DECLARE_CSR(stvec, CSR_STVEC) -DECLARE_CSR(sscratch, CSR_SSCRATCH) -DECLARE_CSR(sepc, CSR_SEPC) -DECLARE_CSR(scause, CSR_SCAUSE) -DECLARE_CSR(sbadaddr, CSR_SBADADDR) -DECLARE_CSR(sip, CSR_SIP) -DECLARE_CSR(sptbr, CSR_SPTBR) -DECLARE_CSR(mstatus, CSR_MSTATUS) -DECLARE_CSR(misa, CSR_MISA) -DECLARE_CSR(medeleg, CSR_MEDELEG) -DECLARE_CSR(mideleg, CSR_MIDELEG) -DECLARE_CSR(mie, CSR_MIE) -DECLARE_CSR(mtvec, CSR_MTVEC) -DECLARE_CSR(mscratch, CSR_MSCRATCH) -DECLARE_CSR(mepc, CSR_MEPC) -DECLARE_CSR(mcause, CSR_MCAUSE) -DECLARE_CSR(mbadaddr, CSR_MBADADDR) -DECLARE_CSR(mip, CSR_MIP) -DECLARE_CSR(tselect, CSR_TSELECT) -DECLARE_CSR(tdata1, CSR_TDATA1) -DECLARE_CSR(tdata2, CSR_TDATA2) -DECLARE_CSR(tdata3, CSR_TDATA3) -DECLARE_CSR(dcsr, CSR_DCSR) -DECLARE_CSR(dpc, CSR_DPC) -DECLARE_CSR(dscratch, CSR_DSCRATCH) -DECLARE_CSR(mcycle, CSR_MCYCLE) -DECLARE_CSR(minstret, CSR_MINSTRET) -DECLARE_CSR(mhpmcounter3, CSR_MHPMCOUNTER3) -DECLARE_CSR(mhpmcounter4, CSR_MHPMCOUNTER4) -DECLARE_CSR(mhpmcounter5, CSR_MHPMCOUNTER5) -DECLARE_CSR(mhpmcounter6, CSR_MHPMCOUNTER6) -DECLARE_CSR(mhpmcounter7, CSR_MHPMCOUNTER7) -DECLARE_CSR(mhpmcounter8, CSR_MHPMCOUNTER8) -DECLARE_CSR(mhpmcounter9, CSR_MHPMCOUNTER9) -DECLARE_CSR(mhpmcounter10, CSR_MHPMCOUNTER10) -DECLARE_CSR(mhpmcounter11, CSR_MHPMCOUNTER11) -DECLARE_CSR(mhpmcounter12, CSR_MHPMCOUNTER12) -DECLARE_CSR(mhpmcounter13, CSR_MHPMCOUNTER13) -DECLARE_CSR(mhpmcounter14, CSR_MHPMCOUNTER14) -DECLARE_CSR(mhpmcounter15, CSR_MHPMCOUNTER15) -DECLARE_CSR(mhpmcounter16, CSR_MHPMCOUNTER16) -DECLARE_CSR(mhpmcounter17, CSR_MHPMCOUNTER17) -DECLARE_CSR(mhpmcounter18, CSR_MHPMCOUNTER18) -DECLARE_CSR(mhpmcounter19, CSR_MHPMCOUNTER19) -DECLARE_CSR(mhpmcounter20, CSR_MHPMCOUNTER20) -DECLARE_CSR(mhpmcounter21, CSR_MHPMCOUNTER21) -DECLARE_CSR(mhpmcounter22, CSR_MHPMCOUNTER22) -DECLARE_CSR(mhpmcounter23, CSR_MHPMCOUNTER23) -DECLARE_CSR(mhpmcounter24, CSR_MHPMCOUNTER24) -DECLARE_CSR(mhpmcounter25, CSR_MHPMCOUNTER25) -DECLARE_CSR(mhpmcounter26, CSR_MHPMCOUNTER26) -DECLARE_CSR(mhpmcounter27, CSR_MHPMCOUNTER27) -DECLARE_CSR(mhpmcounter28, CSR_MHPMCOUNTER28) -DECLARE_CSR(mhpmcounter29, CSR_MHPMCOUNTER29) -DECLARE_CSR(mhpmcounter30, CSR_MHPMCOUNTER30) -DECLARE_CSR(mhpmcounter31, CSR_MHPMCOUNTER31) -DECLARE_CSR(mucounteren, CSR_MUCOUNTEREN) -DECLARE_CSR(mscounteren, CSR_MSCOUNTEREN) -DECLARE_CSR(mhpmevent3, CSR_MHPMEVENT3) -DECLARE_CSR(mhpmevent4, CSR_MHPMEVENT4) -DECLARE_CSR(mhpmevent5, CSR_MHPMEVENT5) -DECLARE_CSR(mhpmevent6, CSR_MHPMEVENT6) -DECLARE_CSR(mhpmevent7, CSR_MHPMEVENT7) -DECLARE_CSR(mhpmevent8, CSR_MHPMEVENT8) -DECLARE_CSR(mhpmevent9, CSR_MHPMEVENT9) -DECLARE_CSR(mhpmevent10, CSR_MHPMEVENT10) -DECLARE_CSR(mhpmevent11, CSR_MHPMEVENT11) -DECLARE_CSR(mhpmevent12, CSR_MHPMEVENT12) -DECLARE_CSR(mhpmevent13, CSR_MHPMEVENT13) -DECLARE_CSR(mhpmevent14, CSR_MHPMEVENT14) -DECLARE_CSR(mhpmevent15, CSR_MHPMEVENT15) -DECLARE_CSR(mhpmevent16, CSR_MHPMEVENT16) -DECLARE_CSR(mhpmevent17, CSR_MHPMEVENT17) -DECLARE_CSR(mhpmevent18, CSR_MHPMEVENT18) -DECLARE_CSR(mhpmevent19, CSR_MHPMEVENT19) -DECLARE_CSR(mhpmevent20, CSR_MHPMEVENT20) -DECLARE_CSR(mhpmevent21, CSR_MHPMEVENT21) -DECLARE_CSR(mhpmevent22, CSR_MHPMEVENT22) -DECLARE_CSR(mhpmevent23, CSR_MHPMEVENT23) -DECLARE_CSR(mhpmevent24, CSR_MHPMEVENT24) -DECLARE_CSR(mhpmevent25, CSR_MHPMEVENT25) -DECLARE_CSR(mhpmevent26, CSR_MHPMEVENT26) -DECLARE_CSR(mhpmevent27, CSR_MHPMEVENT27) -DECLARE_CSR(mhpmevent28, CSR_MHPMEVENT28) -DECLARE_CSR(mhpmevent29, CSR_MHPMEVENT29) -DECLARE_CSR(mhpmevent30, CSR_MHPMEVENT30) -DECLARE_CSR(mhpmevent31, CSR_MHPMEVENT31) -DECLARE_CSR(mvendorid, CSR_MVENDORID) -DECLARE_CSR(marchid, CSR_MARCHID) -DECLARE_CSR(mimpid, CSR_MIMPID) -DECLARE_CSR(mhartid, CSR_MHARTID) -DECLARE_CSR(cycleh, CSR_CYCLEH) -DECLARE_CSR(timeh, CSR_TIMEH) -DECLARE_CSR(instreth, CSR_INSTRETH) -DECLARE_CSR(hpmcounter3h, CSR_HPMCOUNTER3H) -DECLARE_CSR(hpmcounter4h, CSR_HPMCOUNTER4H) -DECLARE_CSR(hpmcounter5h, CSR_HPMCOUNTER5H) -DECLARE_CSR(hpmcounter6h, CSR_HPMCOUNTER6H) -DECLARE_CSR(hpmcounter7h, CSR_HPMCOUNTER7H) -DECLARE_CSR(hpmcounter8h, CSR_HPMCOUNTER8H) -DECLARE_CSR(hpmcounter9h, CSR_HPMCOUNTER9H) -DECLARE_CSR(hpmcounter10h, CSR_HPMCOUNTER10H) -DECLARE_CSR(hpmcounter11h, CSR_HPMCOUNTER11H) -DECLARE_CSR(hpmcounter12h, CSR_HPMCOUNTER12H) -DECLARE_CSR(hpmcounter13h, CSR_HPMCOUNTER13H) -DECLARE_CSR(hpmcounter14h, CSR_HPMCOUNTER14H) -DECLARE_CSR(hpmcounter15h, CSR_HPMCOUNTER15H) -DECLARE_CSR(hpmcounter16h, CSR_HPMCOUNTER16H) -DECLARE_CSR(hpmcounter17h, CSR_HPMCOUNTER17H) -DECLARE_CSR(hpmcounter18h, CSR_HPMCOUNTER18H) -DECLARE_CSR(hpmcounter19h, CSR_HPMCOUNTER19H) -DECLARE_CSR(hpmcounter20h, CSR_HPMCOUNTER20H) -DECLARE_CSR(hpmcounter21h, CSR_HPMCOUNTER21H) -DECLARE_CSR(hpmcounter22h, CSR_HPMCOUNTER22H) -DECLARE_CSR(hpmcounter23h, CSR_HPMCOUNTER23H) -DECLARE_CSR(hpmcounter24h, CSR_HPMCOUNTER24H) -DECLARE_CSR(hpmcounter25h, CSR_HPMCOUNTER25H) -DECLARE_CSR(hpmcounter26h, CSR_HPMCOUNTER26H) -DECLARE_CSR(hpmcounter27h, CSR_HPMCOUNTER27H) -DECLARE_CSR(hpmcounter28h, CSR_HPMCOUNTER28H) -DECLARE_CSR(hpmcounter29h, CSR_HPMCOUNTER29H) -DECLARE_CSR(hpmcounter30h, CSR_HPMCOUNTER30H) -DECLARE_CSR(hpmcounter31h, CSR_HPMCOUNTER31H) -DECLARE_CSR(mcycleh, CSR_MCYCLEH) -DECLARE_CSR(minstreth, CSR_MINSTRETH) -DECLARE_CSR(mhpmcounter3h, CSR_MHPMCOUNTER3H) -DECLARE_CSR(mhpmcounter4h, CSR_MHPMCOUNTER4H) -DECLARE_CSR(mhpmcounter5h, CSR_MHPMCOUNTER5H) -DECLARE_CSR(mhpmcounter6h, CSR_MHPMCOUNTER6H) -DECLARE_CSR(mhpmcounter7h, CSR_MHPMCOUNTER7H) -DECLARE_CSR(mhpmcounter8h, CSR_MHPMCOUNTER8H) -DECLARE_CSR(mhpmcounter9h, CSR_MHPMCOUNTER9H) -DECLARE_CSR(mhpmcounter10h, CSR_MHPMCOUNTER10H) -DECLARE_CSR(mhpmcounter11h, CSR_MHPMCOUNTER11H) -DECLARE_CSR(mhpmcounter12h, CSR_MHPMCOUNTER12H) -DECLARE_CSR(mhpmcounter13h, CSR_MHPMCOUNTER13H) -DECLARE_CSR(mhpmcounter14h, CSR_MHPMCOUNTER14H) -DECLARE_CSR(mhpmcounter15h, CSR_MHPMCOUNTER15H) -DECLARE_CSR(mhpmcounter16h, CSR_MHPMCOUNTER16H) -DECLARE_CSR(mhpmcounter17h, CSR_MHPMCOUNTER17H) -DECLARE_CSR(mhpmcounter18h, CSR_MHPMCOUNTER18H) -DECLARE_CSR(mhpmcounter19h, CSR_MHPMCOUNTER19H) -DECLARE_CSR(mhpmcounter20h, CSR_MHPMCOUNTER20H) -DECLARE_CSR(mhpmcounter21h, CSR_MHPMCOUNTER21H) -DECLARE_CSR(mhpmcounter22h, CSR_MHPMCOUNTER22H) -DECLARE_CSR(mhpmcounter23h, CSR_MHPMCOUNTER23H) -DECLARE_CSR(mhpmcounter24h, CSR_MHPMCOUNTER24H) -DECLARE_CSR(mhpmcounter25h, CSR_MHPMCOUNTER25H) -DECLARE_CSR(mhpmcounter26h, CSR_MHPMCOUNTER26H) -DECLARE_CSR(mhpmcounter27h, CSR_MHPMCOUNTER27H) -DECLARE_CSR(mhpmcounter28h, CSR_MHPMCOUNTER28H) -DECLARE_CSR(mhpmcounter29h, CSR_MHPMCOUNTER29H) -DECLARE_CSR(mhpmcounter30h, CSR_MHPMCOUNTER30H) -DECLARE_CSR(mhpmcounter31h, CSR_MHPMCOUNTER31H) -#endif -#ifdef DECLARE_CAUSE -DECLARE_CAUSE("misaligned fetch", CAUSE_MISALIGNED_FETCH) -DECLARE_CAUSE("fault fetch", CAUSE_FAULT_FETCH) -DECLARE_CAUSE("illegal instruction", CAUSE_ILLEGAL_INSTRUCTION) -DECLARE_CAUSE("breakpoint", CAUSE_BREAKPOINT) -DECLARE_CAUSE("misaligned load", CAUSE_MISALIGNED_LOAD) -DECLARE_CAUSE("fault load", CAUSE_FAULT_LOAD) -DECLARE_CAUSE("misaligned store", CAUSE_MISALIGNED_STORE) -DECLARE_CAUSE("fault store", CAUSE_FAULT_STORE) -DECLARE_CAUSE("user_ecall", CAUSE_USER_ECALL) -DECLARE_CAUSE("supervisor_ecall", CAUSE_SUPERVISOR_ECALL) -DECLARE_CAUSE("hypervisor_ecall", CAUSE_HYPERVISOR_ECALL) -DECLARE_CAUSE("machine_ecall", CAUSE_MACHINE_ECALL) -#endif diff --git a/tests/htif.ld b/tests/htif.ld new file mode 120000 index 00000000..b527740e --- /dev/null +++ b/tests/htif.ld @@ -0,0 +1 @@ +../toolchains/libgloss/util/htif.ld \ No newline at end of file diff --git a/tests/libgloss.mk b/tests/libgloss.mk new file mode 100644 index 00000000..2272df33 --- /dev/null +++ b/tests/libgloss.mk @@ -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 diff --git a/tests/link.ld b/tests/link.ld deleted file mode 100644 index b39944d6..00000000 --- a/tests/link.ld +++ /dev/null @@ -1,65 +0,0 @@ -/*======================================================================*/ -/* Proxy kernel linker script */ -/*======================================================================*/ -/* This is the linker script used when building the proxy kernel. */ - -/*----------------------------------------------------------------------*/ -/* Setup */ -/*----------------------------------------------------------------------*/ - -/* The OUTPUT_ARCH command specifies the machine architecture where the - argument is one of the names used in the BFD library. More - specifically one of the entires in bfd/cpu-mips.c */ - -OUTPUT_ARCH( "riscv" ) -ENTRY(_start) - -/*----------------------------------------------------------------------*/ -/* Sections */ -/*----------------------------------------------------------------------*/ - -SECTIONS -{ - - /* text: test code section */ - . = 0x80000000; - .text.init : { *(.text.init) } - - .tohost ALIGN(0x1000) : { *(.tohost) } - - .text : { *(.text) } - - /* data segment */ - .data ALIGN(0x40) : { *(.data) } - - .sdata : { - __global_pointer$ = . + 0x800; - *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) - *(.sdata .sdata.* .gnu.linkonce.s.*) - } - - /* bss segment */ - .sbss : { - *(.sbss .sbss.* .gnu.linkonce.sb.*) - *(.scommon) - } - .bss ALIGN(0x40) : { *(.bss) } - - /* thread-local data segment */ - .tdata : - { - _tls_data = .; - *(.tdata.begin) - *(.tdata) - *(.tdata.end) - } - .tbss : - { - *(.tbss) - *(.tbss.end) - } - - /* End of uninitalized data segement */ - _end = .; -} - diff --git a/tests/nic-loopback.c b/tests/nic-loopback.c index 1d3c7b96..74eced7d 100644 --- a/tests/nic-loopback.c +++ b/tests/nic-loopback.c @@ -3,8 +3,8 @@ #include #include +#include #include "nic.h" -#include "encoding.h" #define NPACKETS 10 #define TEST_OFFSET 3 diff --git a/tests/syscalls.c b/tests/syscalls.c deleted file mode 100644 index 0a7d6b72..00000000 --- a/tests/syscalls.c +++ /dev/null @@ -1,470 +0,0 @@ -// See LICENSE for license details. - -#include -#include -#include -#include -#include -#include -#include "util.h" - -#define SYS_write 64 - -#undef strcmp - -extern volatile uint64_t tohost; -extern volatile uint64_t fromhost; - -static uintptr_t syscall(uintptr_t which, uint64_t arg0, uint64_t arg1, uint64_t arg2) -{ - volatile uint64_t magic_mem[8] __attribute__((aligned(64))); - magic_mem[0] = which; - magic_mem[1] = arg0; - magic_mem[2] = arg1; - magic_mem[3] = arg2; - __sync_synchronize(); - - tohost = (uintptr_t)magic_mem; - while (fromhost == 0) - ; - fromhost = 0; - - __sync_synchronize(); - return magic_mem[0]; -} - -#define NUM_COUNTERS 2 -static uintptr_t counters[NUM_COUNTERS]; -static char* counter_names[NUM_COUNTERS]; - -void setStats(int enable) -{ - int i = 0; -#define READ_CTR(name) do { \ - while (i >= NUM_COUNTERS) ; \ - uintptr_t csr = read_csr(name); \ - if (!enable) { csr -= counters[i]; counter_names[i] = #name; } \ - counters[i++] = csr; \ - } while (0) - - READ_CTR(mcycle); - READ_CTR(minstret); - -#undef READ_CTR -} - -void __attribute__((noreturn)) tohost_exit(uintptr_t code) -{ - tohost = (code << 1) | 1; - while (1); -} - -uintptr_t __attribute__((weak)) handle_trap(uintptr_t cause, uintptr_t epc, uintptr_t regs[32]) -{ - tohost_exit(1337); -} - -void exit(int code) -{ - tohost_exit(code); -} - -void abort() -{ - exit(128 + SIGABRT); -} - -void printstr(const char* s) -{ - syscall(SYS_write, 1, (uintptr_t)s, strlen(s)); -} - -void __attribute__((weak)) thread_entry(int cid, int nc) -{ - // multi-threaded programs override this function. - // for the case of single-threaded programs, only let core 0 proceed. - while (cid != 0); -} - -int __attribute__((weak)) main(int argc, char** argv) -{ - // single-threaded programs override this function. - printstr("Implement main(), foo!\n"); - return -1; -} - -static void init_tls() -{ - register void* thread_pointer asm("tp"); - extern char _tls_data; - extern __thread char _tdata_begin, _tdata_end, _tbss_end; - size_t tdata_size = &_tdata_end - &_tdata_begin; - memcpy(thread_pointer, &_tls_data, tdata_size); - size_t tbss_size = &_tbss_end - &_tdata_end; - memset(thread_pointer + tdata_size, 0, tbss_size); -} - -void _init(int cid, int nc) -{ - init_tls(); - thread_entry(cid, nc); - - // only single-threaded programs should ever get here. - int ret = main(0, 0); - - char buf[NUM_COUNTERS * 32] __attribute__((aligned(64))); - char* pbuf = buf; - for (int i = 0; i < NUM_COUNTERS; i++) - if (counters[i]) - pbuf += sprintf(pbuf, "%s = %d\n", counter_names[i], counters[i]); - if (pbuf != buf) - printstr(buf); - - exit(ret); -} - -#undef putchar -int putchar(int ch) -{ - static __thread char buf[64] __attribute__((aligned(64))); - static __thread int buflen = 0; - - buf[buflen++] = ch; - - if (ch == '\n' || buflen == sizeof(buf)) - { - syscall(SYS_write, 1, (uintptr_t)buf, buflen); - buflen = 0; - } - - return 0; -} - -void printhex(uint64_t x) -{ - char str[17]; - int i; - for (i = 0; i < 16; i++) - { - str[15-i] = (x & 0xF) + ((x & 0xF) < 10 ? '0' : 'a'-10); - x >>= 4; - } - str[16] = 0; - - printstr(str); -} - -static inline void printnum(void (*putch)(int, void**), void **putdat, - unsigned long long num, unsigned base, int width, int padc) -{ - unsigned digs[sizeof(num)*CHAR_BIT]; - int pos = 0; - - while (1) - { - digs[pos++] = num % base; - if (num < base) - break; - num /= base; - } - - while (width-- > pos) - putch(padc, putdat); - - while (pos-- > 0) - putch(digs[pos] + (digs[pos] >= 10 ? 'a' - 10 : '0'), putdat); -} - -static unsigned long long getuint(va_list *ap, int lflag) -{ - if (lflag >= 2) - return va_arg(*ap, unsigned long long); - else if (lflag) - return va_arg(*ap, unsigned long); - else - return va_arg(*ap, unsigned int); -} - -static long long getint(va_list *ap, int lflag) -{ - if (lflag >= 2) - return va_arg(*ap, long long); - else if (lflag) - return va_arg(*ap, long); - else - return va_arg(*ap, int); -} - -static void vprintfmt(void (*putch)(int, void**), void **putdat, const char *fmt, va_list ap) -{ - register const char* p; - const char* last_fmt; - register int ch, err; - unsigned long long num; - int base, lflag, width, precision, altflag; - char padc; - - while (1) { - while ((ch = *(unsigned char *) fmt) != '%') { - if (ch == '\0') - return; - fmt++; - putch(ch, putdat); - } - fmt++; - - // Process a %-escape sequence - last_fmt = fmt; - padc = ' '; - width = -1; - precision = -1; - lflag = 0; - altflag = 0; - reswitch: - switch (ch = *(unsigned char *) fmt++) { - - // flag to pad on the right - case '-': - padc = '-'; - goto reswitch; - - // flag to pad with 0's instead of spaces - case '0': - padc = '0'; - goto reswitch; - - // width field - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - for (precision = 0; ; ++fmt) { - precision = precision * 10 + ch - '0'; - ch = *fmt; - if (ch < '0' || ch > '9') - break; - } - goto process_precision; - - case '*': - precision = va_arg(ap, int); - goto process_precision; - - case '.': - if (width < 0) - width = 0; - goto reswitch; - - case '#': - altflag = 1; - goto reswitch; - - process_precision: - if (width < 0) - width = precision, precision = -1; - goto reswitch; - - // long flag (doubled for long long) - case 'l': - lflag++; - goto reswitch; - - // character - case 'c': - putch(va_arg(ap, int), putdat); - break; - - // string - case 's': - if ((p = va_arg(ap, char *)) == NULL) - p = "(null)"; - if (width > 0 && padc != '-') - for (width -= strnlen(p, precision); width > 0; width--) - putch(padc, putdat); - for (; (ch = *p) != '\0' && (precision < 0 || --precision >= 0); width--) { - putch(ch, putdat); - p++; - } - for (; width > 0; width--) - putch(' ', putdat); - break; - - // (signed) decimal - case 'd': - num = getint(&ap, lflag); - if ((long long) num < 0) { - putch('-', putdat); - num = -(long long) num; - } - base = 10; - goto signed_number; - - // unsigned decimal - case 'u': - base = 10; - goto unsigned_number; - - // (unsigned) octal - case 'o': - // should do something with padding so it's always 3 octits - base = 8; - goto unsigned_number; - - // pointer - case 'p': - static_assert(sizeof(long) == sizeof(void*)); - lflag = 1; - putch('0', putdat); - putch('x', putdat); - /* fall through to 'x' */ - - // (unsigned) hexadecimal - case 'x': - base = 16; - unsigned_number: - num = getuint(&ap, lflag); - signed_number: - printnum(putch, putdat, num, base, width, padc); - break; - - // escaped '%' character - case '%': - putch(ch, putdat); - break; - - // unrecognized escape sequence - just print it literally - default: - putch('%', putdat); - fmt = last_fmt; - break; - } - } -} - -int printf(const char* fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - - vprintfmt((void*)putchar, 0, fmt, ap); - - va_end(ap); - return 0; // incorrect return value, but who cares, anyway? -} - -int sprintf(char* str, const char* fmt, ...) -{ - va_list ap; - char* str0 = str; - va_start(ap, fmt); - - void sprintf_putch(int ch, void** data) - { - char** pstr = (char**)data; - **pstr = ch; - (*pstr)++; - } - - vprintfmt(sprintf_putch, (void**)&str, fmt, ap); - *str = 0; - - va_end(ap); - return str - str0; -} - -void* memcpy(void* dest, const void* src, size_t len) -{ - if ((((uintptr_t)dest | (uintptr_t)src | len) & (sizeof(uintptr_t)-1)) == 0) { - const uintptr_t* s = src; - uintptr_t *d = dest; - while (d < (uintptr_t*)(dest + len)) - *d++ = *s++; - } else { - const char* s = src; - char *d = dest; - while (d < (char*)(dest + len)) - *d++ = *s++; - } - return dest; -} - -void* memset(void* dest, int byte, size_t len) -{ - if ((((uintptr_t)dest | len) & (sizeof(uintptr_t)-1)) == 0) { - uintptr_t word = byte & 0xFF; - word |= word << 8; - word |= word << 16; - word |= word << 16 << 16; - - uintptr_t *d = dest; - while (d < (uintptr_t*)(dest + len)) - *d++ = word; - } else { - char *d = dest; - while (d < (char*)(dest + len)) - *d++ = byte; - } - return dest; -} - -size_t strlen(const char *s) -{ - const char *p = s; - while (*p) - p++; - return p - s; -} - -size_t strnlen(const char *s, size_t n) -{ - const char *p = s; - while (n-- && *p) - p++; - return p - s; -} - -int strcmp(const char* s1, const char* s2) -{ - unsigned char c1, c2; - - do { - c1 = *s1++; - c2 = *s2++; - } while (c1 != 0 && c1 == c2); - - return c1 - c2; -} - -char* strcpy(char* dest, const char* src) -{ - char* d = dest; - while ((*d++ = *src++)) - ; - return dest; -} - -long atol(const char* str) -{ - long res = 0; - int sign = 0; - - while (*str == ' ') - str++; - - if (*str == '-' || *str == '+') { - sign = *str == '-'; - str++; - } - - while (*str) { - res *= 10; - res += *str++ - '0'; - } - - return sign ? -res : res; -} diff --git a/tests/util.h b/tests/util.h deleted file mode 100644 index 22f81cf9..00000000 --- a/tests/util.h +++ /dev/null @@ -1,135 +0,0 @@ -// See LICENSE for license details. - -#ifndef __UTIL_H -#define __UTIL_H - -//-------------------------------------------------------------------------- -// Macros - -// Set HOST_DEBUG to 1 if you are going to compile this for a host -// machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG -// to 0 if you are compiling with the smips-gcc toolchain. - -#ifndef HOST_DEBUG -#define HOST_DEBUG 0 -#endif - -// Set PREALLOCATE to 1 if you want to preallocate the benchmark -// function before starting stats. If you have instruction/data -// caches and you don't want to count the overhead of misses, then -// you will need to use preallocation. - -#ifndef PREALLOCATE -#define PREALLOCATE 0 -#endif - -// Set SET_STATS to 1 if you want to carve out the piece that actually -// does the computation. - -#if HOST_DEBUG -#include -static void setStats(int enable) {} -#else -extern void setStats(int enable); -#endif - -#include - -#define static_assert(cond) switch(0) { case 0: case !!(long)(cond): ; } - -static void printArray(const char name[], int n, const int arr[]) -{ -#if HOST_DEBUG - int i; - printf( " %10s :", name ); - for ( i = 0; i < n; i++ ) - printf( " %3d ", arr[i] ); - printf( "\n" ); -#endif -} - -static void printDoubleArray(const char name[], int n, const double arr[]) -{ -#if HOST_DEBUG - int i; - printf( " %10s :", name ); - for ( i = 0; i < n; i++ ) - printf( " %g ", arr[i] ); - printf( "\n" ); -#endif -} - -static int verify(int n, const volatile int* test, const int* verify) -{ - int i; - // Unrolled for faster verification - for (i = 0; i < n/2*2; i+=2) - { - int t0 = test[i], t1 = test[i+1]; - int v0 = verify[i], v1 = verify[i+1]; - if (t0 != v0) return i+1; - if (t1 != v1) return i+2; - } - if (n % 2 != 0 && test[n-1] != verify[n-1]) - return n; - return 0; -} - -static int verifyDouble(int n, const volatile double* test, const double* verify) -{ - int i; - // Unrolled for faster verification - for (i = 0; i < n/2*2; i+=2) - { - double t0 = test[i], t1 = test[i+1]; - double v0 = verify[i], v1 = verify[i+1]; - int eq1 = t0 == v0, eq2 = t1 == v1; - if (!(eq1 & eq2)) return i+1+eq1; - } - if (n % 2 != 0 && test[n-1] != verify[n-1]) - return n; - return 0; -} - -static void __attribute__((noinline)) barrier(int ncores) -{ - static volatile int sense; - static volatile int count; - static __thread int threadsense; - - __sync_synchronize(); - - threadsense = !threadsense; - if (__sync_fetch_and_add(&count, 1) == ncores-1) - { - count = 0; - sense = threadsense; - } - else while(sense != threadsense) - ; - - __sync_synchronize(); -} - -static uint64_t lfsr(uint64_t x) -{ - uint64_t bit = (x ^ (x >> 1)) & 1; - return (x >> 1) | (bit << 62); -} - -#ifdef __riscv -#include "encoding.h" -#endif - -#define stringify_1(s) #s -#define stringify(s) stringify_1(s) -#define stats(code, iter) do { \ - unsigned long _c = -read_csr(mcycle), _i = -read_csr(minstret); \ - code; \ - _c += read_csr(mcycle), _i += read_csr(minstret); \ - if (cid == 0) \ - printf("\n%s: %ld cycles, %ld.%ld cycles/iter, %ld.%ld CPI\n", \ - stringify(code), _c, _c/iter, 10*_c/iter%10, _c/_i, 10*_c/_i%10); \ - } while(0) - -#endif //__UTIL_H diff --git a/toolchains/esp-tools/riscv-isa-sim b/toolchains/esp-tools/riscv-isa-sim index 0ffa02e5..9163c430 160000 --- a/toolchains/esp-tools/riscv-isa-sim +++ b/toolchains/esp-tools/riscv-isa-sim @@ -1 +1 @@ -Subproject commit 0ffa02e5b4ca57ec44684119a1a9a31b3871857b +Subproject commit 9163c430be06d43dc0ecc43698791fc36cc3402d diff --git a/toolchains/libgloss b/toolchains/libgloss new file mode 160000 index 00000000..117b9997 --- /dev/null +++ b/toolchains/libgloss @@ -0,0 +1 @@ +Subproject commit 117b9997bf46b93687e52f8ea102bd89478de493 diff --git a/toolchains/riscv-tools/riscv-gnu-toolchain-prebuilt b/toolchains/riscv-tools/riscv-gnu-toolchain-prebuilt index 5e32a015..543ff124 160000 --- a/toolchains/riscv-tools/riscv-gnu-toolchain-prebuilt +++ b/toolchains/riscv-tools/riscv-gnu-toolchain-prebuilt @@ -1 +1 @@ -Subproject commit 5e32a0157f91ebfb5c7ea7113fce28bf40016fa4 +Subproject commit 543ff1245e1c2071ea9d0252a622c9cece88b7f5 diff --git a/tools/axe b/tools/axe new file mode 160000 index 00000000..4a7cf869 --- /dev/null +++ b/tools/axe @@ -0,0 +1 @@ +Subproject commit 4a7cf86960425fbf0b6224865b745ff511dc5742 diff --git a/tools/barstools b/tools/barstools index 26096e07..5198b388 160000 --- a/tools/barstools +++ b/tools/barstools @@ -1 +1 @@ -Subproject commit 26096e07f6ce3e12b2114132c2859ef56fb0cfaf +Subproject commit 5198b3883c8dfb744c24e7586eec5c9e80a8dd68 diff --git a/tools/chisel-testers b/tools/chisel-testers index 41f4eef0..f410c593 160000 --- a/tools/chisel-testers +++ b/tools/chisel-testers @@ -1 +1 @@ -Subproject commit 41f4eef0d85b65fabd0d786efa8baa099513dcf0 +Subproject commit f410c59316e5c43bac96411889aba8c5ab9a8fc0 diff --git a/tools/chisel3 b/tools/chisel3 index e1aa5f3f..d1a61262 160000 --- a/tools/chisel3 +++ b/tools/chisel3 @@ -1 +1 @@ -Subproject commit e1aa5f3f5c0cdeb204047c3ca50801d9f7ea25f1 +Subproject commit d1a61262630b5ea77ebe21a453df9645cb7e4185 diff --git a/tools/firrtl b/tools/firrtl index 84a1c7b1..f738fbe8 160000 --- a/tools/firrtl +++ b/tools/firrtl @@ -1 +1 @@ -Subproject commit 84a1c7b1f7311ce036cb7d3d5eb652466b87dce4 +Subproject commit f738fbe8667ed6b76ec00a15960b9c3a42b8654a diff --git a/variables.mk b/variables.mk index fca782fa..a303eafe 100644 --- a/variables.mk +++ b/variables.mk @@ -140,7 +140,7 @@ JAVA_ARGS ?= -Xmx$(JAVA_HEAP_SIZE) -Xss8M -XX:MaxPermSize=256M ######################################################################################### # default sbt launch command ######################################################################################### -SCALA_VERSION=2.12.4 +SCALA_VERSION=2.12.10 SCALA_VERSION_MAJOR=$(basename $(SCALA_VERSION)) SBT ?= java $(JAVA_ARGS) -jar $(ROCKETCHIP_DIR)/sbt-launch.jar ++$(SCALA_VERSION) diff --git a/vlsi/Makefile b/vlsi/Makefile index cc61b957..a41368c5 100644 --- a/vlsi/Makefile +++ b/vlsi/Makefile @@ -23,12 +23,21 @@ tech_dir ?= $(if $(filter $(tech_name), asap7), $(vlsi_dir)/hammer/src SMEMS_COMP ?= $(tech_dir)/sram-compiler.json SMEMS_CACHE ?= $(tech_dir)/sram-cache.json SMEMS_HAMMER ?= $(build_dir)/$(long_name).mems.hammer.json -MACROCOMPILER_MODE ?= -l $(SMEMS_CACHE) -hir $(SMEMS_HAMMER) -OBJ_DIR ?= $(vlsi_dir)/build +ifeq ($(tech_name),asap7) + MACROCOMPILER_MODE ?= --mode synflops +else + MACROCOMPILER_MODE ?= -l $(SMEMS_CACHE) -hir $(SMEMS_HAMMER) +endif ENV_YML ?= $(vlsi_dir)/env.yml INPUT_CONFS ?= example.yml HAMMER_EXEC ?= ./example-vlsi VLSI_TOP ?= $(TOP) +VLSI_OBJ_DIR ?= $(vlsi_dir)/build +ifneq ($(CUSTOM_VLOG), ) + OBJ_DIR ?= $(VLSI_OBJ_DIR)/custom-$(VLSI_TOP) +else + OBJ_DIR ?= $(VLSI_OBJ_DIR)/$(long_name)-$(VLSI_TOP) +endif ######################################################################################### # general rules @@ -66,8 +75,8 @@ SRAM_CONF=$(build_dir)/sram_generator-output.json srams: sram_generator sram_generator: $(SRAM_CONF) -# This should be built alongside $(SMEMS_FILE) -$(SMEMS_HAMMER): $(SMEMS_FILE) +# This should be built alongside $(TOP_SMEMS_FILE) +$(SMEMS_HAMMER): $(TOP_SMEMS_FILE) $(SRAM_GENERATOR_CONF): $(SMEMS_HAMMER) mkdir -p $(dir $@) @@ -115,4 +124,4 @@ $(OBJ_DIR)/hammer.d: $(HAMMER_D_DEPS) ######################################################################################### .PHONY: clean clean: - rm -rf $(OBJ_DIR) hammer-vlsi*.log __pycache__ output.json $(GENERATED_CONFS) $(gen_dir) + rm -rf $(VLSI_OBJ_DIR) hammer-vlsi*.log __pycache__ output.json $(GENERATED_CONFS) $(gen_dir) diff --git a/vlsi/hammer b/vlsi/hammer index 85c12e98..2f37cd31 160000 --- a/vlsi/hammer +++ b/vlsi/hammer @@ -1 +1 @@ -Subproject commit 85c12e98e63d599f5267c7711a24c174d74974c5 +Subproject commit 2f37cd3121d9a9e775efbe4554d9b74c30d01f61 diff --git a/vlsi/hammer-cadence-plugins b/vlsi/hammer-cadence-plugins index 5f5d9d9e..8f23bfa8 160000 --- a/vlsi/hammer-cadence-plugins +++ b/vlsi/hammer-cadence-plugins @@ -1 +1 @@ -Subproject commit 5f5d9d9e574d54acd3a84d1885c9f9b2897f373b +Subproject commit 8f23bfa8c971ceb39b10aa52d6c9f446c5303cd3 diff --git a/vlsi/hammer-synopsys-plugins b/vlsi/hammer-synopsys-plugins index e0ace734..f812f8ce 160000 --- a/vlsi/hammer-synopsys-plugins +++ b/vlsi/hammer-synopsys-plugins @@ -1 +1 @@ -Subproject commit e0ace7345e98e11b17ce550550c902782010e032 +Subproject commit f812f8ce85b5f77b563807bbb490b46ce82c1711