Merge branch 'dev' of github.com:ucb-bar/chipyard into verilator-makefile-fix
This commit is contained in:
@@ -82,7 +82,12 @@ search
|
||||
|
||||
submodules=("coremark" "firemarshal" "nvdla-workload" "spec2017")
|
||||
dir="software"
|
||||
branches=("master")
|
||||
if [ "$CIRCLE_BRANCH" == "master" ] || [ "$CIRCLE_BRANCH" == "dev" ]
|
||||
then
|
||||
branches=("master")
|
||||
else
|
||||
branches=("master" "dev")
|
||||
fi
|
||||
search
|
||||
|
||||
submodules=("DRAMSim2" "axe" "barstools" "chisel-testers" "dsptools" "firrtl-interpreter" "torture" "treadle")
|
||||
|
||||
@@ -6,7 +6,7 @@ version: 2.1
|
||||
parameters:
|
||||
tools-cache-version:
|
||||
type: string
|
||||
default: "v5"
|
||||
default: "v6"
|
||||
|
||||
# default execution env.s
|
||||
executors:
|
||||
@@ -73,7 +73,7 @@ commands:
|
||||
tools-version:
|
||||
type: string
|
||||
default: "riscv-tools"
|
||||
project-key:
|
||||
group-key:
|
||||
type: string
|
||||
timeout:
|
||||
type: string
|
||||
@@ -85,11 +85,11 @@ commands:
|
||||
- setup-tools:
|
||||
tools-version: "<< parameters.tools-version >>"
|
||||
- run:
|
||||
name: Building << parameters.project-key >> subproject using Verilator
|
||||
command: .circleci/<< parameters.build-script >> << parameters.project-key >>
|
||||
name: Building << parameters.group-key >> subproject using Verilator
|
||||
command: .circleci/<< parameters.build-script >> << parameters.group-key >>
|
||||
no_output_timeout: << parameters.timeout >>
|
||||
- save_cache:
|
||||
key: << parameters.project-key >>-{{ .Branch }}-{{ .Revision }}
|
||||
key: << parameters.group-key >>-{{ .Branch }}-{{ .Revision }}
|
||||
paths:
|
||||
- "/home/riscvuser/project"
|
||||
|
||||
@@ -99,11 +99,10 @@ commands:
|
||||
tools-version:
|
||||
type: string
|
||||
default: "riscv-tools"
|
||||
group-key:
|
||||
type: string
|
||||
project-key:
|
||||
type: string
|
||||
extra-cache-restore:
|
||||
type: string
|
||||
default: ""
|
||||
run-script:
|
||||
type: string
|
||||
default: "run-tests.sh"
|
||||
@@ -115,13 +114,7 @@ commands:
|
||||
tools-version: "<< parameters.tools-version >>"
|
||||
- restore_cache:
|
||||
keys:
|
||||
- << parameters.project-key >>-{{ .Branch }}-{{ .Revision }}
|
||||
- when:
|
||||
condition: << parameters.extra-cache-restore >>
|
||||
steps:
|
||||
- restore_cache:
|
||||
keys:
|
||||
- << parameters.extra-cache-restore >>-{{ .Branch }}-{{ .Revision }}
|
||||
- << parameters.group-key >>-{{ .Branch }}-{{ .Revision }}
|
||||
- run:
|
||||
name: Run << parameters.project-key >> subproject tests
|
||||
command: .circleci/<< parameters.run-script >> << parameters.project-key >>
|
||||
@@ -194,177 +187,154 @@ jobs:
|
||||
key: extra-tests-{{ .Branch }}-{{ .Revision }}
|
||||
paths:
|
||||
- "/home/riscvuser/project/tests"
|
||||
prepare-chipyard-rocket:
|
||||
|
||||
prepare-chipyard-cores:
|
||||
executor: main-env
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
project-key: "chipyard-rocket"
|
||||
prepare-chipyard-sha3:
|
||||
group-key: "group-cores"
|
||||
prepare-chipyard-peripherals:
|
||||
executor: main-env
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
project-key: "chipyard-sha3"
|
||||
prepare-chipyard-streaming-fir:
|
||||
executor: main-env
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
project-key: "chipyard-streaming-fir"
|
||||
prepare-chipyard-streaming-passthrough:
|
||||
executor: main-env
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
project-key: "chipyard-streaming-passthrough"
|
||||
prepare-chipyard-hetero:
|
||||
executor: main-env
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
project-key: "chipyard-hetero"
|
||||
timeout: "240m"
|
||||
prepare-chipyard-boom:
|
||||
executor: main-env
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
project-key: "chipyard-boom"
|
||||
prepare-rocketchip:
|
||||
executor: main-env
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
project-key: "rocketchip"
|
||||
prepare-chipyard-blkdev:
|
||||
executor: main-env
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
project-key: "chipyard-blkdev"
|
||||
prepare-chipyard-hwacha:
|
||||
group-key: "group-peripherals"
|
||||
prepare-chipyard-accels:
|
||||
executor: main-env
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
tools-version: "esp-tools"
|
||||
project-key: "chipyard-hwacha"
|
||||
prepare-chipyard-gemmini:
|
||||
group-key: "group-accels"
|
||||
prepare-chipyard-tracegen:
|
||||
executor: main-env
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
tools-version: "esp-tools"
|
||||
project-key: "chipyard-gemmini"
|
||||
prepare-tracegen:
|
||||
group-key: "group-tracegen"
|
||||
prepare-chipyard-other:
|
||||
executor: main-env
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
project-key: "tracegen"
|
||||
prepare-tracegen-boom:
|
||||
executor: main-env
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
project-key: "tracegen-boom"
|
||||
prepare-chipyard-ariane:
|
||||
executor: main-env
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
project-key: "chipyard-ariane"
|
||||
prepare-icenet:
|
||||
executor: main-env
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
project-key: "icenet"
|
||||
prepare-testchipip:
|
||||
executor: main-env
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
project-key: "testchipip"
|
||||
prepare-chipyard-nvdla:
|
||||
executor: main-env
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
project-key: "chipyard-nvdla"
|
||||
prepare-chipyard-spiflashwrite:
|
||||
executor: main-env
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
project-key: "chipyard-spiflashwrite"
|
||||
prepare-chipyard-spiflashread:
|
||||
executor: main-env
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
project-key: "chipyard-spiflashread"
|
||||
prepare-chipyard-mmios:
|
||||
executor: main-env
|
||||
steps:
|
||||
- prepare-rtl:
|
||||
project-key: "chipyard-mmios"
|
||||
group-key: "group-other"
|
||||
|
||||
chipyard-rocket-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
group-key: "group-cores"
|
||||
project-key: "chipyard-rocket"
|
||||
chipyard-sha3-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
project-key: "chipyard-sha3"
|
||||
chipyard-streaming-fir-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
project-key: "chipyard-streaming-fir"
|
||||
chipyard-streaming-passthrough-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
project-key: "chipyard-streaming-passthrough"
|
||||
chipyard-hetero-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
group-key: "group-cores"
|
||||
project-key: "chipyard-hetero"
|
||||
timeout: "15m"
|
||||
chipyard-boom-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
group-key: "group-cores"
|
||||
project-key: "chipyard-boom"
|
||||
rocketchip-run-tests:
|
||||
chipyard-ariane-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
project-key: "rocketchip"
|
||||
group-key: "group-cores"
|
||||
project-key: "chipyard-ariane"
|
||||
timeout: "30m"
|
||||
chipyard-dmirocket-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
group-key: "group-peripherals"
|
||||
project-key: "chipyard-dmirocket"
|
||||
chipyard-spiflashwrite-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
group-key: "group-peripherals"
|
||||
project-key: "chipyard-spiflashwrite"
|
||||
chipyard-spiflashread-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
group-key: "group-peripherals"
|
||||
project-key: "chipyard-spiflashread"
|
||||
chipyard-lbwif-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
group-key: "group-peripherals"
|
||||
project-key: "chipyard-lbwif"
|
||||
|
||||
chipyard-sha3-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
group-key: "group-accels"
|
||||
project-key: "chipyard-sha3"
|
||||
chipyard-streaming-fir-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
group-key: "group-accels"
|
||||
project-key: "chipyard-streaming-fir"
|
||||
chipyard-streaming-passthrough-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
group-key: "group-accels"
|
||||
project-key: "chipyard-streaming-passthrough"
|
||||
chipyard-hwacha-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
tools-version: "esp-tools"
|
||||
group-key: "group-accels"
|
||||
project-key: "chipyard-hwacha"
|
||||
chipyard-gemmini-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
tools-version: "esp-tools"
|
||||
group-key: "group-accels"
|
||||
project-key: "chipyard-gemmini"
|
||||
chipyard-spiflashwrite-run-tests:
|
||||
chipyard-nvdla-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
project-key: "chipyard-spiflashwrite"
|
||||
chipyard-spiflashread-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
project-key: "chipyard-spiflashread"
|
||||
group-key: "group-accels"
|
||||
project-key: "chipyard-nvdla"
|
||||
tracegen-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
group-key: "group-tracegen"
|
||||
project-key: "tracegen"
|
||||
tracegen-boom-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
group-key: "group-tracegen"
|
||||
project-key: "tracegen-boom"
|
||||
icenet-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
group-key: "group-other"
|
||||
project-key: "icenet"
|
||||
timeout: "30m"
|
||||
testchipip-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
group-key: "group-other"
|
||||
project-key: "testchipip"
|
||||
timeout: "30m"
|
||||
firesim-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
extra-cache-restore: "extra-tests"
|
||||
group-key: "extra-tests"
|
||||
project-key: "firesim"
|
||||
run-script: "run-firesim-scala-tests.sh"
|
||||
timeout: "20m"
|
||||
@@ -372,7 +342,7 @@ jobs:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
extra-cache-restore: "extra-tests"
|
||||
group-key: "extra-tests"
|
||||
project-key: "fireboom"
|
||||
run-script: "run-firesim-scala-tests.sh"
|
||||
timeout: "45m"
|
||||
@@ -380,33 +350,10 @@ jobs:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
extra-cache-restore: "extra-tests"
|
||||
group-key: "extra-tests"
|
||||
project-key: "firesim-multiclock"
|
||||
run-script: "run-firesim-scala-tests.sh"
|
||||
timeout: "20m"
|
||||
chipyard-ariane-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
project-key: "chipyard-ariane"
|
||||
timeout: "30m"
|
||||
chipyard-nvdla-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
project-key: "chipyard-nvdla"
|
||||
icenet-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
project-key: "icenet"
|
||||
timeout: "30m"
|
||||
testchipip-run-tests:
|
||||
executor: main-env
|
||||
steps:
|
||||
- run-tests:
|
||||
project-key: "testchipip"
|
||||
timeout: "30m"
|
||||
|
||||
# Order and dependencies of jobs to run
|
||||
workflows:
|
||||
@@ -446,154 +393,86 @@ workflows:
|
||||
- install-riscv-toolchain
|
||||
|
||||
# Prepare the verilator builds
|
||||
- prepare-chipyard-rocket:
|
||||
- prepare-chipyard-cores:
|
||||
requires:
|
||||
- install-riscv-toolchain
|
||||
- install-verilator
|
||||
|
||||
- prepare-chipyard-sha3:
|
||||
- prepare-chipyard-peripherals:
|
||||
requires:
|
||||
- install-riscv-toolchain
|
||||
- install-verilator
|
||||
|
||||
- prepare-chipyard-streaming-fir:
|
||||
requires:
|
||||
- install-riscv-toolchain
|
||||
- install-verilator
|
||||
|
||||
- prepare-chipyard-streaming-passthrough:
|
||||
requires:
|
||||
- install-riscv-toolchain
|
||||
- install-verilator
|
||||
|
||||
- prepare-chipyard-hetero:
|
||||
requires:
|
||||
- install-riscv-toolchain
|
||||
- install-verilator
|
||||
|
||||
- prepare-chipyard-boom:
|
||||
requires:
|
||||
- install-riscv-toolchain
|
||||
- install-verilator
|
||||
|
||||
- prepare-rocketchip:
|
||||
requires:
|
||||
- install-riscv-toolchain
|
||||
- install-verilator
|
||||
|
||||
- prepare-chipyard-blkdev:
|
||||
requires:
|
||||
- install-riscv-toolchain
|
||||
- install-verilator
|
||||
|
||||
- prepare-chipyard-hwacha:
|
||||
- prepare-chipyard-accels:
|
||||
requires:
|
||||
- install-esp-toolchain
|
||||
- install-verilator
|
||||
|
||||
- prepare-chipyard-gemmini:
|
||||
requires:
|
||||
- install-esp-toolchain
|
||||
- install-verilator
|
||||
|
||||
- prepare-tracegen:
|
||||
- prepare-chipyard-tracegen:
|
||||
requires:
|
||||
- install-riscv-toolchain
|
||||
- install-verilator
|
||||
|
||||
- prepare-tracegen-boom:
|
||||
- prepare-chipyard-other:
|
||||
requires:
|
||||
- install-riscv-toolchain
|
||||
- install-verilator
|
||||
|
||||
- prepare-chipyard-ariane:
|
||||
requires:
|
||||
- install-riscv-toolchain
|
||||
- install-verilator
|
||||
|
||||
- prepare-icenet:
|
||||
requires:
|
||||
- install-riscv-toolchain
|
||||
- install-verilator
|
||||
|
||||
- prepare-testchipip:
|
||||
requires:
|
||||
- install-riscv-toolchain
|
||||
- install-verilator
|
||||
|
||||
- prepare-chipyard-nvdla:
|
||||
requires:
|
||||
- install-riscv-toolchain
|
||||
- install-verilator
|
||||
|
||||
- prepare-chipyard-spiflashwrite:
|
||||
requires:
|
||||
- install-riscv-toolchain
|
||||
- install-verilator
|
||||
|
||||
- prepare-chipyard-spiflashread:
|
||||
requires:
|
||||
- install-riscv-toolchain
|
||||
- install-verilator
|
||||
|
||||
- prepare-chipyard-mmios:
|
||||
requires:
|
||||
- install-riscv-toolchain
|
||||
|
||||
# Run the respective tests
|
||||
|
||||
# Run the example tests
|
||||
- chipyard-rocket-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-rocket
|
||||
- prepare-chipyard-cores
|
||||
- chipyard-hetero-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-cores
|
||||
- chipyard-boom-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-cores
|
||||
- chipyard-ariane-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-cores
|
||||
|
||||
- chipyard-dmirocket-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-peripherals
|
||||
- chipyard-spiflashwrite-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-peripherals
|
||||
- chipyard-spiflashread-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-peripherals
|
||||
- chipyard-lbwif-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-peripherals
|
||||
|
||||
- chipyard-sha3-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-sha3
|
||||
|
||||
- prepare-chipyard-accels
|
||||
- chipyard-streaming-fir-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-streaming-fir
|
||||
|
||||
- prepare-chipyard-accels
|
||||
- chipyard-streaming-passthrough-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-streaming-passthrough
|
||||
|
||||
- chipyard-hetero-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-hetero
|
||||
|
||||
- chipyard-boom-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-boom
|
||||
|
||||
- rocketchip-run-tests:
|
||||
requires:
|
||||
- prepare-rocketchip
|
||||
|
||||
- prepare-chipyard-accels
|
||||
- chipyard-hwacha-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-hwacha
|
||||
|
||||
- prepare-chipyard-accels
|
||||
- chipyard-gemmini-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-gemmini
|
||||
- prepare-chipyard-accels
|
||||
- chipyard-nvdla-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-accels
|
||||
|
||||
- tracegen-run-tests:
|
||||
requires:
|
||||
- prepare-tracegen
|
||||
|
||||
- prepare-chipyard-tracegen
|
||||
- tracegen-boom-run-tests:
|
||||
requires:
|
||||
- prepare-tracegen-boom
|
||||
- prepare-chipyard-tracegen
|
||||
|
||||
- chipyard-spiflashwrite-run-tests:
|
||||
- icenet-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-spiflashwrite
|
||||
|
||||
- chipyard-spiflashread-run-tests:
|
||||
- prepare-chipyard-other
|
||||
- testchipip-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-spiflashread
|
||||
- prepare-chipyard-other
|
||||
|
||||
# Run the firesim tests
|
||||
- firesim-run-tests:
|
||||
@@ -612,17 +491,4 @@ workflows:
|
||||
- install-verilator
|
||||
- build-extra-tests
|
||||
|
||||
- chipyard-ariane-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-ariane
|
||||
|
||||
- chipyard-nvdla-run-tests:
|
||||
requires:
|
||||
- prepare-chipyard-nvdla
|
||||
- icenet-run-tests:
|
||||
requires:
|
||||
- prepare-icenet
|
||||
|
||||
- testchipip-run-tests:
|
||||
requires:
|
||||
- prepare-testchipip
|
||||
|
||||
@@ -45,9 +45,19 @@ LOCAL_CHIPYARD_DIR=$LOCAL_CHECKOUT_DIR
|
||||
LOCAL_SIM_DIR=$LOCAL_CHIPYARD_DIR/sims/verilator
|
||||
LOCAL_FIRESIM_DIR=$LOCAL_CHIPYARD_DIR/sims/firesim/sim
|
||||
|
||||
# key value store to get the build groups
|
||||
declare -A grouping
|
||||
grouping["group-cores"]="chipyard-ariane chipyard-rocket chipyard-hetero chipyard-boom"
|
||||
grouping["group-peripherals"]="chipyard-dmirocket chipyard-blkdev chipyard-spiflashread chipyard-spiflashwrite chipyard-mmios chipyard-lbwif"
|
||||
grouping["group-accels"]="chipyard-nvdla chipyard-sha3 chipyard-hwacha chipyard-gemmini chipyard-streaming-fir chipyard-streaming-passthrough"
|
||||
grouping["group-tracegen"]="tracegen tracegen-boom"
|
||||
grouping["group-other"]="icenet testchipip"
|
||||
|
||||
# key value store to get the build strings
|
||||
declare -A mapping
|
||||
mapping["chipyard-rocket"]=""
|
||||
mapping["chipyard-dmirocket"]=" CONFIG=dmiRocketConfig"
|
||||
mapping["chipyard-lbwif"]=" CONFIG=LBWIFRocketConfig"
|
||||
mapping["chipyard-sha3"]=" CONFIG=Sha3RocketConfig"
|
||||
mapping["chipyard-streaming-fir"]=" CONFIG=StreamingFIRRocketConfig"
|
||||
mapping["chipyard-streaming-passthrough"]=" CONFIG=StreamingPassthroughRocketConfig"
|
||||
@@ -60,9 +70,10 @@ mapping["chipyard-ariane"]=" CONFIG=ArianeConfig"
|
||||
mapping["chipyard-spiflashread"]=" CONFIG=LargeSPIFlashROMRocketConfig"
|
||||
mapping["chipyard-spiflashwrite"]=" CONFIG=SmallSPIFlashRocketConfig"
|
||||
mapping["chipyard-mmios"]=" CONFIG=MMIORocketConfig verilog"
|
||||
mapping["tracegen"]=" CONFIG=NonBlockingTraceGenL2Config TOP=TraceGenSystem"
|
||||
mapping["tracegen-boom"]=" CONFIG=BoomTraceGenConfig TOP=TraceGenSystem"
|
||||
mapping["tracegen"]=" CONFIG=NonBlockingTraceGenL2Config"
|
||||
mapping["tracegen-boom"]=" CONFIG=BoomTraceGenConfig"
|
||||
mapping["chipyard-nvdla"]=" CONFIG=SmallNVDLARocketConfig"
|
||||
|
||||
mapping["firesim"]="SCALA_TEST=firesim.firesim.RocketNICF1Tests"
|
||||
mapping["firesim-multiclock"]="SCALA_TEST=firesim.firesim.RocketMulticlockF1Tests"
|
||||
mapping["fireboom"]="SCALA_TEST=firesim.firesim.BoomF1Tests"
|
||||
|
||||
@@ -31,7 +31,7 @@ run "cp -r ~/.sbt $REMOTE_WORK_DIR"
|
||||
TOOLS_DIR=$REMOTE_RISCV_DIR
|
||||
LD_LIB_DIR=$REMOTE_RISCV_DIR/lib
|
||||
|
||||
if [ $1 = "chipyard-gemmini" ]; then
|
||||
if [ $1 = "group-accels" ]; then
|
||||
export RISCV=$LOCAL_ESP_DIR
|
||||
export LD_LIBRARY_PATH=$LOCAL_ESP_DIR/lib
|
||||
export PATH=$RISCV/bin:$PATH
|
||||
@@ -40,9 +40,7 @@ if [ $1 = "chipyard-gemmini" ]; then
|
||||
git submodule update --init --recursive gemmini-rocc-tests
|
||||
cd gemmini-rocc-tests
|
||||
./build.sh
|
||||
fi
|
||||
|
||||
if [ $1 = "chipyard-hwacha" ] || [ $1 = "chipyard-gemmini" ]; then
|
||||
TOOLS_DIR=$REMOTE_ESP_DIR
|
||||
LD_LIB_DIR=$REMOTE_ESP_DIR/lib
|
||||
run "mkdir -p $REMOTE_ESP_DIR"
|
||||
@@ -54,16 +52,19 @@ fi
|
||||
|
||||
# enter the verilator directory and build the specific config on remote server
|
||||
run "export RISCV=\"$TOOLS_DIR\"; \
|
||||
export LD_LIBRARY_PATH=\"$LD_LIB_DIR\"; \
|
||||
export PATH=\"$REMOTE_VERILATOR_DIR/bin:\$PATH\"; \
|
||||
export VERILATOR_ROOT=\"$REMOTE_VERILATOR_DIR\"; \
|
||||
export COURSIER_CACHE=\"$REMOTE_WORK_DIR/.coursier-cache\"; \
|
||||
make -C $REMOTE_SIM_DIR clean; \
|
||||
make -j$REMOTE_MAKE_NPROC -C $REMOTE_SIM_DIR JAVA_ARGS=\"$REMOTE_JAVA_ARGS\" ${mapping[$1]}"
|
||||
run "rm -rf $REMOTE_CHIPYARD_DIR/project"
|
||||
make -C $REMOTE_SIM_DIR clean;"
|
||||
|
||||
# copy back the final build
|
||||
read -a keys <<< ${grouping[$1]}
|
||||
|
||||
for key in "${keys[@]}"
|
||||
do
|
||||
run "export RISCV=\"$TOOLS_DIR\"; \
|
||||
export LD_LIBRARY_PATH=\"$LD_LIB_DIR\"; \
|
||||
export PATH=\"$REMOTE_VERILATOR_DIR/bin:\$PATH\"; \
|
||||
export VERILATOR_ROOT=\"$REMOTE_VERILATOR_DIR\"; \
|
||||
export COURSIER_CACHE=\"$REMOTE_WORK_DIR/.coursier-cache\"; \
|
||||
make -j$REMOTE_MAKE_NPROC -C $REMOTE_SIM_DIR FIRRTL_LOGLEVEL=info JAVA_ARGS=\"$REMOTE_JAVA_ARGS\" ${mapping[$key]}"
|
||||
done
|
||||
|
||||
run "rm -rf $REMOTE_CHIPYARD_DIR/project"
|
||||
|
||||
|
||||
@@ -32,6 +32,12 @@ case $1 in
|
||||
chipyard-rocket)
|
||||
run_bmark ${mapping[$1]}
|
||||
;;
|
||||
chipyard-dmirocket)
|
||||
run_bmark ${mapping[$1]}
|
||||
;;
|
||||
chipyard-lbwif)
|
||||
run_bmark ${mapping[$1]}
|
||||
;;
|
||||
chipyard-boom)
|
||||
run_bmark ${mapping[$1]}
|
||||
;;
|
||||
@@ -86,7 +92,7 @@ case $1 in
|
||||
run_tracegen ${mapping[$1]}
|
||||
;;
|
||||
chipyard-ariane)
|
||||
make run-binary-fast -C $LOCAL_SIM_DIR ${mapping[$1]} BINARY=$RISCV/riscv64-unknown-elf/share/riscv-tests/benchmarks/dhrystone.riscv
|
||||
make run-binary-fast -C $LOCAL_SIM_DIR ${mapping[$1]} BINARY=$RISCV/riscv64-unknown-elf/share/riscv-tests/benchmarks/multiply.riscv
|
||||
;;
|
||||
chipyard-nvdla)
|
||||
make -C $LOCAL_CHIPYARD_DIR/tests
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -6,6 +6,7 @@ target
|
||||
*.stamp
|
||||
*.vcd
|
||||
*.swp
|
||||
*.swo
|
||||
*.log
|
||||
*#
|
||||
*~
|
||||
|
||||
74
common.mk
74
common.mk
@@ -3,22 +3,49 @@
|
||||
#########################################################################################
|
||||
SHELL=/bin/bash
|
||||
|
||||
|
||||
ifndef RISCV
|
||||
$(error RISCV is unset. You must set RISCV yourself, or through the Chipyard auto-generated env file)
|
||||
else
|
||||
$(info Running with RISCV=$(RISCV))
|
||||
endif
|
||||
|
||||
#########################################################################################
|
||||
# specify user-interface variables
|
||||
#########################################################################################
|
||||
HELP_COMPILATION_VARIABLES += \
|
||||
" EXTRA_GENERATOR_REQS = additional make requirements needed for the main generator" \
|
||||
" EXTRA_SIM_CXXFLAGS = additional CXXFLAGS for building simulators" \
|
||||
" EXTRA_SIM_LDFLAGS = additional LDFLAGS for building simulators" \
|
||||
" EXTRA_SIM_SOURCES = additional simulation sources needed for simulator" \
|
||||
" EXTRA_SIM_REQS = additional make requirements to build the simulator"
|
||||
|
||||
EXTRA_GENERATOR_REQS ?=
|
||||
EXTRA_SIM_CXXFLAGS ?=
|
||||
EXTRA_SIM_LDFLAGS ?=
|
||||
EXTRA_SIM_SOURCES ?=
|
||||
EXTRA_SIM_REQS ?=
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
HELP_SIMULATION_VARIABLES += \
|
||||
" EXTRA_SIM_FLAGS = additional runtime simulation flags (passed within +permissive)" \
|
||||
" NUMACTL = set to '1' to wrap simulator in the appropriate numactl command"
|
||||
|
||||
EXTRA_SIM_FLAGS ?=
|
||||
NUMACTL ?= 0
|
||||
|
||||
NUMA_PREFIX = $(if $(filter $(NUMACTL),0),,$(shell $(base_dir)/scripts/numa_prefix))
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
HELP_COMMANDS += \
|
||||
" run-binary = run [./$(shell basename $(sim))] and log instructions to file" \
|
||||
" run-binary-fast = run [./$(shell basename $(sim))] and don't log instructions" \
|
||||
" run-binary-debug = run [./$(shell basename $(sim_debug))] and log instructions and waveform to files" \
|
||||
" verilog = generate intermediate verilog files from chisel elaboration and firrtl passes" \
|
||||
" run-tests = run all assembly and benchmark tests"
|
||||
|
||||
#########################################################################################
|
||||
# extra make variables/rules from subprojects
|
||||
#
|
||||
# EXTRA_GENERATOR_REQS - requirements needed for the main generator
|
||||
# EXTRA_SIM_FLAGS - runtime simulation flags
|
||||
# EXTRA_SIM_CC_FLAGS - cc flags for simulators
|
||||
# EXTRA_SIM_SOURCES - simulation sources needed for simulator
|
||||
# EXTRA_SIM_REQS - requirements to build the simulator
|
||||
# include additional subproject make fragments
|
||||
# see HELP_COMPILATION_VARIABLES
|
||||
#########################################################################################
|
||||
include $(base_dir)/generators/ariane/ariane.mk
|
||||
include $(base_dir)/generators/tracegen/tracegen.mk
|
||||
@@ -35,7 +62,8 @@ SOURCE_DIRS = $(addprefix $(base_dir)/,generators sims/firesim/sim tools/barstoo
|
||||
SCALA_SOURCES = $(call lookup_srcs,$(SOURCE_DIRS),scala)
|
||||
VLOG_SOURCES = $(call lookup_srcs,$(SOURCE_DIRS),sv) $(call lookup_srcs,$(SOURCE_DIRS),v)
|
||||
# This assumes no SBT meta-build sources
|
||||
SBT_SOURCES = $(call lookup_srcs,$(base_dir),sbt)
|
||||
SBT_SOURCE_DIRS = $(addprefix $(base_dir)/,generators sims/firesim/sim tools)
|
||||
SBT_SOURCES = $(call lookup_srcs,$(SBT_SOURCE_DIRS),sbt) $(base_dir)/build.sbt $(base_dir)/project/plugins.sbt
|
||||
|
||||
#########################################################################################
|
||||
# jar creation variables and rules
|
||||
@@ -55,7 +83,6 @@ $(FIRRTL_TEST_JAR): $(call lookup_srcs,$(CHIPYARD_FIRRTL_DIR),scala)
|
||||
cp -p $(CHIPYARD_FIRRTL_DIR)/utils/bin/firrtl-test.jar $@
|
||||
touch $@
|
||||
|
||||
|
||||
#########################################################################################
|
||||
# Bloop Project Definitions
|
||||
#########################################################################################
|
||||
@@ -140,20 +167,18 @@ verilog: $(sim_vsrcs)
|
||||
# helper rules to run simulations
|
||||
#########################################################################################
|
||||
.PHONY: run-binary run-binary-fast run-binary-debug run-fast
|
||||
|
||||
# run normal binary with hardware-logged insn dissassembly
|
||||
run-binary: $(output_dir) $(sim)
|
||||
(set -o pipefail && $(sim) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(VERBOSE_FLAGS) $(PERMISSIVE_OFF) $(BINARY) </dev/null 2> >(spike-dasm > $(sim_out_name).out) | tee $(sim_out_name).log)
|
||||
(set -o pipefail && $(NUMA_PREFIX) $(sim) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(VERBOSE_FLAGS) $(PERMISSIVE_OFF) $(BINARY) </dev/null 2> >(spike-dasm > $(sim_out_name).out) | tee $(sim_out_name).log)
|
||||
|
||||
#########################################################################################
|
||||
# helper rules to run simulator as fast as possible
|
||||
#########################################################################################
|
||||
# run simulator as fast as possible (no insn disassembly)
|
||||
run-binary-fast: $(output_dir) $(sim)
|
||||
(set -o pipefail && $(sim) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(PERMISSIVE_OFF) $(BINARY) </dev/null | tee $(sim_out_name).log)
|
||||
(set -o pipefail && $(NUMA_PREFIX) $(sim) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(PERMISSIVE_OFF) $(BINARY) </dev/null | tee $(sim_out_name).log)
|
||||
|
||||
#########################################################################################
|
||||
# helper rules to run simulator with as much debug info as possible
|
||||
#########################################################################################
|
||||
# run simulator with as much debug info as possible
|
||||
run-binary-debug: $(output_dir) $(sim_debug)
|
||||
(set -o pipefail && $(sim_debug) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(VERBOSE_FLAGS) $(WAVEFORM_FLAG) $(PERMISSIVE_OFF) $(BINARY) </dev/null 2> >(spike-dasm > $(sim_out_name).out) | tee $(sim_out_name).log)
|
||||
(set -o pipefail && $(NUMA_PREFIX) $(sim_debug) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(VERBOSE_FLAGS) $(WAVEFORM_FLAG) $(PERMISSIVE_OFF) $(BINARY) </dev/null 2> >(spike-dasm > $(sim_out_name).out) | tee $(sim_out_name).log)
|
||||
|
||||
run-fast: run-asm-tests-fast run-bmark-tests-fast
|
||||
|
||||
@@ -189,10 +214,10 @@ $(output_dir)/%: $(RISCV)/riscv64-unknown-elf/share/riscv-tests/isa/% $(output_d
|
||||
ln -sf $< $@
|
||||
|
||||
$(output_dir)/%.run: $(output_dir)/% $(sim)
|
||||
(set -o pipefail && $(sim) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(PERMISSIVE_OFF) $< </dev/null | tee $<.log) && touch $@
|
||||
(set -o pipefail && $(NUMA_PREFIX) $(sim) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(PERMISSIVE_OFF) $< </dev/null | tee $<.log) && touch $@
|
||||
|
||||
$(output_dir)/%.out: $(output_dir)/% $(sim)
|
||||
(set -o pipefail && $(sim) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(VERBOSE_FLAGS) $(PERMISSIVE_OFF) $< </dev/null 2> >(spike-dasm > $@) | tee $<.log)
|
||||
(set -o pipefail && $(NUMA_PREFIX) $(sim) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(VERBOSE_FLAGS) $(PERMISSIVE_OFF) $< </dev/null 2> >(spike-dasm > $@) | tee $<.log)
|
||||
|
||||
#########################################################################################
|
||||
# include build/project specific makefrags made from the generator
|
||||
@@ -211,6 +236,13 @@ dramsim_lib = $(dramsim_dir)/libdramsim.a
|
||||
$(dramsim_lib):
|
||||
$(MAKE) -C $(dramsim_dir) $(notdir $@)
|
||||
|
||||
#########################################################################################
|
||||
# print help text
|
||||
#########################################################################################
|
||||
.PHONY: help
|
||||
help:
|
||||
@for line in $(HELP_LINES); do echo "$$line"; done
|
||||
|
||||
#########################################################################################
|
||||
# Implicit rule handling
|
||||
#########################################################################################
|
||||
|
||||
@@ -130,38 +130,8 @@ Using the JTAG Interface
|
||||
------------------------
|
||||
|
||||
The main way to use JTAG with a Rocket Chip based system is to instantiate the Debug Transfer Module (DTM)
|
||||
and configure it to use a JTAG interface (by default the DTM is setup to use the DMI interface mentioned above).
|
||||
|
||||
Creating a DTM+JTAG Config
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
First, a DTM config must be created for the system that you want to create.
|
||||
This step is similar to the DMI simulation section within the :ref:`Starting the TSI or DMI Simulation` section.
|
||||
The configuration is very similar to a DMI-based configuration. The main difference
|
||||
is the addition of the ``WithJtagDTM`` config fragment that configures the instantiated DTM to use the JTAG protocol as the
|
||||
bringup method.
|
||||
|
||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/config/RocketConfigs.scala
|
||||
:language: scala
|
||||
:start-after: DOC include start: JtagRocket
|
||||
:end-before: DOC include end: JtagRocket
|
||||
|
||||
Building a DTM+JTAG Simulator
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
After creating the config, call the ``make`` command like the following to build a simulator for your RTL:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
cd sims/verilator
|
||||
# or
|
||||
cd sims/vcs
|
||||
|
||||
make CONFIG=jtagRocketConfig
|
||||
|
||||
In this example, the simulation will use the config that you previously specified, as well as set
|
||||
the other parameters that are needed to satisfy the build system. After that point, you
|
||||
should have a JTAG enabled simulator that you can attach to using OpenOCD and GDB!
|
||||
and configure it to use a JTAG interface. The default Chipyard designs instantiate the DTM and configure it
|
||||
to use JTAG. You may attach OpenOCD and GDB to any of the default JTAG-enabled designs.
|
||||
|
||||
Debugging with JTAG
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -12,11 +12,14 @@ to verify functionality.
|
||||
Setting up Dromajo Co-simulation
|
||||
--------------------------------------
|
||||
|
||||
Dromajo co-simulation is setup to work when two config fragments are added to a BOOM config.
|
||||
First, a ``chipyard.config.WithTraceIO`` config fragment must be added so that BOOM's traceport is enabled.
|
||||
Second, a ``chipyard.iobinders.WithSimDromajoBridge`` config fragment must be added to
|
||||
connect the Dromajo co-simulator to the traceport.
|
||||
Once both config fragments are added Dromajo should be enabled.
|
||||
Dromajo co-simulation is setup to work when three config fragments are added to a BOOM config.
|
||||
|
||||
* A ``chipyard.config.WithTraceIO`` config fragment must be added so that BOOM's traceport is enabled.
|
||||
* A ``chipyard.iobinders.WithTraceIOPunchthrough`` config fragment must be added to add the ``TraceIO`` to the ``ChipTop``
|
||||
* A ``chipyard.harness.WithSimDromajoBridge`` config fragment must be added to instantiate a Dromajo cosimulator in the ``TestHarness`` and connect it to the ``ChipTop``'s ``TraceIO``
|
||||
|
||||
|
||||
Once all config fragments are added Dromajo should be enabled.
|
||||
|
||||
To build/run Dromajo with a BOOM design, run your configuration the following make commands:
|
||||
|
||||
|
||||
@@ -14,9 +14,9 @@ ChipTop/DUT
|
||||
``ChipTop`` is the top-level module that instantiates the ``System`` submodule, usually an instance of the concrete class ``DigitalTop``.
|
||||
The vast majority of the design resides in the ``System``.
|
||||
Other components that exist inside the ``ChipTop`` layer are generally IO cells, clock receivers and multiplexers, reset synchronizers, and other analog IP that needs to exist outside of the ``System``.
|
||||
The ``IOBinders`` are responsible for instantiating the IO cells and defining the test harness collateral that connects to the top-level ports.
|
||||
Most of these types of devices can be instantiated using custom ``IOBinders``, so the provided ``ChipTop`` and ``ChipTopCaughtReset`` classes are sufficient.
|
||||
However, if needed, the ``BaseChipTop`` abstract class can be extended for building more custom ``ChipTop`` designs.
|
||||
The ``IOBinders`` are responsible for instantiating the IO cells for ``ChipTop`` IO that correspond to IO of the ``System``.
|
||||
The ``HarnessBinders`` are responsible for instantiating test harness collateral that connects to the ``ChipTop`` ports.
|
||||
Most types of devices and testing collateral can be instantiated using custom ``IOBinders`` and ``HarnessBinders``.
|
||||
|
||||
|
||||
System/DigitalTop
|
||||
|
||||
@@ -1,41 +1,43 @@
|
||||
IOBinders and HarnessBinders
|
||||
============================
|
||||
|
||||
In Chipyard we use special ``Parameters`` keys, ``IOBinders`` and ``HarnessBinders`` to bridge the gap between digital system IOs and TestHarness collateral.
|
||||
|
||||
IOBinders
|
||||
=========
|
||||
|
||||
In Chipyard we use a special ``Parameters`` key, ``IOBinders`` to instantiate IO cells in the ``ChipTop`` layer and determine what modules to bind to the IOs of a ``ChipTop`` in the ``TestHarness``.
|
||||
The ``IOBinder`` functions are responsible for instantiating IO cells and IOPorts in the ``ChipTop`` layer.
|
||||
|
||||
``IOBinders`` are typically defined using the ``OverrideIOBinder`` or ``ComposeIOBinder`` macros. An ``IOBinder`` consists of a function matching ``Systems`` with a given trait that generates IO ports and IOCells, and returns a list of generated ports and cells.
|
||||
|
||||
For example, the ``WithUARTIOCells`` IOBinder will, for any ``System`` that might have UART ports (``HasPeripheryUARTModuleImp``, generate ports within the ``ChipTop`` (``ports``) as well as IOCells with the appropriate type and direction (``cells2d``). This function returns a the list of generated ports, and the list of generated IOCells. The list of generated ports is passed to the ``HarnessBinders`` such that they can be connected to ``TestHarness`` devices.
|
||||
|
||||
|
||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/IOBinders.scala
|
||||
:language: scala
|
||||
:start-after: DOC include start: IOBinders
|
||||
:end-before: DOC include end: IOBinders
|
||||
:start-after: DOC include start: WithUARTIOCells
|
||||
:end-before: DOC include end: WithUARTIOCells
|
||||
|
||||
HarnessBinders
|
||||
==============
|
||||
|
||||
This special key solves the problem of duplicating test-harnesses for each different ``System`` type.
|
||||
You could just as well create a custom harness module that attaches IOs explicitly.
|
||||
Instead, the ``IOBinders`` key provides a map from Scala traits to attachment behaviors.
|
||||
Each ``IOBinder`` returns a tuple of three values: the list of ``ChipTop`` ports created by the ``IOBinder``, the list of all IO cell modules instantiated by the ``IOBinder``, and an optional function to be called inside the test harness.
|
||||
This function is responsible for instantiating logic inside the ``TestHarness`` to appropriately drive the ``ChipTop`` IO ports created by the ``IOBinder``.
|
||||
Conveniently, because the ``IOBinder`` is generating the port, it may also use the port inside this function, which prevents the ``BaseChipTop`` code from ever needing to access the port ``val``, thus having the ``IOBinder`` house all port specific code.
|
||||
This scheme prevents the need to have two separate binder functions for each ``System`` trait.
|
||||
When creating custom ``IOBinders`` it is important to use ``suggestName`` to name ports; otherwise Chisel will raise an exception trying to name the IOs.
|
||||
The example ``IOBinders`` demonstrate this.
|
||||
The ``HarnessBinder`` functions determine what modules to bind to the IOs of a ``ChipTop`` in the ``TestHarness``. The ``HarnessBinder`` interface is designed to be reused across various simulation/implementation modes, enabling decoupling of the target design from simulation and testing concerns.
|
||||
|
||||
As an example, the ``WithGPIOTiedOff`` IOBinder creates IO cells for the GPIO module(s) instantiated in the ``System``, then punches out new ``Analog`` ports for each one.
|
||||
The test harness simply ties these off, but additional logic could be inserted to perform some kind of test in the ``TestHarness``.
|
||||
* For SW RTL or GL simulations, the default set of ``HarnessBinders`` instantiate software-simulated models of various devices, for example external memory or UART, and connect those models to the IOs of the ``ChipTop``.
|
||||
* For FireSim simulations, FireSim-specific ``HarnessBinders`` instantiate ``Bridges``, which faciliate cycle-accurate simulation across the simulated chip's IOs. See the FireSim documentation for more details.
|
||||
* In the future, a Chipyard FPGA prototyping flow may use ``HarnessBinders`` to connect ``ChipTop`` IOs to other devices or IOs in the FPGA harness.
|
||||
|
||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/IOBinders.scala
|
||||
Like ``IOBinders``, ``HarnessBinders`` are defined using macros (``OverrideHarnessBinder, ComposeHarnessBinder``), and match ``Systems`` with a given trait. However, ``HarnessBinders`` are also passed a reference to the ``TestHarness`` (``th: HasHarnessSignalReferences``) and the list of ports generated by the corresponding ``IOBinder`` (``ports: Seq[Data]``).
|
||||
|
||||
For exmaple, the ``WithUARTAdapter`` will connect the UART SW display adapter to the ports generated by the ``WithUARTIOCells`` described earlier, if those ports are present.
|
||||
|
||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/HarnessBinders.scala
|
||||
:language: scala
|
||||
:start-after: DOC include start: WithGPIOTiedOff
|
||||
:end-before: DOC include end: WithGPIOTiedOff
|
||||
:start-after: DOC include start: WithUARTAdapter
|
||||
:end-before: DOC include end: WithUARTAdapter
|
||||
|
||||
The ``IOBinder`` and ``HarnessBinder`` system is designed to enable decoupling of concerns between the target design and the simulation system.
|
||||
|
||||
``IOBinders`` also do not need to create ports. Some ``IOBinders`` can simply insert circuitry inside the ``ChipTop`` layer.
|
||||
For example, the ``WithSimAXIMemTiedOff`` IOBinder specifies that any ``System`` which matches ``CanHaveMasterAXI4MemPortModuleImp`` will have a ``SimAXIMem`` connected inside ``ChipTop``.
|
||||
For a given set of chip IOs, there may be not only multiple simulation platforms ("harnesses", so-to-speak), but also multiple simulation strategies. For example, the choice of whether to connect the backing AXI4 memory port to an accurate DRAM model (``SimDRAM``) or a simple simulated memory model (``SimAXIMem``) is isolated in ``HarnessBinders``, and does not affect target RTL generation.
|
||||
|
||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/IOBinders.scala
|
||||
:language: scala
|
||||
:start-after: DOC include start: WithSimAXIMem
|
||||
:end-before: DOC include end: WithSimAXIMem
|
||||
|
||||
These classes are all ``Config`` objects, which can be mixed into the configs to specify IO connection behaviors.
|
||||
|
||||
There are two macros for generating these ``Config``s. ``OverrideIOBinder`` overrides any existing behaviors set for a particular IO in the ``Config`` object. This macro is frequently used because typically top-level IOs drive or are driven by only one source, so a composition of ``IOBinders`` does not make sense. The ``ComposeIOBinder`` macro provides the functionality of not overriding existing behaviors.
|
||||
Similarly, for a given simulation platform and strategy, there may be multiple strategies for generating the chip IOs. This target-design configuration is isolated in the ``IOBinders``.
|
||||
|
||||
@@ -40,8 +40,7 @@ For a proprietry VCS simulation, enter the ``sims/vcs`` directory
|
||||
# Enter VCS directory
|
||||
cd sims/vcs
|
||||
|
||||
|
||||
.. _sim-default:
|
||||
.. _sw-sim-help:
|
||||
|
||||
Simulating The Default Example
|
||||
-------------------------------
|
||||
@@ -82,6 +81,22 @@ For example:
|
||||
|
||||
.. _sw-sim-custom:
|
||||
|
||||
Makefile Variables and Commands
|
||||
-------------------------------
|
||||
You can get a list of useful Makefile variables and commands available from the Verilator or VCS directories. simply run ``make help``:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
# Enter Verilator directory
|
||||
cd sims/verilator
|
||||
make help
|
||||
|
||||
# Enter VCS directory
|
||||
cd sims/vcs
|
||||
make help
|
||||
|
||||
.. _sim-default:
|
||||
|
||||
Simulating A Custom Project
|
||||
-------------------------------
|
||||
|
||||
@@ -167,3 +182,18 @@ An open-source vcd-capable waveform viewer is `GTKWave <http://gtkwave.sourcefor
|
||||
For a VCS simulation, this will generate a vpd file (this is a proprietary waveform representation format used by Synopsys) that can be loaded to vpd-supported waveform viewers.
|
||||
If you have Synopsys licenses, we recommend using the DVE waveform viewer.
|
||||
|
||||
.. _sw-sim-verilator-opts:
|
||||
|
||||
Additional Verilator Options
|
||||
-------------------------------
|
||||
|
||||
When building the verilator simulator there are some additional options:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
make VERILATOR_THREADS=8 NUMACTL=1
|
||||
|
||||
The ``VERILATOR_THREADS=<num>`` option enables the compiled Verilator simulator to use ``<num>`` parallel threads.
|
||||
On a multi-socket machine, you will want to make sure all threads are on the same socket by using ``NUMACTL=1`` to enable ``numactl``.
|
||||
By enabling this, you will use Chipyard's ``numa_prefix`` wrapper, which is a simple wrapper around ``numactl`` that runs your verilated simulator like this: ``$(numa_prefix) ./simulator-<name> <simulator-args>``.
|
||||
Note that both these flags are mutually exclusive, you can use either independently (though it makes sense to use ``NUMACTL`` just with ``VERILATOR_THREADS=8`` during a Verilator simulation).
|
||||
|
||||
Submodule generators/ariane updated: 0ed9107485...3a2eed602f
Submodule generators/boom updated: 859c60553b...dc22cacf71
@@ -4,118 +4,59 @@ import chisel3._
|
||||
|
||||
import scala.collection.mutable.{ArrayBuffer}
|
||||
|
||||
import freechips.rocketchip.prci.{ClockGroupIdentityNode, ClockSinkParameters, ClockSinkNode, ClockGroup}
|
||||
import freechips.rocketchip.subsystem.{BaseSubsystem, SubsystemDriveAsyncClockGroupsKey}
|
||||
import freechips.rocketchip.config.{Parameters, Field}
|
||||
import freechips.rocketchip.diplomacy.{LazyModule}
|
||||
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, LazyRawModuleImp, LazyModuleImpLike}
|
||||
import freechips.rocketchip.util.{ResetCatchAndSync}
|
||||
import chipyard.config.ConfigValName._
|
||||
import chipyard.iobinders.{IOBinders, TestHarnessFunction, IOBinderTuple}
|
||||
import chipyard.iobinders._
|
||||
|
||||
import barstools.iocell.chisel._
|
||||
|
||||
case object BuildSystem extends Field[Parameters => LazyModule]((p: Parameters) => LazyModule(new DigitalTop()(p)))
|
||||
|
||||
/**
|
||||
* Chipyard provides three baseline, top-level reset schemes, set using the
|
||||
* [[GlobalResetSchemeKey]] in a Parameters instance. These are:
|
||||
*
|
||||
* 1) Synchronous: The input coming to the chip is synchronous to the provided
|
||||
* clocks and will be used without modification as a synchronous reset.
|
||||
* This is safe only for use in FireSim and SW simulation.
|
||||
*
|
||||
* 2) Asynchronous: The input reset is asynchronous to the input clock, but it
|
||||
* is caught and synchronized to that clock before it is dissemenated.
|
||||
* Thus, downsteam modules will be emitted with synchronously reset state
|
||||
* elements.
|
||||
*
|
||||
* 3) Asynchronous Full: The input reset is asynchronous to the input clock,
|
||||
* and is used globally as an async reset. Downstream modules will be emitted
|
||||
* with asynchronously reset state elements.
|
||||
*
|
||||
*/
|
||||
sealed trait GlobalResetScheme {
|
||||
def pinIsAsync: Boolean
|
||||
}
|
||||
sealed trait HasAsyncInput { self: GlobalResetScheme =>
|
||||
def pinIsAsync = true
|
||||
}
|
||||
|
||||
sealed trait HasSyncInput { self: GlobalResetScheme =>
|
||||
def pinIsAsync = false
|
||||
}
|
||||
|
||||
case object GlobalResetSynchronous extends GlobalResetScheme with HasSyncInput
|
||||
case object GlobalResetAsynchronous extends GlobalResetScheme with HasAsyncInput
|
||||
case object GlobalResetAsynchronousFull extends GlobalResetScheme with HasAsyncInput
|
||||
case object GlobalResetSchemeKey extends Field[GlobalResetScheme](GlobalResetSynchronous)
|
||||
case object BuildSystem extends Field[Parameters => LazyModule]((p: Parameters) => new DigitalTop()(p))
|
||||
|
||||
|
||||
/**
|
||||
* The base class used for building chips. This constructor instantiates a module specified by the BuildSystem parameter,
|
||||
* named "system", which is an instance of DigitalTop by default. The default clock and reset for "system" are set by two
|
||||
* wires, "systemClock" and "systemReset", which are intended to be driven by traits mixed-in with this base class.
|
||||
* named "system", which is an instance of DigitalTop by default. The diplomatic clocks of System, as well as its implicit clock,
|
||||
* is aggregated into the clockGroupNode. The parameterized functions controlled by ClockingSchemeKey and GlobalResetSchemeKey
|
||||
* drive clock and reset generation
|
||||
*/
|
||||
abstract class BaseChipTop()(implicit val p: Parameters) extends RawModule with HasTestHarnessFunctions {
|
||||
|
||||
class ChipTop(implicit p: Parameters) extends LazyModule with HasTestHarnessFunctions {
|
||||
// A publicly accessible list of IO cells (useful for a floorplanning tool, for example)
|
||||
val iocells = ArrayBuffer.empty[IOCell]
|
||||
// A list of functions to call in the test harness
|
||||
val harnessFunctions = ArrayBuffer.empty[TestHarnessFunction]
|
||||
// The system clock
|
||||
// These are given so that IOCell can use DataMirror and generate ports with
|
||||
// the right flow (Input/Output)
|
||||
val systemClock = Wire(Input(Clock()))
|
||||
val systemReset = Wire(Input(Reset()))
|
||||
|
||||
// The system module specified by BuildSystem
|
||||
val lSystem = p(BuildSystem)(p).suggestName("system")
|
||||
val system = withClockAndReset(systemClock, systemReset) { Module(lSystem.module) }
|
||||
val lazySystem = LazyModule(p(BuildSystem)(p)).suggestName("system")
|
||||
|
||||
// Call all of the IOBinders and provide them with a default clock and reset
|
||||
withClockAndReset(systemClock, systemReset) {
|
||||
// Call each IOBinder on both the lazyModule instance and the module
|
||||
// instance. Generally, an IOBinder PF should only be defined on one, so
|
||||
// this should not lead to two invocations.
|
||||
val (_ports, _iocells, _harnessFunctions) = p(IOBinders).values.flatMap(f => f(lSystem) ++ f(system)).unzip3
|
||||
// The implicitClockSinkNode provides the implicit clock and reset for the System
|
||||
val implicitClockSinkNode = ClockSinkNode(Seq(ClockSinkParameters()))
|
||||
|
||||
// Generate Clocks and Reset
|
||||
p(ClockingSchemeKey)(this)
|
||||
|
||||
// NOTE: Making this a LazyRawModule is moderately dangerous, as anonymous children
|
||||
// of ChipTop (ex: ClockGroup) do not receive clock or reset.
|
||||
// However. anonymous children of ChipTop should not need an implicit Clock or Reset
|
||||
// anyways, they probably need to be explicitly clocked.
|
||||
lazy val module: LazyModuleImpLike = new LazyRawModuleImp(this) {
|
||||
// These become the implicit clock and reset to the System
|
||||
val implicit_clock = implicitClockSinkNode.in.head._1.clock
|
||||
val implicit_reset = implicitClockSinkNode.in.head._1.reset
|
||||
|
||||
|
||||
// Note: IOBinders cannot rely on the implicit clock/reset, as this is a LazyRawModuleImp
|
||||
val (_ports, _iocells, _portMap) = ApplyIOBinders(lazySystem, p(IOBinders))
|
||||
// We ignore _ports for now...
|
||||
iocells ++= _iocells.flatten
|
||||
harnessFunctions ++= _harnessFunctions.flatten
|
||||
}
|
||||
iocells ++= _iocells
|
||||
portMap ++= _portMap
|
||||
|
||||
// Connect the implicit clock/reset, if present
|
||||
lazySystem.module match { case l: LazyModuleImp => {
|
||||
l.clock := implicit_clock
|
||||
l.reset := implicit_reset
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple clock and reset implementation that punches out clock and reset ports with the same
|
||||
* names as the implicit clock and reset for standard Module classes. Three basic reset schemes
|
||||
* are provided. See [[GlobalResetScheme]].
|
||||
*/
|
||||
trait HasChipTopSimpleClockAndReset { this: BaseChipTop =>
|
||||
|
||||
val (clock, systemClockIO) = IOCell.generateIOFromSignal(systemClock, Some("iocell_clock"))
|
||||
val (reset, systemResetIO) = p(GlobalResetSchemeKey) match {
|
||||
case GlobalResetSynchronous =>
|
||||
IOCell.generateIOFromSignal(systemReset, Some("iocell_reset"))
|
||||
case GlobalResetAsynchronousFull =>
|
||||
IOCell.generateIOFromSignal(systemReset, Some("iocell_reset"), abstractResetAsAsync = true)
|
||||
case GlobalResetAsynchronous =>
|
||||
val asyncResetCore = Wire(Input(AsyncReset()))
|
||||
systemReset := ResetCatchAndSync(systemClock, asyncResetCore.asBool)
|
||||
IOCell.generateIOFromSignal(asyncResetCore, Some("iocell_reset"), abstractResetAsAsync = true)
|
||||
}
|
||||
|
||||
iocells ++= systemClockIO
|
||||
iocells ++= systemResetIO
|
||||
|
||||
// Add a TestHarnessFunction that connects clock and reset
|
||||
harnessFunctions += { (th: TestHarness) => {
|
||||
// Connect clock; it's not done implicitly with RawModule
|
||||
clock := th.clock
|
||||
// Connect reset; it's not done implicitly with RawModule
|
||||
// Note that we need to use dutReset, not harnessReset
|
||||
reset := th.dutReset
|
||||
Nil
|
||||
} }
|
||||
|
||||
}
|
||||
|
||||
class ChipTop()(implicit p: Parameters) extends BaseChipTop()(p)
|
||||
with HasChipTopSimpleClockAndReset
|
||||
|
||||
175
generators/chipyard/src/main/scala/Clocks.scala
Normal file
175
generators/chipyard/src/main/scala/Clocks.scala
Normal file
@@ -0,0 +1,175 @@
|
||||
package chipyard
|
||||
|
||||
import chisel3._
|
||||
|
||||
import scala.collection.mutable.{ArrayBuffer}
|
||||
|
||||
import freechips.rocketchip.prci._
|
||||
import freechips.rocketchip.subsystem.{BaseSubsystem, SubsystemDriveAsyncClockGroupsKey}
|
||||
import freechips.rocketchip.config.{Parameters, Field}
|
||||
import freechips.rocketchip.diplomacy.{OutwardNodeHandle, InModuleBody, LazyModule}
|
||||
import freechips.rocketchip.util.{ResetCatchAndSync, Pow2ClockDivider}
|
||||
|
||||
import barstools.iocell.chisel._
|
||||
|
||||
/**
|
||||
* Chipyard provides three baseline, top-level reset schemes, set using the
|
||||
* [[GlobalResetSchemeKey]] in a Parameters instance. These are:
|
||||
*
|
||||
* 1) Synchronous: The input coming to the chip is synchronous to the provided
|
||||
* clocks and will be used without modification as a synchronous reset.
|
||||
* This is safe only for use in FireSim and SW simulation.
|
||||
*
|
||||
* 2) Asynchronous: The input reset is asynchronous to the input clock, but it
|
||||
* is caught and synchronized to that clock before it is dissemenated.
|
||||
* Thus, downsteam modules will be emitted with synchronously reset state
|
||||
* elements.
|
||||
*
|
||||
* 3) Asynchronous Full: The input reset is asynchronous to the input clock,
|
||||
* and is used globally as an async reset. Downstream modules will be emitted
|
||||
* with asynchronously reset state elements.
|
||||
*
|
||||
*/
|
||||
sealed trait GlobalResetScheme {
|
||||
def pinIsAsync: Boolean
|
||||
}
|
||||
sealed trait HasAsyncInput { self: GlobalResetScheme =>
|
||||
def pinIsAsync = true
|
||||
}
|
||||
|
||||
sealed trait HasSyncInput { self: GlobalResetScheme =>
|
||||
def pinIsAsync = false
|
||||
}
|
||||
|
||||
case object GlobalResetSynchronous extends GlobalResetScheme with HasSyncInput
|
||||
case object GlobalResetAsynchronous extends GlobalResetScheme with HasAsyncInput
|
||||
case object GlobalResetAsynchronousFull extends GlobalResetScheme with HasAsyncInput
|
||||
case object GlobalResetSchemeKey extends Field[GlobalResetScheme](GlobalResetSynchronous)
|
||||
|
||||
/**
|
||||
* A simple reset implementation that punches out reset ports
|
||||
* for standard Module classes. Three basic reset schemes
|
||||
* are provided. See [[GlobalResetScheme]].
|
||||
*/
|
||||
object GenerateReset {
|
||||
def apply(chiptop: ChipTop, clock: Clock): Reset = {
|
||||
implicit val p = chiptop.p
|
||||
// this needs directionality so generateIOFromSignal works
|
||||
val reset_wire = Wire(Input(Reset()))
|
||||
val (reset_io, resetIOCell) = p(GlobalResetSchemeKey) match {
|
||||
case GlobalResetSynchronous =>
|
||||
IOCell.generateIOFromSignal(reset_wire, "reset")
|
||||
case GlobalResetAsynchronousFull =>
|
||||
IOCell.generateIOFromSignal(reset_wire, "reset", abstractResetAsAsync = true)
|
||||
case GlobalResetAsynchronous => {
|
||||
val async_reset_wire = Wire(Input(AsyncReset()))
|
||||
reset_wire := ResetCatchAndSync(clock, async_reset_wire.asBool())
|
||||
IOCell.generateIOFromSignal(async_reset_wire, "reset", abstractResetAsAsync = true)
|
||||
}
|
||||
}
|
||||
chiptop.iocells ++= resetIOCell
|
||||
chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => {
|
||||
reset_io := th.dutReset
|
||||
Nil
|
||||
})
|
||||
reset_wire
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
case object ClockingSchemeKey extends Field[ChipTop => Unit](ClockingSchemeGenerators.harnessClock)
|
||||
|
||||
|
||||
|
||||
object ClockingSchemeGenerators {
|
||||
// A simple clock provider, for testing
|
||||
val harnessClock: ChipTop => Unit = { chiptop =>
|
||||
implicit val p = chiptop.p
|
||||
|
||||
val implicitClockSourceNode = ClockSourceNode(Seq(ClockSourceParameters()))
|
||||
chiptop.implicitClockSinkNode := implicitClockSourceNode
|
||||
|
||||
// Drive the diplomaticclock graph of the DigitalTop (if present)
|
||||
val simpleClockGroupSourceNode = chiptop.lazySystem match {
|
||||
case l: BaseSubsystem if (p(SubsystemDriveAsyncClockGroupsKey).isEmpty) => {
|
||||
val n = ClockGroupSourceNode(Seq(ClockGroupSourceParameters()))
|
||||
l.asyncClockGroupsNode := n
|
||||
Some(n)
|
||||
}
|
||||
case _ => None
|
||||
}
|
||||
|
||||
InModuleBody {
|
||||
//this needs directionality so generateIOFromSignal works
|
||||
val clock_wire = Wire(Input(Clock()))
|
||||
val reset_wire = GenerateReset(chiptop, clock_wire)
|
||||
val (clock_io, clockIOCell) = IOCell.generateIOFromSignal(clock_wire, "clock")
|
||||
chiptop.iocells ++= clockIOCell
|
||||
|
||||
implicitClockSourceNode.out.unzip._1.map { o =>
|
||||
o.clock := clock_wire
|
||||
o.reset := reset_wire
|
||||
}
|
||||
|
||||
simpleClockGroupSourceNode.map { n => n.out.unzip._1.map { out: ClockGroupBundle =>
|
||||
out.member.data.foreach { o =>
|
||||
o.clock := clock_wire
|
||||
o.reset := reset_wire
|
||||
}
|
||||
}}
|
||||
|
||||
chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => {
|
||||
clock_io := th.harnessClock
|
||||
Nil
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
val harnessDividedClock: ChipTop => Unit = { chiptop =>
|
||||
implicit val p = chiptop.p
|
||||
|
||||
require(false, "Divided clock is broken until we fix passing onchip clocks to TestHarness objects")
|
||||
|
||||
val implicitClockSourceNode = ClockSourceNode(Seq(ClockSourceParameters()))
|
||||
chiptop.implicitClockSinkNode := implicitClockSourceNode
|
||||
|
||||
val simpleClockGroupSourceNode = chiptop.lazySystem match {
|
||||
case l: BaseSubsystem if (p(SubsystemDriveAsyncClockGroupsKey).isEmpty) => {
|
||||
val n = ClockGroupSourceNode(Seq(ClockGroupSourceParameters()))
|
||||
l.asyncClockGroupsNode := n
|
||||
Some(n)
|
||||
}
|
||||
case _ => throw new Exception("Harness multiclock assumes BaseSubsystem")
|
||||
}
|
||||
|
||||
InModuleBody {
|
||||
// this needs directionality so generateIOFromSignal works
|
||||
val clock_wire = Wire(Input(Clock()))
|
||||
val reset_wire = GenerateReset(chiptop, clock_wire)
|
||||
val (clock_io, clockIOCell) = IOCell.generateIOFromSignal(clock_wire, "clock")
|
||||
chiptop.iocells ++= clockIOCell
|
||||
val div_clock = Pow2ClockDivider(clock_wire, 2)
|
||||
|
||||
implicitClockSourceNode.out.unzip._1.map { o =>
|
||||
o.clock := div_clock
|
||||
o.reset := reset_wire
|
||||
}
|
||||
|
||||
simpleClockGroupSourceNode.map { n => n.out.unzip._1.map { out: ClockGroupBundle =>
|
||||
out.member.elements.map { case (name, data) =>
|
||||
// This is mega hacks, how are you actually supposed to do this?
|
||||
data.clock := (if (name.contains("core")) clock_wire else div_clock)
|
||||
data.reset := reset_wire
|
||||
}
|
||||
}}
|
||||
|
||||
chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => {
|
||||
clock_io := th.harnessClock
|
||||
Nil
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,13 @@ import chisel3.util.{log2Up}
|
||||
import freechips.rocketchip.config.{Field, Parameters, Config}
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.diplomacy.{LazyModule, ValName}
|
||||
import freechips.rocketchip.devices.tilelink.BootROMParams
|
||||
import freechips.rocketchip.devices.debug.{Debug}
|
||||
import freechips.rocketchip.devices.tilelink.{BootROMLocated}
|
||||
import freechips.rocketchip.devices.debug.{Debug, ExportDebug, DebugModuleKey, DMI}
|
||||
import freechips.rocketchip.groundtest.{GroundTestSubsystem}
|
||||
import freechips.rocketchip.tile._
|
||||
import freechips.rocketchip.rocket.{RocketCoreParams, MulDivParams, DCacheParams, ICacheParams}
|
||||
import freechips.rocketchip.util.{AsyncResetReg}
|
||||
import freechips.rocketchip.prci._
|
||||
|
||||
import testchipip._
|
||||
import tracegen.{TraceGenSystem}
|
||||
@@ -25,23 +26,15 @@ import sifive.blocks.devices.gpio._
|
||||
import sifive.blocks.devices.uart._
|
||||
import sifive.blocks.devices.spi._
|
||||
|
||||
import chipyard.{BuildTop, BuildSystem, TestSuitesKey, TestSuiteHelper}
|
||||
import chipyard.{BuildTop, BuildSystem, ClockingSchemeGenerators, ClockingSchemeKey, TestSuitesKey, TestSuiteHelper}
|
||||
|
||||
/**
|
||||
* TODO: Why do we need this?
|
||||
*/
|
||||
object ConfigValName {
|
||||
implicit val valName = ValName("TestHarness")
|
||||
}
|
||||
import ConfigValName._
|
||||
|
||||
// -----------------------
|
||||
// Common Config Fragments
|
||||
// -----------------------
|
||||
|
||||
class WithBootROM extends Config((site, here, up) => {
|
||||
case BootROMParams => BootROMParams(
|
||||
contentFileName = s"./bootrom/bootrom.rv${site(XLen)}.img")
|
||||
case BootROMLocated(x) => up(BootROMLocated(x), site).map(_.copy(contentFileName = s"./bootrom/bootrom.rv${site(XLen)}.img"))
|
||||
})
|
||||
|
||||
// DOC include start: gpio config fragment
|
||||
@@ -73,7 +66,7 @@ class WithL2TLBs(entries: Int) extends Config((site, here, up) => {
|
||||
})
|
||||
|
||||
class WithTracegenSystem extends Config((site, here, up) => {
|
||||
case BuildSystem => (p: Parameters) => LazyModule(new TraceGenSystem()(p))
|
||||
case BuildSystem => (p: Parameters) => new TraceGenSystem()(p)
|
||||
})
|
||||
|
||||
/**
|
||||
@@ -105,7 +98,8 @@ class WithMultiRoCCHwacha(harts: Int*) extends Config(
|
||||
case MultiRoCCKey => {
|
||||
up(MultiRoCCKey, site) ++ harts.distinct.map{ i =>
|
||||
(i -> Seq((p: Parameters) => {
|
||||
LazyModule(new Hwacha()(p)).suggestName("hwacha")
|
||||
val hwacha = LazyModule(new Hwacha()(p))
|
||||
hwacha
|
||||
}))
|
||||
}
|
||||
}
|
||||
@@ -156,3 +150,23 @@ class WithHwachaTest extends Config((site, here, up) => {
|
||||
"SRC_EXTENSION = $(base_dir)/hwacha/$(src_path)/*.scala" + "\nDISASM_EXTENSION = --extension=hwacha"
|
||||
}
|
||||
})
|
||||
|
||||
// The default RocketChip BaseSubsystem drives its diplomatic clock graph
|
||||
// with the implicit clocks of Subsystem. Don't do that, instead we extend
|
||||
// the diplomacy graph upwards into the ChipTop, where we connect it to
|
||||
// our clock drivers
|
||||
class WithNoSubsystemDrivenClocks extends Config((site, here, up) => {
|
||||
case SubsystemDriveAsyncClockGroupsKey => None
|
||||
})
|
||||
|
||||
class WithTileDividedClock extends Config((site, here, up) => {
|
||||
case ClockingSchemeKey => ClockingSchemeGenerators.harnessDividedClock
|
||||
})
|
||||
|
||||
class WithDMIDTM extends Config((site, here, up) => {
|
||||
case ExportDebug => up(ExportDebug, site).copy(protocols = Set(DMI))
|
||||
})
|
||||
|
||||
class WithNoDebug extends Config((site, here, up) => {
|
||||
case DebugModuleKey => None
|
||||
})
|
||||
|
||||
@@ -16,7 +16,7 @@ class DigitalTop(implicit p: Parameters) extends ChipyardSystem
|
||||
with testchipip.CanHaveTraceIO // Enables optionally adding trace IO
|
||||
with testchipip.CanHaveBackingScratchpad // Enables optionally adding a backing scratchpad
|
||||
with testchipip.CanHavePeripheryBlockDevice // Enables optionally adding the block device
|
||||
with testchipip.CanHavePeripherySerial // Enables optionally adding the TSI serial-adapter and port
|
||||
with testchipip.CanHavePeripheryTLSerial // Enables optionally adding the backing memory and serial adapter
|
||||
with sifive.blocks.devices.uart.HasPeripheryUART // Enables optionally adding the sifive UART
|
||||
with sifive.blocks.devices.gpio.HasPeripheryGPIO // Enables optionally adding the sifive GPIOs
|
||||
with sifive.blocks.devices.spi.HasPeripherySPIFlash // Enables optionally adding the sifive SPI flash controller
|
||||
@@ -32,12 +32,9 @@ class DigitalTop(implicit p: Parameters) extends ChipyardSystem
|
||||
|
||||
class DigitalTopModule[+L <: DigitalTop](l: L) extends ChipyardSystemModule(l)
|
||||
with testchipip.CanHaveTraceIOModuleImp
|
||||
with testchipip.CanHavePeripheryBlockDeviceModuleImp
|
||||
with testchipip.CanHavePeripherySerialModuleImp
|
||||
with sifive.blocks.devices.uart.HasPeripheryUARTModuleImp
|
||||
with sifive.blocks.devices.gpio.HasPeripheryGPIOModuleImp
|
||||
with sifive.blocks.devices.spi.HasPeripherySPIFlashModuleImp
|
||||
with icenet.CanHavePeripheryIceNICModuleImp
|
||||
with chipyard.example.CanHavePeripheryGCDModuleImp
|
||||
with freechips.rocketchip.util.DontTouch
|
||||
// DOC include end: DigitalTop
|
||||
|
||||
259
generators/chipyard/src/main/scala/HarnessBinders.scala
Normal file
259
generators/chipyard/src/main/scala/HarnessBinders.scala
Normal file
@@ -0,0 +1,259 @@
|
||||
package chipyard.harness
|
||||
|
||||
import chisel3._
|
||||
import chisel3.experimental.{Analog}
|
||||
|
||||
import freechips.rocketchip.config.{Field, Config, Parameters}
|
||||
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike}
|
||||
import freechips.rocketchip.amba.axi4.{AXI4Bundle, AXI4SlaveNode, AXI4MasterNode, AXI4EdgeParameters}
|
||||
import freechips.rocketchip.devices.debug._
|
||||
import freechips.rocketchip.jtag.{JTAGIO}
|
||||
import freechips.rocketchip.system.{SimAXIMem}
|
||||
import freechips.rocketchip.subsystem._
|
||||
|
||||
import sifive.blocks.devices.gpio._
|
||||
import sifive.blocks.devices.uart._
|
||||
import sifive.blocks.devices.spi._
|
||||
|
||||
import barstools.iocell.chisel._
|
||||
|
||||
import testchipip._
|
||||
|
||||
import chipyard.HasHarnessSignalReferences
|
||||
import chipyard.iobinders.GetSystemParameters
|
||||
|
||||
import tracegen.{TraceGenSystemModuleImp}
|
||||
import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly}
|
||||
|
||||
import scala.reflect.{ClassTag}
|
||||
|
||||
case object HarnessBinders extends Field[Map[String, (Any, HasHarnessSignalReferences, Seq[Data]) => Seq[Any]]](
|
||||
Map[String, (Any, HasHarnessSignalReferences, Seq[Data]) => Seq[Any]]().withDefaultValue((t: Any, th: HasHarnessSignalReferences, d: Seq[Data]) => Nil)
|
||||
)
|
||||
|
||||
|
||||
object ApplyHarnessBinders {
|
||||
def apply(th: HasHarnessSignalReferences, sys: LazyModule, map: Map[String, (Any, HasHarnessSignalReferences, Seq[Data]) => Seq[Any]], portMap: Map[String, Seq[Data]]) = {
|
||||
val pm = portMap.withDefaultValue(Nil)
|
||||
map.map { case (s, f) => f(sys, th, pm(s)) ++ f(sys.module, th, pm(s)) }
|
||||
}
|
||||
}
|
||||
|
||||
class OverrideHarnessBinder[T, S <: Data](fn: => (T, HasHarnessSignalReferences, Seq[S]) => Seq[Any])(implicit tag: ClassTag[T], ptag: ClassTag[S]) extends Config((site, here, up) => {
|
||||
case HarnessBinders => up(HarnessBinders, site) + (tag.runtimeClass.toString ->
|
||||
((t: Any, th: HasHarnessSignalReferences, ports: Seq[Data]) => {
|
||||
val pts = ports.collect({case p: S => p})
|
||||
require (pts.length == ports.length, s"Port type mismatch between IOBinder and HarnessBinder: ${ptag}")
|
||||
t match {
|
||||
case system: T => fn(system, th, pts)
|
||||
case _ => Nil
|
||||
}
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
class ComposeHarnessBinder[T, S <: Data](fn: => (T, HasHarnessSignalReferences, Seq[S]) => Seq[Any])(implicit tag: ClassTag[T], ptag: ClassTag[S]) extends Config((site, here, up) => {
|
||||
case HarnessBinders => up(HarnessBinders, site) + (tag.runtimeClass.toString ->
|
||||
((t: Any, th: HasHarnessSignalReferences, ports: Seq[Data]) => {
|
||||
val pts = ports.collect({case p: S => p})
|
||||
require (pts.length == ports.length, s"Port type mismatch between IOBinder and HarnessBinder: ${ptag}")
|
||||
t match {
|
||||
case system: T => up(HarnessBinders, site)(tag.runtimeClass.toString)(system, th, pts) ++ fn(system, th, pts)
|
||||
case _ => Nil
|
||||
}
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
class WithGPIOTiedOff extends OverrideHarnessBinder({
|
||||
(system: HasPeripheryGPIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[Analog]) => {
|
||||
ports.foreach { _ <> AnalogConst(0) }
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
// DOC include start: WithUARTAdapter
|
||||
class WithUARTAdapter extends OverrideHarnessBinder({
|
||||
(system: HasPeripheryUARTModuleImp, th: HasHarnessSignalReferences, ports: Seq[UARTPortIO]) => {
|
||||
UARTAdapter.connect(ports)(system.p)
|
||||
Nil
|
||||
}
|
||||
})
|
||||
// DOC include end: WithUARTAdapter
|
||||
|
||||
class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideHarnessBinder({
|
||||
(system: HasPeripherySPIFlashModuleImp, th: HasHarnessSignalReferences, ports: Seq[SPIChipIO]) => {
|
||||
SimSPIFlashModel.connect(ports, th.harnessReset, rdOnly)(system.p)
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithSimBlockDevice extends OverrideHarnessBinder({
|
||||
(system: CanHavePeripheryBlockDevice, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => {
|
||||
implicit val p: Parameters = GetSystemParameters(system)
|
||||
ports.map { b => SimBlockDevice.connect(b.clock, th.harnessReset.asBool, Some(b.bits)) }
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithBlockDeviceModel extends OverrideHarnessBinder({
|
||||
(system: CanHavePeripheryBlockDevice, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => {
|
||||
implicit val p: Parameters = GetSystemParameters(system)
|
||||
ports.map { b => withClockAndReset(b.clock, th.harnessReset) { BlockDeviceModel.connect(Some(b.bits)) } }
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithLoopbackNIC extends OverrideHarnessBinder({
|
||||
(system: CanHavePeripheryIceNIC, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => {
|
||||
implicit val p: Parameters = GetSystemParameters(system)
|
||||
ports.map { n =>
|
||||
withClockAndReset(n.clock, th.harnessReset) {
|
||||
NicLoopback.connect(Some(n.bits), p(NICKey))
|
||||
}
|
||||
}
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithSimNetwork extends OverrideHarnessBinder({
|
||||
(system: CanHavePeripheryIceNIC, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => {
|
||||
implicit val p: Parameters = GetSystemParameters(system)
|
||||
ports.map { n => SimNetwork.connect(Some(n.bits), n.clock, th.harnessReset.asBool) }
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithSimAXIMem extends OverrideHarnessBinder({
|
||||
(system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => {
|
||||
val p: Parameters = chipyard.iobinders.GetSystemParameters(system)
|
||||
(ports zip system.memAXI4Node.edges.in).map { case (port, edge) =>
|
||||
val mem = LazyModule(new SimAXIMem(edge, size=p(ExtMem).get.master.size)(p))
|
||||
withClockAndReset(port.clock, th.harnessReset) {
|
||||
Module(mem.module).suggestName("mem")
|
||||
}
|
||||
mem.io_axi4.head <> port.bits
|
||||
}
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithBlackBoxSimMem extends OverrideHarnessBinder({
|
||||
(system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => {
|
||||
val p: Parameters = chipyard.iobinders.GetSystemParameters(system)
|
||||
(ports zip system.memAXI4Node.edges.in).map { case (port, edge) =>
|
||||
val memSize = p(ExtMem).get.master.size
|
||||
val lineSize = p(CacheBlockBytes)
|
||||
val mem = Module(new SimDRAM(memSize, lineSize, edge.bundle)).suggestName("simdram")
|
||||
mem.io.axi <> port.bits
|
||||
mem.io.clock := port.clock
|
||||
mem.io.reset := th.harnessReset
|
||||
}
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithSimAXIMMIO extends OverrideHarnessBinder({
|
||||
(system: CanHaveMasterAXI4MMIOPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => {
|
||||
val p: Parameters = chipyard.iobinders.GetSystemParameters(system)
|
||||
(ports zip system.mmioAXI4Node.edges.in).map { case (port, edge) =>
|
||||
val mmio_mem = LazyModule(new SimAXIMem(edge, size = p(ExtBus).get.size)(p))
|
||||
withClockAndReset(port.clock, th.harnessReset) {
|
||||
Module(mmio_mem.module).suggestName("mmio_mem")
|
||||
}
|
||||
mmio_mem.io_axi4.head <> port.bits
|
||||
}
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithTieOffInterrupts extends OverrideHarnessBinder({
|
||||
(system: HasExtInterruptsModuleImp, th: HasHarnessSignalReferences, ports: Seq[UInt]) => {
|
||||
ports.foreach { _ := 0.U }
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithTieOffL2FBusAXI extends OverrideHarnessBinder({
|
||||
(system: CanHaveSlaveAXI4Port, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => {
|
||||
ports.foreach({ p => p := DontCare; p.bits.tieoff() })
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithSimDebug extends OverrideHarnessBinder({
|
||||
(system: HasPeripheryDebugModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => {
|
||||
ports.map {
|
||||
case d: ClockedDMIIO =>
|
||||
val dtm_success = WireInit(false.B)
|
||||
when (dtm_success) { th.success := true.B }
|
||||
val dtm = Module(new SimDTM()(system.p)).connect(th.harnessClock, th.harnessReset.asBool, d, dtm_success)
|
||||
case j: JTAGIO =>
|
||||
val dtm_success = WireInit(false.B)
|
||||
when (dtm_success) { th.success := true.B }
|
||||
val jtag = Module(new SimJTAG(tickDelay=3)).connect(j, th.harnessClock, th.harnessReset.asBool, ~(th.harnessReset.asBool), dtm_success)
|
||||
}
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithTiedOffDebug extends OverrideHarnessBinder({
|
||||
(system: HasPeripheryDebugModuleImp, th: HasHarnessSignalReferences, ports: Seq[Data]) => {
|
||||
ports.map {
|
||||
case j: JTAGIO =>
|
||||
j.TCK := true.B.asClock
|
||||
j.TMS := true.B
|
||||
j.TDI := true.B
|
||||
j.TRSTn.foreach { r => r := true.B }
|
||||
case d: ClockedDMIIO =>
|
||||
d.dmi.req.valid := false.B
|
||||
d.dmi.req.bits := DontCare
|
||||
d.dmi.resp.ready := true.B
|
||||
d.dmiClock := false.B.asClock
|
||||
d.dmiReset := true.B
|
||||
case a: ClockedAPBBundle =>
|
||||
a.tieoff()
|
||||
a.clock := false.B.asClock
|
||||
a.reset := true.B.asAsyncReset
|
||||
a.psel := false.B
|
||||
a.penable := false.B
|
||||
}
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
class WithSerialAdapterTiedOff extends OverrideHarnessBinder({
|
||||
(system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => {
|
||||
implicit val p = chipyard.iobinders.GetSystemParameters(system)
|
||||
ports.map({ port =>
|
||||
val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, port, th.harnessReset)
|
||||
SerialAdapter.tieoff(ram.module.io.tsi_ser)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
class WithSimSerial extends OverrideHarnessBinder({
|
||||
(system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => {
|
||||
implicit val p = chipyard.iobinders.GetSystemParameters(system)
|
||||
ports.map({ port =>
|
||||
val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, port, th.harnessReset)
|
||||
val success = SerialAdapter.connectSimSerial(ram.module.io.tsi_ser, port.clock, th.harnessReset.asBool)
|
||||
when (success) { th.success := true.B }
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
class WithTraceGenSuccess extends OverrideHarnessBinder({
|
||||
(system: TraceGenSystemModuleImp, th: HasHarnessSignalReferences, ports: Seq[Bool]) => {
|
||||
ports.map { p => when (p) { th.success := true.B } }
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithSimDromajoBridge extends ComposeHarnessBinder({
|
||||
(system: CanHaveTraceIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[TraceOutputTop]) => {
|
||||
ports.map { p => p.traces.map(tileTrace => SimDromajoBridge(tileTrace)(system.p)) }
|
||||
Nil
|
||||
}
|
||||
})
|
||||
@@ -1,12 +1,13 @@
|
||||
package chipyard
|
||||
package object iobinders {
|
||||
package chipyard.iobinders
|
||||
|
||||
import chisel3._
|
||||
import chisel3.experimental.{Analog, IO}
|
||||
import chisel3.util.experimental.{BoringUtils}
|
||||
import chisel3.experimental.{Analog, IO, DataMirror}
|
||||
|
||||
import freechips.rocketchip.config.{Field, Config, Parameters}
|
||||
import freechips.rocketchip.config._
|
||||
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike}
|
||||
import freechips.rocketchip.devices.debug._
|
||||
import freechips.rocketchip.jtag.{JTAGIO}
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.system.{SimAXIMem}
|
||||
import freechips.rocketchip.amba.axi4.{AXI4Bundle, AXI4SlaveNode, AXI4MasterNode, AXI4EdgeParameters}
|
||||
@@ -21,7 +22,9 @@ import tracegen.{TraceGenSystemModuleImp}
|
||||
import barstools.iocell.chisel._
|
||||
|
||||
import testchipip._
|
||||
import icenet.{CanHavePeripheryIceNICModuleImp, SimNetwork, NicLoopback, NICKey}
|
||||
import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly}
|
||||
|
||||
import chipyard.GlobalResetSchemeKey
|
||||
|
||||
import scala.reflect.{ClassTag}
|
||||
|
||||
@@ -37,20 +40,22 @@ import scala.reflect.{ClassTag}
|
||||
|
||||
// You can add your own binder by adding a new (key, fn) pair, typically by using
|
||||
// the OverrideIOBinder or ComposeIOBinder macros
|
||||
|
||||
|
||||
// DOC include start: IOBinders
|
||||
// This type describes a function callable on the TestHarness instance. Its return type is unused.
|
||||
type TestHarnessFunction = (chipyard.TestHarness) => Seq[Any]
|
||||
// IOBinders will return a Seq of this tuple, which contains three fields:
|
||||
// 1. A Seq containing all IO ports created by the IOBinder function
|
||||
// 2. A Seq containing all IO cell modules created by the IOBinder function
|
||||
// 3. An optional function to call inside the test harness (e.g. to connect the IOs)
|
||||
type IOBinderTuple = (Seq[Data], Seq[IOCell], Option[TestHarnessFunction])
|
||||
|
||||
case object IOBinders extends Field[Map[String, (Any) => Seq[IOBinderTuple]]](
|
||||
Map[String, (Any) => Seq[IOBinderTuple]]().withDefaultValue((Any) => Nil)
|
||||
case object IOBinders extends Field[Map[String, (Any) => (Seq[Data], Seq[IOCell])]](
|
||||
Map[String, (Any) => (Seq[Data], Seq[IOCell])]().withDefaultValue((Any) => (Nil, Nil))
|
||||
)
|
||||
object ApplyIOBinders {
|
||||
def apply(sys: LazyModule, map: Map[String, (Any) => (Seq[Data], Seq[IOCell])]):
|
||||
(Iterable[Data], Iterable[IOCell], Map[String, Seq[Data]]) = {
|
||||
val lzy = map.map({ case (s,f) => s -> f(sys) })
|
||||
val imp = map.map({ case (s,f) => s -> f(sys.module) })
|
||||
val unzipped = (lzy.values ++ imp.values).unzip
|
||||
|
||||
val ports: Iterable[Data] = unzipped._1.flatten
|
||||
val cells: Iterable[IOCell] = unzipped._2.flatten
|
||||
val portMap: Map[String, Seq[Data]] = map.keys.map(k => k -> (lzy(k)._1 ++ imp(k)._1)).toMap
|
||||
(ports, cells, portMap)
|
||||
}
|
||||
}
|
||||
|
||||
// Note: The parameters instance is accessible only through LazyModule
|
||||
// or LazyModuleImpLike. The self-type requirement in traits like
|
||||
@@ -67,14 +72,18 @@ object GetSystemParameters {
|
||||
}
|
||||
}
|
||||
|
||||
class IOBinder(f: (View, View, View) => PartialFunction[Any, Any]) extends Config(f)
|
||||
|
||||
// This macro overrides previous matches on some Top mixin. This is useful for
|
||||
// binders which drive IO, since those typically cannot be composed
|
||||
class OverrideIOBinder[T](fn: => (T) => Seq[IOBinderTuple])(implicit tag: ClassTag[T]) extends Config((site, here, up) => {
|
||||
class OverrideIOBinder[T, S <: Data](fn: => (T) => (Seq[S], Seq[IOCell]))(implicit tag: ClassTag[T]) extends IOBinder((site, here, up) => {
|
||||
case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString ->
|
||||
((t: Any) => {
|
||||
t match {
|
||||
case system: T => fn(system)
|
||||
case _ => Nil
|
||||
case system: T =>
|
||||
val (ports, cells) = fn(system)
|
||||
(ports, cells)
|
||||
case _ => (Nil, Nil)
|
||||
}
|
||||
})
|
||||
)
|
||||
@@ -82,32 +91,44 @@ class OverrideIOBinder[T](fn: => (T) => Seq[IOBinderTuple])(implicit tag: ClassT
|
||||
|
||||
// This macro composes with previous matches on some Top mixin. This is useful for
|
||||
// annotation-like binders, since those can typically be composed
|
||||
class ComposeIOBinder[T](fn: => (T) => Seq[IOBinderTuple])(implicit tag: ClassTag[T]) extends Config((site, here, up) => {
|
||||
class ComposeIOBinder[T, S <: Data](fn: => (T) => (Seq[S], Seq[IOCell]))(implicit tag: ClassTag[T]) extends IOBinder((site, here, up) => {
|
||||
case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString ->
|
||||
((t: Any) => {
|
||||
t match {
|
||||
case system: T => (up(IOBinders, site)(tag.runtimeClass.toString)(system)
|
||||
++ fn(system))
|
||||
case _ => Nil
|
||||
case system: T =>
|
||||
val r = up(IOBinders, site)(tag.runtimeClass.toString)(system)
|
||||
val h = fn(system)
|
||||
val ports = r._1 ++ h._1
|
||||
val cells = r._2 ++ h._2
|
||||
(ports, cells)
|
||||
case _ => (Nil, Nil)
|
||||
}
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
// DOC include end: IOBinders
|
||||
object BoreHelper {
|
||||
def apply(name: String, source: Clock): Clock = {
|
||||
val clock_io = IO(Output(Clock())).suggestName(name)
|
||||
val clock_wire = Wire(Clock()).suggestName(s"chiptop_${name}")
|
||||
dontTouch(clock_wire)
|
||||
clock_wire := false.B.asClock // necessary for BoringUtils to work properly
|
||||
BoringUtils.bore(source, Seq(clock_wire))
|
||||
clock_io := clock_wire
|
||||
clock_io
|
||||
}
|
||||
}
|
||||
|
||||
object AddIOCells {
|
||||
/**
|
||||
* Add IO cells to a SiFive GPIO devices and name the IO ports.
|
||||
* @param gpios A Seq of GPIO port bundles
|
||||
* @param genFn A callable function to generate a DigitalGPIOCell module to use
|
||||
* @return Returns a tuple of (a 2D Seq of Analog IOs corresponding to individual GPIO pins; a 2D Seq of IOCell module references)
|
||||
*/
|
||||
def gpio(gpios: Seq[GPIOPortIO], genFn: () => DigitalGPIOCell = IOCell.genericGPIO): (Seq[Seq[Analog]], Seq[Seq[IOCell]]) = {
|
||||
gpios.zipWithIndex.map({ case (gpio, i) =>
|
||||
|
||||
case object IOCellKey extends Field[IOCellTypeParams](GenericIOCellParams())
|
||||
|
||||
|
||||
class WithGPIOCells extends OverrideIOBinder({
|
||||
(system: HasPeripheryGPIOModuleImp) => {
|
||||
val (ports2d, cells2d) = system.gpio.zipWithIndex.map({ case (gpio, i) =>
|
||||
gpio.pins.zipWithIndex.map({ case (pin, j) =>
|
||||
val g = IO(Analog(1.W)).suggestName(s"gpio_${i}_${j}")
|
||||
val iocell = genFn().suggestName(s"iocell_gpio_${i}_${j}")
|
||||
val iocell = system.p(IOCellKey).gpio().suggestName(s"iocell_gpio_${i}_${j}")
|
||||
iocell.io.o := pin.o.oval
|
||||
iocell.io.oe := pin.o.oe
|
||||
iocell.io.ie := pin.o.ie
|
||||
@@ -116,40 +137,37 @@ object AddIOCells {
|
||||
(g, iocell)
|
||||
}).unzip
|
||||
}).unzip
|
||||
val ports: Seq[Analog] = ports2d.flatten
|
||||
(ports, cells2d.flatten)
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Add IO cells to a SiFive UART devices and name the IO ports.
|
||||
* @param uartPins A Seq of UART port bundles
|
||||
* @return Returns a tuple of (A Seq of top-level UARTPortIO IOs; a 2D Seq of IOCell module references)
|
||||
*/
|
||||
def uart(uartPins: Seq[UARTPortIO]): (Seq[UARTPortIO], Seq[Seq[IOCell]]) = {
|
||||
uartPins.zipWithIndex.map({ case (u, i) =>
|
||||
val (port, ios) = IOCell.generateIOFromSignal(u, Some(s"iocell_uart_${i}"))
|
||||
port.suggestName(s"uart_${i}")
|
||||
// DOC include start: WithUARTIOCells
|
||||
class WithUARTIOCells extends OverrideIOBinder({
|
||||
(system: HasPeripheryUARTModuleImp) => {
|
||||
val (ports: Seq[UARTPortIO], cells2d) = system.uart.zipWithIndex.map({ case (u, i) =>
|
||||
val (port, ios) = IOCell.generateIOFromSignal(u, s"uart_${i}", system.p(IOCellKey))
|
||||
(port, ios)
|
||||
}).unzip
|
||||
(ports, cells2d.flatten)
|
||||
}
|
||||
})
|
||||
// DOC include end: WithUARTIOCells
|
||||
|
||||
/**
|
||||
* Add IO cells to a SiFive SPI devices and name the IO ports.
|
||||
* @param spiPins A Seq of SPI port bundles
|
||||
* @param basename The base name for this port (defaults to "spi")
|
||||
* @param genFn A callable function to generate a DigitalGPIOCell module to use
|
||||
* @return Returns a tuple of (A Seq of top-level SPIChipIO IOs; a 2D Seq of IOCell module references)
|
||||
*/
|
||||
def spi(spiPins: Seq[SPIPortIO], basename: String = "spi", genFn: () => DigitalGPIOCell = IOCell.genericGPIO): (Seq[SPIChipIO], Seq[Seq[IOCell]]) = {
|
||||
spiPins.zipWithIndex.map({ case (s, i) =>
|
||||
val port = IO(new SPIChipIO(s.c.csWidth)).suggestName(s"${basename}_${i}")
|
||||
val iocellBase = s"iocell_${basename}_${i}"
|
||||
class WithSPIIOCells extends OverrideIOBinder({
|
||||
(system: HasPeripherySPIFlashModuleImp) => {
|
||||
val (ports: Seq[SPIChipIO], cells2d) = system.qspi.zipWithIndex.map({ case (s, i) =>
|
||||
val name = s"spi_${i}"
|
||||
val port = IO(new SPIChipIO(s.c.csWidth)).suggestName(name)
|
||||
val iocellBase = s"iocell_${name}"
|
||||
|
||||
// SCK and CS are unidirectional outputs
|
||||
val sckIOs = IOCell.generateFromSignal(s.sck, port.sck, Some(s"${iocellBase}_sck"))
|
||||
val csIOs = IOCell.generateFromSignal(s.cs, port.cs, Some(s"${iocellBase}_cs"))
|
||||
val sckIOs = IOCell.generateFromSignal(s.sck, port.sck, Some(s"${iocellBase}_sck"), system.p(IOCellKey))
|
||||
val csIOs = IOCell.generateFromSignal(s.cs, port.cs, Some(s"${iocellBase}_cs"), system.p(IOCellKey))
|
||||
|
||||
// DQ are bidirectional, so then need special treatment
|
||||
val dqIOs = s.dq.zip(port.dq).zipWithIndex.map { case ((pin, ana), j) =>
|
||||
val iocell = genFn().suggestName(s"${iocellBase}_dq_${j}")
|
||||
val iocell = system.p(IOCellKey).gpio().suggestName(s"${iocellBase}_dq_${j}")
|
||||
iocell.io.o := pin.o
|
||||
iocell.io.oe := pin.oe
|
||||
iocell.io.ie := true.B
|
||||
@@ -160,279 +178,162 @@ object AddIOCells {
|
||||
|
||||
(port, dqIOs ++ csIOs ++ sckIOs)
|
||||
}).unzip
|
||||
}
|
||||
|
||||
/**
|
||||
* Add IO cells to a debug module and name the IO ports.
|
||||
* @param psd A PSDIO bundle
|
||||
* @param resetctrlOpt An optional ResetCtrlIO bundle
|
||||
* @param debugOpt An optional DebugIO bundle
|
||||
* @return Returns a tuple3 of (Top-level PSDIO IO; Optional top-level DebugIO IO; a list of IOCell module references)
|
||||
*/
|
||||
def debug(psd: PSDIO, resetctrlOpt: Option[ResetCtrlIO], debugOpt: Option[DebugIO])(implicit p: Parameters):
|
||||
(PSDIO, Option[ResetCtrlIO], Option[DebugIO], Seq[IOCell]) = {
|
||||
val (psdPort, psdIOs) = IOCell.generateIOFromSignal(
|
||||
psd, Some("iocell_psd"), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync)
|
||||
val debugTuple = debugOpt.map(d =>
|
||||
IOCell.generateIOFromSignal(d, Some("iocell_debug"), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync))
|
||||
val debugPortOpt: Option[DebugIO] = debugTuple.map(_._1)
|
||||
val debugIOs: Seq[IOCell] = debugTuple.map(_._2).toSeq.flatten
|
||||
debugPortOpt.foreach(_.suggestName("debug"))
|
||||
|
||||
val resetctrlTuple = resetctrlOpt.map(d =>
|
||||
IOCell.generateIOFromSignal(d, Some("iocell_resetctrl"), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync))
|
||||
val resetctrlPortOpt: Option[ResetCtrlIO] = resetctrlTuple.map(_._1)
|
||||
val resetctrlIOs: Seq[IOCell] = resetctrlTuple.map(_._2).toSeq.flatten
|
||||
resetctrlPortOpt.foreach(_.suggestName("resetctrl"))
|
||||
|
||||
psdPort.suggestName("psd")
|
||||
(psdPort, resetctrlPortOpt, debugPortOpt, psdIOs ++ debugIOs ++ resetctrlIOs)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add IO cells to a serial module and name the IO ports.
|
||||
* @param serial A SerialIO bundle
|
||||
* @return Returns a tuple of (Top-level SerialIO IO; a list of IOCell module references)
|
||||
*/
|
||||
def serial(serial: SerialIO): (SerialIO, Seq[IOCell]) = {
|
||||
val (port, ios) = IOCell.generateIOFromSignal(serial, Some("iocell_serial"))
|
||||
port.suggestName("serial")
|
||||
(port, ios)
|
||||
}
|
||||
|
||||
def axi4(io: Seq[AXI4Bundle], node: AXI4SlaveNode, name: String): Seq[(AXI4Bundle, AXI4EdgeParameters, Seq[IOCell])] = {
|
||||
io.zip(node.in).zipWithIndex.map{ case ((mem_axi4, (_, edge)), i) => {
|
||||
val (port, ios) = IOCell.generateIOFromSignal(mem_axi4, Some(s"iocell_${name}_axi4_slave_${i}"))
|
||||
port.suggestName(s"${name}_axi4_slave_${i}")
|
||||
(port, edge, ios)
|
||||
}}
|
||||
}
|
||||
def axi4(io: Seq[AXI4Bundle], node: AXI4MasterNode, name: String): Seq[(AXI4Bundle, AXI4EdgeParameters, Seq[IOCell])] = {
|
||||
io.zip(node.out).zipWithIndex.map{ case ((mem_axi4, (_, edge)), i) => {
|
||||
//val (port, ios) = IOCell.generateIOFromSignal(mem_axi4, Some(s"iocell_${name}_axi4_master_${i}"))
|
||||
val port = IO(Flipped(AXI4Bundle(edge.bundle)))
|
||||
val ios = IOCell.generateFromSignal(mem_axi4, port, Some(s"iocell_${name}_axi4_master_${i}"))
|
||||
port.suggestName(s"${name}_axi4_master_${i}")
|
||||
(port, edge, ios)
|
||||
}}
|
||||
}
|
||||
|
||||
def blockDev(bdev: BlockDeviceIO): (BlockDeviceIO, Seq[IOCell]) = {
|
||||
val (port, ios) = IOCell.generateIOFromSignal(bdev, Some("iocell_bdev"))
|
||||
port.suggestName("bdev")
|
||||
(port, ios)
|
||||
}
|
||||
}
|
||||
|
||||
// DOC include start: WithGPIOTiedOff
|
||||
class WithGPIOTiedOff extends OverrideIOBinder({
|
||||
(system: HasPeripheryGPIOModuleImp) => {
|
||||
val (ports2d, ioCells2d) = AddIOCells.gpio(system.gpio)
|
||||
val harnessFn = (th: chipyard.TestHarness) => { ports2d.flatten.foreach(_ <> AnalogConst(0)); Nil }
|
||||
Seq((ports2d.flatten, ioCells2d.flatten, Some(harnessFn)))
|
||||
}
|
||||
})
|
||||
// DOC include end: WithGPIOTiedOff
|
||||
|
||||
class WithUARTAdapter extends OverrideIOBinder({
|
||||
(system: HasPeripheryUARTModuleImp) => {
|
||||
val (ports, ioCells2d) = AddIOCells.uart(system.uart)
|
||||
val harnessFn = (th: chipyard.TestHarness) => { UARTAdapter.connect(ports)(system.p); Nil }
|
||||
Seq((ports, ioCells2d.flatten, Some(harnessFn)))
|
||||
(ports, cells2d.flatten)
|
||||
}
|
||||
})
|
||||
|
||||
class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideIOBinder({
|
||||
(system: HasPeripherySPIFlashModuleImp) => {
|
||||
val (ports, ioCells2d) = AddIOCells.spi(system.qspi, "qspi")
|
||||
val harnessFn = (th: chipyard.TestHarness) => { SimSPIFlashModel.connect(ports, th.reset, rdOnly)(system.p); Nil }
|
||||
Seq((ports, ioCells2d.flatten, Some(harnessFn)))
|
||||
}
|
||||
})
|
||||
|
||||
class WithSimBlockDevice extends OverrideIOBinder({
|
||||
(system: CanHavePeripheryBlockDeviceModuleImp) => system.bdev.map { bdev =>
|
||||
val (port, ios) = AddIOCells.blockDev(bdev)
|
||||
val harnessFn = (th: chipyard.TestHarness) => {
|
||||
SimBlockDevice.connect(th.clock, th.reset.asBool, Some(port))(system.p)
|
||||
Nil
|
||||
class WithExtInterruptIOCells extends OverrideIOBinder({
|
||||
(system: HasExtInterruptsModuleImp) => {
|
||||
if (system.outer.nExtInterrupts > 0) {
|
||||
val (port: UInt, cells) = IOCell.generateIOFromSignal(system.interrupts, "ext_interrupts", system.p(IOCellKey))
|
||||
(Seq(port), cells)
|
||||
} else {
|
||||
(Nil, Nil)
|
||||
}
|
||||
Seq((Seq(port), ios, Some(harnessFn)))
|
||||
}.getOrElse(Nil)
|
||||
}
|
||||
})
|
||||
|
||||
class WithBlockDeviceModel extends OverrideIOBinder({
|
||||
(system: CanHavePeripheryBlockDeviceModuleImp) => system.bdev.map { bdev =>
|
||||
val (port, ios) = AddIOCells.blockDev(bdev)
|
||||
val harnessFn = (th: chipyard.TestHarness) => {
|
||||
BlockDeviceModel.connect(Some(port))(system.p)
|
||||
Nil
|
||||
}
|
||||
Seq((Seq(port), ios, Some(harnessFn)))
|
||||
}.getOrElse(Nil)
|
||||
})
|
||||
|
||||
class WithLoopbackNIC extends OverrideIOBinder({
|
||||
(system: CanHavePeripheryIceNICModuleImp) => system.connectNicLoopback(); Nil
|
||||
})
|
||||
class WithDebugIOCells extends OverrideIOBinder({
|
||||
(system: HasPeripheryDebugModuleImp) => {
|
||||
system.debug.map({ debug =>
|
||||
val p = system.p
|
||||
val tlbus = system.outer.asInstanceOf[BaseSubsystem].locateTLBusWrapper(p(ExportDebug).slaveWhere)
|
||||
val debug_clock = Wire(Clock()).suggestName("debug_clock")
|
||||
val debug_reset = Wire(Reset()).suggestName("debug_reset")
|
||||
debug_clock := false.B.asClock // must provide default assignment to avoid firrtl unassigned error
|
||||
debug_reset := false.B // must provide default assignment to avoid firrtl unassigned error
|
||||
BoringUtils.bore(tlbus.module.clock, Seq(debug_clock))
|
||||
BoringUtils.bore(tlbus.module.reset, Seq(debug_reset))
|
||||
|
||||
class WithSimNIC extends OverrideIOBinder({
|
||||
(system: CanHavePeripheryIceNICModuleImp) => system.connectSimNetwork(system.clock, system.reset.asBool); Nil
|
||||
})
|
||||
|
||||
// DOC include start: WithSimAXIMem
|
||||
class WithSimAXIMem extends OverrideIOBinder({
|
||||
(system: CanHaveMasterAXI4MemPort) => {
|
||||
implicit val p: Parameters = GetSystemParameters(system)
|
||||
val peiTuples = AddIOCells.axi4(system.mem_axi4, system.memAXI4Node, "mem")
|
||||
// TODO: we are inlining the connectMem method of SimAXIMem because
|
||||
// it takes in a dut rather than seq of axi4 ports
|
||||
val harnessFn = (th: chipyard.TestHarness) => {
|
||||
peiTuples.map { case (port, edge, ios) =>
|
||||
val mem = LazyModule(new SimAXIMem(edge, size = p(ExtMem).get.master.size))
|
||||
Module(mem.module).suggestName("mem")
|
||||
mem.io_axi4.head <> port
|
||||
// We never use the PSDIO, so tie it off on-chip
|
||||
system.psd.psd.foreach { _ <> 0.U.asTypeOf(new PSDTestMode) }
|
||||
system.resetctrl.map { rcio => rcio.hartIsInReset.map { _ := debug_reset.asBool } }
|
||||
system.debug.map { d =>
|
||||
// Tie off extTrigger
|
||||
d.extTrigger.foreach { t =>
|
||||
t.in.req := false.B
|
||||
t.out.ack := t.out.req
|
||||
}
|
||||
// Tie off disableDebug
|
||||
d.disableDebug.foreach { d => d := false.B }
|
||||
// Drive JTAG on-chip IOs
|
||||
d.systemjtag.map { j =>
|
||||
j.reset := debug_reset
|
||||
j.mfr_id := system.p(JtagDTMKey).idcodeManufId.U(11.W)
|
||||
j.part_number := system.p(JtagDTMKey).idcodePartNum.U(16.W)
|
||||
j.version := system.p(JtagDTMKey).idcodeVersion.U(4.W)
|
||||
}
|
||||
}
|
||||
Nil
|
||||
}
|
||||
Seq((peiTuples.map(_._1), peiTuples.flatMap(_._3), Some(harnessFn)))
|
||||
}
|
||||
})
|
||||
// DOC include end: WithSimAXIMem
|
||||
Debug.connectDebugClockAndReset(Some(debug), debug_clock)(system.p)
|
||||
|
||||
class WithBlackBoxSimMem extends OverrideIOBinder({
|
||||
(system: CanHaveMasterAXI4MemPort) => {
|
||||
implicit val p: Parameters = GetSystemParameters(system)
|
||||
val peiTuples = AddIOCells.axi4(system.mem_axi4, system.memAXI4Node, "mem")
|
||||
val harnessFn = (th: chipyard.TestHarness) => {
|
||||
peiTuples.map { case (port, edge, ios) =>
|
||||
val memSize = p(ExtMem).get.master.size
|
||||
val lineSize = p(CacheBlockBytes)
|
||||
val mem = Module(new SimDRAM(memSize, lineSize, edge.bundle))
|
||||
mem.io.axi <> port
|
||||
mem.io.clock := th.clock
|
||||
mem.io.reset := th.reset
|
||||
// Add IOCells for the DMI/JTAG/APB ports
|
||||
val dmiTuple = debug.clockeddmi.map { d =>
|
||||
IOCell.generateIOFromSignal(d, "dmi", p(IOCellKey), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync)
|
||||
}
|
||||
Nil
|
||||
}
|
||||
Seq((peiTuples.map(_._1), peiTuples.flatMap(_._3), Some(harnessFn)))
|
||||
|
||||
val jtagTuple = debug.systemjtag.map { j =>
|
||||
IOCell.generateIOFromSignal(j.jtag, "jtag", p(IOCellKey), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync)
|
||||
}
|
||||
|
||||
val apbTuple = debug.apb.map { a =>
|
||||
IOCell.generateIOFromSignal(a, "apb", p(IOCellKey), abstractResetAsAsync = p(GlobalResetSchemeKey).pinIsAsync)
|
||||
}
|
||||
|
||||
val allTuples = (dmiTuple ++ jtagTuple ++ apbTuple).toSeq
|
||||
(allTuples.map(_._1).toSeq, allTuples.flatMap(_._2).toSeq)
|
||||
}).getOrElse((Nil, Nil))
|
||||
}
|
||||
})
|
||||
|
||||
class WithSimAXIMMIO extends OverrideIOBinder({
|
||||
class WithSerialTLIOCells extends OverrideIOBinder({
|
||||
(system: CanHavePeripheryTLSerial) => system.serial_tl.map({ s =>
|
||||
val sys = system.asInstanceOf[BaseSubsystem]
|
||||
val (port, cells) = IOCell.generateIOFromSignal(s.getWrappedValue, "serial_tl", sys.p(IOCellKey))
|
||||
(Seq(port), cells)
|
||||
}).getOrElse((Nil, Nil))
|
||||
})
|
||||
|
||||
|
||||
class WithAXI4MemPunchthrough extends OverrideIOBinder({
|
||||
(system: CanHaveMasterAXI4MemPort) => {
|
||||
val ports: Seq[ClockedIO[AXI4Bundle]] = system.mem_axi4.zipWithIndex.map({ case (m, i) =>
|
||||
val p = IO(new ClockedIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mem_${i}")
|
||||
p.bits <> m
|
||||
p.clock := BoreHelper("axi4_mem_clock", system.asInstanceOf[BaseSubsystem].mbus.module.clock)
|
||||
p
|
||||
})
|
||||
(ports, Nil)
|
||||
}
|
||||
})
|
||||
|
||||
class WithAXI4MMIOPunchthrough extends OverrideIOBinder({
|
||||
(system: CanHaveMasterAXI4MMIOPort) => {
|
||||
implicit val p: Parameters = GetSystemParameters(system)
|
||||
val peiTuples = AddIOCells.axi4(system.mmio_axi4, system.mmioAXI4Node, "mmio_mem")
|
||||
val harnessFn = (th: chipyard.TestHarness) => {
|
||||
peiTuples.zipWithIndex.map { case ((port, edge, ios), i) =>
|
||||
val mmio_mem = LazyModule(new SimAXIMem(edge, size = 4096))
|
||||
Module(mmio_mem.module).suggestName(s"mmio_mem_${i}")
|
||||
mmio_mem.io_axi4.head <> port
|
||||
}
|
||||
Nil
|
||||
}
|
||||
Seq((peiTuples.map(_._1), peiTuples.flatMap(_._3), Some(harnessFn)))
|
||||
val ports: Seq[ClockedIO[AXI4Bundle]] = system.mmio_axi4.zipWithIndex.map({ case (m, i) =>
|
||||
val p = IO(new ClockedIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mmio_${i}")
|
||||
p.bits <> m
|
||||
p.clock := BoreHelper("axi4_mmio_clock", system.asInstanceOf[BaseSubsystem].mbus.module.clock)
|
||||
p
|
||||
})
|
||||
(ports, Nil)
|
||||
}
|
||||
})
|
||||
|
||||
class WithL2FBusAXI4Punchthrough extends OverrideIOBinder({
|
||||
(system: CanHaveSlaveAXI4Port) => {
|
||||
val ports: Seq[ClockedIO[AXI4Bundle]] = system.l2_frontend_bus_axi4.zipWithIndex.map({ case (m, i) =>
|
||||
val p = IO(new ClockedIO(Flipped(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)))).suggestName(s"axi4_fbus_${i}")
|
||||
m <> p.bits
|
||||
p.clock := BoreHelper("axi4_fbus_clock", system.asInstanceOf[BaseSubsystem].fbus.module.clock)
|
||||
p
|
||||
})
|
||||
(ports, Nil)
|
||||
}
|
||||
})
|
||||
|
||||
class WithBlockDeviceIOPunchthrough extends OverrideIOBinder({
|
||||
(system: CanHavePeripheryBlockDevice) => {
|
||||
val ports: Seq[ClockedIO[BlockDeviceIO]] = system.bdev.map({ bdev =>
|
||||
val p = IO(new ClockedIO(new BlockDeviceIO()(GetSystemParameters(system)))).suggestName("blockdev")
|
||||
p <> bdev
|
||||
p
|
||||
}).toSeq
|
||||
(ports, Nil)
|
||||
}
|
||||
})
|
||||
|
||||
class WithNICIOPunchthrough extends OverrideIOBinder({
|
||||
(system: CanHavePeripheryIceNIC) => {
|
||||
val ports: Seq[ClockedIO[NICIOvonly]] = system.icenicOpt.map({ n =>
|
||||
val p = IO(new ClockedIO(new NICIOvonly)).suggestName("nic")
|
||||
p <> n
|
||||
p
|
||||
}).toSeq
|
||||
(ports, Nil)
|
||||
}
|
||||
})
|
||||
|
||||
class WithTraceGenSuccessPunchthrough extends OverrideIOBinder({
|
||||
(system: TraceGenSystemModuleImp) => {
|
||||
val success: Bool = IO(Output(Bool())).suggestName("success")
|
||||
success := system.success
|
||||
(Seq(success), Nil)
|
||||
}
|
||||
})
|
||||
|
||||
class WithTraceIOPunchthrough extends OverrideIOBinder({
|
||||
(system: CanHaveTraceIOModuleImp) => {
|
||||
val ports: Option[TraceOutputTop] = system.traceIO.map { t =>
|
||||
val trace = IO(DataMirror.internal.chiselTypeClone[TraceOutputTop](t)).suggestName("trace")
|
||||
trace <> t
|
||||
trace
|
||||
}
|
||||
(ports.toSeq, Nil)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
class WithDontTouchPorts extends OverrideIOBinder({
|
||||
(system: DontTouch) => system.dontTouchPorts(); Nil
|
||||
(system: DontTouch) => system.dontTouchPorts(); (Nil, Nil)
|
||||
})
|
||||
|
||||
class WithTieOffInterrupts extends OverrideIOBinder({
|
||||
(system: HasExtInterruptsModuleImp) => {
|
||||
val (port, ioCells) = IOCell.generateIOFromSignal(system.interrupts, Some("iocell_interrupts"))
|
||||
port.suggestName("interrupts")
|
||||
val harnessFn = (th: chipyard.TestHarness) => { port := 0.U; Nil }
|
||||
Seq((Seq(port), ioCells, Some(harnessFn)))
|
||||
}
|
||||
})
|
||||
|
||||
class WithTieOffL2FBusAXI extends OverrideIOBinder({
|
||||
(system: CanHaveSlaveAXI4Port) => {
|
||||
val peiTuples = AddIOCells.axi4(system.l2_frontend_bus_axi4, system.l2FrontendAXI4Node, "l2_fbus")
|
||||
val harnessFn = (th: chipyard.TestHarness) => {
|
||||
peiTuples.zipWithIndex.map { case ((port, edge, ios), i) =>
|
||||
port := DontCare // tieoff doesn't completely tie-off, for some reason
|
||||
port.tieoff()
|
||||
}
|
||||
Nil
|
||||
}
|
||||
Seq((peiTuples.map(_._1), peiTuples.flatMap(_._3), Some(harnessFn)))
|
||||
}
|
||||
})
|
||||
|
||||
class WithTiedOffDebug extends OverrideIOBinder({
|
||||
(system: HasPeripheryDebugModuleImp) => {
|
||||
val (psdPort, resetctrlOpt, debugPortOpt, ioCells) =
|
||||
AddIOCells.debug(system.psd, system.resetctrl, system.debug)(system.p)
|
||||
val harnessFn = (th: chipyard.TestHarness) => {
|
||||
Debug.tieoffDebug(debugPortOpt, resetctrlOpt, Some(psdPort))(system.p)
|
||||
// tieoffDebug doesn't actually tie everything off :/
|
||||
debugPortOpt.foreach { d =>
|
||||
d.clockeddmi.foreach({ cdmi => cdmi.dmi.req.bits := DontCare; cdmi.dmiClock := th.clock })
|
||||
d.dmactiveAck := DontCare
|
||||
d.clock := th.clock
|
||||
}
|
||||
Nil
|
||||
}
|
||||
Seq((Seq(psdPort) ++ resetctrlOpt ++ debugPortOpt.toSeq, Nil, Some(harnessFn)))
|
||||
}
|
||||
})
|
||||
|
||||
class WithSimDebug extends OverrideIOBinder({
|
||||
(system: HasPeripheryDebugModuleImp) => {
|
||||
val (psdPort, resetctrlPortOpt, debugPortOpt, ioCells) =
|
||||
AddIOCells.debug(system.psd, system.resetctrl, system.debug)(system.p)
|
||||
val harnessFn = (th: chipyard.TestHarness) => {
|
||||
val dtm_success = Wire(Bool())
|
||||
Debug.connectDebug(debugPortOpt, resetctrlPortOpt, psdPort, th.clock, th.harnessReset, dtm_success)(system.p)
|
||||
when (dtm_success) { th.success := true.B }
|
||||
th.dutReset := th.harnessReset | debugPortOpt.map { debug => AsyncResetReg(debug.ndreset).asBool }.getOrElse(false.B)
|
||||
Nil
|
||||
}
|
||||
Seq((Seq(psdPort) ++ debugPortOpt.toSeq, ioCells, Some(harnessFn)))
|
||||
}
|
||||
})
|
||||
|
||||
class WithTiedOffSerial extends OverrideIOBinder({
|
||||
(system: CanHavePeripherySerialModuleImp) => system.serial.map({ serial =>
|
||||
val (port, ioCells) = AddIOCells.serial(serial)
|
||||
val harnessFn = (th: chipyard.TestHarness) => {
|
||||
SerialAdapter.tieoff(port)
|
||||
Nil
|
||||
}
|
||||
Seq((Seq(port), ioCells, Some(harnessFn)))
|
||||
}).getOrElse(Nil)
|
||||
})
|
||||
|
||||
class WithSimSerial extends OverrideIOBinder({
|
||||
(system: CanHavePeripherySerialModuleImp) => system.serial.map({ serial =>
|
||||
val (port, ioCells) = AddIOCells.serial(serial)
|
||||
val harnessFn = (th: chipyard.TestHarness) => {
|
||||
val ser_success = SerialAdapter.connectSimSerial(port, th.clock, th.harnessReset)
|
||||
when (ser_success) { th.success := true.B }
|
||||
Nil
|
||||
}
|
||||
Seq((Seq(port), ioCells, Some(harnessFn)))
|
||||
}).getOrElse(Nil)
|
||||
})
|
||||
|
||||
class WithTraceGenSuccessBinder extends OverrideIOBinder({
|
||||
(system: TraceGenSystemModuleImp) => {
|
||||
val (successPort, ioCells) = IOCell.generateIOFromSignal(system.success, Some("iocell_success"))
|
||||
successPort.suggestName("success")
|
||||
val harnessFn = (th: chipyard.TestHarness) => { when (successPort) { th.success := true.B }; Nil }
|
||||
Seq((Seq(successPort), ioCells, Some(harnessFn)))
|
||||
}
|
||||
})
|
||||
|
||||
class WithSimDromajoBridge extends ComposeIOBinder({
|
||||
(system: CanHaveTraceIOModuleImp) => {
|
||||
system.traceIO match { case Some(t) => t.traces.map(tileTrace => SimDromajoBridge(tileTrace)(system.p)) }
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
} /* end package object */
|
||||
|
||||
@@ -8,6 +8,7 @@ package chipyard
|
||||
import chisel3._
|
||||
import chisel3.internal.sourceinfo.{SourceInfo}
|
||||
|
||||
import freechips.rocketchip.prci._
|
||||
import freechips.rocketchip.config.{Field, Parameters}
|
||||
import freechips.rocketchip.devices.tilelink._
|
||||
import freechips.rocketchip.devices.debug.{HasPeripheryDebug, HasPeripheryDebugModuleImp, ExportDebug}
|
||||
@@ -24,14 +25,13 @@ import freechips.rocketchip.amba.axi4._
|
||||
import boom.common.{BoomTile}
|
||||
|
||||
|
||||
import testchipip.{DromajoHelper, CanHavePeripherySerial, SerialKey}
|
||||
|
||||
import testchipip.{DromajoHelper, CanHavePeripheryTLSerial, SerialTLKey}
|
||||
|
||||
trait CanHaveHTIF { this: BaseSubsystem =>
|
||||
// Advertise HTIF if system can communicate with fesvr
|
||||
if (this match {
|
||||
case _: CanHavePeripherySerial if p(SerialKey) => true
|
||||
case _: HasPeripheryDebug if p(ExportDebug).protocols.nonEmpty => true
|
||||
case _: CanHavePeripheryTLSerial if p(SerialTLKey).nonEmpty => true
|
||||
case _: HasPeripheryDebug if p(ExportDebug).dmi => true
|
||||
case _ => false
|
||||
}) {
|
||||
ResourceBinding {
|
||||
@@ -47,7 +47,6 @@ trait CanHaveHTIF { this: BaseSubsystem =>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ChipyardSubsystem(implicit p: Parameters) extends BaseSubsystem
|
||||
with HasTiles
|
||||
with CanHaveHTIF
|
||||
@@ -56,25 +55,17 @@ class ChipyardSubsystem(implicit p: Parameters) extends BaseSubsystem
|
||||
case r: RocketTile => r.module.core.rocketImpl.coreMonitorBundle
|
||||
case b: BoomTile => b.module.core.coreMonitorBundle
|
||||
}.toList
|
||||
|
||||
override lazy val module = new ChipyardSubsystemModuleImp(this)
|
||||
}
|
||||
|
||||
|
||||
class ChipyardSubsystemModuleImp[+L <: ChipyardSubsystem](_outer: L) extends BaseSubsystemModuleImp(_outer)
|
||||
with HasResetVectorWire
|
||||
with HasTilesModuleImp
|
||||
{
|
||||
|
||||
for (i <- 0 until outer.tiles.size) {
|
||||
val wire = tile_inputs(i)
|
||||
wire.hartid := outer.hartIdList(i).U
|
||||
wire.reset_vector := global_reset_vector
|
||||
}
|
||||
|
||||
// create file with core params
|
||||
ElaborationArtefacts.add("""core.config""", outer.tiles.map(x => x.module.toString).mkString("\n"))
|
||||
// Generate C header with relevant information for Dromajo
|
||||
// This is included in the `dromajo_params.h` header file
|
||||
DromajoHelper.addArtefacts()
|
||||
DromajoHelper.addArtefacts(InSubsystem)
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,10 @@ class ChipyardSystem(implicit p: Parameters) extends ChipyardSubsystem
|
||||
with CanHaveMasterAXI4MemPort
|
||||
with CanHaveMasterAXI4MMIOPort
|
||||
with CanHaveSlaveAXI4Port
|
||||
with HasPeripheryBootROM
|
||||
{
|
||||
|
||||
val bootROM = p(BootROMLocated(location)).map { BootROM.attach(_, this, CBUS) }
|
||||
val maskROMs = p(MaskROMLocated(location)).map { MaskROM.attach(_, this, CBUS) }
|
||||
override lazy val module = new ChipyardSystemModule(this)
|
||||
}
|
||||
|
||||
@@ -37,5 +39,4 @@ class ChipyardSystem(implicit p: Parameters) extends ChipyardSubsystem
|
||||
class ChipyardSystemModule[+L <: ChipyardSystem](_outer: L) extends ChipyardSubsystemModuleImp(_outer)
|
||||
with HasRTCModuleImp
|
||||
with HasExtInterruptsModuleImp
|
||||
with HasPeripheryBootROMModuleImp
|
||||
with DontTouch
|
||||
|
||||
@@ -1,37 +1,50 @@
|
||||
package chipyard
|
||||
|
||||
import chisel3._
|
||||
|
||||
import scala.collection.mutable.{ArrayBuffer}
|
||||
import freechips.rocketchip.diplomacy.{LazyModule}
|
||||
import freechips.rocketchip.config.{Field, Parameters}
|
||||
import chipyard.iobinders.{TestHarnessFunction}
|
||||
import chipyard.config.ConfigValName._
|
||||
|
||||
import chipyard.harness.{ApplyHarnessBinders, HarnessBinders}
|
||||
|
||||
// -------------------------------
|
||||
// BOOM and/or Rocket Test Harness
|
||||
// Chipyard Test Harness
|
||||
// -------------------------------
|
||||
|
||||
case object BuildTop extends Field[Parameters => HasTestHarnessFunctions]((p: Parameters) => Module(new ChipTop()(p)))
|
||||
case object BuildTop extends Field[Parameters => LazyModule]((p: Parameters) => new ChipTop()(p))
|
||||
|
||||
trait HasTestHarnessFunctions {
|
||||
val harnessFunctions: Seq[TestHarnessFunction]
|
||||
val lazySystem: LazyModule
|
||||
val harnessFunctions = ArrayBuffer.empty[HasHarnessSignalReferences => Seq[Any]]
|
||||
val portMap = scala.collection.mutable.Map[String, Seq[Data]]()
|
||||
}
|
||||
|
||||
class TestHarness(implicit val p: Parameters) extends Module {
|
||||
trait HasHarnessSignalReferences {
|
||||
def harnessClock: Clock
|
||||
def harnessReset: Reset
|
||||
def dutReset: Reset
|
||||
def success: Bool
|
||||
}
|
||||
|
||||
class TestHarness(implicit val p: Parameters) extends Module with HasHarnessSignalReferences {
|
||||
val io = IO(new Bundle {
|
||||
val success = Output(Bool())
|
||||
})
|
||||
|
||||
val dut = p(BuildTop)(p)
|
||||
val lazyDut = LazyModule(p(BuildTop)(p)).suggestName("chiptop")
|
||||
val dut = Module(lazyDut.module)
|
||||
io.success := false.B
|
||||
|
||||
val harnessClock = clock
|
||||
val harnessReset = WireInit(reset)
|
||||
val success = io.success
|
||||
|
||||
// dutReset assignment can be overridden via a harnessFunction, but by default it is just reset
|
||||
val dutReset = WireDefault(if (p(GlobalResetSchemeKey).pinIsAsync) reset.asAsyncReset else reset)
|
||||
|
||||
dut.harnessFunctions.foreach(_(this))
|
||||
|
||||
def success = io.success
|
||||
def harnessReset = this.reset.asBool
|
||||
|
||||
lazyDut match { case d: HasTestHarnessFunctions =>
|
||||
d.harnessFunctions.foreach(_(this))
|
||||
ApplyHarnessBinders(this, d.lazySystem, p(HarnessBinders), d.portMap.toMap)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,18 +5,45 @@ import freechips.rocketchip.config.{Config}
|
||||
// --------------
|
||||
// Chipyard abstract ("base") configuration
|
||||
// NOTE: This configuration is NOT INSTANTIABLE, as it defines a empty system with no tiles
|
||||
//
|
||||
// The default set of IOBinders instantiate IOcells and ChipTop IOs for digital IO bundles.
|
||||
// The default set of HarnessBinders instantiate TestHarness hardware for interacting with ChipTop IOs
|
||||
// --------------
|
||||
|
||||
class AbstractConfig extends Config(
|
||||
new chipyard.iobinders.WithUARTAdapter ++ // display UART with a SimUARTAdapter
|
||||
new chipyard.iobinders.WithTieOffInterrupts ++ // tie off top-level interrupts
|
||||
new chipyard.iobinders.WithBlackBoxSimMem ++ // drive the master AXI4 memory with a blackbox DRAMSim model
|
||||
new chipyard.iobinders.WithTiedOffDebug ++ // tie off debug (since we are using SimSerial for testing)
|
||||
new chipyard.iobinders.WithSimSerial ++ // drive TSI with SimSerial for testing
|
||||
new testchipip.WithTSI ++ // use testchipip serial offchip link
|
||||
// The HarnessBinders control generation of hardware in the TestHarness
|
||||
new chipyard.harness.WithUARTAdapter ++ // add UART adapter to display UART on stdout, if uart is present
|
||||
new chipyard.harness.WithBlackBoxSimMem ++ // add SimDRAM DRAM model for axi4 backing memory, if axi4 mem is enabled
|
||||
new chipyard.harness.WithSimSerial ++ // add external serial-adapter and RAM
|
||||
new chipyard.harness.WithSimDebug ++ // add SimJTAG or SimDTM adapters if debug module is enabled
|
||||
new chipyard.harness.WithGPIOTiedOff ++ // tie-off chiptop GPIOs, if GPIOs are present
|
||||
new chipyard.harness.WithSimSPIFlashModel ++ // add simulated SPI flash memory, if SPI is enabled
|
||||
new chipyard.harness.WithSimAXIMMIO ++ // add SimAXIMem for axi4 mmio port, if enabled
|
||||
new chipyard.harness.WithTieOffInterrupts ++ // tie-off interrupt ports, if present
|
||||
new chipyard.harness.WithTieOffL2FBusAXI ++ // tie-off external AXI4 master, if present
|
||||
|
||||
// The IOBinders instantiate ChipTop IOs to match desired digital IOs
|
||||
// IOCells are generated for "Chip-like" IOs, while simulation-only IOs are directly punched through
|
||||
new chipyard.iobinders.WithAXI4MemPunchthrough ++
|
||||
new chipyard.iobinders.WithAXI4MMIOPunchthrough ++
|
||||
new chipyard.iobinders.WithL2FBusAXI4Punchthrough ++
|
||||
new chipyard.iobinders.WithBlockDeviceIOPunchthrough ++
|
||||
new chipyard.iobinders.WithNICIOPunchthrough ++
|
||||
new chipyard.iobinders.WithSerialTLIOCells ++
|
||||
new chipyard.iobinders.WithDebugIOCells ++
|
||||
new chipyard.iobinders.WithUARTIOCells ++
|
||||
new chipyard.iobinders.WithGPIOCells ++
|
||||
new chipyard.iobinders.WithUARTIOCells ++
|
||||
new chipyard.iobinders.WithSPIIOCells ++
|
||||
new chipyard.iobinders.WithTraceIOPunchthrough ++
|
||||
new chipyard.iobinders.WithExtInterruptIOCells ++
|
||||
|
||||
new testchipip.WithDefaultSerialTL ++ // use serialized tilelink port to external serialadapter/harnessRAM
|
||||
new chipyard.config.WithBootROM ++ // use default bootrom
|
||||
new chipyard.config.WithUART ++ // add a UART
|
||||
new chipyard.config.WithL2TLBs(1024) ++ // use L2 TLBs
|
||||
new chipyard.config.WithNoSubsystemDrivenClocks ++ // drive the subsystem diplomatic clocks from ChipTop instead of using implicit clocks
|
||||
new freechips.rocketchip.subsystem.WithJtagDTM ++ // set the debug module to expose a JTAG port
|
||||
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
|
||||
|
||||
@@ -13,7 +13,7 @@ class ArianeConfig extends Config(
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class dmiArianeConfig extends Config(
|
||||
new chipyard.iobinders.WithTiedOffSerial ++ // Tie off the serial port, override default instantiation of SimSerial
|
||||
new chipyard.iobinders.WithSimDebug ++ // add SimDebug and use it to drive simulation, override default tie-off debug
|
||||
new chipyard.harness.WithSerialAdapterTiedOff ++ // Tie off the serial port, override default instantiation of SimSerial
|
||||
new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port
|
||||
new ariane.WithNArianeCores(1) ++ // single Ariane core
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
@@ -33,13 +33,13 @@ class HwachaLargeBoomConfig extends Config(
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class LoopbackNICLargeBoomConfig extends Config(
|
||||
new chipyard.iobinders.WithLoopbackNIC ++ // drive NIC IOs with loopback
|
||||
new chipyard.harness.WithLoopbackNIC ++ // drive NIC IOs with loopback
|
||||
new icenet.WithIceNIC ++ // build a NIC
|
||||
new boom.common.WithNLargeBooms(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class DromajoBoomConfig extends Config(
|
||||
new chipyard.iobinders.WithSimDromajoBridge ++ // attach Dromajo
|
||||
new chipyard.harness.WithSimDromajoBridge ++ // attach Dromajo
|
||||
new chipyard.config.WithTraceIO ++ // enable the traceio
|
||||
new boom.common.WithNSmallBooms(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
@@ -12,29 +12,21 @@ class RocketConfig extends Config(
|
||||
|
||||
class HwachaRocketConfig extends Config(
|
||||
new chipyard.config.WithHwachaTest ++
|
||||
new hwacha.DefaultHwachaConfig ++ // use Hwacha vector accelerator
|
||||
new hwacha.DefaultHwachaConfig ++ // use Hwacha vector accelerator
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
// DOC include start: GemminiRocketConfig
|
||||
class GemminiRocketConfig extends Config(
|
||||
new gemmini.DefaultGemminiConfig ++ // use Gemmini systolic array GEMM accelerator
|
||||
new gemmini.DefaultGemminiConfig ++ // use Gemmini systolic array GEMM accelerator
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
// DOC include end: GemminiRocketConfig
|
||||
|
||||
// DOC include start: JtagRocket
|
||||
class jtagRocketConfig extends Config(
|
||||
new chipyard.iobinders.WithSimDebug ++ // add SimDebug, in addition to default SimSerial
|
||||
new freechips.rocketchip.subsystem.WithJtagDTM ++ // sets DTM communication interface to JTAG
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
// DOC include end: JtagRocket
|
||||
|
||||
// DOC include start: DmiRocket
|
||||
class dmiRocketConfig extends Config(
|
||||
new chipyard.iobinders.WithTiedOffSerial ++ // tie-off serial, override default add SimSerial
|
||||
new chipyard.iobinders.WithSimDebug ++ // add SimDebug, override default tie-off debug
|
||||
new chipyard.harness.WithSerialAdapterTiedOff ++ // don't attach an external SimSerial
|
||||
new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
// DOC include end: DmiRocket
|
||||
@@ -48,54 +40,53 @@ class GCDTLRocketConfig extends Config(
|
||||
|
||||
// DOC include start: GCDAXI4BlackBoxRocketConfig
|
||||
class GCDAXI4BlackBoxRocketConfig extends Config(
|
||||
new chipyard.example.WithGCD(useAXI4=true, useBlackBox=true) ++ // Use GCD blackboxed verilog, connect by AXI4->Tilelink
|
||||
new chipyard.example.WithGCD(useAXI4=true, useBlackBox=true) ++ // Use GCD blackboxed verilog, connect by AXI4->Tilelink
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
// DOC include end: GCDAXI4BlackBoxRocketConfig
|
||||
|
||||
class LargeSPIFlashROMRocketConfig extends Config(
|
||||
new chipyard.iobinders.WithSimSPIFlashModel(true) ++ // add the SPI flash model in the harness (read-only)
|
||||
new chipyard.harness.WithSimSPIFlashModel(true) ++ // add the SPI flash model in the harness (read-only)
|
||||
new chipyard.config.WithSPIFlash ++ // add the SPI flash controller
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class SmallSPIFlashRocketConfig extends Config(
|
||||
new chipyard.iobinders.WithSimSPIFlashModel(false) ++ // add the SPI flash model in the harness (writeable)
|
||||
new chipyard.harness.WithSimSPIFlashModel(false) ++ // add the SPI flash model in the harness (writeable)
|
||||
new chipyard.config.WithSPIFlash(0x100000) ++ // add the SPI flash controller (1 MiB)
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class SimAXIRocketConfig extends Config(
|
||||
new chipyard.iobinders.WithSimAXIMem ++ // drive the master AXI4 memory with a SimAXIMem, a 1-cycle magic memory, instead of default SimDRAM
|
||||
new chipyard.harness.WithSimAXIMem ++ // drive the master AXI4 memory with a SimAXIMem, a 1-cycle magic memory, instead of default SimDRAM
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class SimBlockDeviceRocketConfig extends Config(
|
||||
new chipyard.iobinders.WithSimBlockDevice ++ // drive block-device IOs with SimBlockDevice
|
||||
new testchipip.WithBlockDevice ++ // add block-device module to peripherybus
|
||||
new chipyard.harness.WithSimBlockDevice ++ // drive block-device IOs with SimBlockDevice
|
||||
new testchipip.WithBlockDevice ++ // add block-device module to peripherybus
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class BlockDeviceModelRocketConfig extends Config(
|
||||
new chipyard.iobinders.WithBlockDeviceModel ++ // drive block-device IOs with a BlockDeviceModel
|
||||
new testchipip.WithBlockDevice ++ // add block-device module to periphery bus
|
||||
new chipyard.harness.WithBlockDeviceModel ++ // drive block-device IOs with a BlockDeviceModel
|
||||
new testchipip.WithBlockDevice ++ // add block-device module to periphery bus
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
// DOC include start: GPIORocketConfig
|
||||
class GPIORocketConfig extends Config(
|
||||
new chipyard.iobinders.WithGPIOTiedOff ++ // tie off GPIO inputs into the top
|
||||
new chipyard.config.WithGPIO ++ // add GPIOs to the peripherybus
|
||||
new chipyard.config.WithGPIO ++ // add GPIOs to the peripherybus
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
// DOC include end: GPIORocketConfig
|
||||
|
||||
class QuadRocketConfig extends Config(
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(4) ++ // quad-core (4 RocketTiles)
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(4) ++ // quad-core (4 RocketTiles)
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class RV32RocketConfig extends Config(
|
||||
new freechips.rocketchip.subsystem.WithRV32 ++ // set RocketTiles to be 32-bit
|
||||
new freechips.rocketchip.subsystem.WithRV32 ++ // set RocketTiles to be 32-bit
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
@@ -113,14 +104,14 @@ class Sha3RocketConfig extends Config(
|
||||
|
||||
// DOC include start: InitZeroRocketConfig
|
||||
class InitZeroRocketConfig extends Config(
|
||||
new chipyard.example.WithInitZero(0x88000000L, 0x1000L) ++ // add InitZero
|
||||
new chipyard.example.WithInitZero(0x88000000L, 0x1000L) ++ // add InitZero
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
// DOC include end: InitZeroRocketConfig
|
||||
|
||||
class LoopbackNICRocketConfig extends Config(
|
||||
new chipyard.iobinders.WithLoopbackNIC ++ // drive NIC IOs with loopback
|
||||
new icenet.WithIceNIC ++ // add an IceNIC
|
||||
new chipyard.harness.WithLoopbackNIC ++ // drive NIC IOs with loopback
|
||||
new icenet.WithIceNIC ++ // add an IceNIC
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
@@ -135,8 +126,8 @@ class ScratchpadOnlyRocketConfig extends Config(
|
||||
// DOC include end: l1scratchpadrocket
|
||||
|
||||
class L1ScratchpadRocketConfig extends Config(
|
||||
new chipyard.config.WithRocketICacheScratchpad ++ // use rocket ICache scratchpad
|
||||
new chipyard.config.WithRocketDCacheScratchpad ++ // use rocket DCache scratchpad
|
||||
new chipyard.config.WithRocketICacheScratchpad ++ // use rocket ICache scratchpad
|
||||
new chipyard.config.WithRocketDCacheScratchpad ++ // use rocket DCache scratchpad
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
@@ -150,37 +141,49 @@ class MbusScratchpadRocketConfig extends Config(
|
||||
|
||||
// DOC include start: RingSystemBusRocket
|
||||
class RingSystemBusRocketConfig extends Config(
|
||||
new testchipip.WithRingSystemBus ++ // Ring-topology system bus
|
||||
new testchipip.WithRingSystemBus ++ // Ring-topology system bus
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
// DOC include end: RingSystemBusRocket
|
||||
|
||||
class StreamingPassthroughRocketConfig extends Config(
|
||||
new chipyard.example.WithStreamingPassthrough ++ // use top with tilelink-controlled streaming passthrough
|
||||
new chipyard.example.WithStreamingPassthrough ++ // use top with tilelink-controlled streaming passthrough
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
// DOC include start: StreamingFIRRocketConfig
|
||||
class StreamingFIRRocketConfig extends Config (
|
||||
new chipyard.example.WithStreamingFIR ++ // use top with tilelink-controlled streaming FIR
|
||||
new chipyard.example.WithStreamingFIR ++ // use top with tilelink-controlled streaming FIR
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
// DOC include end: StreamingFIRRocketConfig
|
||||
|
||||
class SmallNVDLARocketConfig extends Config(
|
||||
new nvidia.blocks.dla.WithNVDLA("small") ++ // add a small NVDLA
|
||||
new nvidia.blocks.dla.WithNVDLA("small") ++ // add a small NVDLA
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class LargeNVDLARocketConfig extends Config(
|
||||
new nvidia.blocks.dla.WithNVDLA("large", true) ++ // add a large NVDLA with synth. rams
|
||||
new nvidia.blocks.dla.WithNVDLA("large", true) ++ // add a large NVDLA with synth. rams
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class MMIORocketConfig extends Config(
|
||||
new chipyard.iobinders.WithTieOffL2FBusAXI ++ // Tie-off the incoming MMIO port
|
||||
new chipyard.iobinders.WithSimAXIMMIO ++ // Attach a simulated memory to the outwards MMIO port
|
||||
new freechips.rocketchip.subsystem.WithDefaultMMIOPort ++ // add default external master port
|
||||
new freechips.rocketchip.subsystem.WithDefaultMMIOPort ++ // add default external master port
|
||||
new freechips.rocketchip.subsystem.WithDefaultSlavePort ++ // add default external slave port
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
// NOTE: This config doesn't work yet because SimWidgets in the TestHarness
|
||||
// always get the TestHarness clock. The Tiles and Uncore receive the correct clocks
|
||||
class DividedClockRocketConfig extends Config(
|
||||
new chipyard.config.WithTileDividedClock ++ // Put the Tile on its own clock domain
|
||||
new freechips.rocketchip.subsystem.WithRationalRocketTiles ++ // Add rational crossings between RocketTile and uncore
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class LBWIFRocketConfig extends Config(
|
||||
new testchipip.WithSerialTLMem(isMainMemory=true) ++ // set lbwif memory base to DRAM_BASE, use as main memory
|
||||
new freechips.rocketchip.subsystem.WithNoMemPort ++ // remove AXI4 backing memory
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
@@ -3,46 +3,37 @@ package chipyard
|
||||
import freechips.rocketchip.config.{Config}
|
||||
import freechips.rocketchip.rocket.{DCacheParams}
|
||||
|
||||
class TraceGenConfig extends Config(
|
||||
new chipyard.iobinders.WithBlackBoxSimMem ++
|
||||
new chipyard.iobinders.WithTraceGenSuccessBinder ++
|
||||
class AbstractTraceGenConfig extends Config(
|
||||
new chipyard.harness.WithBlackBoxSimMem ++
|
||||
new chipyard.harness.WithTraceGenSuccess ++
|
||||
new chipyard.iobinders.WithAXI4MemPunchthrough ++
|
||||
new chipyard.iobinders.WithTraceGenSuccessPunchthrough ++
|
||||
new chipyard.config.WithTracegenSystem ++
|
||||
new tracegen.WithTraceGen()(List.fill(2) { DCacheParams(nMSHRs = 0, nSets = 16, nWays = 2) }) ++
|
||||
new chipyard.config.WithNoSubsystemDrivenClocks ++
|
||||
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++
|
||||
new freechips.rocketchip.groundtest.GroundTestBaseConfig)
|
||||
|
||||
|
||||
class TraceGenConfig extends Config(
|
||||
new tracegen.WithTraceGen()(List.fill(2) { DCacheParams(nMSHRs = 0, nSets = 16, nWays = 2) }) ++
|
||||
new AbstractTraceGenConfig)
|
||||
|
||||
class NonBlockingTraceGenConfig extends Config(
|
||||
new chipyard.iobinders.WithBlackBoxSimMem ++
|
||||
new chipyard.iobinders.WithTraceGenSuccessBinder ++
|
||||
new chipyard.config.WithTracegenSystem ++
|
||||
new tracegen.WithTraceGen()(List.fill(2) { DCacheParams(nMSHRs = 2, nSets = 16, nWays = 2) }) ++
|
||||
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++
|
||||
new freechips.rocketchip.groundtest.GroundTestBaseConfig)
|
||||
new AbstractTraceGenConfig)
|
||||
|
||||
class BoomTraceGenConfig extends Config(
|
||||
new chipyard.iobinders.WithBlackBoxSimMem ++
|
||||
new chipyard.iobinders.WithTraceGenSuccessBinder ++
|
||||
new chipyard.config.WithTracegenSystem ++
|
||||
new tracegen.WithBoomTraceGen()(List.fill(2) { DCacheParams(nMSHRs = 8, nSets = 16, nWays = 2) }) ++
|
||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++
|
||||
new freechips.rocketchip.groundtest.GroundTestBaseConfig)
|
||||
new AbstractTraceGenConfig)
|
||||
|
||||
class NonBlockingTraceGenL2Config extends Config(
|
||||
new chipyard.iobinders.WithBlackBoxSimMem ++
|
||||
new chipyard.iobinders.WithTraceGenSuccessBinder ++
|
||||
new chipyard.config.WithTracegenSystem ++
|
||||
new tracegen.WithL2TraceGen()(List.fill(2)(DCacheParams(nMSHRs = 2, nSets = 16, nWays = 4))) ++
|
||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++
|
||||
new freechips.rocketchip.groundtest.GroundTestBaseConfig)
|
||||
new AbstractTraceGenConfig)
|
||||
|
||||
class NonBlockingTraceGenL2RingConfig extends Config(
|
||||
new chipyard.iobinders.WithBlackBoxSimMem ++
|
||||
new chipyard.iobinders.WithTraceGenSuccessBinder ++
|
||||
new chipyard.config.WithTracegenSystem ++
|
||||
new tracegen.WithL2TraceGen()(List.fill(2)(DCacheParams(nMSHRs = 2, nSets = 16, nWays = 4))) ++
|
||||
new testchipip.WithRingSystemBus ++
|
||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++
|
||||
new freechips.rocketchip.groundtest.GroundTestBaseConfig)
|
||||
new AbstractTraceGenConfig)
|
||||
|
||||
@@ -12,26 +12,16 @@ import freechips.rocketchip.config.{Config}
|
||||
|
||||
// This file was originally developed for the cancelled ASPLOS-2020
|
||||
// Chipyard tutorial. While the configs here work, the corresponding
|
||||
// slideware has not yet been created
|
||||
// slideware has not yet been created.
|
||||
|
||||
// NOTE: Configs should be read bottom-up, since they are applied bottom-up
|
||||
|
||||
// NOTE: The TutorialConfigs build off of the AbstractConfig defined in AbstractConfig.scala
|
||||
// Users should try to understand the functionality of the AbstractConfig before proceeding
|
||||
// with the TutorialConfigs below
|
||||
|
||||
// Tutorial Phase 1: Configure the cores, caches
|
||||
class TutorialStarterConfig extends Config(
|
||||
// IOBinders specify how to connect to IOs in our TestHarness
|
||||
// These config fragments do not affect
|
||||
new chipyard.iobinders.WithUARTAdapter ++ // Connect a SimUART adapter to display UART on stdout
|
||||
new chipyard.iobinders.WithBlackBoxSimMem ++ // Connect simulated external memory
|
||||
new chipyard.iobinders.WithTieOffInterrupts ++ // Do not simulate external interrupts
|
||||
new chipyard.iobinders.WithTiedOffDebug ++ // Disconnect the debug module, since we use TSI for bring-up
|
||||
new chipyard.iobinders.WithSimSerial ++ // Connect external SimSerial widget to drive TSI
|
||||
|
||||
// Config fragments below this line affect hardware generation
|
||||
// of the Top
|
||||
new testchipip.WithTSI ++ // Add a TSI (Test Serial Interface) widget to bring-up the core
|
||||
new chipyard.config.WithBootROM ++ // Use the Chipyard BootROM
|
||||
new chipyard.config.WithUART ++ // Add a UART
|
||||
|
||||
// CUSTOMIZE THE CORE
|
||||
// Uncomment out one (or multiple) of the lines below, and choose
|
||||
// how many cores you want.
|
||||
@@ -42,29 +32,11 @@ class TutorialStarterConfig extends Config(
|
||||
// Uncomment this line, and specify a size if you want to have a L2
|
||||
// new freechips.rocketchip.subsystem.WithInclusiveCache(nBanks=1, nWays=4, capacityKB=128) ++
|
||||
|
||||
// For simpler designs, we want to minimize IOs on
|
||||
// our Top. These config fragments remove unnecessary
|
||||
// ports
|
||||
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++
|
||||
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ // hierarchical buses including mbus+l2
|
||||
// BaseConfig configures "bare" rocketchip system
|
||||
new freechips.rocketchip.system.BaseConfig
|
||||
new chipyard.config.AbstractConfig
|
||||
)
|
||||
|
||||
|
||||
// Tutorial Phase 2: Integrate a TileLink or AXI4 MMIO device
|
||||
class TutorialMMIOConfig extends Config(
|
||||
new chipyard.iobinders.WithUARTAdapter ++
|
||||
new chipyard.iobinders.WithBlackBoxSimMem ++
|
||||
new chipyard.iobinders.WithTieOffInterrupts ++
|
||||
new chipyard.iobinders.WithTiedOffDebug ++
|
||||
new chipyard.iobinders.WithSimSerial ++
|
||||
|
||||
new testchipip.WithTSI ++
|
||||
new chipyard.config.WithBootROM ++
|
||||
new chipyard.config.WithUART ++
|
||||
|
||||
// Attach either a TileLink or AXI4 version of GCD
|
||||
// Uncomment one of the below lines
|
||||
@@ -73,61 +45,26 @@ class TutorialMMIOConfig extends Config(
|
||||
|
||||
// For this demonstration we assume the base system is a single-core Rocket, for fast elaboration
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++
|
||||
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++
|
||||
new freechips.rocketchip.system.BaseConfig
|
||||
new chipyard.config.AbstractConfig
|
||||
)
|
||||
|
||||
// Tutorial Phase 3: Integrate a SHA3 RoCC accelerator
|
||||
class TutorialSha3Config extends Config(
|
||||
new chipyard.iobinders.WithUARTAdapter ++
|
||||
new chipyard.iobinders.WithBlackBoxSimMem ++
|
||||
new chipyard.iobinders.WithTieOffInterrupts ++
|
||||
new chipyard.iobinders.WithTiedOffDebug ++
|
||||
new chipyard.iobinders.WithSimSerial ++
|
||||
|
||||
new testchipip.WithTSI ++
|
||||
new chipyard.config.WithBootROM ++
|
||||
new chipyard.config.WithUART ++
|
||||
|
||||
// Uncomment this line once you added SHA3 to the build.sbt, and cloned the SHA3 repo
|
||||
// new sha3.WithSha3Accel ++
|
||||
|
||||
// For this demonstration we assume the base system is a single-core Rocket, for fast elaboration
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++
|
||||
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++
|
||||
new freechips.rocketchip.system.BaseConfig
|
||||
new chipyard.config.AbstractConfig
|
||||
)
|
||||
|
||||
// Tutorial Phase 4: Integrate a Black-box verilog version of the SHA3 RoCC accelerator
|
||||
class TutorialSha3BlackBoxConfig extends Config(
|
||||
new chipyard.iobinders.WithUARTAdapter ++
|
||||
new chipyard.iobinders.WithBlackBoxSimMem ++
|
||||
new chipyard.iobinders.WithTieOffInterrupts ++
|
||||
new chipyard.iobinders.WithTiedOffDebug ++
|
||||
new chipyard.iobinders.WithSimSerial ++
|
||||
|
||||
new testchipip.WithTSI ++
|
||||
new chipyard.config.WithBootROM ++
|
||||
new chipyard.config.WithUART ++
|
||||
|
||||
// Uncomment these lines once SHA3 is integrated
|
||||
// new sha3.WithSha3BlackBox ++ // Specify we want the Black-box verilog version of Sha3 Ctrl
|
||||
// new sha3.WithSha3Accel ++
|
||||
|
||||
// For this demonstration we assume the base system is a single-core Rocket, for fast elaboration
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||
new freechips.rocketchip.subsystem.WithNoMMIOPort ++
|
||||
new freechips.rocketchip.subsystem.WithNoSlavePort ++
|
||||
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++
|
||||
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++
|
||||
new freechips.rocketchip.system.BaseConfig
|
||||
new chipyard.config.AbstractConfig
|
||||
)
|
||||
|
||||
@@ -8,13 +8,13 @@ import chisel3.experimental.annotate
|
||||
import freechips.rocketchip.config.{Field, Config, Parameters}
|
||||
import freechips.rocketchip.diplomacy.{LazyModule}
|
||||
import freechips.rocketchip.devices.debug.{Debug, HasPeripheryDebugModuleImp}
|
||||
import freechips.rocketchip.amba.axi4.{AXI4Bundle}
|
||||
import freechips.rocketchip.subsystem.{CanHaveMasterAXI4MemPort, HasExtInterruptsModuleImp, BaseSubsystem, HasTilesModuleImp}
|
||||
import freechips.rocketchip.tile.{RocketTile}
|
||||
import sifive.blocks.devices.uart.HasPeripheryUARTModuleImp
|
||||
import sifive.blocks.devices.gpio.{HasPeripheryGPIOModuleImp}
|
||||
import sifive.blocks.devices.uart._
|
||||
|
||||
import testchipip.{CanHavePeripherySerialModuleImp, CanHavePeripheryBlockDeviceModuleImp}
|
||||
import icenet.CanHavePeripheryIceNICModuleImp
|
||||
import testchipip._
|
||||
import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly}
|
||||
|
||||
import junctions.{NastiKey, NastiParameters}
|
||||
import midas.models.{FASEDBridge, AXI4EdgeSummary, CompleteConfig}
|
||||
@@ -25,73 +25,119 @@ import tracegen.{TraceGenSystemModuleImp}
|
||||
import ariane.ArianeTile
|
||||
|
||||
import boom.common.{BoomTile}
|
||||
|
||||
import chipyard.iobinders.{IOBinders, OverrideIOBinder, ComposeIOBinder, GetSystemParameters}
|
||||
import testchipip.{CanHaveTraceIOModuleImp}
|
||||
import barstools.iocell.chisel._
|
||||
import chipyard.iobinders.{IOBinders, OverrideIOBinder, ComposeIOBinder, GetSystemParameters, IOCellKey}
|
||||
import chipyard.{HasHarnessSignalReferences}
|
||||
import chipyard.harness._
|
||||
|
||||
object MainMemoryConsts {
|
||||
val regionNamePrefix = "MainMemory"
|
||||
def globalName = s"${regionNamePrefix}_${NodeIdx()}"
|
||||
}
|
||||
|
||||
class WithSerialBridge extends OverrideIOBinder({
|
||||
(system: CanHavePeripherySerialModuleImp) =>
|
||||
system.serial.foreach(s => SerialBridge(system.clock, s, MainMemoryConsts.globalName)(system.p)); Nil
|
||||
trait Unsupported {
|
||||
require(false, "We do not support this IOCell type")
|
||||
}
|
||||
|
||||
class FireSimAnalogIOCell extends RawModule with AnalogIOCell with Unsupported {
|
||||
val io = IO(new AnalogIOCellBundle)
|
||||
}
|
||||
class FireSimDigitalGPIOCell extends RawModule with DigitalGPIOCell with Unsupported {
|
||||
val io = IO(new DigitalGPIOCellBundle)
|
||||
}
|
||||
class FireSimDigitalInIOCell extends RawModule with DigitalInIOCell {
|
||||
val io = IO(new DigitalInIOCellBundle)
|
||||
io.i := io.pad
|
||||
}
|
||||
class FireSimDigitalOutIOCell extends RawModule with DigitalOutIOCell {
|
||||
val io = IO(new DigitalOutIOCellBundle)
|
||||
io.pad := io.o
|
||||
}
|
||||
|
||||
case class FireSimIOCellParams() extends IOCellTypeParams {
|
||||
def analog() = Module(new FireSimAnalogIOCell)
|
||||
def gpio() = Module(new FireSimDigitalGPIOCell)
|
||||
def input() = Module(new FireSimDigitalInIOCell)
|
||||
def output() = Module(new FireSimDigitalOutIOCell)
|
||||
}
|
||||
|
||||
class WithFireSimIOCellModels extends Config((site, here, up) => {
|
||||
case IOCellKey => FireSimIOCellParams()
|
||||
})
|
||||
|
||||
class WithNICBridge extends OverrideIOBinder({
|
||||
(system: CanHavePeripheryIceNICModuleImp) =>
|
||||
system.net.foreach(n => NICBridge(system.clock, n)(system.p)); Nil
|
||||
class WithSerialBridge extends OverrideHarnessBinder({
|
||||
(system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => {
|
||||
ports.map { p =>
|
||||
val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, p, th.harnessReset)
|
||||
withClockAndReset(p.clock, th.harnessReset) {
|
||||
SerialBridge(p.clock, ram.module.io.tsi_ser, MainMemoryConsts.globalName)(GetSystemParameters(system))
|
||||
}
|
||||
}
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithUARTBridge extends OverrideIOBinder({
|
||||
(system: HasPeripheryUARTModuleImp) =>
|
||||
system.uart.foreach(u => UARTBridge(system.clock, u)(system.p)); Nil
|
||||
class WithNICBridge extends OverrideHarnessBinder({
|
||||
(system: CanHavePeripheryIceNIC, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => {
|
||||
val p: Parameters = GetSystemParameters(system)
|
||||
ports.map { n => withClockAndReset(n.clock, th.harnessReset) { NICBridge(n.clock, n.bits)(p) } }
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithBlockDeviceBridge extends OverrideIOBinder({
|
||||
(system: CanHavePeripheryBlockDeviceModuleImp) =>
|
||||
system.bdev.foreach(b => BlockDevBridge(system.clock, b, system.reset.toBool)(system.p)); Nil
|
||||
class WithUARTBridge extends OverrideHarnessBinder({
|
||||
(system: HasPeripheryUARTModuleImp, th: HasHarnessSignalReferences, ports: Seq[UARTPortIO]) =>
|
||||
ports.map { p => UARTBridge(th.harnessClock, p)(system.p) }; Nil
|
||||
})
|
||||
|
||||
|
||||
class WithFASEDBridge extends OverrideIOBinder({
|
||||
(system: CanHaveMasterAXI4MemPort) => {
|
||||
class WithBlockDeviceBridge extends OverrideHarnessBinder({
|
||||
(system: CanHavePeripheryBlockDevice, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => {
|
||||
implicit val p: Parameters = GetSystemParameters(system)
|
||||
(system.mem_axi4 zip system.memAXI4Node.in).foreach({ case (axi4, (_, edge)) =>
|
||||
val nastiKey = NastiParameters(axi4.r.bits.data.getWidth,
|
||||
axi4.ar.bits.addr.getWidth,
|
||||
axi4.ar.bits.id.getWidth)
|
||||
ports.map { b => BlockDevBridge(b.clock, b.bits, th.harnessReset.toBool) }
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithFASEDBridge extends OverrideHarnessBinder({
|
||||
(system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[AXI4Bundle]]) => {
|
||||
implicit val p: Parameters = GetSystemParameters(system)
|
||||
(ports zip system.memAXI4Node.edges.in).map { case (axi4, edge) =>
|
||||
val nastiKey = NastiParameters(axi4.bits.r.bits.data.getWidth,
|
||||
axi4.bits.ar.bits.addr.getWidth,
|
||||
axi4.bits.ar.bits.id.getWidth)
|
||||
system match {
|
||||
case s: BaseSubsystem => FASEDBridge(s.module.clock, axi4, s.module.reset.toBool,
|
||||
case s: BaseSubsystem => FASEDBridge(axi4.clock, axi4.bits, th.harnessReset.asBool,
|
||||
CompleteConfig(p(firesim.configs.MemModelKey),
|
||||
nastiKey,
|
||||
Some(AXI4EdgeSummary(edge)),
|
||||
Some(MainMemoryConsts.globalName)))
|
||||
case _ => throw new Exception("Attempting to attach FASED Bridge to misconfigured design")
|
||||
}
|
||||
})
|
||||
}
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithTracerVBridge extends ComposeIOBinder({
|
||||
(system: CanHaveTraceIOModuleImp) =>
|
||||
system.traceIO.foreach(_.traces.map(tileTrace => TracerVBridge(tileTrace)(system.p))); Nil
|
||||
})
|
||||
|
||||
|
||||
|
||||
class WithDromajoBridge extends ComposeIOBinder({
|
||||
(system: CanHaveTraceIOModuleImp) => {
|
||||
system.traceIO.foreach(_.traces.map(tileTrace => DromajoBridge(tileTrace)(system.p))); Nil
|
||||
class WithTracerVBridge extends ComposeHarnessBinder({
|
||||
(system: CanHaveTraceIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[TraceOutputTop]) => {
|
||||
ports.map { p =>
|
||||
p.traces.map(
|
||||
tileTrace => withClockAndReset(tileTrace.clock, tileTrace.reset) { TracerVBridge(tileTrace)(system.p) }
|
||||
)
|
||||
}
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithDromajoBridge extends ComposeHarnessBinder({
|
||||
(system: CanHaveTraceIOModuleImp, th: HasHarnessSignalReferences, ports: Seq[TraceOutputTop]) =>
|
||||
ports.map { p => p.traces.map(tileTrace => DromajoBridge(tileTrace)(system.p)) }; Nil
|
||||
})
|
||||
|
||||
class WithTraceGenBridge extends OverrideIOBinder({
|
||||
(system: TraceGenSystemModuleImp) =>
|
||||
GroundTestBridge(system.clock, system.success)(system.p); Nil
|
||||
|
||||
class WithTraceGenBridge extends OverrideHarnessBinder({
|
||||
(system: TraceGenSystemModuleImp, th: HasHarnessSignalReferences, ports: Seq[Bool]) =>
|
||||
ports.map { p => GroundTestBridge(th.harnessClock, p)(system.p) }; Nil
|
||||
})
|
||||
|
||||
class WithFireSimMultiCycleRegfile extends ComposeIOBinder({
|
||||
@@ -105,52 +151,25 @@ class WithFireSimMultiCycleRegfile extends ComposeIOBinder({
|
||||
val core = b.module.core
|
||||
core.iregfile match {
|
||||
case irf: boom.exu.RegisterFileSynthesizable => annotate(MemModelAnnotation(irf.regfile))
|
||||
case _ => Nil
|
||||
}
|
||||
if (core.fp_pipeline != null) core.fp_pipeline.fregfile match {
|
||||
case frf: boom.exu.RegisterFileSynthesizable => annotate(MemModelAnnotation(frf.regfile))
|
||||
case _ => Nil
|
||||
}
|
||||
}
|
||||
case _ =>
|
||||
}
|
||||
Nil
|
||||
(Nil, Nil)
|
||||
}
|
||||
})
|
||||
|
||||
class WithTiedOffSystemGPIO extends OverrideIOBinder({
|
||||
(system: HasPeripheryGPIOModuleImp) =>
|
||||
system.gpio.foreach(_.pins.foreach(_.i.ival := false.B)); Nil
|
||||
})
|
||||
|
||||
class WithTiedOffSystemDebug extends OverrideIOBinder({
|
||||
(system: HasPeripheryDebugModuleImp) => {
|
||||
Debug.tieoffDebug(system.debug, system.resetctrl, Some(system.psd))(system.p)
|
||||
// tieoffDebug doesn't actually tie everything off :/
|
||||
system.debug.foreach { d =>
|
||||
d.clockeddmi.foreach({ cdmi => cdmi.dmi.req.bits := DontCare })
|
||||
d.dmactiveAck := DontCare
|
||||
}
|
||||
Nil
|
||||
}
|
||||
})
|
||||
|
||||
class WithTiedOffSystemInterrupts extends OverrideIOBinder({
|
||||
(system: HasExtInterruptsModuleImp) =>
|
||||
system.interrupts := 0.U; Nil
|
||||
})
|
||||
|
||||
|
||||
// Shorthand to register all of the provided bridges above
|
||||
class WithDefaultFireSimBridges extends Config(
|
||||
new WithTiedOffSystemGPIO ++
|
||||
new WithTiedOffSystemDebug ++
|
||||
new WithTiedOffSystemInterrupts ++
|
||||
new WithSerialBridge ++
|
||||
new WithNICBridge ++
|
||||
new WithUARTBridge ++
|
||||
new WithBlockDeviceBridge ++
|
||||
new WithFASEDBridge ++
|
||||
new WithFireSimMultiCycleRegfile ++
|
||||
new WithTracerVBridge
|
||||
new WithTracerVBridge ++
|
||||
new WithFireSimIOCellModels
|
||||
)
|
||||
|
||||
@@ -3,14 +3,19 @@
|
||||
package firesim.firesim
|
||||
|
||||
import chisel3._
|
||||
import chisel3.experimental.{IO}
|
||||
|
||||
import freechips.rocketchip.prci._
|
||||
import freechips.rocketchip.subsystem.{BaseSubsystem, SubsystemDriveAsyncClockGroupsKey}
|
||||
import freechips.rocketchip.config.{Field, Config, Parameters}
|
||||
import freechips.rocketchip.diplomacy.{LazyModule}
|
||||
import freechips.rocketchip.diplomacy.{LazyModule, InModuleBody}
|
||||
import freechips.rocketchip.util.{ResetCatchAndSync}
|
||||
|
||||
import midas.widgets.{Bridge, PeekPokeBridge, RationalClockBridge}
|
||||
import midas.widgets.{Bridge, PeekPokeBridge, RationalClockBridge, RationalClock}
|
||||
|
||||
import chipyard.{BuildSystem}
|
||||
import chipyard.iobinders.{IOBinders}
|
||||
import chipyard._
|
||||
import chipyard.harness._
|
||||
import chipyard.iobinders._
|
||||
|
||||
// Determines the number of times to instantiate the DUT in the harness.
|
||||
// Subsumes legacy supernode support
|
||||
@@ -20,6 +25,16 @@ class WithNumNodes(n: Int) extends Config((pname, site, here) => {
|
||||
case NumNodes => n
|
||||
})
|
||||
|
||||
// Note, the main prerequisite for supporting an additional clock domain in a
|
||||
// FireSim simulation is to supply an additional clock parameter
|
||||
// (RationalClock) to the clock bridge (RationalClockBridge). The bridge
|
||||
// produces a vector of clocks, based on the provided parameter list, which you
|
||||
// may use freely without further modifications to your target design.
|
||||
case class FireSimClockParameters(additionalClocks: Seq[RationalClock]) {
|
||||
def numClocks(): Int = additionalClocks.size + 1
|
||||
}
|
||||
case object FireSimClockKey extends Field[FireSimClockParameters](FireSimClockParameters(Seq()))
|
||||
|
||||
// Hacky: Set before each node is generated. Ideally we'd give IO binders
|
||||
// accesses to the the Harness's parameters instance. We could then alter that.
|
||||
object NodeIdx {
|
||||
@@ -28,33 +43,130 @@ object NodeIdx {
|
||||
def apply(): Int = idx
|
||||
}
|
||||
|
||||
class FireSim(implicit val p: Parameters) extends RawModule {
|
||||
freechips.rocketchip.util.property.cover.setPropLib(new midas.passes.FireSimPropertyLibrary())
|
||||
val clockBridge = Module(new RationalClockBridge)
|
||||
val clock = clockBridge.io.clocks.head
|
||||
val reset = WireInit(false.B)
|
||||
withClockAndReset(clock, reset) {
|
||||
// Instantiate multiple instances of the DUT to implement supernode
|
||||
val targets = Seq.fill(p(NumNodes)) {
|
||||
// It's not a RC bump without some hacks...
|
||||
// Copy the AsyncClockGroupsKey to generate a fresh node on each
|
||||
// instantiation of the dut, otherwise the initial instance will be
|
||||
// reused across each node
|
||||
import freechips.rocketchip.subsystem.AsyncClockGroupsKey
|
||||
val lazyModule = p(BuildSystem)(p.alterPartial({
|
||||
case AsyncClockGroupsKey => p(AsyncClockGroupsKey).copy
|
||||
}))
|
||||
(lazyModule, Module(lazyModule.module))
|
||||
class WithFireSimSimpleClocks extends Config((site, here, up) => {
|
||||
case ClockingSchemeKey => { chiptop: ChipTop =>
|
||||
implicit val p = chiptop.p
|
||||
|
||||
val implicitClockSourceNode = ClockSourceNode(Seq(ClockSourceParameters()))
|
||||
chiptop.implicitClockSinkNode := implicitClockSourceNode
|
||||
|
||||
// Drive the diplomaticclock graph of the DigitalTop (if present)
|
||||
val simpleClockGroupSourceNode = chiptop.lazySystem match {
|
||||
case l: BaseSubsystem if (p(SubsystemDriveAsyncClockGroupsKey).isEmpty) => {
|
||||
val n = ClockGroupSourceNode(Seq(ClockGroupSourceParameters()))
|
||||
l.asyncClockGroupsNode := n
|
||||
Some(n)
|
||||
}
|
||||
case _ => None
|
||||
}
|
||||
|
||||
val peekPokeBridge = PeekPokeBridge(clock, reset)
|
||||
// A Seq of partial functions that will instantiate the right bridge only
|
||||
// if that Mixin trait is present in the target's LazyModule class instance
|
||||
//
|
||||
// Apply each partial function to each DUT instance
|
||||
for ((lazyModule, module) <- targets) {
|
||||
p(IOBinders).values.foreach(f => f(lazyModule) ++ f(module))
|
||||
NodeIdx.increment()
|
||||
InModuleBody {
|
||||
val clock = IO(Input(Clock())).suggestName("clock")
|
||||
val reset = IO(Input(Reset())).suggestName("reset")
|
||||
|
||||
implicitClockSourceNode.out.unzip._1.map { o =>
|
||||
o.clock := clock
|
||||
o.reset := reset
|
||||
}
|
||||
|
||||
simpleClockGroupSourceNode.map { n => n.out.unzip._1.map { out: ClockGroupBundle =>
|
||||
out.member.data.foreach { o =>
|
||||
o.clock := clock
|
||||
o.reset := reset
|
||||
}
|
||||
}}
|
||||
|
||||
chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => {
|
||||
clock := th.harnessClock
|
||||
reset := th.harnessReset
|
||||
Nil
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
class WithFireSimRationalTileDomain(multiplier: Int, divisor: Int) extends Config((site, here, up) => {
|
||||
case FireSimClockKey => FireSimClockParameters(Seq(RationalClock("TileDomain", multiplier, divisor)))
|
||||
case ClockingSchemeKey => { chiptop: ChipTop =>
|
||||
implicit val p = chiptop.p
|
||||
|
||||
val implicitClockSourceNode = ClockSourceNode(Seq(ClockSourceParameters()))
|
||||
chiptop.implicitClockSinkNode := implicitClockSourceNode
|
||||
|
||||
// Drive the diplomaticclock graph of the DigitalTop (if present)
|
||||
val simpleClockGroupSourceNode = chiptop.lazySystem match {
|
||||
case l: BaseSubsystem if (p(SubsystemDriveAsyncClockGroupsKey).isEmpty) => {
|
||||
val n = ClockGroupSourceNode(Seq(ClockGroupSourceParameters()))
|
||||
l.asyncClockGroupsNode := n
|
||||
Some(n)
|
||||
}
|
||||
case _ => None
|
||||
}
|
||||
|
||||
InModuleBody {
|
||||
val uncore_clock = IO(Input(Clock())).suggestName("uncore_clock")
|
||||
val tile_clock = IO(Input(Clock())).suggestName("tile_clock")
|
||||
val reset = IO(Input(Reset())).suggestName("reset")
|
||||
|
||||
implicitClockSourceNode.out.unzip._1.map { o =>
|
||||
o.clock := uncore_clock
|
||||
o.reset := reset
|
||||
}
|
||||
|
||||
simpleClockGroupSourceNode.map { n => n.out.unzip._1.map { out: ClockGroupBundle =>
|
||||
out.member.elements.map { case (name, data) =>
|
||||
// This is mega hacks, how are you actually supposed to do this?
|
||||
if (name.contains("core")) {
|
||||
data.clock := tile_clock
|
||||
data.reset := ResetCatchAndSync(tile_clock, reset.asBool)
|
||||
} else {
|
||||
data.clock := uncore_clock
|
||||
data.reset := reset
|
||||
}
|
||||
}
|
||||
}}
|
||||
|
||||
chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => {
|
||||
uncore_clock := th.harnessClock
|
||||
reset := th.harnessReset
|
||||
th match {
|
||||
case f: FireSim => tile_clock := f.additionalClocks(0)
|
||||
case _ => throw new Exception("FireSimMultiClock must be used with FireSim")
|
||||
}
|
||||
Nil
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
class FireSim(implicit val p: Parameters) extends RawModule with HasHarnessSignalReferences {
|
||||
freechips.rocketchip.util.property.cover.setPropLib(new midas.passes.FireSimPropertyLibrary())
|
||||
val clockBridge = Module(new RationalClockBridge(p(FireSimClockKey).additionalClocks:_*))
|
||||
val harnessClock = clockBridge.io.clocks.head // This is the reference clock
|
||||
val additionalClocks = clockBridge.io.clocks.tail
|
||||
val harnessReset = WireInit(false.B)
|
||||
val peekPokeBridge = PeekPokeBridge(harnessClock, harnessReset)
|
||||
def dutReset = { require(false, "dutReset should not be used in Firesim"); false.B }
|
||||
def success = { require(false, "success should not be used in Firesim"); false.B }
|
||||
|
||||
// Instantiate multiple instances of the DUT to implement supernode
|
||||
for (i <- 0 until p(NumNodes)) {
|
||||
// It's not a RC bump without some hacks...
|
||||
// Copy the AsyncClockGroupsKey to generate a fresh node on each
|
||||
// instantiation of the dut, otherwise the initial instance will be
|
||||
// reused across each node
|
||||
import freechips.rocketchip.subsystem.AsyncClockGroupsKey
|
||||
val lazyModule = LazyModule(p(BuildTop)(p.alterPartial({
|
||||
case AsyncClockGroupsKey => p(AsyncClockGroupsKey).copy
|
||||
})))
|
||||
val module = Module(lazyModule.module)
|
||||
lazyModule match { case d: HasTestHarnessFunctions =>
|
||||
require(d.harnessFunctions.size == 1, "There should only be 1 harness function to connect clock+reset")
|
||||
d.harnessFunctions.foreach(_(this))
|
||||
ApplyHarnessBinders(this, d.lazySystem, p(HarnessBinders), d.portMap.toMap)
|
||||
}
|
||||
|
||||
|
||||
NodeIdx.increment()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
//See LICENSE for license details.
|
||||
|
||||
package firesim.firesim
|
||||
|
||||
import chisel3._
|
||||
|
||||
import freechips.rocketchip.config.{Field, Config, Parameters}
|
||||
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, RationalCrossing}
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.util.{ResetCatchAndSync}
|
||||
|
||||
import midas.widgets.{Bridge, PeekPokeBridge, RationalClockBridge, RationalClock}
|
||||
import firesim.configs._
|
||||
|
||||
import boom.common.{WithRationalBoomTiles}
|
||||
|
||||
import chipyard.{BuildSystem, DigitalTop, DigitalTopModule}
|
||||
import chipyard.config.ConfigValName._
|
||||
import chipyard.iobinders.{IOBinders}
|
||||
|
||||
// WIP! This file is a sketch of one means of defining a multiclock target-design
|
||||
// that can be simulated in FireSim, pending a canonicalized form in Chipyard.
|
||||
//
|
||||
// Note, the main prerequisite for supporting an additional clock domain in a
|
||||
// FireSim simulation is to supply an additional clock parameter
|
||||
// (RationalClock) to the clock bridge (RationalClockBridge). The bridge
|
||||
// produces a vector of clocks, based on the provided parameter list, which you
|
||||
// may use freely without further modifications to your target design.
|
||||
|
||||
case class FireSimClockParameters(additionalClocks: Seq[RationalClock]) {
|
||||
def numClocks(): Int = additionalClocks.size + 1
|
||||
}
|
||||
case object FireSimClockKey extends Field[FireSimClockParameters](FireSimClockParameters(Seq()))
|
||||
|
||||
trait HasAdditionalClocks extends LazyModuleImp {
|
||||
val clocks = IO(Vec(p(FireSimClockKey).numClocks, Input(Clock())))
|
||||
}
|
||||
|
||||
// Presupposes only 1 or 2 clocks.
|
||||
trait HasFireSimClockingImp extends HasAdditionalClocks {
|
||||
val outer: HasTiles
|
||||
val (tileClock, tileReset) = p(FireSimClockKey).additionalClocks.headOption match {
|
||||
case Some(RationalClock(_, numer, denom)) if numer != denom => (clocks(1), ResetCatchAndSync(clocks(1), reset.toBool))
|
||||
case None => (clocks.head, reset)
|
||||
}
|
||||
|
||||
outer.tiles.foreach({ case tile =>
|
||||
tile.module.clock := tileClock
|
||||
tile.module.reset := tileReset
|
||||
})
|
||||
}
|
||||
|
||||
// Config Fragment
|
||||
class WithSingleRationalTileDomain(multiplier: Int, divisor: Int) extends Config(
|
||||
new WithRationalRocketTiles ++
|
||||
new WithRationalBoomTiles ++
|
||||
new Config((site, here, up) => {
|
||||
case FireSimClockKey => FireSimClockParameters(Seq(RationalClock("TileDomain", multiplier, divisor)))
|
||||
})
|
||||
)
|
||||
|
||||
class HalfRateUncore extends WithSingleRationalTileDomain(2,1)
|
||||
|
||||
class WithFiresimMulticlockTop extends Config((site, here, up) => {
|
||||
case BuildSystem => (p: Parameters) => LazyModule(new FiresimMulticlockTop()(p)).suggestName("system")
|
||||
})
|
||||
|
||||
// Complete Config
|
||||
class FireSimQuadRocketMulticlockConfig extends Config(
|
||||
new HalfRateUncore ++
|
||||
new WithFiresimMulticlockTop ++
|
||||
new FireSimQuadRocketConfig)
|
||||
|
||||
// Top Definition
|
||||
class FiresimMulticlockTop(implicit p: Parameters) extends chipyard.DigitalTop
|
||||
{
|
||||
override lazy val module = new FiresimMulticlockTopModule(this)
|
||||
}
|
||||
|
||||
|
||||
class FiresimMulticlockTopModule[+L <: DigitalTop](l: L) extends chipyard.DigitalTopModule(l) with HasFireSimClockingImp
|
||||
|
||||
// Harness Definition
|
||||
class FireSimMulticlockPOC(implicit val p: Parameters) extends RawModule {
|
||||
freechips.rocketchip.util.property.cover.setPropLib(new midas.passes.FireSimPropertyLibrary())
|
||||
val clockBridge = Module(new RationalClockBridge(p(FireSimClockKey).additionalClocks:_*))
|
||||
val refClock = clockBridge.io.clocks.head
|
||||
val reset = WireInit(false.B)
|
||||
withClockAndReset(refClock, reset) {
|
||||
// Instantiate multiple instances of the DUT to implement supernode
|
||||
val targets = Seq.fill(p(NumNodes)) {
|
||||
val lazyModule = p(BuildSystem)(p)
|
||||
(lazyModule, Module(lazyModule.module))
|
||||
}
|
||||
val peekPokeBridge = PeekPokeBridge(refClock, reset)
|
||||
// A Seq of partial functions that will instantiate the right bridge only
|
||||
// if that Mixin trait is present in the target's class instance
|
||||
//
|
||||
// Apply each partial function to each DUT instance
|
||||
for ((lazyModule, module) <- targets) {
|
||||
p(IOBinders).values.foreach(f => f(lazyModule) ++ f(module))
|
||||
}
|
||||
targets.collect({ case (_, t: HasAdditionalClocks) => t.clocks := clockBridge.io.clocks })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,10 +10,10 @@ import freechips.rocketchip.tile._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.rocket.DCacheParams
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.devices.tilelink.BootROMParams
|
||||
import freechips.rocketchip.devices.tilelink.{BootROMLocated, BootROMParams}
|
||||
import freechips.rocketchip.devices.debug.{DebugModuleParams, DebugModuleKey}
|
||||
import freechips.rocketchip.diplomacy.LazyModule
|
||||
import testchipip.{BlockDeviceKey, BlockDeviceConfig, SerialKey, TracePortKey, TracePortParams}
|
||||
import testchipip.{BlockDeviceKey, BlockDeviceConfig, TracePortKey, TracePortParams}
|
||||
import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTParams}
|
||||
import scala.math.{min, max}
|
||||
|
||||
@@ -22,19 +22,18 @@ import testchipip.WithRingSystemBus
|
||||
|
||||
import firesim.bridges._
|
||||
import firesim.configs._
|
||||
import chipyard.config.ConfigValName._
|
||||
|
||||
class WithBootROM extends Config((site, here, up) => {
|
||||
case BootROMParams => {
|
||||
case BootROMLocated(x) => {
|
||||
val chipyardBootROM = new File(s"./generators/testchipip/bootrom/bootrom.rv${site(XLen)}.img")
|
||||
val firesimBootROM = new File(s"./target-rtl/chipyard/generators/testchipip/bootrom/bootrom.rv${site(XLen)}.img")
|
||||
|
||||
val bootROMPath = if (chipyardBootROM.exists()) {
|
||||
val bootROMPath = if (chipyardBootROM.exists()) {
|
||||
chipyardBootROM.getAbsolutePath()
|
||||
} else {
|
||||
firesimBootROM.getAbsolutePath()
|
||||
}
|
||||
BootROMParams(contentFileName = bootROMPath)
|
||||
up(BootROMLocated(x), site).map(_.copy(contentFileName = bootROMPath))
|
||||
}
|
||||
})
|
||||
|
||||
@@ -67,6 +66,8 @@ class WithNVDLASmall extends nvidia.blocks.dla.WithNVDLA("small")
|
||||
|
||||
// Tweaks that are generally applied to all firesim configs
|
||||
class WithFireSimConfigTweaks extends Config(
|
||||
// Required*: Uses FireSim ClockBridge and PeekPokeBridge to drive the system with a single clock/reset
|
||||
new WithFireSimSimpleClocks ++
|
||||
// Required*: When using FireSim-as-top to provide a correct path to the target bootrom source
|
||||
new WithBootROM ++
|
||||
// Optional*: Removing this will require adjusting the UART baud rate and
|
||||
@@ -83,11 +84,13 @@ class WithFireSimConfigTweaks extends Config(
|
||||
// Required: Adds IO to attach SerialBridge. The SerialBridges is responsible
|
||||
// for signalling simulation termination under simulation success. This fragment can
|
||||
// be removed if you supply an auxiliary bridge that signals simulation termination
|
||||
new testchipip.WithTSI ++
|
||||
new testchipip.WithDefaultSerialTL ++
|
||||
// Optional: Removing this will require using an initramfs under linux
|
||||
new testchipip.WithBlockDevice ++
|
||||
// Required*: Scale default baud rate with periphery bus frequency
|
||||
new chipyard.config.WithUART(BigInt(3686400L))
|
||||
new chipyard.config.WithUART(BigInt(3686400L)) ++
|
||||
// Required: Do not support debug module w. JTAG until FIRRTL stops emitting @(posedge ~clock)
|
||||
new chipyard.config.WithNoDebug
|
||||
)
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -128,7 +131,7 @@ class FireSimSmallSystemConfig extends Config(
|
||||
new WithoutClockGating ++
|
||||
new WithoutTLMonitors ++
|
||||
new freechips.rocketchip.subsystem.WithExtMemSize(1 << 28) ++
|
||||
new testchipip.WithTSI ++
|
||||
new testchipip.WithDefaultSerialTL ++
|
||||
new testchipip.WithBlockDevice ++
|
||||
new chipyard.config.WithUART ++
|
||||
new freechips.rocketchip.subsystem.WithInclusiveCache(nWays = 2, capacityKB = 64) ++
|
||||
@@ -186,3 +189,14 @@ class FireSimArianeConfig extends Config(
|
||||
new WithDefaultMemModel ++
|
||||
new WithFireSimConfigTweaks ++
|
||||
new chipyard.ArianeConfig)
|
||||
|
||||
//**********************************************************************************
|
||||
//* Multiclock Configurations
|
||||
//*********************************************************************************/
|
||||
class FireSimMulticlockRocketConfig extends Config(
|
||||
new WithFireSimRationalTileDomain(2, 1) ++
|
||||
new WithDefaultFireSimBridges ++
|
||||
new WithDefaultMemModel ++
|
||||
new WithFireSimConfigTweaks ++
|
||||
new chipyard.DividedClockRocketConfig)
|
||||
|
||||
|
||||
@@ -106,8 +106,8 @@ class BoomF1Tests extends FireSimTestSuite("FireSim", "DDR3FRFCFSLLC4MB_FireSimL
|
||||
class RocketNICF1Tests extends FireSimTestSuite("FireSim", "WithNIC_DDR3FRFCFSLLC4MB_FireSimRocketConfig", "BaseF1Config")
|
||||
// Multiclock tests
|
||||
class RocketMulticlockF1Tests extends FireSimTestSuite(
|
||||
"FireSimMulticlockPOC",
|
||||
"FireSimQuadRocketMulticlockConfig",
|
||||
"FireSim",
|
||||
"FireSimMulticlockRocketConfig",
|
||||
"WithSynthAsserts_BaseF1Config")
|
||||
|
||||
class ArianeF1Tests extends FireSimTestSuite("FireSim", "WithNIC_DDR3FRFCFSLLC4MB_FireSimArianeConfig", "BaseF1Config")
|
||||
|
||||
Submodule generators/hwacha updated: a989b69759...e29b65db86
Submodule generators/icenet updated: 705ca50690...277a9080fe
Submodule generators/rocket-chip updated: 653efa99a2...6eb1a3de08
Submodule generators/testchipip updated: 3366844f50...bdca33ec16
@@ -12,6 +12,10 @@ class TraceGenSystem(implicit p: Parameters) extends BaseSubsystem
|
||||
with CanHaveMasterAXI4MemPort {
|
||||
|
||||
def coreMonitorBundles = Nil
|
||||
val tileStatusNodes = tiles.collect {
|
||||
case t: GroundTestTile => t.statusNode.makeSink()
|
||||
case t: BoomTraceGenTile => t.statusNode.makeSink()
|
||||
}
|
||||
override lazy val module = new TraceGenSystemModuleImp(this)
|
||||
}
|
||||
|
||||
@@ -20,12 +24,8 @@ class TraceGenSystemModuleImp(outer: TraceGenSystem)
|
||||
{
|
||||
val success = IO(Output(Bool()))
|
||||
|
||||
outer.tiles.zipWithIndex.map { case(t, i) => t.module.constants.hartid := i.U }
|
||||
val status = dontTouch(DebugCombiner(outer.tileStatusNodes.map(_.bundle)))
|
||||
|
||||
val status = dontTouch(DebugCombiner(outer.tiles.collect {
|
||||
case t: GroundTestTile => t.module.status
|
||||
case t: BoomTraceGenTile => t.module.status
|
||||
}))
|
||||
success := outer.tileCeaseSinkNode.in.head._1.asUInt.andR
|
||||
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package tracegen
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import freechips.rocketchip.config.Parameters
|
||||
import freechips.rocketchip.diplomacy.{SimpleDevice, LazyModule, SynchronousCrossing, ClockCrossingType}
|
||||
import freechips.rocketchip.diplomacy.{SimpleDevice, LazyModule, SynchronousCrossing, ClockCrossingType, BundleBridgeSource}
|
||||
import freechips.rocketchip.groundtest._
|
||||
import freechips.rocketchip.rocket._
|
||||
import freechips.rocketchip.rocket.constants.{MemoryOpConstants}
|
||||
@@ -206,11 +206,13 @@ class BoomTraceGenTile private(
|
||||
val cpuDevice: SimpleDevice = new SimpleDevice("groundtest", Nil)
|
||||
val intOutwardNode: IntOutwardNode = IntIdentityNode()
|
||||
val slaveNode: TLInwardNode = TLIdentityNode()
|
||||
val statusNode = BundleBridgeSource(() => new GroundTestStatus)
|
||||
|
||||
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))
|
||||
core=BoomCoreParams(nPMPs=0, numLdqEntries=16, numStqEntries=16, useVM=false))))
|
||||
val dcache = LazyModule(new BoomNonBlockingDCache(staticIdForMetadataUseOnly)(boom_params))
|
||||
|
||||
|
||||
val masterNode: TLOutwardNode = TLIdentityNode() := visibilityNode := dcache.node
|
||||
|
||||
@@ -220,11 +222,11 @@ class BoomTraceGenTile private(
|
||||
class BoomTraceGenTileModuleImp(outer: BoomTraceGenTile)
|
||||
extends BaseTileModuleImp(outer){
|
||||
|
||||
val status = IO(new GroundTestStatus)
|
||||
val status = outer.statusNode.bundle
|
||||
val halt_and_catch_fire = None
|
||||
|
||||
val tracegen = Module(new TraceGenerator(outer.params.traceParams))
|
||||
tracegen.io.hartid := constants.hartid
|
||||
tracegen.io.hartid := outer.hartIdSinkNode.bundle
|
||||
|
||||
val ptw = Module(new DummyPTW(1))
|
||||
val lsu = Module(new LSU()(outer.boom_params, outer.dcache.module.edge))
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
// See LICENSE.SiFive for license details.
|
||||
// See LICENSE.Berkeley for license details.
|
||||
|
||||
#include "verilated.h"
|
||||
#if VM_TRACE
|
||||
#include <memory>
|
||||
#if CY_FST_TRACE
|
||||
#include "verilated_fst_c.h"
|
||||
#else
|
||||
#include "verilated.h"
|
||||
#include "verilated_vcd_c.h"
|
||||
#endif
|
||||
#endif // CY_FST_TRACE
|
||||
#endif // VM_TRACE
|
||||
#include <fesvr/dtm.h>
|
||||
#include <fesvr/tsi.h>
|
||||
#include "remote_bitbang.h"
|
||||
@@ -110,9 +114,10 @@ int main(int argc, char** argv)
|
||||
uint64_t max_cycles = -1;
|
||||
int ret = 0;
|
||||
bool print_cycles = false;
|
||||
// Port numbers are 16 bit unsigned integers.
|
||||
// Port numbers are 16 bit unsigned integers.
|
||||
uint16_t rbb_port = 0;
|
||||
#if VM_TRACE
|
||||
const char* vcdfile_name = NULL;
|
||||
FILE * vcdfile = NULL;
|
||||
uint64_t start = 0;
|
||||
#endif
|
||||
@@ -157,6 +162,7 @@ int main(int argc, char** argv)
|
||||
case 'o': opterr = 1; break;
|
||||
#if VM_TRACE
|
||||
case 'v': {
|
||||
vcdfile_name = optarg;
|
||||
vcdfile = strcmp(optarg, "-") == 0 ? stdout : fopen(optarg, "w");
|
||||
if (!vcdfile) {
|
||||
std::cerr << "Unable to open " << optarg << " for VCD write\n";
|
||||
@@ -264,17 +270,20 @@ done_processing:
|
||||
|
||||
#if VM_TRACE
|
||||
Verilated::traceEverOn(true); // Verilator must compute traced signals
|
||||
#if CY_FST_TRACE
|
||||
std::unique_ptr<VerilatedFstC> tfp(new VerilatedFstC);
|
||||
#else
|
||||
std::unique_ptr<VerilatedVcdFILE> vcdfd(new VerilatedVcdFILE(vcdfile));
|
||||
std::unique_ptr<VerilatedVcdC> tfp(new VerilatedVcdC(vcdfd.get()));
|
||||
if (vcdfile) {
|
||||
#endif // CY_FST_TRACE
|
||||
if (vcdfile_name) {
|
||||
tile->trace(tfp.get(), 99); // Trace 99 levels of hierarchy
|
||||
tfp->open("");
|
||||
tfp->open(vcdfile_name);
|
||||
}
|
||||
#endif
|
||||
#endif // VM_TRACE
|
||||
|
||||
// RocketChip currently only supports RBB port 0, so this needs to stay here
|
||||
jtag = new remote_bitbang_t(rbb_port);
|
||||
dtm = new dtm_t(argc, argv);
|
||||
tsi = new tsi_t(argc, argv);
|
||||
|
||||
signal(SIGTERM, handle_sigterm);
|
||||
|
||||
@@ -304,8 +313,7 @@ done_processing:
|
||||
tile->reset = 0;
|
||||
done_reset = true;
|
||||
|
||||
while (!dtm->done() && !jtag->done() && !tsi->done() &&
|
||||
!tile->io_success && trace_count < max_cycles) {
|
||||
do {
|
||||
tile->clock = 0;
|
||||
tile->eval();
|
||||
#if VM_TRACE
|
||||
@@ -322,6 +330,13 @@ done_processing:
|
||||
#endif
|
||||
trace_count++;
|
||||
}
|
||||
// for verilator multithreading. need to do 1 loop before checking if
|
||||
// tsi exists, since tsi is created by verilated thread on the first
|
||||
// serial_tick.
|
||||
while ((!dtm || !dtm->done()) &&
|
||||
(!jtag || !jtag->done()) &&
|
||||
(!tsi || !tsi->done()) &&
|
||||
!tile->io_success && trace_count < max_cycles);
|
||||
|
||||
#if VM_TRACE
|
||||
if (tfp)
|
||||
@@ -330,17 +345,17 @@ done_processing:
|
||||
fclose(vcdfile);
|
||||
#endif
|
||||
|
||||
if (dtm->exit_code())
|
||||
if (dtm && dtm->exit_code())
|
||||
{
|
||||
fprintf(stderr, "*** FAILED *** via dtm (code = %d, seed %d) after %ld cycles\n", dtm->exit_code(), random_seed, trace_count);
|
||||
ret = dtm->exit_code();
|
||||
}
|
||||
else if (tsi->exit_code())
|
||||
else if (tsi && tsi->exit_code())
|
||||
{
|
||||
fprintf(stderr, "*** FAILED *** (code = %d, seed %d) after %ld cycles\n", tsi->exit_code(), random_seed, trace_count);
|
||||
ret = tsi->exit_code();
|
||||
}
|
||||
else if (jtag->exit_code())
|
||||
else if (jtag && jtag->exit_code())
|
||||
{
|
||||
fprintf(stderr, "*** FAILED *** via jtag (code = %d, seed %d) after %ld cycles\n", jtag->exit_code(), random_seed, trace_count);
|
||||
ret = jtag->exit_code();
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
RDIR=$(pwd)
|
||||
CHIPYARD_DIR="${CHIPYARD_DIR:-$(git rev-parse --show-toplevel)}"
|
||||
DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"
|
||||
CHIPYARD_DIR="$(dirname "$DIR")"
|
||||
|
||||
usage() {
|
||||
echo "usage: ${0} [OPTIONS] [riscv-tools | esp-tools | ec2fast]"
|
||||
@@ -134,18 +134,16 @@ SRCDIR="$(pwd)/toolchains" module_all qemu --prefix="${RISCV}" --target-list=ris
|
||||
git submodule update --init $CHIPYARD_DIR/tools/dromajo/dromajo-src
|
||||
make -C $CHIPYARD_DIR/tools/dromajo/dromajo-src/src
|
||||
|
||||
cd "$RDIR"
|
||||
|
||||
# create specific env.sh
|
||||
{
|
||||
echo "# auto-generated by build-toolchains.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-$TOOLCHAIN.sh
|
||||
cat > "$CHIPYARD_DIR/env-$TOOLCHAIN.sh" <<EOF
|
||||
# auto-generated by build-toolchains.sh
|
||||
export CHIPYARD_TOOLCHAIN_SOURCED=1
|
||||
export RISCV=$(printf '%q' "$RISCV")
|
||||
export PATH=\${RISCV}/bin:\${PATH}
|
||||
export LD_LIBRARY_PATH=\${RISCV}/lib\${LD_LIBRARY_PATH:+":\${LD_LIBRARY_PATH}"}
|
||||
EOF
|
||||
|
||||
# create general env.sh
|
||||
echo "# line auto-generated by build-toolchains.sh" >> env.sh
|
||||
echo "source \$( realpath \$(dirname "\${BASH_SOURCE[0]:-\${\(%\):-%x}}") )/env-$TOOLCHAIN.sh" >> env.sh
|
||||
echo "source $(printf '%q' "$CHIPYARD_DIR/env-$TOOLCHAIN.sh")" >> env.sh
|
||||
echo "Toolchain Build Complete!"
|
||||
|
||||
@@ -15,7 +15,7 @@ case ${ncpu} in
|
||||
esac
|
||||
|
||||
# Allow user to override MAKE
|
||||
[ -n "${MAKE}" ] || MAKE=$(command -v gnumake || command -v gmake || command -v make)
|
||||
[ -n "${MAKE:+x}" ] || MAKE=$(command -v gnumake || command -v gmake || command -v make)
|
||||
readonly MAKE
|
||||
|
||||
|
||||
|
||||
@@ -17,10 +17,11 @@ if [ "$MINGIT" != "$(echo -e "$MINGIT\n$MYGIT" | sort -V | head -n1)" ]; then
|
||||
false
|
||||
fi
|
||||
|
||||
RDIR=$(git rev-parse --show-toplevel)
|
||||
DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"
|
||||
CHIPYARD_DIR="$(dirname "$DIR")"
|
||||
|
||||
# Ignore toolchain submodules
|
||||
cd "$RDIR"
|
||||
cd "$CHIPYARD_DIR"
|
||||
for name in toolchains/*-tools/*/ ; do
|
||||
git config submodule."${name%/}".update none
|
||||
done
|
||||
@@ -71,8 +72,11 @@ git config submodule.sims/firesim.update none
|
||||
git submodule update --init software/firemarshal
|
||||
|
||||
# Configure firemarshal to know where our firesim installation is
|
||||
if [ ! -f $RDIR/software/firemarshal/marshal-config.yaml ]; then
|
||||
echo "firesim-dir: '../../sims/firesim/'" > $RDIR/software/firemarshal/marshal-config.yaml
|
||||
if [ ! -f ./software/firemarshal/marshal-config.yaml ]; then
|
||||
echo "firesim-dir: '../../sims/firesim/'" > ./software/firemarshal/marshal-config.yaml
|
||||
fi
|
||||
echo "# line auto-generated by init-submodules-no-riscv-tools.sh" >> $RDIR/env.sh
|
||||
echo "PATH=\$( realpath \$(dirname "\${BASH_SOURCE[0]:-\${\(%\):-%x}}") )/software/firemarshal:\$PATH" >> $RDIR/env.sh
|
||||
|
||||
echo "# line auto-generated by init-submodules-no-riscv-tools.sh" >> env.sh
|
||||
echo '__DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")"' >> env.sh
|
||||
echo "PATH=\$__DIR/bin:\$PATH" >> env.sh
|
||||
echo "PATH=\$__DIR/software/firemarshal:\$PATH" >> env.sh
|
||||
|
||||
76
scripts/numa_prefix
Executable file
76
scripts/numa_prefix
Executable file
@@ -0,0 +1,76 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#============================================================================
|
||||
# - really simple script, which just prints out the numactl cmd to
|
||||
# prefix before your actual command. it determines this based on free
|
||||
# memory size attached to every node.
|
||||
# - when you run this on a machine without `numactl`, the output is empty,
|
||||
# so `$(numa_prefix) <cmd> <args>` turns in to `<cmd> <args>`.
|
||||
# - when the machine has `numactl` installed, regardless of the socket-count
|
||||
# on the machine, the resulting command is:
|
||||
# `numactl -m <socket> -C <core-id list> -- <cmd> <args>`
|
||||
# - example output from `numactl -H` on a 2 socket machine:
|
||||
# available: 2 nodes (0-1)
|
||||
# node 0 cpus: 0 2 4 6 8 10 12 14 16 18 20 22
|
||||
# node 0 size: 131026 MB
|
||||
# node 0 free: 7934 MB
|
||||
# node 1 cpus: 1 3 5 7 9 11 13 15 17 19 21 23
|
||||
# node 1 size: 65536 MB
|
||||
# node 1 free: 429 MB
|
||||
# node distances:
|
||||
# node 0 1
|
||||
# 0: 10 20
|
||||
# 1: 20 10
|
||||
#============================================================================
|
||||
|
||||
import subprocess
|
||||
import re
|
||||
import sys
|
||||
|
||||
which_proc = subprocess.Popen(["which", "numactl"], stdout=subprocess.PIPE)
|
||||
out, err = which_proc.communicate()
|
||||
|
||||
if out != "":
|
||||
numactl_proc = subprocess.Popen(["numactl", "-H"], stdout=subprocess.PIPE)
|
||||
out, err = numactl_proc.communicate()
|
||||
|
||||
lines = out.split("\n")
|
||||
line_idx = 0
|
||||
|
||||
head_line = lines[line_idx]
|
||||
line_idx += 1
|
||||
node_match = re.match(r"^ *available: +(\d+) nodes", head_line)
|
||||
if node_match:
|
||||
avail_nodes = node_match.group(1)
|
||||
best_node_id = ""
|
||||
best_cpus = ""
|
||||
best_free_size = 0
|
||||
|
||||
# loop through available nodes, selecting the node with the most free mem
|
||||
for i in avail_nodes:
|
||||
cpu_line = lines[line_idx]
|
||||
# mem. size unused. skip and use mem. free
|
||||
mem_free_line = lines[line_idx + 2]
|
||||
line_idx += 3
|
||||
|
||||
cpu_match = re.match(r"^ *node (\d+) cpus: (\d.*\d)$", cpu_line)
|
||||
if cpu_match:
|
||||
node_id = cpu_match.group(1)
|
||||
cpus = cpu_match.group(2).replace(" ", ",")
|
||||
|
||||
mem_free_match = re.match(r"^ *node " + node_id + " free: (\d+) \S+$", mem_free_line)
|
||||
if mem_free_match:
|
||||
free_size = mem_free_match.group(1)
|
||||
if int(free_size) > int(best_free_size):
|
||||
best_node_id = node_id
|
||||
best_cpus = cpus
|
||||
best_free_size = free_size
|
||||
else:
|
||||
sys.exit("[ERROR] Malformed mem free line: " + mem_free_line)
|
||||
|
||||
else:
|
||||
sys.exit("[ERROR] Malformed cpus line: " + cpu_line)
|
||||
|
||||
sys.stdout.write("numactl -m " + best_node_id + " -C " + best_cpus + " --")
|
||||
else:
|
||||
sys.exit("[ERROR] Malformed head line: " + head_line)
|
||||
@@ -8,7 +8,9 @@ binary=$1
|
||||
segments=`readelf --segments --wide $binary`
|
||||
entry_hex=`echo -e "$segments" | grep "Entry point" | cut -f3 -d' ' | sed 's/0x//' | tr [:lower:] [:upper:]`
|
||||
entry_dec=`bc <<< "ibase=16;$entry_hex"`
|
||||
length_hex=`echo "$segments" | grep LOAD | tail -n 1 | tr -s [:space:] | cut -f4,6 -d' '`
|
||||
length_hex=`echo "$segments" | grep "LOAD\|TLS" | tail -n 1 | tr -s [:space:] | cut -f4,6 -d' '`
|
||||
length_dec=`echo $length_hex | tr -d x | tr [:lower:] [:upper:] | tr ' ' + | sed 's/^/ibase=16;/' | sed "s/$/-$entry_hex/" | bc`
|
||||
power_2_length=`echo "x=l($length_dec)/l(2); scale=0; 2^((x+1)/1)" | bc -l`
|
||||
elf2hex 64 $power_2_length $binary $entry_dec
|
||||
width=64
|
||||
depth=$((power_2_length / width))
|
||||
elf2hex $width $depth $binary $entry_dec
|
||||
|
||||
@@ -24,4 +24,4 @@ sudo apt-get install -y device-tree-compiler
|
||||
git clone http://git.veripool.org/git/verilator
|
||||
cd verilator
|
||||
git checkout v4.034
|
||||
autoconf && ./configure && make -j16 && sudo make install
|
||||
autoconf && ./configure && make -j$(nproc) && sudo make install
|
||||
|
||||
23
sims/common-sim-flags.mk
Normal file
23
sims/common-sim-flags.mk
Normal file
@@ -0,0 +1,23 @@
|
||||
#----------------------------------------------------------------------------------------
|
||||
# common gcc configuration/optimization
|
||||
#----------------------------------------------------------------------------------------
|
||||
SIM_OPT_CXXFLAGS := -O3
|
||||
|
||||
SIM_CXXFLAGS = \
|
||||
$(CXXFLAGS) \
|
||||
$(SIM_OPT_CXXFLAGS) \
|
||||
-std=c++11 \
|
||||
-I$(RISCV)/include \
|
||||
-I$(dramsim_dir) \
|
||||
-I$(build_dir) \
|
||||
$(EXTRA_SIM_CXXFLAGS)
|
||||
|
||||
SIM_LDFLAGS = \
|
||||
$(LDFLAGS) \
|
||||
-L$(RISCV)/lib \
|
||||
-Wl,-rpath,$(RISCV)/lib \
|
||||
-L$(sim_dir) \
|
||||
-L$(dramsim_dir) \
|
||||
-lfesvr \
|
||||
-ldramsim \
|
||||
$(EXTRA_SIM_LDFLAGS)
|
||||
Submodule sims/firesim updated: b13e75296c...3dbe8aee3f
@@ -41,16 +41,24 @@ include $(base_dir)/common.mk
|
||||
#########################################################################################
|
||||
VCS = vcs -full64
|
||||
|
||||
VCS_OPTS = -notice -line $(VCS_CC_OPTS) $(VCS_NONCC_OPTS) $(VCS_DEFINE_OPTS) $(EXTRA_SIM_SOURCES)
|
||||
VCS_OPTS = $(VCS_CC_OPTS) $(VCS_NONCC_OPTS) $(PREPROC_DEFINES)
|
||||
|
||||
#########################################################################################
|
||||
# vcs build paths
|
||||
#########################################################################################
|
||||
model_dir = $(build_dir)/$(long_name)
|
||||
model_dir_debug = $(build_dir)/$(long_name).debug
|
||||
|
||||
#########################################################################################
|
||||
# vcs simulator rules
|
||||
#########################################################################################
|
||||
$(sim): $(sim_vsrcs) $(sim_common_files) $(dramsim_lib) $(EXTRA_SIM_REQS)
|
||||
rm -rf csrc && $(VCS) $(VCS_OPTS) -o $@
|
||||
rm -rf $(model_dir)
|
||||
$(VCS) $(VCS_OPTS) $(EXTRA_SIM_SOURCES) -o $@ -Mdir=$(model_dir)
|
||||
|
||||
$(sim_debug): $(sim_vsrcs) $(sim_common_files) $(dramsim_lib) $(EXTRA_SIM_REQS)
|
||||
rm -rf csrc && $(VCS) $(VCS_OPTS) -o $@ \
|
||||
rm -rf $(model_dir_debug)
|
||||
$(VCS) $(VCS_OPTS) $(EXTRA_SIM_SOURCES) -o $@ -Mdir=$(model_dir_debug) \
|
||||
+define+DEBUG
|
||||
|
||||
#########################################################################################
|
||||
@@ -61,8 +69,14 @@ $(output_dir)/%.vpd: $(output_dir)/% $(sim_debug)
|
||||
(set -o pipefail && $(sim_debug) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(VERBOSE_FLAGS) +vcdplusfile=$@ $(PERMISSIVE_OFF) $< </dev/null 2> >(spike-dasm > $<.out) | tee $<.log)
|
||||
|
||||
#########################################################################################
|
||||
# general cleanup rule
|
||||
# general cleanup rules
|
||||
#########################################################################################
|
||||
.PHONY: clean
|
||||
.PHONY: clean clean-sim clean-sim-debug
|
||||
clean:
|
||||
rm -rf $(gen_dir) csrc $(sim_prefix)-* ucli.key vc_hdrs.h
|
||||
rm -rf $(gen_dir) $(sim_prefix)-* ucli.key
|
||||
|
||||
clean-sim:
|
||||
rm -rf $(model_dir) $(build_dir)/vc_hdrs.h $(sim) $(sim).daidir ucli.key
|
||||
|
||||
clean-sim-debug:
|
||||
rm -rf $(model_dir_debug) $(build_dir)/vc_hdrs.h $(sim_debug) $(sim_debug).daidir ucli.key
|
||||
|
||||
@@ -22,7 +22,7 @@ include $(base_dir)/variables.mk
|
||||
sim_name = verilator
|
||||
|
||||
#########################################################################################
|
||||
# vcs simulator types and rules
|
||||
# verilator simulator types and rules
|
||||
#########################################################################################
|
||||
sim_prefix = simulator
|
||||
sim = $(sim_dir)/$(sim_prefix)-$(MODEL_PACKAGE)-$(CONFIG)
|
||||
@@ -47,35 +47,53 @@ debug: $(sim_debug)
|
||||
include $(base_dir)/common.mk
|
||||
|
||||
#########################################################################################
|
||||
# verilator binary and flags
|
||||
# verilator-specific user-interface variables and commands
|
||||
#########################################################################################
|
||||
HELP_COMPILATION_VARIABLES += \
|
||||
" VERILATOR_PROFILE = 'none' if no verilator profiling (default)" \
|
||||
" 'all' if full verilator runtime profiling" \
|
||||
" 'threads' if runtime thread profiling only" \
|
||||
" VERILATOR_THREADS = how many threads the simulator will use (default 1)" \
|
||||
" VERILATOR_FST_MODE = enable FST waveform instead of VCD. use with debug build"
|
||||
|
||||
#########################################################################################
|
||||
# verilator/cxx binary and flags
|
||||
#########################################################################################
|
||||
VERILATOR := verilator --cc --exe
|
||||
|
||||
CXXFLAGS := \
|
||||
$(CXXFLAGS) -O1 -std=c++11 \
|
||||
-I$(RISCV)/include \
|
||||
-I$(dramsim_dir) \
|
||||
-D__STDC_FORMAT_MACROS \
|
||||
$(EXTRA_SIM_CC_FLAGS)
|
||||
#----------------------------------------------------------------------------------------
|
||||
# user configs
|
||||
#----------------------------------------------------------------------------------------
|
||||
VERILATOR_PROFILE ?= none
|
||||
RUNTIME_PROFILING_CFLAGS := $(if $(filter $(VERILATOR_PROFILE),all),-g -pg,)
|
||||
RUNTIME_PROFILING_VFLAGS := $(if $(filter $(VERILATOR_PROFILE),all),\
|
||||
--prof-threads --prof-cfuncs,\
|
||||
$(if $(filter $(VERILATOR_PROFILE),threads),\
|
||||
--prof-threads,))
|
||||
|
||||
LDFLAGS := \
|
||||
$(LDFLAGS) \
|
||||
-L$(sim_dir) \
|
||||
-lpthread
|
||||
VERILATOR_THREADS ?= 1
|
||||
RUNTIME_THREADS := --threads $(VERILATOR_THREADS) --threads-dpi all
|
||||
|
||||
VERILATOR_CC_OPTS = \
|
||||
VERILATOR_FST_MODE ?= 0
|
||||
TRACING_OPTS := $(if $(filter $(VERILATOR_FST_MODE),0),\
|
||||
--trace,--trace-fst --trace-threads 1)
|
||||
TRACING_CFLAGS := $(if $(filter $(VERILATOR_FST_MODE),0),,-DCY_FST_TRACE)
|
||||
|
||||
#----------------------------------------------------------------------------------------
|
||||
# verilation configuration/optimization
|
||||
#----------------------------------------------------------------------------------------
|
||||
# we initially had --noassert for performance, but several modules use
|
||||
# assertions, including dramsim, so we enable --assert by default
|
||||
VERILATOR_OPT_FLAGS := \
|
||||
-O3 \
|
||||
-CFLAGS "$(CXXFLAGS) -DTEST_HARNESS=V$(VLOG_MODEL) -DVERILATOR" \
|
||||
-CFLAGS "-I$(build_dir) -include $(build_dir)/$(long_name).plusArgs -include $(build_dir)/verilator.h" \
|
||||
-LDFLAGS "$(LDFLAGS)" \
|
||||
$(RISCV)/lib/libfesvr.a \
|
||||
$(dramsim_lib)
|
||||
--x-assign fast \
|
||||
--x-initial fast \
|
||||
--output-split 10000 \
|
||||
--output-split-cfuncs 100
|
||||
|
||||
# default flags added for ariane
|
||||
ARIANE_VERILATOR_FLAGS = \
|
||||
# default flags added for external IP (ariane/NVDLA)
|
||||
VERILOG_IP_VERILATOR_FLAGS := \
|
||||
--unroll-count 256 \
|
||||
-Werror-PINMISSING \
|
||||
-Werror-IMPLICIT \
|
||||
-Wno-PINCONNECTEMPTY \
|
||||
-Wno-ASSIGNDLY \
|
||||
-Wno-DECLFILENAME \
|
||||
@@ -85,29 +103,66 @@ ARIANE_VERILATOR_FLAGS = \
|
||||
-Wno-style \
|
||||
-Wall
|
||||
|
||||
# normal flags used for chipyard builds (that are incompatible with ariane)
|
||||
CHIPYARD_VERILATOR_FLAGS = \
|
||||
# normal flags used for chipyard builds (that are incompatible with vlog ip aka ariane/NVDLA)
|
||||
CHIPYARD_VERILATOR_FLAGS := \
|
||||
--assert
|
||||
|
||||
# options dependent on whether external IP (ariane/NVDLA) or just chipyard is used
|
||||
# NOTE: defer the evaluation of this until it is used!
|
||||
PLATFORM_OPTS = $(shell \
|
||||
if grep -qiP "module\s+(Ariane|NVDLA)" $(build_dir)/*.*v; \
|
||||
then echo "$(VERILOG_IP_VERILATOR_FLAGS)"; \
|
||||
else echo "$(CHIPYARD_VERILATOR_FLAGS)"; fi)
|
||||
|
||||
# Use --timescale to approximate timescale behavior of pre-4.034
|
||||
TIMESCALE_OPTS := $(shell verilator --version | perl -lne 'if (/(\d.\d+)/ && $$1 >= 4.034) { print "--timescale 1ns/1ps"; }')
|
||||
VERILATOR_NONCC_OPTS = \
|
||||
$(TIMESCALE_OPTS) \
|
||||
--top-module $(VLOG_MODEL) \
|
||||
--vpi \
|
||||
-Wno-fatal \
|
||||
$(shell if ! grep -iq "module.*ariane" $(build_dir)/*.*v; then echo "$(CHIPYARD_VERILATOR_FLAGS)"; else echo "$(ARIANE_VERILATOR_FLAGS)"; fi) \
|
||||
--output-split 10000 \
|
||||
--output-split-cfuncs 100 \
|
||||
--max-num-width 1048576 \
|
||||
-f $(sim_common_files) \
|
||||
$(sim_vsrcs)
|
||||
|
||||
VERILATOR_DEFINES = \
|
||||
# see: https://github.com/ucb-bar/riscv-mini/issues/31
|
||||
MAX_WIDTH_OPTS = $(shell verilator --version | perl -lne 'if (/(\d.\d+)/ && $$1 > 4.016) { print "--max-num-width 1048576"; }')
|
||||
|
||||
PREPROC_DEFINES := \
|
||||
+define+PRINTF_COND=\$$c\(\"verbose\",\"\&\&\"\,\"done_reset\"\) \
|
||||
+define+STOP_COND=\$$c\(\"done_reset\"\)
|
||||
|
||||
VERILATOR_OPTS = $(VERILATOR_CC_OPTS) $(VERILATOR_NONCC_OPTS) $(VERILATOR_DEFINES) $(EXTRA_SIM_SOURCES)
|
||||
VERILATOR_NONCC_OPTS = \
|
||||
$(RUNTIME_PROFILING_VFLAGS) \
|
||||
$(RUNTIME_THREADS) \
|
||||
$(VERILATOR_OPT_FLAGS) \
|
||||
$(PLATFORM_OPTS) \
|
||||
-Wno-fatal \
|
||||
$(TIMESCALE_OPTS) \
|
||||
$(MAX_WIDTH_OPTS) \
|
||||
$(PREPROC_DEFINES) \
|
||||
--top-module $(VLOG_MODEL) \
|
||||
--vpi \
|
||||
-f $(sim_common_files) \
|
||||
$(sim_vsrcs)
|
||||
|
||||
#----------------------------------------------------------------------------------------
|
||||
# gcc configuration/optimization
|
||||
#----------------------------------------------------------------------------------------
|
||||
include $(base_dir)/sims/common-sim-flags.mk
|
||||
|
||||
VERILATOR_CXXFLAGS = \
|
||||
$(SIM_CXXFLAGS) \
|
||||
$(RUNTIME_PROFILING_CFLAGS) \
|
||||
$(TRACING_CFLAGS) \
|
||||
-D__STDC_FORMAT_MACROS \
|
||||
-DTEST_HARNESS=V$(VLOG_MODEL) \
|
||||
-DVERILATOR \
|
||||
-include $(build_dir)/$(long_name).plusArgs \
|
||||
-include $(build_dir)/verilator.h
|
||||
|
||||
VERILATOR_LDFLAGS = $(SIM_LDFLAGS)
|
||||
|
||||
VERILATOR_CC_OPTS = \
|
||||
-CFLAGS "$(VERILATOR_CXXFLAGS)" \
|
||||
-LDFLAGS "$(VERILATOR_LDFLAGS)"
|
||||
|
||||
#----------------------------------------------------------------------------------------
|
||||
# full verilator+gcc opts
|
||||
#----------------------------------------------------------------------------------------
|
||||
VERILATOR_OPTS = $(VERILATOR_CC_OPTS) $(VERILATOR_NONCC_OPTS)
|
||||
|
||||
#########################################################################################
|
||||
# verilator build paths and file names
|
||||
@@ -127,13 +182,13 @@ model_mk_debug = $(model_dir_debug)/V$(VLOG_MODEL).mk
|
||||
$(model_mk): $(sim_vsrcs) $(sim_common_files) $(EXTRA_SIM_REQS)
|
||||
rm -rf $(model_dir)
|
||||
mkdir -p $(model_dir)
|
||||
$(VERILATOR) $(VERILATOR_OPTS) -o $(sim) -Mdir $(model_dir) -CFLAGS "-include $(model_header)"
|
||||
$(VERILATOR) $(VERILATOR_OPTS) $(EXTRA_SIM_SOURCES) -o $(sim) -Mdir $(model_dir) -CFLAGS "-include $(model_header)"
|
||||
touch $@
|
||||
|
||||
$(model_mk_debug): $(sim_vsrcs) $(sim_common_files) $(EXTRA_SIM_REQS)
|
||||
rm -rf $(model_dir_debug)
|
||||
mkdir -p $(model_dir_debug)
|
||||
$(VERILATOR) $(VERILATOR_OPTS) -o $(sim_debug) --trace -Mdir $(model_dir_debug) -CFLAGS "-include $(model_header_debug)"
|
||||
$(VERILATOR) $(VERILATOR_OPTS) $(EXTRA_SIM_SOURCES) -o $(sim_debug) $(TRACING_OPTS) -Mdir $(model_dir_debug) -CFLAGS "-include $(model_header_debug)"
|
||||
touch $@
|
||||
|
||||
#########################################################################################
|
||||
@@ -152,11 +207,17 @@ $(sim_debug): $(model_mk_debug) $(dramsim_lib)
|
||||
$(output_dir)/%.vpd: $(output_dir)/% $(sim_debug)
|
||||
rm -f $@.vcd && mkfifo $@.vcd
|
||||
vcd2vpd $@.vcd $@ > /dev/null &
|
||||
(set -o pipefail && $(sim_debug) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(VERBOSE_FLAGS) -v$@.vcd $(PERMISSIVE_OFF) $< </dev/null 2> >(spike-dasm > $<.out) | tee $<.log)
|
||||
(set -o pipefail && $(NUMA_PREFIX) $(sim_debug) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(VERBOSE_FLAGS) -v$@.vcd $(PERMISSIVE_OFF) $< </dev/null 2> >(spike-dasm > $<.out) | tee $<.log)
|
||||
|
||||
#########################################################################################
|
||||
# general cleanup rule
|
||||
# general cleanup rules
|
||||
#########################################################################################
|
||||
.PHONY: clean
|
||||
.PHONY: clean clean-sim clean-sim-debug
|
||||
clean:
|
||||
rm -rf $(gen_dir) $(sim_prefix)-*
|
||||
|
||||
clean-sim:
|
||||
rm -rf $(model_dir) $(sim)
|
||||
|
||||
clean-sim-debug:
|
||||
rm -rf $(model_dir_debug) $(sim_debug)
|
||||
|
||||
Submodule toolchains/esp-tools/riscv-isa-sim updated: a1ff6b03f7...fa94e84d4f
Submodule toolchains/esp-tools/riscv-tests updated: f1370d0543...e116930c7d
Submodule toolchains/riscv-tools/riscv-isa-sim updated: 8d860c1906...acd953afd2
Submodule toolchains/riscv-tools/riscv-openocd updated: 7c82a7b9d5...cbb15587dc
Submodule toolchains/riscv-tools/riscv-tests updated: 249796cec9...19bfdab48c
Submodule tools/barstools updated: aa1c90c4cc...4a5c75fcf8
Submodule tools/chisel3 updated: 21ea734d80...cc2971feb1
@@ -49,7 +49,7 @@ ifdef ENABLE_DROMAJO
|
||||
EXTRA_SIM_FLAGS += $(DROMAJO_FLAGS)
|
||||
|
||||
# CC flags needed for all simulations
|
||||
EXTRA_SIM_CC_FLAGS += -I$(DROMAJO_DIR)
|
||||
EXTRA_SIM_CXXFLAGS += -I$(DROMAJO_DIR)
|
||||
|
||||
# sourced needed for simulation
|
||||
EXTRA_SIM_SOURCES += $(DROMAJO_LIB)
|
||||
|
||||
Submodule tools/firrtl updated: 7c6f58d986...c07da8a581
62
variables.mk
62
variables.mk
@@ -1,23 +1,51 @@
|
||||
#########################################################################################
|
||||
# makefile variables shared across multiple makefiles
|
||||
# - to use the help text, your Makefile should have a 'help' target that just
|
||||
# prints all the HELP_LINES
|
||||
#########################################################################################
|
||||
HELP_COMPILATION_VARIABLES =
|
||||
HELP_PROJECT_VARIABLES = \
|
||||
" SUB_PROJECT = use the specific subproject default variables [$(SUB_PROJECT)]" \
|
||||
" SBT_PROJECT = the SBT project that you should find the classes/packages in [$(SBT_PROJECT)]" \
|
||||
" MODEL = the top level module of the project in Chisel (normally the harness) [$(MODEL)]" \
|
||||
" VLOG_MODEL = the top level module of the project in Firrtl/Verilog (normally the harness) [$(VLOG_MODEL)]" \
|
||||
" MODEL_PACKAGE = the scala package to find the MODEL in [$(MODEL_PACKAGE)]" \
|
||||
" CONFIG = the configuration class to give the parameters for the project [$(CONFIG)]" \
|
||||
" CONFIG_PACKAGE = the scala package to find the CONFIG class [$(CONFIG_PACKAGE)]" \
|
||||
" GENERATOR_PACKAGE = the scala package to find the Generator class in [$(GENERATOR_PACKAGE)]" \
|
||||
" TB = testbench wrapper over the TestHarness needed to simulate in a verilog simulator [$(TB)]" \
|
||||
" TOP = top level module of the project (normally the module instantiated by the harness) [$(TOP)]"
|
||||
|
||||
#########################################################################################
|
||||
# variables to invoke the generator
|
||||
# descriptions:
|
||||
# SBT_PROJECT = the SBT project that you should find the classes/packages in
|
||||
# MODEL = the top level module of the project in Chisel (normally the harness)
|
||||
# VLOG_MODEL = the top level module of the project in Firrtl/Verilog (normally the harness)
|
||||
# MODEL_PACKAGE = the scala package to find the MODEL in
|
||||
# CONFIG = the configuration class to give the parameters for the project
|
||||
# CONFIG_PACKAGE = the scala package to find the CONFIG class
|
||||
# GENERATOR_PACKAGE = the scala package to find the Generator class in
|
||||
# TB = wrapper over the TestHarness needed to simulate in a verilog simulator
|
||||
# TOP = top level module of the project (normally the module instantiated by the harness)
|
||||
#
|
||||
# project specific:
|
||||
# SUB_PROJECT = use the specific subproject default variables
|
||||
#########################################################################################
|
||||
HELP_SIMULATION_VARIABLES = \
|
||||
" BINARY = riscv elf binary that the simulator will run when using the run-binary* targets" \
|
||||
" VERBOSE_FLAGS = flags used when doing verbose simulation [$(VERBOSE_FLAGS)]"
|
||||
|
||||
# include default simulation rules
|
||||
HELP_COMMANDS = \
|
||||
" help = display this help" \
|
||||
" default = compiles non-debug simulator [./$(shell basename $(sim))]" \
|
||||
" debug = compiles debug simulator [./$(shell basename $(sim_debug))]" \
|
||||
" clean = remove all debug/non-debug simulators and intermediate files" \
|
||||
" clean-sim = removes non-debug simulator and simulator-generated files" \
|
||||
" clean-sim-debug = removes debug simulator and simulator-generated files"
|
||||
|
||||
HELP_LINES = "" \
|
||||
" design specifier variables:" \
|
||||
" ---------------------------" \
|
||||
$(HELP_PROJECT_VARIABLES) \
|
||||
"" \
|
||||
" compilation variables:" \
|
||||
" ----------------------" \
|
||||
$(HELP_COMPILATION_VARIABLES) \
|
||||
"" \
|
||||
" simulation variables:" \
|
||||
" ---------------------" \
|
||||
$(HELP_SIMULATION_VARIABLES) \
|
||||
"" \
|
||||
" some useful general commands:" \
|
||||
" -----------------------------" \
|
||||
$(HELP_COMMANDS) \
|
||||
""
|
||||
|
||||
#########################################################################################
|
||||
# subproject overrides
|
||||
@@ -140,7 +168,7 @@ override SCALA_BUILDTOOL_DEPS += $(BLOOP_CONFIG_DIR)/TIMESTAMP
|
||||
# 1) the sed removes a leading {file:<path>} that sometimes needs to be
|
||||
# provided to SBT when a project but not for bloop.
|
||||
# 2) Generally, one could could pass '--' to indicate all remaining arguments are
|
||||
# destined for the scala Main, however a bug in Bloop's argument parsing causes the
|
||||
# destined for the scala Main, however a bug in Bloop's argument parsing causes the
|
||||
# --nailgun-port argument to be lost in this case. Workaround this by prefixing
|
||||
# every main-destined argument with "--args"
|
||||
define run_scala_main
|
||||
|
||||
26
vcs.mk
26
vcs.mk
@@ -11,15 +11,23 @@ endif
|
||||
CLOCK_PERIOD ?= 1.0
|
||||
RESET_DELAY ?= 777.7
|
||||
|
||||
#----------------------------------------------------------------------------------------
|
||||
# gcc configuration/optimization
|
||||
#----------------------------------------------------------------------------------------
|
||||
include $(base_dir)/sims/common-sim-flags.mk
|
||||
|
||||
VCS_CXXFLAGS = $(SIM_CXXFLAGS)
|
||||
VCS_LDFLAGS = $(SIM_LDFLAGS)
|
||||
|
||||
# vcs requires LDFLAGS to not include library names (i.e. -l needs to be separate)
|
||||
VCS_CC_OPTS = \
|
||||
-CC "-I$(RISCV)/include" \
|
||||
-CC "-I$(dramsim_dir)" \
|
||||
-CC "-std=c++11" \
|
||||
-CC "$(EXTRA_SIM_CC_FLAGS)"
|
||||
-CFLAGS "$(VCS_CXXFLAGS)" \
|
||||
-LDFLAGS "$(filter-out -l%,$(VCS_LDFLAGS))" \
|
||||
$(filter -l%,$(VCS_LDFLAGS))
|
||||
|
||||
VCS_NONCC_OPTS = \
|
||||
$(dramsim_lib) \
|
||||
$(RISCV)/lib/libfesvr.a \
|
||||
-notice \
|
||||
-line \
|
||||
+lint=all,noVCDE,noONGS,noUI \
|
||||
-error=PCWM-L \
|
||||
-error=noZMMCM \
|
||||
@@ -27,7 +35,6 @@ VCS_NONCC_OPTS = \
|
||||
-quiet \
|
||||
-q \
|
||||
+rad \
|
||||
+v2k \
|
||||
+vcs+lic+wait \
|
||||
+vc+list \
|
||||
-f $(sim_common_files) \
|
||||
@@ -35,10 +42,9 @@ VCS_NONCC_OPTS = \
|
||||
+v2k +verilog2001ext+.v95+.vt+.vp +libext+.v \
|
||||
-debug_pp \
|
||||
+incdir+$(build_dir) \
|
||||
$(sim_vsrcs) \
|
||||
+libext+.v
|
||||
$(sim_vsrcs)
|
||||
|
||||
VCS_DEFINE_OPTS = \
|
||||
PREPROC_DEFINES = \
|
||||
+define+VCS \
|
||||
+define+CLOCK_PERIOD=$(CLOCK_PERIOD) \
|
||||
+define+RESET_DELAY=$(RESET_DELAY) \
|
||||
|
||||
@@ -34,7 +34,7 @@ INPUT_CONFS ?= $(if $(filter $(tech_name),nangate45),\
|
||||
example-asap7.yml)
|
||||
HAMMER_EXEC ?= example-vlsi
|
||||
VLSI_TOP ?= $(TOP)
|
||||
VLSI_HARNESS_DUT_NAME ?= dut
|
||||
VLSI_HARNESS_DUT_NAME ?= chiptop
|
||||
VLSI_OBJ_DIR ?= $(vlsi_dir)/build
|
||||
ifneq ($(CUSTOM_VLOG),)
|
||||
OBJ_DIR ?= $(VLSI_OBJ_DIR)/custom-$(VLSI_TOP)
|
||||
@@ -115,15 +115,20 @@ $(SIM_CONF): $(VLSI_RTL) $(HARNESS_FILE) $(HARNESS_SMEMS_FILE) $(sim_common_file
|
||||
done
|
||||
echo " options_meta: 'append'" >> $@
|
||||
echo " defines:" >> $@
|
||||
for x in $(subst +define+,,$(VCS_DEFINE_OPTS)); do \
|
||||
for x in $(subst +define+,,$(PREPROC_DEFINES)); do \
|
||||
echo ' - "'$$x'"' >> $@; \
|
||||
done
|
||||
echo " defines_meta: 'append'" >> $@
|
||||
echo " compiler_opts:" >> $@
|
||||
for x in $(filter-out "",$(filter-out -CC,$(VCS_CC_OPTS))); do \
|
||||
echo " compiler_cc_opts:" >> $@
|
||||
for x in $(filter-out "",$(VCS_CXXFLAGS)); do \
|
||||
echo ' - "'$$x'"' >> $@; \
|
||||
done
|
||||
echo " compiler_opts_meta: 'append'" >> $@
|
||||
echo " compiler_cc_opts_meta: 'append'" >> $@
|
||||
echo " compiler_ld_opts:" >> $@
|
||||
for x in $(filter-out "",$(VCS_LDFLAGS)); do \
|
||||
echo ' - "'$$x'"' >> $@; \
|
||||
done
|
||||
echo " compiler_ld_opts_meta: 'append'" >> $@
|
||||
echo " execution_flags_prepend: ['$(PERMISSIVE_ON)']" >> $@
|
||||
echo " execution_flags_append: ['$(PERMISSIVE_OFF)']" >> $@
|
||||
echo " execution_flags:" >> $@
|
||||
|
||||
Submodule vlsi/hammer updated: cbc907dfe8...bed4d34094
Submodule vlsi/hammer-synopsys-plugins updated: e5ec0da8ad...f8a7922220
Reference in New Issue
Block a user