Merge remote-tracking branch 'upstream/main' into graphics

This commit is contained in:
Hansung Kim
2023-07-22 14:45:48 -07:00
175 changed files with 5277 additions and 4019 deletions

View File

@@ -10,8 +10,8 @@ runs:
else else
echo "Creating a conda environment for each toolchain with the toolchain installed" echo "Creating a conda environment for each toolchain with the toolchain installed"
conda activate base conda activate base
conda-lock install -n ${{ env.conda-env-name-no-time }}-$(date --date "${{ env.workflow-timestamp }}" +%Y%m%d)-riscv-tools ./conda-reqs/conda-lock-reqs/conda-requirements-riscv-tools-linux-64.conda-lock.yml conda-lock install --conda $(which conda) -n ${{ env.conda-env-name-no-time }}-$(date --date "${{ env.workflow-timestamp }}" +%Y%m%d)-riscv-tools ./conda-reqs/conda-lock-reqs/conda-requirements-riscv-tools-linux-64.conda-lock.yml
conda-lock install -n ${{ env.conda-env-name-no-time }}-$(date --date "${{ env.workflow-timestamp }}" +%Y%m%d)-esp-tools ./conda-reqs/conda-lock-reqs/conda-requirements-esp-tools-linux-64.conda-lock.yml conda-lock install --conda $(which conda) -n ${{ env.conda-env-name-no-time }}-$(date --date "${{ env.workflow-timestamp }}" +%Y%m%d)-esp-tools ./conda-reqs/conda-lock-reqs/conda-requirements-esp-tools-linux-64.conda-lock.yml
conda deactivate conda deactivate
echo "Add extra toolchain collateral to RISC-V install area" echo "Add extra toolchain collateral to RISC-V install area"

View File

@@ -45,7 +45,7 @@ search () {
done done
} }
submodules=("cva6" "boom" "ibex" "gemmini" "hwacha" "icenet" "nvdla" "rocket-chip" "sha3" "sifive-blocks" "sifive-cache" "testchipip" "riscv-sodor" "mempress") submodules=("cva6" "boom" "ibex" "gemmini" "hwacha" "icenet" "nvdla" "rocket-chip" "sha3" "sifive-blocks" "sifive-cache" "testchipip" "riscv-sodor" "mempress" "bar-fetchers" "shuttle")
dir="generators" dir="generators"
branches=("master" "main" "dev") branches=("master" "main" "dev")
search search
@@ -91,11 +91,6 @@ dir="tools"
branches=("master" "dev") branches=("master" "dev")
search search
submodules=("firesim")
dir="sims"
branches=("master" "main" "dev" "1.13.x")
search
submodules=("fpga-shells") submodules=("fpga-shells")
dir="fpga" dir="fpga"
branches=("main") branches=("main")

View File

@@ -28,37 +28,42 @@ REMOTE_COURSIER_CACHE=$REMOTE_WORK_DIR/.coursier-cache
# key value store to get the build groups # key value store to get the build groups
declare -A grouping declare -A grouping
grouping["group-cores"]="chipyard-cva6 chipyard-ibex chipyard-rocket chipyard-hetero chipyard-boom chipyard-sodor chipyard-digitaltop chipyard-multiclock-rocket chipyard-nomem-scratchpad chipyard-spike chipyard-clone" grouping["group-cores"]="chipyard-cva6 chipyard-ibex chipyard-rocket chipyard-hetero chipyard-boom chipyard-sodor chipyard-digitaltop chipyard-multiclock-rocket chipyard-nomem-scratchpad chipyard-spike chipyard-clone chipyard-prefetchers chipyard-shuttle"
grouping["group-peripherals"]="chipyard-dmirocket chipyard-spiflashwrite chipyard-mmios chipyard-nocores chipyard-manyperipherals chipyard-chiplike" grouping["group-peripherals"]="chipyard-dmirocket chipyard-dmiboom chipyard-spiflashwrite chipyard-mmios chipyard-nocores chipyard-manyperipherals chipyard-chiplike chipyard-tethered"
grouping["group-accels"]="chipyard-mempress chipyard-sha3 chipyard-hwacha chipyard-gemmini chipyard-manymmioaccels" grouping["group-accels"]="chipyard-mempress chipyard-sha3 chipyard-hwacha chipyard-gemmini chipyard-manymmioaccels chipyard-nvdla"
grouping["group-constellation"]="chipyard-constellation" grouping["group-constellation"]="chipyard-constellation"
grouping["group-tracegen"]="tracegen tracegen-boom" grouping["group-tracegen"]="tracegen tracegen-boom"
grouping["group-other"]="icenet testchipip constellation" grouping["group-other"]="icenet testchipip constellation rocketchip-amba rocketchip-tlsimple rocketchip-tlwidth rocketchip-tlxbar"
grouping["group-fpga"]="arty vcu118 vc707" grouping["group-fpga"]="arty vcu118 vc707"
# key value store to get the build strings # key value store to get the build strings
declare -A mapping declare -A mapping
mapping["chipyard-rocket"]="" mapping["chipyard-rocket"]=" CONFIG=QuadChannelRocketConfig"
mapping["chipyard-dmirocket"]=" CONFIG=dmiRocketConfig" mapping["chipyard-dmirocket"]=" CONFIG=dmiRocketConfig"
mapping["chipyard-sha3"]=" CONFIG=Sha3RocketConfig" mapping["chipyard-sha3"]=" CONFIG=Sha3RocketConfig"
mapping["chipyard-mempress"]=" CONFIG=MempressRocketConfig" mapping["chipyard-mempress"]=" CONFIG=MempressRocketConfig"
mapping["chipyard-prefetchers"]=" CONFIG=PrefetchingRocketConfig"
mapping["chipyard-digitaltop"]=" TOP=DigitalTop" mapping["chipyard-digitaltop"]=" TOP=DigitalTop"
mapping["chipyard-manymmioaccels"]=" CONFIG=ManyMMIOAcceleratorRocketConfig" mapping["chipyard-manymmioaccels"]=" CONFIG=ManyMMIOAcceleratorRocketConfig"
mapping["chipyard-nvdla"]=" CONFIG=SmallNVDLARocketConfig verilog"
mapping["chipyard-hetero"]=" CONFIG=LargeBoomAndRocketConfig" mapping["chipyard-hetero"]=" CONFIG=LargeBoomAndRocketConfig"
mapping["chipyard-boom"]=" CONFIG=MediumBoomCosimConfig" mapping["chipyard-boom"]=" CONFIG=MediumBoomCosimConfig"
mapping["chipyard-spike"]=" CONFIG=SpikeFastUARTConfig EXTRA_SIM_FLAGS='+spike-ipc=10'" mapping["chipyard-dmiboom"]=" CONFIG=dmiMediumBoomCosimConfig"
mapping["chipyard-spike"]=" CONFIG=SpikeConfig EXTRA_SIM_FLAGS='+spike-ipc=10'"
mapping["chipyard-hwacha"]=" CONFIG=HwachaRocketConfig" mapping["chipyard-hwacha"]=" CONFIG=HwachaRocketConfig"
mapping["chipyard-gemmini"]=" CONFIG=GemminiRocketConfig" mapping["chipyard-gemmini"]=" CONFIG=GemminiRocketConfig"
mapping["chipyard-cva6"]=" CONFIG=CVA6Config" mapping["chipyard-cva6"]=" CONFIG=CVA6Config"
mapping["chipyard-ibex"]=" CONFIG=IbexConfig" mapping["chipyard-ibex"]=" CONFIG=IbexConfig"
mapping["chipyard-spiflashwrite"]=" CONFIG=SmallSPIFlashRocketConfig EXTRA_SIM_FLAGS='+spiflash0=${LOCAL_CHIPYARD_DIR}/tests/spiflash.img'" mapping["chipyard-spiflashwrite"]=" CONFIG=SmallSPIFlashRocketConfig EXTRA_SIM_FLAGS='+spiflash0=${LOCAL_CHIPYARD_DIR}/tests/spiflash.img'"
mapping["chipyard-manyperipherals"]=" CONFIG=ManyPeripheralsRocketConfig EXTRA_SIM_FLAGS='+spiflash0=${LOCAL_CHIPYARD_DIR}/tests/spiflash.img'" mapping["chipyard-manyperipherals"]=" CONFIG=ManyPeripheralsRocketConfig EXTRA_SIM_FLAGS='+spiflash0=${LOCAL_CHIPYARD_DIR}/tests/spiflash.img'"
mapping["chipyard-chiplike"]=" CONFIG=ChipLikeQuadRocketConfig MODEL=FlatTestHarness MODEL_PACKAGE=chipyard.example verilog" mapping["chipyard-chiplike"]=" CONFIG=ChipLikeRocketConfig MODEL=FlatTestHarness MODEL_PACKAGE=chipyard.example verilog"
mapping["chipyard-tethered"]=" CONFIG=VerilatorCITetheredChipLikeRocketConfig"
mapping["chipyard-cloneboom"]=" CONFIG=Cloned64MegaBoomConfig verilog" mapping["chipyard-cloneboom"]=" CONFIG=Cloned64MegaBoomConfig verilog"
mapping["chipyard-nocores"]=" CONFIG=NoCoresConfig verilog" mapping["chipyard-nocores"]=" CONFIG=NoCoresConfig verilog"
mapping["tracegen"]=" CONFIG=NonBlockingTraceGenL2Config" mapping["tracegen"]=" CONFIG=NonBlockingTraceGenL2Config"
mapping["tracegen-boom"]=" CONFIG=BoomTraceGenConfig" mapping["tracegen-boom"]=" CONFIG=BoomTraceGenConfig"
mapping["chipyard-sodor"]=" CONFIG=Sodor5StageConfig" mapping["chipyard-sodor"]=" CONFIG=Sodor5StageConfig"
mapping["chipyard-shuttle"]=" CONFIG=ShuttleConfig"
mapping["chipyard-multiclock-rocket"]=" CONFIG=MulticlockRocketConfig" mapping["chipyard-multiclock-rocket"]=" CONFIG=MulticlockRocketConfig"
mapping["chipyard-nomem-scratchpad"]=" CONFIG=MMIOScratchpadOnlyRocketConfig" mapping["chipyard-nomem-scratchpad"]=" CONFIG=MMIOScratchpadOnlyRocketConfig"
mapping["chipyard-constellation"]=" CONFIG=SharedNoCConfig" mapping["chipyard-constellation"]=" CONFIG=SharedNoCConfig"
@@ -68,6 +73,10 @@ mapping["firesim"]="SCALA_TEST=firesim.firesim.RocketNICF1Tests"
mapping["fireboom"]="SCALA_TEST=firesim.firesim.BoomF1Tests" mapping["fireboom"]="SCALA_TEST=firesim.firesim.BoomF1Tests"
mapping["icenet"]="SUB_PROJECT=icenet" mapping["icenet"]="SUB_PROJECT=icenet"
mapping["testchipip"]="SUB_PROJECT=testchipip" mapping["testchipip"]="SUB_PROJECT=testchipip"
mapping["rocketchip-amba"]="SUB_PROJECT=rocketchip CONFIG=AMBAUnitTestConfig"
mapping["rocketchip-tlsimple"]="SUB_PROJECT=rocketchip CONFIG=TLSimpleUnitTestConfig"
mapping["rocketchip-tlwidth"]="SUB_PROJECT=rocketchip CONFIG=TLWidthUnitTestConfig"
mapping["rocketchip-tlxbar"]="SUB_PROJECT=rocketchip CONFIG=TLXbarUnitTestConfig"
mapping["arty"]="SUB_PROJECT=arty verilog" mapping["arty"]="SUB_PROJECT=arty verilog"
mapping["vcu118"]="SUB_PROJECT=vcu118 verilog" mapping["vcu118"]="SUB_PROJECT=vcu118 verilog"

View File

@@ -1,7 +1,9 @@
#!/bin/bash #!/bin/bash
export HOME="${HOME:-/root}"
CONDA_INSTALL_PREFIX=/opt/conda CONDA_INSTALL_PREFIX=/opt/conda
CONDA_INSTALLER_VERSION=4.12.0-0 CONDA_INSTALLER_VERSION=23.1.0-1
CONDA_INSTALLER="https://github.com/conda-forge/miniforge/releases/download/${CONDA_INSTALLER_VERSION}/Miniforge3-${CONDA_INSTALLER_VERSION}-Linux-x86_64.sh" CONDA_INSTALLER="https://github.com/conda-forge/miniforge/releases/download/${CONDA_INSTALLER_VERSION}/Miniforge3-${CONDA_INSTALLER_VERSION}-Linux-x86_64.sh"
CONDA_CMD="conda" # some installers install mamba or micromamba CONDA_CMD="conda" # some installers install mamba or micromamba
@@ -143,15 +145,18 @@ else
$SUDO bash ./install_conda.sh -b -p "$CONDA_INSTALL_PREFIX" $conda_install_extra $SUDO bash ./install_conda.sh -b -p "$CONDA_INSTALL_PREFIX" $conda_install_extra
rm ./install_conda.sh rm ./install_conda.sh
# get most up-to-date conda version
"${DRY_RUN_ECHO[@]}" $SUDO "$CONDA_EXE" update $DRY_RUN_OPTION -y -n base -c conda-forge conda
# see https://conda-forge.org/docs/user/tipsandtricks.html#multiple-channels # see https://conda-forge.org/docs/user/tipsandtricks.html#multiple-channels
# for more information on strict channel_priority # for more information on flexible channel_priority
"${DRY_RUN_ECHO[@]}" $SUDO "$CONDA_EXE" config --system --set channel_priority strict "${DRY_RUN_ECHO[@]}" $SUDO "$CONDA_EXE" config --system --set channel_priority flexible
# By default, don't mess with people's PS1, I personally find it annoying # By default, don't mess with people's PS1, I personally find it annoying
"${DRY_RUN_ECHO[@]}" $SUDO "$CONDA_EXE" config --system --set changeps1 false "${DRY_RUN_ECHO[@]}" $SUDO "$CONDA_EXE" config --system --set changeps1 false
# don't automatically activate the 'base' environment when intializing shells # don't automatically activate the 'base' environment when initializing shells
"${DRY_RUN_ECHO[@]}" $SUDO "$CONDA_EXE" config --system --set auto_activate_base false "${DRY_RUN_ECHO[@]}" $SUDO "$CONDA_EXE" config --system --set auto_activate_base false
# don't automatically update conda to avoid https://github.com/conda-forge/conda-libmamba-solver-feedstock/issues/2 # automatically use the ucb-bar channel for specific packages https://anaconda.org/ucb-bar/repo
"${DRY_RUN_ECHO[@]}" $SUDO "$CONDA_EXE" config --system --set auto_update_conda false "${DRY_RUN_ECHO[@]}" $SUDO "$CONDA_EXE" config --system --add channels ucb-bar
# conda-build is a special case and must always be installed into the base environment # conda-build is a special case and must always be installed into the base environment
$SUDO "$CONDA_EXE" install $DRY_RUN_OPTION -y -n base conda-build $SUDO "$CONDA_EXE" install $DRY_RUN_OPTION -y -n base conda-build
@@ -160,12 +165,12 @@ else
# see https://www.anaconda.com/blog/a-faster-conda-for-a-growing-community # see https://www.anaconda.com/blog/a-faster-conda-for-a-growing-community
$SUDO "$CONDA_EXE" install $DRY_RUN_OPTION -y -n base conda-libmamba-solver $SUDO "$CONDA_EXE" install $DRY_RUN_OPTION -y -n base conda-libmamba-solver
# conda-lock is a special case and must always be installed into the base environment
$SUDO "$CONDA_EXE" install $DRY_RUN_OPTION -y -n base conda-lock
# Use the fast solver by default # Use the fast solver by default
"${DRY_RUN_ECHO[@]}" $SUDO "$CONDA_EXE" config --system --set experimental_solver libmamba "${DRY_RUN_ECHO[@]}" $SUDO "$CONDA_EXE" config --system --set experimental_solver libmamba
# conda-lock is a special case and must always be installed into the base environment
$SUDO "$CONDA_EXE" install $DRY_RUN_OPTION -y -n base conda-lock=1.4
conda_init_extra_args=() conda_init_extra_args=()
if [[ "$INSTALL_TYPE" == system ]]; then if [[ "$INSTALL_TYPE" == system ]]; then
# if we're installing into a root-owned directory using sudo, or we're already root # if we're installing into a root-owned directory using sudo, or we're already root

View File

@@ -16,8 +16,6 @@ source $SCRIPT_DIR/defaults.sh
cd $REMOTE_CHIPYARD_DIR cd $REMOTE_CHIPYARD_DIR
./scripts/init-submodules-no-riscv-tools.sh --force ./scripts/init-submodules-no-riscv-tools.sh --force
./scripts/init-fpga.sh
# Constellation can run without espresso, but this improves # Constellation can run without espresso, but this improves
# elaboration time drastically # elaboration time drastically

View File

@@ -14,8 +14,9 @@ cd $REMOTE_CHIPYARD_DIR
./scripts/init-submodules-no-riscv-tools.sh --force ./scripts/init-submodules-no-riscv-tools.sh --force
# Run Firesim Scala Tests # Run Firesim Scala Tests
export FIRESIM_ENV_SOURCED=1; export FIRESIM_ENV_SOURCED=1
export COURSIER_CACHE=$REMOTE_COURSIER_CACHE export COURSIER_CACHE=$REMOTE_COURSIER_CACHE
export JVM_MEMORY=10G export JVM_MEMORY=10G
export JAVA_TMP_DIR=$REMOTE_JAVA_TMP_DIR export JAVA_TMP_DIR=$REMOTE_JAVA_TMP_DIR
export TEST_DISABLE_VIVADO=1
make -C $REMOTE_FIRESIM_DIR TARGET_SBT_PROJECT="{file:$REMOTE_CHIPYARD_DIR}firechip" testOnly ${mapping[$1]} make -C $REMOTE_FIRESIM_DIR TARGET_SBT_PROJECT="{file:$REMOTE_CHIPYARD_DIR}firechip" testOnly ${mapping[$1]}

View File

@@ -10,13 +10,14 @@ SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
source $SCRIPT_DIR/defaults.sh source $SCRIPT_DIR/defaults.sh
DISABLE_SIM_PREREQ="BREAK_SIM_PREREQ=1" DISABLE_SIM_PREREQ="BREAK_SIM_PREREQ=1"
MAPPING_FLAGS=${mapping[$1]}
run_bmark () { run_bmark () {
make run-bmark-tests-fast -j$CI_MAKE_NPROC -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ $@ make run-bmark-tests-fast -j$CI_MAKE_NPROC -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ $MAPPING_FLAGS $@
} }
run_asm () { run_asm () {
make run-asm-tests-fast -j$CI_MAKE_NPROC -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ $@ make run-asm-tests-fast -j$CI_MAKE_NPROC -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ $MAPPING_FLAGS $@
} }
run_both () { run_both () {
@@ -25,102 +26,137 @@ run_both () {
} }
run_tracegen () { run_tracegen () {
make tracegen -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ $@ make tracegen -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ $MAPPING_FLAGS $@
}
run_binary () {
make run-binary-fast -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ $MAPPING_FLAGS $@
} }
case $1 in case $1 in
chipyard-rocket) chipyard-rocket)
run_bmark ${mapping[$1]} run_bmark
make -C $LOCAL_CHIPYARD_DIR/tests
# Test run-binary with and without loadmem
run_binary BINARY=$LOCAL_CHIPYARD_DIR/tests/hello.riscv LOADMEM=1
run_binary BINARY=$LOCAL_CHIPYARD_DIR/tests/hello.riscv
;; ;;
chipyard-dmirocket) chipyard-dmirocket)
run_bmark ${mapping[$1]} # Test checkpoint-restore
$LOCAL_CHIPYARD_DIR/scripts/generate-ckpt.sh -b $RISCV/riscv64-unknown-elf/share/riscv-tests/benchmarks/dhrystone.riscv -i 10000
run_binary LOADARCH=$PWD/dhrystone.riscv.0x80000000.10000.loadarch
;; ;;
chipyard-boom) chipyard-boom)
run_bmark
;;
chipyard-shuttle)
run_bmark ${mapping[$1]} run_bmark ${mapping[$1]}
;; ;;
chipyard-dmiboom)
# Test checkpoint-restore
$LOCAL_CHIPYARD_DIR/scripts/generate-ckpt.sh -b $RISCV/riscv64-unknown-elf/share/riscv-tests/benchmarks/dhrystone.riscv -i 10000
run_binary LOADARCH=$PWD/dhrystone.riscv.0x80000000.10000.loadarch
;;
chipyard-spike) chipyard-spike)
run_bmark ${mapping[$1]} run_bmark
;; ;;
chipyard-hetero) chipyard-hetero)
run_bmark ${mapping[$1]} run_bmark
;;
chipyard-prefetchers)
run_binary BINARY=$RISCV/riscv64-unknown-elf/share/riscv-tests/benchmarks/dhrystone.riscv
;; ;;
rocketchip) rocketchip)
run_bmark ${mapping[$1]} run_bmark
;; ;;
chipyard-hwacha) chipyard-hwacha)
make run-rv64uv-p-asm-tests -j$CI_MAKE_NPROC -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} make run-rv64uv-p-asm-tests -j$CI_MAKE_NPROC -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ $MAPPING_FLAGS
;; ;;
chipyard-gemmini) chipyard-gemmini)
GEMMINI_SOFTWARE_DIR=$LOCAL_SIM_DIR/../../generators/gemmini/software/gemmini-rocc-tests GEMMINI_SOFTWARE_DIR=$LOCAL_SIM_DIR/../../generators/gemmini/software/gemmini-rocc-tests
rm -rf $GEMMINI_SOFTWARE_DIR/riscv-tests rm -rf $GEMMINI_SOFTWARE_DIR/riscv-tests
cd $LOCAL_SIM_DIR cd $LOCAL_SIM_DIR
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} run-binary-fast BINARY=$GEMMINI_SOFTWARE_DIR/build/bareMetalC/aligned-baremetal run_binary BINARY=$GEMMINI_SOFTWARE_DIR/build/bareMetalC/aligned-baremetal
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} run-binary-fast BINARY=$GEMMINI_SOFTWARE_DIR/build/bareMetalC/raw_hazard-baremetal run_binary BINARY=$GEMMINI_SOFTWARE_DIR/build/bareMetalC/raw_hazard-baremetal
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} run-binary-fast BINARY=$GEMMINI_SOFTWARE_DIR/build/bareMetalC/mvin_mvout-baremetal run_binary BINARY=$GEMMINI_SOFTWARE_DIR/build/bareMetalC/mvin_mvout-baremetal
;; ;;
chipyard-sha3) chipyard-sha3)
(cd $LOCAL_CHIPYARD_DIR/generators/sha3/software && ./build.sh) (cd $LOCAL_CHIPYARD_DIR/generators/sha3/software && ./build.sh)
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} run-binary-fast BINARY=$LOCAL_CHIPYARD_DIR/generators/sha3/software/tests/bare/sha3-rocc.riscv run_binary BINARY=$LOCAL_CHIPYARD_DIR/generators/sha3/software/tests/bare/sha3-rocc.riscv
;; ;;
chipyard-mempress) chipyard-mempress)
(cd $LOCAL_CHIPYARD_DIR/generators/mempress/software/src && make) (cd $LOCAL_CHIPYARD_DIR/generators/mempress/software/src && make)
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} run-binary-fast BINARY=$LOCAL_CHIPYARD_DIR/generators/mempress/software/src/mempress-rocc.riscv run_binary BINARY=$LOCAL_CHIPYARD_DIR/generators/mempress/software/src/mempress-rocc.riscv
;; ;;
chipyard-manymmioaccels) chipyard-manymmioaccels)
make -C $LOCAL_CHIPYARD_DIR/tests make -C $LOCAL_CHIPYARD_DIR/tests
# test streaming-passthrough # test streaming-passthrough
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} run-binary-fast BINARY=$LOCAL_CHIPYARD_DIR/tests/streaming-passthrough.riscv run_binary BINARY=$LOCAL_CHIPYARD_DIR/tests/streaming-passthrough.riscv
# test streaming-fir # test streaming-fir
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} run-binary-fast BINARY=$LOCAL_CHIPYARD_DIR/tests/streaming-fir.riscv run_binary BINARY=$LOCAL_CHIPYARD_DIR/tests/streaming-fir.riscv
# test nvdla
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} BINARY=$LOCAL_CHIPYARD_DIR/tests/nvdla.riscv run-binary-fast
# test fft # test fft
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} BINARY=$LOCAL_CHIPYARD_DIR/tests/fft.riscv run-binary-fast run_binary BINARY=$LOCAL_CHIPYARD_DIR/tests/fft.riscv
;;
chipyard-nvdla)
make -C $LOCAL_CHIPYARD_DIR/tests
run_binary BINARY=$LOCAL_CHIPYARD_DIR/tests/nvdla.riscv
;; ;;
chipyard-manyperipherals) chipyard-manyperipherals)
# SPI Flash read tests, then bmark tests # SPI Flash read tests
make -C $LOCAL_CHIPYARD_DIR/tests make -C $LOCAL_CHIPYARD_DIR/tests
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} BINARY=$LOCAL_CHIPYARD_DIR/tests/spiflashread.riscv run-binary-fast run_binary BINARY=$LOCAL_CHIPYARD_DIR/tests/spiflashread.riscv
run_bmark ${mapping[$1]}
;; ;;
chipyard-spiflashwrite) chipyard-spiflashwrite)
make -C $LOCAL_CHIPYARD_DIR/tests make -C $LOCAL_CHIPYARD_DIR/tests
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} BINARY=$LOCAL_CHIPYARD_DIR/tests/spiflashwrite.riscv run-binary-fast run_binary BINARY=$LOCAL_CHIPYARD_DIR/tests/spiflashwrite.riscv
[[ "`xxd $LOCAL_CHIPYARD_DIR/tests/spiflash.img | grep 1337\ 00ff\ aa55\ face | wc -l`" == "6" ]] || false [[ "`xxd $LOCAL_CHIPYARD_DIR/tests/spiflash.img | grep 1337\ 00ff\ aa55\ face | wc -l`" == "6" ]] || false
;; ;;
chipyard-tethered)
make -C $LOCAL_CHIPYARD_DIR/tests
run_binary BINARY=$LOCAL_CHIPYARD_DIR/tests/hello.riscv LOADMEM=1 EXTRA_SIM_FLAGS="+cflush_addr=0x2010200"
;;
tracegen) tracegen)
run_tracegen ${mapping[$1]} run_tracegen
;; ;;
tracegen-boom) tracegen-boom)
run_tracegen ${mapping[$1]} run_tracegen
;; ;;
chipyard-cva6) chipyard-cva6)
make run-binary-fast -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} BINARY=$RISCV/riscv64-unknown-elf/share/riscv-tests/benchmarks/multiply.riscv run_binary BINARY=$RISCV/riscv64-unknown-elf/share/riscv-tests/benchmarks/multiply.riscv
;; ;;
chipyard-ibex) chipyard-ibex)
run_bmark ${mapping[$1]} #TODO: Find 32-bit test # Ibex cannot run the riscv-tests binaries for some reason
# run_binary BINARY=$RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv32ui-p-simple
;; ;;
chipyard-sodor) chipyard-sodor)
run_asm ${mapping[$1]} run_asm
;; ;;
chipyard-constellation) chipyard-constellation)
make run-binary-hex BINARY=$RISCV/riscv64-unknown-elf/share/riscv-tests/benchmarks/dhrystone.riscv -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} run_binary LOADMEM=1 BINARY=$RISCV/riscv64-unknown-elf/share/riscv-tests/benchmarks/dhrystone.riscv
;; ;;
icenet) icenet)
make run-binary-fast BINARY=none -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} run_binary BINARY=none
;; ;;
testchipip) testchipip)
make run-binary-fast BINARY=none -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} run_binary BINARY=none
;; ;;
constellation) constellation)
make run-binary-fast BINARY=none -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} run_binary BINARY=none
;;
rocketchip-amba)
run_binary BINARY=none
;;
rocketchip-tlsimple)
run_binary BINARY=none
;;
rocketchip-tlwidth)
run_binary BINARY=none
;;
rocketchip-tlxbar)
run_binary BINARY=none
;; ;;
*) *)
echo "No set of tests for $1. Did you spell it right?" echo "No set of tests for $1. Did you spell it right?"

View File

@@ -6,6 +6,9 @@ on:
branches: branches:
- main - main
- '1.[0-9]*.x' - '1.[0-9]*.x'
schedule:
# run at 00:00 on sunday
- cron: "0 0 * * 0"
defaults: defaults:
run: run:
@@ -62,7 +65,7 @@ jobs:
name: setup-repo name: setup-repo
needs: [change-filters, cancel-prior-workflows] needs: [change-filters, cancel-prior-workflows]
if: needs.change-filters.outputs.needs-rtl == 'true' if: needs.change-filters.outputs.needs-rtl == 'true'
runs-on: ferry runs-on: jktqos
steps: steps:
- name: Delete old checkout - name: Delete old checkout
run: | run: |
@@ -80,12 +83,12 @@ jobs:
eval "$(conda shell.bash hook)" eval "$(conda shell.bash hook)"
mkdir ${{ env.JAVA_TMP_DIR }} mkdir ${{ env.JAVA_TMP_DIR }}
export MAKEFLAGS="-j32" export MAKEFLAGS="-j32"
./build-setup.sh -f ./build-setup.sh -f -v
run-cfg-finder: run-cfg-finder:
name: run-cfg-finder name: run-cfg-finder
needs: [setup-repo] needs: [setup-repo]
runs-on: ferry runs-on: jktqos
steps: steps:
- name: Run config finder - name: Run config finder
run: | run: |
@@ -98,7 +101,7 @@ jobs:
run-tutorial: run-tutorial:
name: run-tutorial name: run-tutorial
needs: [setup-repo] needs: [setup-repo]
runs-on: ferry runs-on: jktqos
steps: steps:
- name: Run smoke test - name: Run smoke test
run: | run: |
@@ -165,9 +168,10 @@ jobs:
cleanup: cleanup:
name: cleanup name: cleanup
needs: [run-tutorial] needs: [run-tutorial]
runs-on: ferry runs-on: jktqos
if: ${{ always() && contains(join(needs.*.result, ','), 'success') }} if: ${{ always() }}
steps: steps:
- name: Delete repo copy and conda env - name: Delete repo copy and conda env
run: | run: |
rm -rf ${{ env.REMOTE_WORK_DIR }} rm -rf ${{ env.REMOTE_WORK_DIR }}
rm -rf ${{ env.JAVA_TMP_DIR }}

View File

@@ -166,7 +166,7 @@ jobs:
- name: Generate keys - name: Generate keys
id: genkey id: genkey
run: | run: |
echo "::set-output name=extra-tests-cache-key::extra-tests-${{ github.sha }}" echo "extra-tests-cache-key=extra-tests-${{ github.sha }}" >> $GITHUB_OUTPUT
- uses: actions/cache@v3 - uses: actions/cache@v3
id: build-extra-tools-cache id: build-extra-tools-cache
with: with:
@@ -178,11 +178,11 @@ jobs:
conda activate ${{ env.conda-env-name-no-time }}-$(date --date "${{ env.workflow-timestamp }}" +%Y%m%d)-riscv-tools conda activate ${{ env.conda-env-name-no-time }}-$(date --date "${{ env.workflow-timestamp }}" +%Y%m%d)-riscv-tools
.github/scripts/build-extra-tests.sh .github/scripts/build-extra-tests.sh
create-conda-env-knight: create-conda-env-jktgz:
name: create-conda-env-knight name: create-conda-env-jktgz
needs: [change-filters, cancel-prior-workflows] needs: [change-filters, cancel-prior-workflows]
if: needs.change-filters.outputs.needs-rtl == 'true' if: needs.change-filters.outputs.needs-rtl == 'true'
runs-on: knight runs-on: jktgz
steps: steps:
- name: Delete old checkout - name: Delete old checkout
run: | run: |
@@ -199,11 +199,11 @@ jobs:
- name: Create conda env - name: Create conda env
uses: ./.github/actions/create-conda-env uses: ./.github/actions/create-conda-env
create-conda-env-ferry: create-conda-env-jktqos:
name: create-conda-env-ferry name: create-conda-env-jktqos
needs: [change-filters, cancel-prior-workflows] needs: [change-filters, cancel-prior-workflows]
if: needs.change-filters.outputs.needs-rtl == 'true' if: needs.change-filters.outputs.needs-rtl == 'true'
runs-on: ferry runs-on: jktqos
steps: steps:
- name: Delete old checkout - name: Delete old checkout
run: | run: |
@@ -225,7 +225,7 @@ jobs:
# When adding new prep jobs, please add them to `needs` below # When adding new prep jobs, please add them to `needs` below
setup-complete: setup-complete:
name: setup-complete name: setup-complete
needs: [create-conda-env-knight, create-conda-env-ferry, build-extra-tests] needs: [create-conda-env-jktgz, create-conda-env-jktqos, build-extra-tests]
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Set up complete - name: Set up complete
@@ -393,7 +393,7 @@ jobs:
chipyard-spike-gemmini-run-tests: chipyard-spike-gemmini-run-tests:
name: chipyard-spike-gemmini-run-tests name: chipyard-spike-gemmini-run-tests
needs: prepare-chipyard-accels # technically doesn't depend on RTL but should be after the build.sh for Gemmini needs: prepare-chipyard-accels # technically doesn't depend on RTL but should be after the build.sh for Gemmini
runs-on: ferry runs-on: jktqos
steps: steps:
- name: Delete old checkout - name: Delete old checkout
run: | run: |
@@ -442,6 +442,29 @@ jobs:
group-key: "group-cores" group-key: "group-cores"
project-key: "chipyard-rocket" project-key: "chipyard-rocket"
chipyard-prefetchers-run-tests:
name: chipyard-prefetchers-run-tests
needs: prepare-chipyard-cores
runs-on: self-hosted
steps:
- name: Delete old checkout
run: |
ls -alh .
rm -rf ${{ github.workspace }}/* || true
rm -rf ${{ github.workspace }}/.* || true
ls -alh .
- name: Checkout
uses: actions/checkout@v3
- name: Git workaround
uses: ./.github/actions/git-workaround
- name: Create conda env
uses: ./.github/actions/create-conda-env
- name: Run tests
uses: ./.github/actions/run-tests
with:
group-key: "group-cores"
project-key: "chipyard-prefetchers"
chipyard-hetero-run-tests: chipyard-hetero-run-tests:
name: chipyard-hetero-run-tests name: chipyard-hetero-run-tests
needs: prepare-chipyard-cores needs: prepare-chipyard-cores
@@ -488,6 +511,29 @@ jobs:
group-key: "group-cores" group-key: "group-cores"
project-key: "chipyard-boom" project-key: "chipyard-boom"
chipyard-shuttle-run-tests:
name: chipyard-shuttle-run-tests
needs: prepare-chipyard-cores
runs-on: self-hosted
steps:
- name: Delete old checkout
run: |
ls -alh .
rm -rf ${{ github.workspace }}/* || true
rm -rf ${{ github.workspace }}/.* || true
ls -alh .
- name: Checkout
uses: actions/checkout@v3
- name: Git workaround
uses: ./.github/actions/git-workaround
- name: Create conda env
uses: ./.github/actions/create-conda-env
- name: Run tests
uses: ./.github/actions/run-tests
with:
group-key: "group-cores"
project-key: "chipyard-shuttle"
chipyard-cva6-run-tests: chipyard-cva6-run-tests:
name: chipyard-cva6-run-tests name: chipyard-cva6-run-tests
needs: prepare-chipyard-cores needs: prepare-chipyard-cores
@@ -603,6 +649,29 @@ jobs:
group-key: "group-peripherals" group-key: "group-peripherals"
project-key: "chipyard-dmirocket" project-key: "chipyard-dmirocket"
chipyard-dmiboom-run-tests:
name: chipyard-dmiboom-run-tests
needs: prepare-chipyard-peripherals
runs-on: self-hosted
steps:
- name: Delete old checkout
run: |
ls -alh .
rm -rf ${{ github.workspace }}/* || true
rm -rf ${{ github.workspace }}/.* || true
ls -alh .
- name: Checkout
uses: actions/checkout@v3
- name: Git workaround
uses: ./.github/actions/git-workaround
- name: Create conda env
uses: ./.github/actions/create-conda-env
- name: Run tests
uses: ./.github/actions/run-tests
with:
group-key: "group-peripherals"
project-key: "chipyard-dmiboom"
chipyard-spiflashwrite-run-tests: chipyard-spiflashwrite-run-tests:
name: chipyard-spiflashwrite-run-tests name: chipyard-spiflashwrite-run-tests
needs: prepare-chipyard-peripherals needs: prepare-chipyard-peripherals
@@ -649,6 +718,29 @@ jobs:
group-key: "group-peripherals" group-key: "group-peripherals"
project-key: "chipyard-manyperipherals" project-key: "chipyard-manyperipherals"
chipyard-tethered-run-tests:
name: chipyard-tethered-run-tests
needs: prepare-chipyard-peripherals
runs-on: self-hosted
steps:
- name: Delete old checkout
run: |
ls -alh .
rm -rf ${{ github.workspace }}/* || true
rm -rf ${{ github.workspace }}/.* || true
ls -alh .
- name: Checkout
uses: actions/checkout@v3
- name: Git workaround
uses: ./.github/actions/git-workaround
- name: Create conda env
uses: ./.github/actions/create-conda-env
- name: Run tests
uses: ./.github/actions/run-tests
with:
group-key: "group-peripherals"
project-key: "chipyard-tethered"
chipyard-sha3-run-tests: chipyard-sha3-run-tests:
name: chipyard-sha3-run-tests name: chipyard-sha3-run-tests
needs: prepare-chipyard-accels needs: prepare-chipyard-accels
@@ -718,6 +810,29 @@ jobs:
group-key: "group-accels" group-key: "group-accels"
project-key: "chipyard-manymmioaccels" project-key: "chipyard-manymmioaccels"
# chipyard-nvdla-run-tests:
# name: chipyard-nvdla-run-tests
# needs: prepare-chipyard-accels
# runs-on: self-hosted
# steps:
# - name: Delete old checkout
# run: |
# ls -alh .
# rm -rf ${{ github.workspace }}/* || true
# rm -rf ${{ github.workspace }}/.* || true
# ls -alh .
# - name: Checkout
# uses: actions/checkout@v3
# - name: Git workaround
# uses: ./.github/actions/git-workaround
# - name: Create conda env
# uses: ./.github/actions/create-conda-env
# - name: Run tests
# uses: ./.github/actions/run-tests
# with:
# group-key: "group-accels"
# project-key: "chipyard-nvdla"
chipyard-mempress-run-tests: chipyard-mempress-run-tests:
name: chipyard-mempress-run-tests name: chipyard-mempress-run-tests
needs: prepare-chipyard-accels needs: prepare-chipyard-accels
@@ -834,6 +949,45 @@ jobs:
group-key: "group-other" group-key: "group-other"
project-key: "testchipip" project-key: "testchipip"
rocketchip-run-tests:
name: rocketchip-run-tests
needs: prepare-chipyard-other
runs-on: self-hosted
steps:
- name: Delete old checkout
run: |
ls -alh .
rm -rf ${{ github.workspace }}/* || true
rm -rf ${{ github.workspace }}/.* || true
ls -alh .
- name: Checkout
uses: actions/checkout@v3
- name: Git workaround
uses: ./.github/actions/git-workaround
- name: Create conda env
uses: ./.github/actions/create-conda-env
- name: Run amba tests
uses: ./.github/actions/run-tests
with:
group-key: "group-other"
project-key: "rocketchip-amba"
# Below tests segfault with verilator, work fine in VCS
# - name: Run tlsimple tests
# uses: ./.github/actions/run-tests
# with:
# group-key: "group-other"
# project-key: "rocketchip-tlsimple"
# - name: Run tlwidth tests
# uses: ./.github/actions/run-tests
# with:
# group-key: "group-other"
# project-key: "rocketchip-tlwidth"
# - name: Run tlxbar tests
# uses: ./.github/actions/run-tests
# with:
# group-key: "group-other"
# project-key: "rocketchip-tlxbar"
constellation-run-tests: constellation-run-tests:
name: constellation-run-tests name: constellation-run-tests
needs: prepare-chipyard-other needs: prepare-chipyard-other
@@ -941,21 +1095,26 @@ jobs:
chipyard-rocket-run-tests, chipyard-rocket-run-tests,
chipyard-hetero-run-tests, chipyard-hetero-run-tests,
chipyard-boom-run-tests, chipyard-boom-run-tests,
chipyard-shuttle-run-tests,
chipyard-cva6-run-tests, chipyard-cva6-run-tests,
chipyard-ibex-run-tests, chipyard-ibex-run-tests,
chipyard-sodor-run-tests, chipyard-sodor-run-tests,
chipyard-dmiboom-run-tests,
chipyard-dmirocket-run-tests, chipyard-dmirocket-run-tests,
chipyard-spiflashwrite-run-tests, chipyard-spiflashwrite-run-tests,
chipyard-manyperipherals-run-tests, chipyard-manyperipherals-run-tests,
chipyard-tethered-run-tests,
chipyard-sha3-run-tests, chipyard-sha3-run-tests,
chipyard-gemmini-run-tests, chipyard-gemmini-run-tests,
chipyard-manymmioaccels-run-tests, chipyard-manymmioaccels-run-tests, # chipyard-nvdla-run-tests,
chipyard-prefetchers-run-tests,
chipyard-mempress-run-tests, chipyard-mempress-run-tests,
chipyard-constellation-run-tests, chipyard-constellation-run-tests,
tracegen-boom-run-tests, tracegen-boom-run-tests,
tracegen-run-tests, tracegen-run-tests,
icenet-run-tests, icenet-run-tests,
testchipip-run-tests, testchipip-run-tests,
rocketchip-run-tests,
constellation-run-tests, constellation-run-tests,
prepare-chipyard-fpga, # firesim-run-tests, prepare-chipyard-fpga, # firesim-run-tests,
fireboom-run-tests] fireboom-run-tests]

View File

@@ -0,0 +1,56 @@
{
"categories": [
{
"title": "## Added",
"labels": ["changelog:added"]
},
{
"title": "## Changed",
"labels": ["changelog:changed"]
},
{
"title": "## Fixed",
"labels": ["changelog:fixed"]
},
{
"title": "## Removed",
"labels": ["changelog:removed"]
},
{
"title": "## Uncategorized",
"labels": []
}
],
"ignore_labels": [
"changelog:omit"
],
"sort": {
"order": "ASC",
"on_property": "mergedAt"
},
"template": "${{CHANGELOG}}\n\n**Full Changelog:** ${{RELEASE_DIFF}}\n",
"pr_template": "- ${{TITLE}} (by @${{AUTHOR}} in ${{URL}})${{RELEASE_NOTES}}",
"empty_template": "- no changes",
"transformers": [
{
"pattern": "<!--.*-->",
"flags": "gus",
"target": ""
}
],
"custom_placeholders": [
{
"name": "RELEASE_NOTES",
"source": "BODY",
"transformer": {
"pattern": ".*#### Release Notes(?:[\n\\s]|(?:<!--.*?-->))*((?:\\S(?!!--)).*?)[\n\\s]*\n#.*",
"flags": "gus",
"target": "\n $1"
}
}
],
"trim_values": false,
"max_tags_to_fetch": 200,
"max_pull_requests": 500,
"max_back_track_time_days": 365
}

51
.github/workflows/release-notes.yml vendored Normal file
View File

@@ -0,0 +1,51 @@
# adapted from https://github.com/chipsalliance/chisel/blob/main/.github/workflows/release-notes.yml
name: Generate Release Notes
on:
release:
types: [created]
workflow_dispatch:
inputs:
toTag:
description: 'Tag or ref for which to generate release notes'
required: true
fromTag:
# If you leave this blank, it'll select previous SemVer version
# WARNING: Cannot use anything older than a005498 because of the git tree merge
description: 'Tag or ref from which to start generating release notes'
required: false
jobs:
generate_release_notes:
name: Generate Release Notes
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Build Release Notes
id: release-notes
uses: mikepenz/release-changelog-builder-action@v3.7.0
with:
configuration: .github/workflows/config/release-notes.json
failOnError: true
# Amazingly, on release where the inputs are empty, this just does the right thing
# The "toTag" is the released tag, and the "fromTag" is the previous tag according to SemVer
fromTag: ${{ github.event.inputs.fromTag }}
toTag: ${{ github.event.inputs.toTag }}
token: ${{ secrets.GITHUB_TOKEN }}
- name: Report Release Notes
# Put output through env variable to make it robust to quotes
env:
CHANGELOG: ${{steps.release-notes.outputs.changelog}}
run: echo "$CHANGELOG" >> $GITHUB_STEP_SUMMARY
- name: Upload Release Notes (on release)
if: github.event_name == 'release'
uses: softprops/action-gh-release@v0.1.15
with:
body: ${{ steps.release-notes.outputs.changelog }}
- name: Error on uncategorized PRs
if: steps.release-notes.outputs.uncategorized_prs != 0
run: exit 1

24
.github/workflows/require-label.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
# adapted from https://github.com/chipsalliance/chisel/blob/main/.github/workflows/require-label.yml
name: Require Release Notes Label
on:
pull_request:
branches:
- main
types:
- opened
- synchronize
- reopened
- labeled
- unlabeled
jobs:
check_labels:
name: Check Labels
runs-on: ubuntu-latest
steps:
- uses: docker://agilepathway/pull-request-label-checker:v1.4.25
with:
one_of: changelog:added,changelog:changed,changelog:fixed,changelog:omit,changelog:removed
repo_token: ${{ secrets.GITHUB_TOKEN }}

2
.gitignore vendored
View File

@@ -26,3 +26,5 @@ project/metals.sbt
project/project/ project/project/
.ivy2 .ivy2
.sbt .sbt
.classpath_cache/
.vscode/

9
.gitmodules vendored
View File

@@ -121,3 +121,12 @@
[submodule "tools/cde"] [submodule "tools/cde"]
path = tools/cde path = tools/cde
url = https://github.com/chipsalliance/cde.git url = https://github.com/chipsalliance/cde.git
[submodule "software/embench/embench-iot"]
path = software/embench/embench-iot
url = https://github.com/embench/embench-iot.git
[submodule "shuttle"]
path = generators/shuttle
url = https://github.com/ucb-bar/shuttle.git
[submodule "generators/bar-fetchers"]
path = generators/bar-fetchers
url = https://github.com/ucb-bar/bar-fetchers.git

View File

@@ -2,6 +2,117 @@
This changelog follows the format defined here: https://keepachangelog.com/en/1.0.0/ This changelog follows the format defined here: https://keepachangelog.com/en/1.0.0/
## [1.10.0] - 2023-6-16
Adds superscalar in-order core, prefetchers, architectural checkpointing, examples for custom-chiptop/tapeout-chip/flat-chiptop. FireSim bumped with new local FPGA support: Xilinx VCU118 (w/XDMA), Xilinx Alveo U250/U280 (w/XDMA, in addition to previous Vitis support), RHSResearch NiteFury II (w/XDMA). FireSim now also supports Xcelium for metasims.
### Added
* QoL improvement to IOBinders + custom ChipTop example by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1399
* New Scala-based Config Finder by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1424
* ADD: improve Makefile in tests/, add explicit arch flags by @T-K-233 in https://github.com/ucb-bar/chipyard/pull/1439
* Add mt-helloworld example by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1428
* Add tutorial software by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1447
* Support not instantiating the TileClockGater/ResetSetter PRCI control by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1459
* ELF-based-loadmem | architectural restartable checkpoints by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1438
* Add embench build support by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1479
* Support multi-run of binaries by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1480
* Integrate barf (prefetchers) by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1505
* Add higher level explanations of RoCC + more resources by @nikhiljha in https://github.com/ucb-bar/chipyard/pull/1486
* Support banked/partitioned scratchpads by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1431
* Add dual-issue in-order "shuttle" core by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1495
* Improve peripheral fragments to include more peripheral devices and support instantiating multiple instances of same device by @T-K-233 in https://github.com/ucb-bar/chipyard/pull/1511
### Changed
* Bump to latest rocket-chip/chisel3.5.6 by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1411
* Resolve merge conflicts in chisel3.5.6 bump by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1430
* PLL integration example + FlatChipTop/TestHarness by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1427
* bump testchipip by @joey0320 in https://github.com/ucb-bar/chipyard/pull/1434
* Fix ChipLikeQuadRocketConfig crossing by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1436
* Bump TestChipIp to improve default serial_tl behavior by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1435
* Bump testchipip to standardize TL serdesser bundle params by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1446
* Bump to Hammer 1.1.1 by @harrisonliew in https://github.com/ucb-bar/chipyard/pull/1451
* Always initialize fpga-shells with init-submodules.sh by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1456
* Support uni-directional TLSerdesser by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1476
* Move xcelium.mk out of top-level by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1482
* Set default config back to 1-channel by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1483
* Unify supernode/harness-clocking across chipyard/firesim/fpga by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1474
* Use fat jar's to remove SBT invocations by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1375
* Bump to latest rocket-chip by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1475
* Improvements to chipyard clocking by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1489
* Downgrade cryptography | Pin linux sysroot by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1494
* bump mempress by @joey0320 in https://github.com/ucb-bar/chipyard/pull/1498
* bump sha3 by @joey0320 in https://github.com/ucb-bar/chipyard/pull/1499
* Bump FireMarshal by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1502
* Split NVDLA config out of ManyMMIOAccels config to reduce CI load by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1503
* Ignore barstools compilation if not needed by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1504
* Disable NVDLA simulations in CI by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1507
* Update NoC example config to match new PRCI organization by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1509
* Bump gemmini by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1519
### Fixed
* Various improvements and fixes by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1420
* Ensure conda cleanup regex properly filters out non-numeric chars by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1425
* Clear screen on prompt by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1449
* misc: many fixes to cospike by @tianrui-wei in https://github.com/ucb-bar/chipyard/pull/1450
* Uniquify module names that are common to Top & Model by @joey0320 in https://github.com/ucb-bar/chipyard/pull/1442
* Use pk/encoding.h for hello/mt-hello by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1454
* Fix no-uart configs by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1457
* Fix support for no-bootROM systems by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1458
* Check that HarnessClockInstantiator doesn't receive requests for similarly-named-clocks with different frequencies by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1460
* uniquify module names by @joey0320 in https://github.com/ucb-bar/chipyard/pull/1452
* Flip serial_tl_clock to be generated off-chip by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1445
* Move TestHarness to chipyard.harness, make chipyard/harness directory by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1463
* Separate out conda-lock generation into new script by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1466
* Bump DRAMSim2 to avoid verbose log files by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1468
* Bump Verilator and use `TestDriver.v` as top by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1398
* Add 1GB / 4GB DRAM firechip configs for FireSim VCU118 by @sagark in https://github.com/ucb-bar/chipyard/pull/1471
* Rename SerialAdapter+SimSerial to TSIToTileLink/SimTSI/TSIHarness by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1465
* Make BootAddrReg optional by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1464
* Fix vcd/fst/fsdb waveform generation by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1473
* Switch RTL sims to absolute clock-generators by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1472
* Generate objdump | check BINARY | cospike fixes by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1467
* Small QOL fixes for Xcelium by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1485
* (VCU118 DDR HarnessBinder)Fix data field width mismatch between DDR AXI and TileLink MemoryBus by @jerryhethatday in https://github.com/ucb-bar/chipyard/pull/1487
* Force conda-lock to v1 by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1492
* Loosen/tighten conda requirements | Fix conda-lock req by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1497
* Misc Makefile Fixes by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1496
* Bump constellation to fix interconnect FIFO-fixers by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1510
* [ci skip] Fix broken docs link by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1515
* Revert changes to peripheral fragments by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1518
### New Contributors
* @tianrui-wei made their first contribution in https://github.com/ucb-bar/chipyard/pull/1450
* @jerryhethatday made their first contribution in https://github.com/ucb-bar/chipyard/pull/1487
* @nikhiljha made their first contribution in https://github.com/ucb-bar/chipyard/pull/1486
## [1.9.1] - 2023-04-21
Various fixes for Linux boot, More Chip/bringup examples, Chisel 3.5.6 bump
### Added
* QoL improvement to IOBinders + custom ChipTop example by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1399
* PLL integration example + FlatChipTop/TestHarness by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1427
* Bump TestChipIp to improve default serial_tl behavior by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1435
* Bump testchipip to standardize TL serdesser bundle params by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1446
* HarnessBinder asserts to catch bad clock generation by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1460
### Changed
* New Scala-based Config Finder by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1424
* Bump to latest rocket-chip/chisel3.5.6 by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1411
* Resolve merge conflicts in chisel3.5.6 bump by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1430
* bump testchipip by @joey0320 in https://github.com/ucb-bar/chipyard/pull/1434
* ADD: improve Makefile in tests/, add explicit arch flags by @T-K-233 in https://github.com/ucb-bar/chipyard/pull/1439
* Various submodule bumps by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1448
* Support not instantiating tile reset/clock contorl features by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1459
### Fixed
* Various improvements and fixes by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1420
* Ensure conda cleanup regex properly filters out non-numeric chars by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1425
* Fix ChipLikeQuadRocketConfig crossing by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1436
* Uniquify module names that are common to Top & Model by @joey0320 in https://github.com/ucb-bar/chipyard/pull/1442
* Support for no-bootROM systems by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1458
* Support for no-UART systems by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1457
## [1.9.0] - 2023-03-23 ## [1.9.0] - 2023-03-23
Faster FIRRTL build support work CIRCT. New software support for RISC-V GCC12 and Linux 6.2. Various bumps and fixes of all submodules. Faster FIRRTL build support work CIRCT. New software support for RISC-V GCC12 and Linux 6.2. Various bumps and fixes of all submodules.

View File

@@ -2,9 +2,6 @@
# Chipyard Framework [![Test](https://github.com/ucb-bar/chipyard/actions/workflows/chipyard-run-tests.yml/badge.svg)](https://github.com/ucb-bar/chipyard/actions) # Chipyard Framework [![Test](https://github.com/ucb-bar/chipyard/actions/workflows/chipyard-run-tests.yml/badge.svg)](https://github.com/ucb-bar/chipyard/actions)
| We're running the First FireSim and Chipyard User/Developer Workshop at ASPLOS 2023 on March 26, 2023! This workshop will feature a full-day of submitted talks from users and developers in the FireSim and Chipyard community. Learn more and **submit your work** on the [2023 Workshop Page](https://fires.im/workshop-2023/)! |
|-----|
## Quick Links ## Quick Links
* **Stable Documentation**: https://chipyard.readthedocs.io/ * **Stable Documentation**: https://chipyard.readthedocs.io/
@@ -26,9 +23,8 @@ Chipyard is actively developed in the [Berkeley Architecture Research Group][ucb
## Resources ## Resources
* Chipyard Stable Documentation: https://chipyard.readthedocs.io/ * Chipyard Stable Documentation: https://chipyard.readthedocs.io/
* Chipyard (x FireSim) Tutorial: https://fires.im/tutorial * Chipyard (x FireSim) Tutorial: https://fires.im/tutorial-recent/
* Chipyard Basics slides: https://fires.im/isca22-slides-pdf/02_chipyard_basics.pdf * Chipyard Basics slides: https://fires.im/asplos23-slides-pdf/02_chipyard_basics.pdf
* Chipyard Tutorial Exercise slides: https://fires.im/isca22-slides-pdf/03_building_custom_socs.pdf
## Need help? ## Need help?
@@ -77,6 +73,7 @@ These additional publications cover many of the internal components used in Chip
* **FASED**: D. Biancolin, et al., *FPGA'19*. [PDF](https://people.eecs.berkeley.edu/~biancolin/papers/fased-fpga19.pdf). * **FASED**: D. Biancolin, et al., *FPGA'19*. [PDF](https://people.eecs.berkeley.edu/~biancolin/papers/fased-fpga19.pdf).
* **Golden Gate**: A. Magyar, et al., *ICCAD'19*. [PDF](https://davidbiancolin.github.io/papers/goldengate-iccad19.pdf). * **Golden Gate**: A. Magyar, et al., *ICCAD'19*. [PDF](https://davidbiancolin.github.io/papers/goldengate-iccad19.pdf).
* **FirePerf**: S. Karandikar, et al., *ASPLOS'20*. [PDF](https://sagark.org/assets/pubs/fireperf-asplos2020.pdf). * **FirePerf**: S. Karandikar, et al., *ASPLOS'20*. [PDF](https://sagark.org/assets/pubs/fireperf-asplos2020.pdf).
* **FireSim ISCA@50 Retrospective**: S. Karandikar, et al., *ISCA@50 Retrospective: 1996-2020*. [PDF](https://sites.coecis.cornell.edu/isca50retrospective/files/2023/06/Karandikar_2018_FireSim.pdf)
* **Tools** * **Tools**
* **Chisel**: J. Bachrach, et al., *DAC'12*. [PDF](https://people.eecs.berkeley.edu/~krste/papers/chisel-dac2012.pdf). * **Chisel**: J. Bachrach, et al., *DAC'12*. [PDF](https://people.eecs.berkeley.edu/~krste/papers/chisel-dac2012.pdf).
* **FIRRTL**: A. Izraelevitz, et al., *ICCAD'17*. [PDF](https://ieeexplore.ieee.org/document/8203780). * **FIRRTL**: A. Izraelevitz, et al., *ICCAD'17*. [PDF](https://ieeexplore.ieee.org/document/8203780).

View File

@@ -4,14 +4,34 @@ import Tests._
// implicit one // implicit one
lazy val chipyardRoot = Project("chipyardRoot", file(".")) lazy val chipyardRoot = Project("chipyardRoot", file("."))
// keep chisel/firrtl specific class files, rename other conflicts
val chiselFirrtlMergeStrategy = CustomMergeStrategy.rename { dep =>
import sbtassembly.Assembly.{Project, Library}
val nm = dep match {
case p: Project => p.name
case l: Library => l.moduleCoord.name
}
if (Seq("firrtl", "chisel3").contains(nm.split("_")(0))) { // split by _ to avoid checking on major/minor version
dep.target
} else {
"renamed/" + dep.target
}
}
lazy val commonSettings = Seq( lazy val commonSettings = Seq(
organization := "edu.berkeley.cs", organization := "edu.berkeley.cs",
version := "1.6", version := "1.6",
scalaVersion := "2.13.10", scalaVersion := "2.13.10",
assembly / test := {}, assembly / test := {},
assembly / assemblyMergeStrategy := { _ match { assembly / assemblyMergeStrategy := {
case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard case PathList("chisel3", "stage", xs @ _*) => chiselFirrtlMergeStrategy
case _ => MergeStrategy.first}}, case PathList("firrtl", "stage", xs @ _*) => chiselFirrtlMergeStrategy
// should be safe in JDK11: https://stackoverflow.com/questions/54834125/sbt-assembly-deduplicate-module-info-class
case x if x.endsWith("module-info.class") => MergeStrategy.discard
case x =>
val oldStrategy = (assembly / assemblyMergeStrategy).value
oldStrategy(x)
},
scalacOptions ++= Seq( scalacOptions ++= Seq(
"-deprecation", "-deprecation",
"-unchecked", "-unchecked",
@@ -86,8 +106,6 @@ lazy val hardfloat = (project in rocketChipDir / "hardfloat")
.settings(commonSettings) .settings(commonSettings)
.settings( .settings(
libraryDependencies ++= Seq( libraryDependencies ++= Seq(
"org.scala-lang" % "scala-reflect" % scalaVersion.value,
"org.json4s" %% "json4s-jackson" % "3.6.6",
"org.scalatest" %% "scalatest" % "3.2.0" % "test" "org.scalatest" %% "scalatest" % "3.2.0" % "test"
) )
) )
@@ -97,8 +115,6 @@ lazy val rocketMacros = (project in rocketChipDir / "macros")
.settings( .settings(
libraryDependencies ++= Seq( libraryDependencies ++= Seq(
"org.scala-lang" % "scala-reflect" % scalaVersion.value, "org.scala-lang" % "scala-reflect" % scalaVersion.value,
"org.json4s" %% "json4s-jackson" % "3.6.6",
"org.scalatest" %% "scalatest" % "3.2.0" % "test"
) )
) )
@@ -110,7 +126,8 @@ lazy val rocketchip = freshProject("rocketchip", rocketChipDir)
libraryDependencies ++= Seq( libraryDependencies ++= Seq(
"org.scala-lang" % "scala-reflect" % scalaVersion.value, "org.scala-lang" % "scala-reflect" % scalaVersion.value,
"org.json4s" %% "json4s-jackson" % "3.6.6", "org.json4s" %% "json4s-jackson" % "3.6.6",
"org.scalatest" %% "scalatest" % "3.2.0" % "test" "org.scalatest" %% "scalatest" % "3.2.0" % "test",
"org.scala-graph" %% "graph-core" % "1.13.5"
) )
) )
.settings( // Settings for scalafix .settings( // Settings for scalafix
@@ -137,7 +154,7 @@ lazy val chipyard = (project in file("generators/chipyard"))
sha3, // On separate line to allow for cleaner tutorial-setup patches sha3, // On separate line to allow for cleaner tutorial-setup patches
dsptools, `rocket-dsp-utils`, dsptools, `rocket-dsp-utils`,
gemmini, icenet, tracegen, cva6, nvdla, sodor, ibex, fft_generator, gemmini, icenet, tracegen, cva6, nvdla, sodor, ibex, fft_generator,
constellation, mempress) constellation, mempress, barf, shuttle)
.settings(libraryDependencies ++= rocketLibDeps.value) .settings(libraryDependencies ++= rocketLibDeps.value)
.settings( .settings(
libraryDependencies ++= Seq( libraryDependencies ++= Seq(
@@ -152,6 +169,11 @@ lazy val mempress = (project in file("generators/mempress"))
.settings(chiselTestSettings) .settings(chiselTestSettings)
.settings(commonSettings) .settings(commonSettings)
lazy val barf = (project in file("generators/bar-fetchers"))
.dependsOn(rocketchip)
.settings(libraryDependencies ++= rocketLibDeps.value)
.settings(commonSettings)
lazy val constellation = (project in file("generators/constellation")) lazy val constellation = (project in file("generators/constellation"))
.dependsOn(rocketchip) .dependsOn(rocketchip)
.settings(libraryDependencies ++= rocketLibDeps.value) .settings(libraryDependencies ++= rocketLibDeps.value)
@@ -182,6 +204,11 @@ lazy val boom = (project in file("generators/boom"))
.settings(libraryDependencies ++= rocketLibDeps.value) .settings(libraryDependencies ++= rocketLibDeps.value)
.settings(commonSettings) .settings(commonSettings)
lazy val shuttle = (project in file("generators/shuttle"))
.dependsOn(rocketchip)
.settings(libraryDependencies ++= rocketLibDeps.value)
.settings(commonSettings)
lazy val cva6 = (project in file("generators/cva6")) lazy val cva6 = (project in file("generators/cva6"))
.dependsOn(rocketchip) .dependsOn(rocketchip)
.settings(libraryDependencies ++= rocketLibDeps.value) .settings(libraryDependencies ++= rocketLibDeps.value)
@@ -214,18 +241,13 @@ lazy val nvdla = (project in file("generators/nvdla"))
.settings(libraryDependencies ++= rocketLibDeps.value) .settings(libraryDependencies ++= rocketLibDeps.value)
.settings(commonSettings) .settings(commonSettings)
lazy val iocell = Project(id = "iocell", base = file("./tools/barstools/") / "src") lazy val iocell = Project(id = "iocell", base = file("./tools/barstools/") / "iocell")
.settings(
Compile / scalaSource := baseDirectory.value / "main" / "scala" / "barstools" / "iocell",
Compile / resourceDirectory := baseDirectory.value / "main" / "resources"
)
.settings(chiselSettings) .settings(chiselSettings)
.settings(commonSettings) .settings(commonSettings)
lazy val tapeout = (project in file("./tools/barstools/")) lazy val tapeout = (project in file("./tools/barstools/"))
.settings(chiselSettings) .settings(chiselSettings)
.settings(chiselTestSettings) .settings(chiselTestSettings)
.enablePlugins(sbtassembly.AssemblyPlugin)
.settings(commonSettings) .settings(commonSettings)
lazy val dsptools = freshProject("dsptools", file("./tools/dsptools")) lazy val dsptools = freshProject("dsptools", file("./tools/dsptools"))

231
common.mk
View File

@@ -16,11 +16,12 @@ HELP_COMPILATION_VARIABLES += \
" EXTRA_SIM_LDFLAGS = additional LDFLAGS for building simulators" \ " EXTRA_SIM_LDFLAGS = additional LDFLAGS for building simulators" \
" EXTRA_SIM_SOURCES = additional simulation sources needed for simulator" \ " EXTRA_SIM_SOURCES = additional simulation sources needed for simulator" \
" EXTRA_SIM_REQS = additional make requirements to build the simulator" \ " EXTRA_SIM_REQS = additional make requirements to build the simulator" \
" ENABLE_SBT_THIN_CLIENT = if set, use sbt's experimental thin client (works best when overridding SBT_BIN with the mainline sbt script)" \
" ENABLE_CUSTOM_FIRRTL_PASS = if set, enable custom firrtl passes (SFC lowers to LowFIRRTL & MFC converts to Verilog)" \ " ENABLE_CUSTOM_FIRRTL_PASS = if set, enable custom firrtl passes (SFC lowers to LowFIRRTL & MFC converts to Verilog)" \
" ENABLE_YOSYS_FLOW = if set, add compilation flags to enable the vlsi flow for yosys(tutorial flow)" \ " ENABLE_YOSYS_FLOW = if set, add compilation flags to enable the vlsi flow for yosys(tutorial flow)" \
" EXTRA_CHISEL_OPTIONS = additional options to pass to the Chisel compiler" \ " EXTRA_CHISEL_OPTIONS = additional options to pass to the Chisel compiler" \
" EXTRA_FIRRTL_OPTIONS = additional options to pass to the FIRRTL compiler" " EXTRA_BASE_FIRRTL_OPTIONS = additional options to pass to the Scala FIRRTL compiler" \
" MFC_BASE_LOWERING_OPTIONS = override lowering options to pass to the MLIR FIRRTL compiler" \
" ASPECTS = comma separated list of Chisel aspect flows to run (e.x. chipyard.upf.ChipTopUPFAspect)"
EXTRA_GENERATOR_REQS ?= $(BOOTROM_TARGETS) EXTRA_GENERATOR_REQS ?= $(BOOTROM_TARGETS)
EXTRA_SIM_CXXFLAGS ?= EXTRA_SIM_CXXFLAGS ?=
@@ -29,6 +30,11 @@ EXTRA_SIM_SOURCES ?=
EXTRA_SIM_REQS ?= EXTRA_SIM_REQS ?=
ENABLE_CUSTOM_FIRRTL_PASS += $(ENABLE_YOSYS_FLOW) ENABLE_CUSTOM_FIRRTL_PASS += $(ENABLE_YOSYS_FLOW)
ifneq ($(ASPECTS), )
comma = ,
ASPECT_ARGS = $(foreach aspect, $(subst $(comma), , $(ASPECTS)), --with-aspect $(aspect))
endif
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
HELP_SIMULATION_VARIABLES += \ HELP_SIMULATION_VARIABLES += \
" EXTRA_SIM_FLAGS = additional runtime simulation flags (passed within +permissive)" \ " EXTRA_SIM_FLAGS = additional runtime simulation flags (passed within +permissive)" \
@@ -45,11 +51,13 @@ HELP_COMMANDS += \
" run-binary = run [./$(shell basename $(sim))] and log instructions to file" \ " 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-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" \ " run-binary-debug = run [./$(shell basename $(sim_debug))] and log instructions and waveform to files" \
" run-binaries = run [./$(shell basename $(sim))] and log instructions to file" \
" run-binaries-fast = run [./$(shell basename $(sim))] and don't log instructions" \
" run-binaries-debug = run [./$(shell basename $(sim_debug))] and log instructions and waveform to files" \
" verilog = generate intermediate verilog files from chisel elaboration and firrtl passes" \ " verilog = generate intermediate verilog files from chisel elaboration and firrtl passes" \
" firrtl = generate intermediate firrtl files from chisel elaboration" \ " firrtl = generate intermediate firrtl files from chisel elaboration" \
" run-tests = run all assembly and benchmark tests" \ " run-tests = run all assembly and benchmark tests" \
" launch-sbt = start sbt terminal" \ " launch-sbt = start sbt terminal" \
" {shutdown,start}-sbt-server = shutdown or start sbt server if using ENABLE_SBT_THIN_CLIENT" \
" find-config-fragments = list all config. fragments" " find-config-fragments = list all config. fragments"
######################################################################################### #########################################################################################
@@ -66,7 +74,7 @@ include $(base_dir)/tools/torture.mk
######################################################################################### #########################################################################################
# Prerequisite lists # Prerequisite lists
######################################################################################### #########################################################################################
# Returns a list of files in directory $1 with file extension $2. # Returns a list of files in directories $1 with single file extension $2.
# If available, use 'fd' to find the list of files, which is faster than 'find'. # If available, use 'fd' to find the list of files, which is faster than 'find'.
ifeq ($(shell which fd 2> /dev/null),) ifeq ($(shell which fd 2> /dev/null),)
lookup_srcs = $(shell find -L $(1)/ -name target -prune -o \( -iname "*.$(2)" ! -iname ".*" \) -print 2> /dev/null) lookup_srcs = $(shell find -L $(1)/ -name target -prune -o \( -iname "*.$(2)" ! -iname ".*" \) -print 2> /dev/null)
@@ -74,9 +82,17 @@ else
lookup_srcs = $(shell fd -L -t f -e $(2) . $(1)) lookup_srcs = $(shell fd -L -t f -e $(2) . $(1))
endif endif
SOURCE_DIRS = $(addprefix $(base_dir)/,generators sims/firesim/sim tools/barstools fpga/fpga-shells fpga/src) # Returns a list of files in directories $1 with *any* of the file extensions in $2
SCALA_SOURCES = $(call lookup_srcs,$(SOURCE_DIRS),scala) lookup_srcs_by_multiple_type = $(foreach type,$(2),$(call lookup_srcs,$(1),$(type)))
VLOG_SOURCES = $(call lookup_srcs,$(SOURCE_DIRS),sv) $(call lookup_srcs,$(SOURCE_DIRS),v)
SCALA_EXT = scala
VLOG_EXT = sv v
CHIPYARD_SOURCE_DIRS = $(addprefix $(base_dir)/,generators sims/firesim/sim fpga/fpga-shells fpga/src)
CHIPYARD_SCALA_SOURCES = $(call lookup_srcs_by_multiple_type,$(CHIPYARD_SOURCE_DIRS),$(SCALA_EXT))
CHIPYARD_VLOG_SOURCES = $(call lookup_srcs_by_multiple_type,$(CHIPYARD_SOURCE_DIRS),$(VLOG_EXT))
BARSTOOLS_SOURCE_DIRS = $(addprefix $(base_dir)/,tools/barstools)
BARSTOOLS_SCALA_SOURCES = $(call lookup_srcs_by_multiple_type,$(BARSTOOLS_SOURCE_DIRS),$(SCALA_EXT))
BARSTOOLS_VLOG_SOURCES = $(call lookup_srcs_by_multiple_type,$(BARSTOOLS_SOURCE_DIRS),$(VLOG_EXT))
# This assumes no SBT meta-build sources # This assumes no SBT meta-build sources
SBT_SOURCE_DIRS = $(addprefix $(base_dir)/,generators sims/firesim/sim tools) 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 $(base_dir)/project/build.properties SBT_SOURCES = $(call lookup_srcs,$(SBT_SOURCE_DIRS),sbt) $(base_dir)/build.sbt $(base_dir)/project/plugins.sbt $(base_dir)/project/build.properties
@@ -102,16 +118,29 @@ $(BOOTROM_TARGETS): $(build_dir)/bootrom.%.img: $(TESTCHIP_RSRCS_DIR)/testchipip
cp -f $< $@ cp -f $< $@
######################################################################################### #########################################################################################
# create firrtl file rule and variables # compile scala jars
#########################################################################################
$(CHIPYARD_CLASSPATH_TARGETS) &: $(CHIPYARD_SCALA_SOURCES) $(SCALA_BUILDTOOL_DEPS)
mkdir -p $(dir $@)
$(call run_sbt_assembly,$(SBT_PROJECT),$(CHIPYARD_CLASSPATH))
# order only dependency between sbt runs needed to avoid concurrent sbt runs
$(TAPEOUT_CLASSPATH_TARGETS) &: $(BARSTOOLS_SCALA_SOURCES) $(SCALA_BUILDTOOL_DEPS) | $(CHIPYARD_CLASSPATH_TARGETS)
mkdir -p $(dir $@)
$(call run_sbt_assembly,tapeout,$(TAPEOUT_CLASSPATH))
#########################################################################################
# verilog generation pipeline
######################################################################################### #########################################################################################
# AG: must re-elaborate if cva6 sources have changed... otherwise just run firrtl compile # AG: must re-elaborate if cva6 sources have changed... otherwise just run firrtl compile
$(FIRRTL_FILE) $(ANNO_FILE) $(CHISEL_LOG_FILE) &: $(SCALA_SOURCES) $(SCALA_BUILDTOOL_DEPS) $(EXTRA_GENERATOR_REQS) $(FIRRTL_FILE) $(ANNO_FILE) $(CHISEL_LOG_FILE) &: $(CHIPYARD_CLASSPATH_TARGETS) $(EXTRA_GENERATOR_REQS)
mkdir -p $(build_dir) mkdir -p $(build_dir)
(set -o pipefail && $(call run_scala_main,$(SBT_PROJECT),$(GENERATOR_PACKAGE).Generator,\ (set -o pipefail && $(call run_jar_scala_main,$(CHIPYARD_CLASSPATH),$(GENERATOR_PACKAGE).Generator,\
--target-dir $(build_dir) \ --target-dir $(build_dir) \
--name $(long_name) \ --name $(long_name) \
--top-module $(MODEL_PACKAGE).$(MODEL) \ --top-module $(MODEL_PACKAGE).$(MODEL) \
--legacy-configs $(CONFIG_PACKAGE):$(CONFIG) \ --legacy-configs $(CONFIG_PACKAGE):$(CONFIG) \
$(ASPECT_ARGS) \
$(EXTRA_CHISEL_OPTIONS)) | tee $(CHISEL_LOG_FILE)) $(EXTRA_CHISEL_OPTIONS)) | tee $(CHISEL_LOG_FILE))
define mfc_extra_anno_contents define mfc_extra_anno_contents
@@ -162,7 +191,7 @@ SFC_MFC_TARGETS = \
$(GEN_COLLATERAL_DIR) $(GEN_COLLATERAL_DIR)
SFC_REPL_SEQ_MEM = --infer-rw --repl-seq-mem -c:$(MODEL):-o:$(SFC_SMEMS_CONF) SFC_REPL_SEQ_MEM = --infer-rw --repl-seq-mem -c:$(MODEL):-o:$(SFC_SMEMS_CONF)
MFC_BASE_LOWERING_OPTIONS = emittedLineLength=2048,noAlwaysComb,disallowLocalVariables,verifLabels,locationInfoStyle=wrapInAtSquareBracket MFC_BASE_LOWERING_OPTIONS ?= emittedLineLength=2048,noAlwaysComb,disallowLocalVariables,verifLabels,locationInfoStyle=wrapInAtSquareBracket
# DOC include start: FirrtlCompiler # DOC include start: FirrtlCompiler
# There are two possible cases for this step. In the first case, SFC # There are two possible cases for this step. In the first case, SFC
@@ -175,26 +204,33 @@ MFC_BASE_LOWERING_OPTIONS = emittedLineLength=2048,noAlwaysComb,disallowLocalVar
# hack: lower to low firrtl if Fixed types are found # hack: lower to low firrtl if Fixed types are found
# hack: when using dontTouch, io.cpu annotations are not removed by SFC, # hack: when using dontTouch, io.cpu annotations are not removed by SFC,
# hence we remove them manually by using jq before passing them to firtool # hence we remove them manually by using jq before passing them to firtool
$(SFC_LEVEL) $(EXTRA_FIRRTL_OPTIONS) $(FINAL_ANNO_FILE) $(MFC_LOWERING_OPTIONS) &: $(FIRRTL_FILE) $(EXTRA_ANNO_FILE) $(SFC_EXTRA_ANNO_FILE) $(VLOG_SOURCES)
$(SFC_LEVEL) $(EXTRA_FIRRTL_OPTIONS) &: $(FIRRTL_FILE)
ifeq (,$(ENABLE_CUSTOM_FIRRTL_PASS)) ifeq (,$(ENABLE_CUSTOM_FIRRTL_PASS))
$(eval SFC_LEVEL := $(if $(shell grep "Fixed<" $(FIRRTL_FILE)), low, none)) echo $(if $(shell grep "Fixed<" $(FIRRTL_FILE)), low, none) > $(SFC_LEVEL)
$(eval EXTRA_FIRRTL_OPTIONS += $(if $(shell grep "Fixed<" $(FIRRTL_FILE)), $(SFC_REPL_SEQ_MEM),)) echo "$(EXTRA_BASE_FIRRTL_OPTIONS)" $(if $(shell grep "Fixed<" $(FIRRTL_FILE)), "$(SFC_REPL_SEQ_MEM)",) > $(EXTRA_FIRRTL_OPTIONS)
else else
$(eval SFC_LEVEL := low) echo low > $(SFC_LEVEL)
$(eval EXTRA_FIRRTL_OPTIONS += $(SFC_REPL_SEQ_MEM)) echo "$(EXTRA_BASE_FIRRTL_OPTIONS)" "$(SFC_REPL_SEQ_MEM)" > $(EXTRA_FIRRTL_OPTIONS)
endif endif
$(MFC_LOWERING_OPTIONS):
mkdir -p $(dir $@)
ifeq (,$(ENABLE_YOSYS_FLOW)) ifeq (,$(ENABLE_YOSYS_FLOW))
$(eval MFC_LOWERING_OPTIONS = $(MFC_BASE_LOWERING_OPTIONS)) echo "$(MFC_BASE_LOWERING_OPTIONS)" > $@
else else
$(eval MFC_LOWERING_OPTIONS = $(MFC_BASE_LOWERING_OPTIONS),disallowPackedArrays) echo "$(MFC_BASE_LOWERING_OPTIONS),disallowPackedArrays" > $@
endif endif
if [ $(SFC_LEVEL) = low ]; then jq -s '[.[][]]' $(EXTRA_ANNO_FILE) $(SFC_EXTRA_ANNO_FILE) > $(FINAL_ANNO_FILE); fi
if [ $(SFC_LEVEL) = none ]; then cat $(EXTRA_ANNO_FILE) > $(FINAL_ANNO_FILE); fi $(FINAL_ANNO_FILE): $(EXTRA_ANNO_FILE) $(SFC_EXTRA_ANNO_FILE) $(SFC_LEVEL)
if [ $(shell cat $(SFC_LEVEL)) = low ]; then jq -s '[.[][]]' $(EXTRA_ANNO_FILE) $(SFC_EXTRA_ANNO_FILE) > $@; fi
if [ $(shell cat $(SFC_LEVEL)) = none ]; then cat $(EXTRA_ANNO_FILE) > $@; fi
touch $@
$(SFC_MFC_TARGETS) &: private TMP_DIR := $(shell mktemp -d -t cy-XXXXXXXX) $(SFC_MFC_TARGETS) &: private TMP_DIR := $(shell mktemp -d -t cy-XXXXXXXX)
$(SFC_MFC_TARGETS) &: $(FIRRTL_FILE) $(FINAL_ANNO_FILE) $(SFC_LEVEL) $(EXTRA_FIRRTL_OPTIONS) $(SFC_MFC_TARGETS) &: $(TAPEOUT_CLASSPATH_TARGETS) $(FIRRTL_FILE) $(FINAL_ANNO_FILE) $(SFC_LEVEL) $(EXTRA_FIRRTL_OPTIONS) $(MFC_LOWERING_OPTIONS) $(CHIPYARD_VLOG_SOURCES) $(BARSTOOLS_VLOG_SOURCES)
rm -rf $(GEN_COLLATERAL_DIR) rm -rf $(GEN_COLLATERAL_DIR)
$(call run_scala_main,tapeout,barstools.tapeout.transforms.GenerateModelStageMain,\ $(call run_jar_scala_main,$(TAPEOUT_CLASSPATH),barstools.tapeout.transforms.GenerateModelStageMain,\
--no-dedup \ --no-dedup \
--output-file $(SFC_FIRRTL_BASENAME) \ --output-file $(SFC_FIRRTL_BASENAME) \
--output-annotation-file $(SFC_ANNO_FILE) \ --output-annotation-file $(SFC_ANNO_FILE) \
@@ -203,12 +239,12 @@ $(SFC_MFC_TARGETS) &: $(FIRRTL_FILE) $(FINAL_ANNO_FILE) $(SFC_LEVEL) $(EXTRA_FIR
--annotation-file $(FINAL_ANNO_FILE) \ --annotation-file $(FINAL_ANNO_FILE) \
--log-level $(FIRRTL_LOGLEVEL) \ --log-level $(FIRRTL_LOGLEVEL) \
--allow-unrecognized-annotations \ --allow-unrecognized-annotations \
-X $(SFC_LEVEL) \ -X $(shell cat $(SFC_LEVEL)) \
$(EXTRA_FIRRTL_OPTIONS)) $(shell cat $(EXTRA_FIRRTL_OPTIONS)))
-mv $(SFC_FIRRTL_BASENAME).lo.fir $(SFC_FIRRTL_FILE) 2> /dev/null # Optionally change file type when SFC generates LowFIRRTL -mv $(SFC_FIRRTL_BASENAME).lo.fir $(SFC_FIRRTL_FILE) 2> /dev/null # Optionally change file type when SFC generates LowFIRRTL
@if [ $(SFC_LEVEL) = low ]; then cat $(SFC_ANNO_FILE) | jq 'del(.[] | select(.target | test("io.cpu"))?)' > $(TMP_DIR)/unnec-anno-deleted.sfc.anno.json; fi @if [ $(shell cat $(SFC_LEVEL)) = low ]; then cat $(SFC_ANNO_FILE) | jq 'del(.[] | select(.target | test("io.cpu"))?)' > $(TMP_DIR)/unnec-anno-deleted.sfc.anno.json; fi
@if [ $(SFC_LEVEL) = low ]; then cat $(TMP_DIR)/unnec-anno-deleted.sfc.anno.json | jq 'del(.[] | select(.class | test("SRAMAnnotation"))?)' > $(TMP_DIR)/unnec-anno-deleted2.sfc.anno.json; fi @if [ $(shell cat $(SFC_LEVEL)) = low ]; then cat $(TMP_DIR)/unnec-anno-deleted.sfc.anno.json | jq 'del(.[] | select(.class | test("SRAMAnnotation"))?)' > $(TMP_DIR)/unnec-anno-deleted2.sfc.anno.json; fi
@if [ $(SFC_LEVEL) = low ]; then cat $(TMP_DIR)/unnec-anno-deleted2.sfc.anno.json > $(SFC_ANNO_FILE) && rm $(TMP_DIR)/unnec-anno-deleted.sfc.anno.json && rm $(TMP_DIR)/unnec-anno-deleted2.sfc.anno.json; fi @if [ $(shell cat $(SFC_LEVEL)) = low ]; then cat $(TMP_DIR)/unnec-anno-deleted2.sfc.anno.json > $(SFC_ANNO_FILE) && rm $(TMP_DIR)/unnec-anno-deleted.sfc.anno.json && rm $(TMP_DIR)/unnec-anno-deleted2.sfc.anno.json; fi
firtool \ firtool \
--format=fir \ --format=fir \
--dedup \ --dedup \
@@ -219,7 +255,7 @@ $(SFC_MFC_TARGETS) &: $(FIRRTL_FILE) $(FINAL_ANNO_FILE) $(SFC_LEVEL) $(EXTRA_FIR
--disable-annotation-classless \ --disable-annotation-classless \
--disable-annotation-unknown \ --disable-annotation-unknown \
--mlir-timing \ --mlir-timing \
--lowering-options=$(MFC_LOWERING_OPTIONS) \ --lowering-options=$(shell cat $(MFC_LOWERING_OPTIONS)) \
--repl-seq-mem \ --repl-seq-mem \
--repl-seq-mem-file=$(MFC_SMEMS_CONF) \ --repl-seq-mem-file=$(MFC_SMEMS_CONF) \
--repl-seq-mem-circuit=$(MODEL) \ --repl-seq-mem-circuit=$(MODEL) \
@@ -231,36 +267,24 @@ $(SFC_MFC_TARGETS) &: $(FIRRTL_FILE) $(FINAL_ANNO_FILE) $(SFC_LEVEL) $(EXTRA_FIR
$(SED) -i 's/.*/& /' $(MFC_SMEMS_CONF) # need trailing space for SFC macrocompiler $(SED) -i 's/.*/& /' $(MFC_SMEMS_CONF) # need trailing space for SFC macrocompiler
# DOC include end: FirrtlCompiler # DOC include end: FirrtlCompiler
$(TOP_MODS_FILELIST) $(MODEL_MODS_FILELIST) $(ALL_MODS_FILELIST) $(BB_MODS_FILELIST) $(MFC_MODEL_HRCHY_JSON_UNIQUIFIED) &: $(MFC_MODEL_HRCHY_JSON) $(MFC_FILELIST) $(MFC_BB_MODS_FILELIST) $(TOP_MODS_FILELIST) $(MODEL_MODS_FILELIST) $(ALL_MODS_FILELIST) $(BB_MODS_FILELIST) $(MFC_MODEL_HRCHY_JSON_UNIQUIFIED) &: $(MFC_MODEL_HRCHY_JSON) $(MFC_TOP_HRCHY_JSON) $(MFC_FILELIST) $(MFC_BB_MODS_FILELIST)
$(base_dir)/scripts/split-module-files.py \ $(base_dir)/scripts/uniquify-module-names.py \
--model-hier-json $(MFC_MODEL_HRCHY_JSON) \ --model-hier-json $(MFC_MODEL_HRCHY_JSON) \
--top-hier-json $(MFC_TOP_HRCHY_JSON) \
--in-all-filelist $(MFC_FILELIST) \
--dut $(TOP) \ --dut $(TOP) \
--model $(MODEL) \
--target-dir $(GEN_COLLATERAL_DIR) \
--out-dut-filelist $(TOP_MODS_FILELIST) \ --out-dut-filelist $(TOP_MODS_FILELIST) \
--out-model-filelist $(MODEL_MODS_FILELIST) \ --out-model-filelist $(MODEL_MODS_FILELIST) \
--in-all-filelist $(MFC_FILELIST) \ --out-model-hier-json $(MFC_MODEL_HRCHY_JSON_UNIQUIFIED) \
--target-dir $(GEN_COLLATERAL_DIR) --gcpath $(GEN_COLLATERAL_DIR)
$(SED) -e 's;^;$(GEN_COLLATERAL_DIR)/;' $(MFC_BB_MODS_FILELIST) > $(BB_MODS_FILELIST) $(SED) -e 's;^;$(GEN_COLLATERAL_DIR)/;' $(MFC_BB_MODS_FILELIST) > $(BB_MODS_FILELIST)
$(SED) -i 's/\.\///' $(TOP_MODS_FILELIST) $(SED) -i 's/\.\///' $(TOP_MODS_FILELIST)
$(SED) -i 's/\.\///' $(MODEL_MODS_FILELIST) $(SED) -i 's/\.\///' $(MODEL_MODS_FILELIST)
$(SED) -i 's/\.\///' $(BB_MODS_FILELIST) $(SED) -i 's/\.\///' $(BB_MODS_FILELIST)
$(base_dir)/scripts/uniqify-module-names.py \
--top-filelist $(TOP_MODS_FILELIST) \
--mod-filelist $(MODEL_MODS_FILELIST) \
--gen-collateral-path $(GEN_COLLATERAL_DIR) \
--model-hier-json $(MFC_MODEL_HRCHY_JSON) \
--out-model-hier-json $(MFC_MODEL_HRCHY_JSON_UNIQUIFIED) \
--dut $(TOP) \
--model $(MODEL)
sort -u $(TOP_MODS_FILELIST) $(MODEL_MODS_FILELIST) $(BB_MODS_FILELIST) > $(ALL_MODS_FILELIST) sort -u $(TOP_MODS_FILELIST) $(MODEL_MODS_FILELIST) $(BB_MODS_FILELIST) > $(ALL_MODS_FILELIST)
$(TOP_BB_MODS_FILELIST) $(MODEL_BB_MODS_FILELIST) &: $(BB_MODS_FILELIST) $(MFC_TOP_HRCHY_JSON) $(FINAL_ANNO_FILE)
$(base_dir)/scripts/split-bb-files.py \
--in-bb-f $(BB_MODS_FILELIST) \
--in-top-hrchy-json $(MFC_TOP_HRCHY_JSON) \
--in-anno-json $(FINAL_ANNO_FILE) \
--out-top-bb-f $(TOP_BB_MODS_FILELIST) \
--out-model-bb-f $(MODEL_BB_MODS_FILELIST)
$(TOP_SMEMS_CONF) $(MODEL_SMEMS_CONF) &: $(MFC_SMEMS_CONF) $(MFC_MODEL_HRCHY_JSON_UNIQUIFIED) $(TOP_SMEMS_CONF) $(MODEL_SMEMS_CONF) &: $(MFC_SMEMS_CONF) $(MFC_MODEL_HRCHY_JSON_UNIQUIFIED)
$(base_dir)/scripts/split-mems-conf.py \ $(base_dir)/scripts/split-mems-conf.py \
--in-smems-conf $(MFC_SMEMS_CONF) \ --in-smems-conf $(MFC_SMEMS_CONF) \
@@ -272,19 +296,19 @@ $(TOP_SMEMS_CONF) $(MODEL_SMEMS_CONF) &: $(MFC_SMEMS_CONF) $(MFC_MODEL_HRCHY_JS
# This file is for simulation only. VLSI flows should replace this file with one containing hard SRAMs # This file is for simulation only. VLSI flows should replace this file with one containing hard SRAMs
TOP_MACROCOMPILER_MODE ?= --mode synflops TOP_MACROCOMPILER_MODE ?= --mode synflops
$(TOP_SMEMS_FILE) $(TOP_SMEMS_FIR) &: $(TOP_SMEMS_CONF) $(TOP_SMEMS_FILE) $(TOP_SMEMS_FIR) &: $(TAPEOUT_CLASSPATH_TARGETS) $(TOP_SMEMS_CONF)
$(call run_scala_main,tapeout,barstools.macros.MacroCompiler,-n $(TOP_SMEMS_CONF) -v $(TOP_SMEMS_FILE) -f $(TOP_SMEMS_FIR) $(TOP_MACROCOMPILER_MODE)) $(call run_jar_scala_main,$(TAPEOUT_CLASSPATH),barstools.macros.MacroCompiler,-n $(TOP_SMEMS_CONF) -v $(TOP_SMEMS_FILE) -f $(TOP_SMEMS_FIR) $(TOP_MACROCOMPILER_MODE))
MODEL_MACROCOMPILER_MODE = --mode synflops MODEL_MACROCOMPILER_MODE = --mode synflops
$(MODEL_SMEMS_FILE) $(MODEL_SMEMS_FIR) &: $(MODEL_SMEMS_CONF) | $(TOP_SMEMS_FILE) $(MODEL_SMEMS_FILE) $(MODEL_SMEMS_FIR) &: $(TAPEOUT_CLASSPATH_TARGETS) $(MODEL_SMEMS_CONF) | $(TOP_SMEMS_FILE)
$(call run_scala_main,tapeout,barstools.macros.MacroCompiler, -n $(MODEL_SMEMS_CONF) -v $(MODEL_SMEMS_FILE) -f $(MODEL_SMEMS_FIR) $(MODEL_MACROCOMPILER_MODE)) $(call run_jar_scala_main,$(TAPEOUT_CLASSPATH),barstools.macros.MacroCompiler, -n $(MODEL_SMEMS_CONF) -v $(MODEL_SMEMS_FILE) -f $(MODEL_SMEMS_FIR) $(MODEL_MACROCOMPILER_MODE))
######################################################################################## ########################################################################################
# remove duplicate files and headers in list of simulation file inputs # remove duplicate files and headers in list of simulation file inputs
# note: {MODEL,TOP}_BB_MODS_FILELIST is added as a req. so that the files get generated, # note: {MODEL,TOP}_BB_MODS_FILELIST is added as a req. so that the files get generated,
# however it is really unneeded since ALL_MODS_FILELIST includes all BB files # however it is really unneeded since ALL_MODS_FILELIST includes all BB files
######################################################################################## ########################################################################################
$(sim_common_files): $(sim_files) $(ALL_MODS_FILELIST) $(TOP_SMEMS_FILE) $(MODEL_SMEMS_FILE) $(TOP_BB_MODS_FILELIST) $(MODEL_BB_MODS_FILELIST) $(sim_common_files): $(sim_files) $(ALL_MODS_FILELIST) $(TOP_SMEMS_FILE) $(MODEL_SMEMS_FILE) $(BB_MODS_FILELIST)
sort -u $(sim_files) $(ALL_MODS_FILELIST) | grep -v '.*\.\(svh\|h\)$$' > $@ sort -u $(sim_files) $(ALL_MODS_FILELIST) | grep -v '.*\.\(svh\|h\)$$' > $@
echo "$(TOP_SMEMS_FILE)" >> $@ echo "$(TOP_SMEMS_FILE)" >> $@
echo "$(MODEL_SMEMS_FILE)" >> $@ echo "$(MODEL_SMEMS_FILE)" >> $@
@@ -299,56 +323,81 @@ verilog: $(sim_common_files)
# helper rules to run simulations # helper rules to run simulations
######################################################################################### #########################################################################################
.PHONY: run-binary run-binary-fast run-binary-debug run-fast .PHONY: run-binary run-binary-fast run-binary-debug run-fast
%.check-exists check-binary check-binaries
check-binary: check-binary:
ifeq (,$(BINARY)) ifeq (,$(BINARY))
$(error BINARY variable is not set. Set it to the simulation binary) $(error BINARY variable is not set. Set it to the simulation binary)
endif endif
check-binaries:
ifeq (,$(BINARIES))
$(error BINARIES variable is not set. Set it to the list of simulation binaries to run)
endif
%.check-exists:
if [ "$*" != "none" ] && [ ! -f "$*" ]; then printf "\n\nBinary $* not found\n\n"; exit 1; fi
# allow you to override sim prereq # allow you to override sim prereq
ifeq (,$(BREAK_SIM_PREREQ)) ifeq (,$(BREAK_SIM_PREREQ))
SIM_PREREQ = $(sim) SIM_PREREQ = $(sim)
SIM_DEBUG_PREREQ = $(sim_debug) SIM_DEBUG_PREREQ = $(sim_debug)
endif endif
# Function to generate the loadmem flag. First arg is the binary
ifeq ($(LOADMEM),1)
# If LOADMEM=1, assume BINARY is the loadmem elf
get_loadmem_flag = +loadmem=$(1)
else ifneq ($(LOADMEM),)
# Otherwise, assume the variable points to an elf file
get_loadmem_flag = +loadmem=$(LOADMEM)
endif
ifneq ($(LOADARCH),)
get_loadarch_flag = +loadarch=$(subst mem.elf,loadarch,$(1))
endif
# get the output path base name for simulation outputs, First arg is the binary
get_sim_out_name = $(output_dir)/$(call get_out_name,$(1))
# sim flags that are common to run-binary/run-binary-fast/run-binary-debug
get_common_sim_flags = $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(call get_loadmem_flag,$(1)) $(call get_loadarch_flag,$(1))
.PHONY: %.run %.run.debug %.run.fast
# run normal binary with hardware-logged insn dissassembly # run normal binary with hardware-logged insn dissassembly
run-binary: $(SIM_PREREQ) check-binary | $(output_dir) run-binary: check-binary $(BINARY).run
(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) run-binaries: check-binaries $(addsuffix .run,$(BINARIES))
%.run: %.check-exists $(SIM_PREREQ) | $(output_dir)
(set -o pipefail && $(NUMA_PREFIX) $(sim) $(PERMISSIVE_ON) $(call get_common_sim_flags,$*) $(VERBOSE_FLAGS) $(PERMISSIVE_OFF) $* </dev/null 2> >(spike-dasm > $(call get_sim_out_name,$*).out) | tee $(call get_sim_out_name,$*).log)
# run simulator as fast as possible (no insn disassembly) # run simulator as fast as possible (no insn disassembly)
run-binary-fast: $(SIM_PREREQ) check-binary | $(output_dir) run-binary-fast: check-binary $(BINARY).run.fast
(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) run-binaries-fast: check-binaries $(addsuffix .run.fast,$(BINARIES))
%.run.fast: %.check-exists $(SIM_PREREQ) | $(output_dir)
(set -o pipefail && $(NUMA_PREFIX) $(sim) $(PERMISSIVE_ON) $(call get_common_sim_flags,$*) $(PERMISSIVE_OFF) $* </dev/null | tee $(call get_sim_out_name,$*).log)
# run simulator with as much debug info as possible # run simulator with as much debug info as possible
run-binary-debug: $(SIM_DEBUG_PREREQ) check-binary | $(output_dir) run-binary-debug: check-binary $(BINARY).run.debug
(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-binaries-debug: check-binaries $(addsuffix .run.debug,$(BINARIES))
%.run.debug: %.check-exists $(SIM_DEBUG_PREREQ) | $(output_dir)
if [ "$*" != "none" ]; then riscv64-unknown-elf-objdump -D -S $* > $(call get_sim_out_name,$*).dump ; fi
(set -o pipefail && $(NUMA_PREFIX) $(sim_debug) $(PERMISSIVE_ON) $(call get_common_sim_flags,$*) $(VERBOSE_FLAGS) $(call get_waveform_flag,$(call get_sim_out_name,$*)) $(PERMISSIVE_OFF) $* </dev/null 2> >(spike-dasm > $(call get_sim_out_name,$*).out) | tee $(call get_sim_out_name,$*).log)
run-fast: run-asm-tests-fast run-bmark-tests-fast run-fast: run-asm-tests-fast run-bmark-tests-fast
######################################################################################### #########################################################################################
# helper rules to run simulator with fast loadmem via hex files # helper rules to run simulator with fast loadmem
# LEGACY - use LOADMEM=1 instead
######################################################################################### #########################################################################################
$(binary_hex): $(firstword $(BINARY)) | $(output_dir) run-binary-hex: $(BINARY).run
$(base_dir)/scripts/smartelf2hex.sh $(firstword $(BINARY)) > $(binary_hex) run-binary-hex: override SIM_FLAGS += +loadmem=$(BINARY)
run-binary-debug-hex: $(BINARY).run.debug
run-binary-hex: check-binary run-binary-debug-hex: override SIM_FLAGS += +loadmem=$(BINARY)
run-binary-hex: $(SIM_PREREQ) $(binary_hex) | $(output_dir) run-binary-fast-hex: $(BINARY).run.fast
run-binary-hex: run-binary run-binary-fast-hex: override SIM_FLAGS += +loadmem=$(BINARY)
run-binary-hex: override LOADMEM_ADDR = 80000000
run-binary-hex: override LOADMEM = $(binary_hex)
run-binary-hex: override SIM_FLAGS += +loadmem=$(LOADMEM) +loadmem_addr=$(LOADMEM_ADDR)
run-binary-debug-hex: check-binary
run-binary-debug-hex: $(SIM_DEBUG_REREQ) $(binary_hex) | $(output_dir)
run-binary-debug-hex: run-binary-debug
run-binary-debug-hex: override LOADMEM_ADDR = 80000000
run-binary-debug-hex: override LOADMEM = $(binary_hex)
run-binary-debug-hex: override SIM_FLAGS += +loadmem=$(LOADMEM) +loadmem_addr=$(LOADMEM_ADDR)
run-binary-fast-hex: check-binary
run-binary-fast-hex: $(SIM_PREREQ) $(binary_hex) | $(output_dir)
run-binary-fast-hex: run-binary-fast
run-binary-fast-hex: override LOADMEM_ADDR = 80000000
run-binary-fast-hex: override LOADMEM = $(binary_hex)
run-binary-fast-hex: override SIM_FLAGS += +loadmem=$(LOADMEM) +loadmem_addr=$(LOADMEM_ADDR)
######################################################################################### #########################################################################################
# run assembly/benchmarks rules # run assembly/benchmarks rules
@@ -375,7 +424,6 @@ endif
####################################### #######################################
# Rules for building DRAMSim2 library # Rules for building DRAMSim2 library
####################################### #######################################
dramsim_dir = $(base_dir)/tools/DRAMSim2 dramsim_dir = $(base_dir)/tools/DRAMSim2
dramsim_lib = $(dramsim_dir)/libdramsim.a dramsim_lib = $(dramsim_dir)/libdramsim.a
@@ -383,27 +431,12 @@ $(dramsim_lib):
$(MAKE) -C $(dramsim_dir) $(notdir $@) $(MAKE) -C $(dramsim_dir) $(notdir $@)
################################################ ################################################
# Helper to run SBT or manage the SBT server # Helper to run SBT
################################################ ################################################
SBT_COMMAND ?= shell SBT_COMMAND ?= shell
.PHONY: launch-sbt .PHONY: launch-sbt
launch-sbt: launch-sbt:
cd $(base_dir) && $(SBT_NON_THIN) "$(SBT_COMMAND)" cd $(base_dir) && $(SBT) "$(SBT_COMMAND)"
.PHONY: check-thin-client
check-thin-client:
ifeq (,$(ENABLE_SBT_THIN_CLIENT))
$(error ENABLE_SBT_THIN_CLIENT not set.)
endif
.PHONY: shutdown-sbt-server
shutdown-sbt-server: check-thin-client
cd $(base_dir) && $(SBT) "shutdown"
.PHONY: start-sbt-server
start-sbt-server: check-thin-client
cd $(base_dir) && $(SBT) "exit"
######################################################################################### #########################################################################################
# print help text (and other help) # print help text (and other help)

View File

@@ -23,9 +23,9 @@ dependencies:
# bundle FireSim driver with deps into installer shell-script # bundle FireSim driver with deps into installer shell-script
- constructor - constructor
- gcc - gcc<13
- gxx - gxx<13
- sysroot_linux-64>=2.17 # needed to match pre-built CI XRT glibc version - sysroot_linux-64=2.17 # needed to match pre-built CI XRT glibc version
- conda-gcc-specs - conda-gcc-specs
- binutils - binutils
@@ -89,11 +89,11 @@ dependencies:
- graphviz - graphviz
- expect - expect
- dtc - dtc
- verilator==4.226 - verilator==5.008
- screen - screen
- elfutils - elfutils
- libdwarf-dev==0.0.0.20190110_28_ga81397fc4 # from ucb-bar channel - using mainline libdwarf-feedstock - libdwarf-dev==0.0.0.20190110_28_ga81397fc4 # from ucb-bar channel - using mainline libdwarf-feedstock
- conda-lock>=1 - conda-lock=1.4
# clang-format for driver coding style enforcement. # clang-format for driver coding style enforcement.
- clang-format - clang-format
@@ -131,7 +131,7 @@ dependencies:
- pytest-mock - pytest-mock
- moto - moto
- mypy - mypy
- s3fs - s3fs==0.4.2
- aiohttp - aiohttp
- pip: - pip:
- sure - sure
@@ -143,6 +143,7 @@ dependencies:
- mypy-boto3-s3 - mypy-boto3-s3
- mypy_boto3_ec2 - mypy_boto3_ec2
- botocore-stubs - botocore-stubs
- cryptography<41
- pytz - pytz
- types-pytz - types-pytz
- pyyaml - pyyaml

View File

@@ -15,4 +15,4 @@ dependencies:
# https://docs.conda.io/projects/conda/en/latest/user-guide/concepts/pkg-specs.html#package-match-specifications # https://docs.conda.io/projects/conda/en/latest/user-guide/concepts/pkg-specs.html#package-match-specifications
# documentation on package_spec syntax for constraining versions # documentation on package_spec syntax for constraining versions
- esp-tools=1.0.1 # from ucb-bar channel - https://github.com/ucb-bar/esp-tools-feedstock - esp-tools==1.0.1 # from ucb-bar channel - https://github.com/ucb-bar/esp-tools-feedstock

View File

@@ -15,4 +15,4 @@ dependencies:
# https://docs.conda.io/projects/conda/en/latest/user-guide/concepts/pkg-specs.html#package-match-specifications # https://docs.conda.io/projects/conda/en/latest/user-guide/concepts/pkg-specs.html#package-match-specifications
# documentation on package_spec syntax for constraining versions # documentation on package_spec syntax for constraining versions
- riscv-tools=1.0.3 # from ucb-bar channel - https://github.com/ucb-bar/riscv-tools-feedstock - riscv-tools==1.0.3 # from ucb-bar channel - https://github.com/ucb-bar/riscv-tools-feedstock

View File

@@ -0,0 +1,39 @@
.. _checkpointing:
Architectural Checkpoints
=========================
Chipyard supports generating architectural checkpoints using Spike.
These checkpoints contain a snapshot of the architectural state of a RISC-V SoC at some point in the execution of a program.
The checkpoints include the contents of cacheable memory, core architectural registers, and core CSRs.
RTL simulations of SoCs can resume execution from checkpoints after restoring the architectural state.
.. note::
Currently, only checkpoints of single-core systems are supported
Generating Checkpoints
------------------------
``scripts/generate-ckpt.sh`` is a script that runs spike with the right commands to generate an architectural checkpoint
``scripts/generate-ckpt.sh -h`` lists options for checkpoint generation.
Example: run the ``hello.riscv`` binary for 1000 instructions before generating a checkpoint.
This should produce a directory named ``hello.riscv.0x80000000.1000.loadarch``
.. code::
scripts/generate-ckpt.sh -b tests/hello.riscv -i 1000
Loading Checkpoints in RTL Simulation
--------------------------------------
Checkpoints can be loaded in RTL simulations with the ``LOADARCH`` flag.
The target config **MUST** use dmi-based bringup (as opposed to the default TSI-based bringup), and support fast ``LOADMEM``.
The target config should also match the architectural configuration of however spike was configured when generating the checkpoint.
.. code::
cd sims/vcs
make CONFIG=dmiRocketConfig run-binary LOADARCH=../../hello.riscv.0x80000000.1000.loadarch

View File

@@ -21,24 +21,37 @@ Consider the following example using CDEs.
class WithX(b: Boolean) extends Config((site, here, up) => { class WithX(b: Boolean) extends Config((site, here, up) => {
case SomeKeyX => b case SomeKeyX => b
} })
class WithY(b: Boolean) extends Config((site, here, up) => { class WithY(b: Boolean) extends Config((site, here, up) => {
case SomeKeyY => b case SomeKeyY => b
} })
When forming a query based on a ``Parameters`` object, like ``p(SomeKeyX)``, the configuration system traverses the "chain" of config fragments until it finds a partial function which is defined at the key, and then returns that value. When forming a query based on a ``Parameters`` object, like ``p(SomeKeyX)``, the configuration system traverses the "chain" of config fragments until it finds a partial function which is defined at the key, and then returns that value.
.. code:: scala .. code:: scala
val params = Config(new WithX(true) ++ new WithY(true)) // "chain" together config fragments val params = new Config(new WithX(true) ++ new WithY(true)) // "chain" together config fragments
params(SomeKeyX) // evaluates to true params(SomeKeyX) // evaluates to true
params(SomeKeyY) // evaluates to true params(SomeKeyY) // evaluates to true
params(SomeKeyZ) // evaluates to false params(SomeKeyZ) // evaluates to false
In this example, the evaluation of ``params(SomeKeyX)`` will terminate in the partial function defined in ``WithX(true)``, while the evaluation of ``params(SomeKeyY)`` will terminate in the partial function defined in ``WithY(true)``. Note that when no partial functions match, the evaluation will return the default value for that parameter. In this example, the evaluation of ``params(SomeKeyX)`` will terminate in the partial function defined in ``WithX(true)``, while the evaluation of ``params(SomeKeyY)`` will terminate in the partial function defined in ``WithY(true)``. Note that when no partial functions match, the evaluation will return the default value for that parameter.
Config fragments take precedence from left to right, meaning that a fragment at the start of the chain can override the value of a fragment to the right. It helps to read the fragment chain from right to left.
.. code:: scala
case object SomeKeyX extends Field[Int](0)
class WithX(n: Int) extends Config((site, here, up) => {
case SomeKeyX => n
})
val params = new Config(new WithX(10) ++ new WithX(5))
println(params(SomeKeyX)) // evaluates to 10
The real power of CDEs arises from the ``(site, here, up)`` parameters to the partial functions, which provide useful "views" into the global parameterization that the partial functions may access to determine a parameterization. The real power of CDEs arises from the ``(site, here, up)`` parameters to the partial functions, which provide useful "views" into the global parameterization that the partial functions may access to determine a parameterization.
.. note:: .. note::
@@ -54,10 +67,10 @@ Site
class WithXEqualsYSite extends Config((site, here, up) => { class WithXEqualsYSite extends Config((site, here, up) => {
case SomeKeyX => site(SomeKeyY) // expands to site(SomeKeyY, site) case SomeKeyX => site(SomeKeyY) // expands to site(SomeKeyY, site)
} })
val params_1 = Config(new WithXEqualsYSite ++ new WithY(true)) val params_1 = new Config(new WithXEqualsYSite ++ new WithY(true))
val params_2 = Config(new WithY(true) ++ new WithXEqualsYSite) val params_2 = new Config(new WithY(true) ++ new WithXEqualsYSite)
params_1(SomeKeyX) // evaluates to true params_1(SomeKeyX) // evaluates to true
params_2(SomeKeyX) // evaluates to true params_2(SomeKeyX) // evaluates to true
@@ -75,10 +88,10 @@ Here
class WithXEqualsYHere extends Config((site, here, up) => { class WithXEqualsYHere extends Config((site, here, up) => {
case SomeKeyY => false case SomeKeyY => false
case SomeKeyX => here(SomeKeyY, site) case SomeKeyX => here(SomeKeyY, site)
} })
val params_1 = Config(new WithXEqualsYHere ++ new WithY(true)) val params_1 = new Config(new WithXEqualsYHere ++ new WithY(true))
val params_2 = Config(new WithY(true) ++ new WithXEqualsYHere) val params_2 = new Config(new WithY(true) ++ new WithXEqualsYHere)
params_1(SomeKeyX) // evaluates to false params_1(SomeKeyX) // evaluates to false
params_2(SomeKeyX) // evaluates to false params_2(SomeKeyX) // evaluates to false
@@ -95,10 +108,10 @@ Up
class WithXEqualsYUp extends Config((site, here, up) => { class WithXEqualsYUp extends Config((site, here, up) => {
case SomeKeyX => up(SomeKeyY, site) case SomeKeyX => up(SomeKeyY, site)
} })
val params_1 = Config(new WithXEqualsYUp ++ new WithY(true)) val params_1 = new Config(new WithXEqualsYUp ++ new WithY(true))
val params_2 = Config(new WithY(true) ++ new WithXEqualsYUp) val params_2 = new Config(new WithY(true) ++ new WithXEqualsYUp)
params_1(SomeKeyX) // evaluates to true params_1(SomeKeyX) // evaluates to true
params_2(SomeKeyX) // evaluates to false params_2(SomeKeyX) // evaluates to false

View File

@@ -47,12 +47,12 @@ Using the Tethered Serial Interface (TSI)
By default, Chipyard uses the Tethered Serial Interface (TSI) to communicate with the DUT. By default, Chipyard uses the Tethered Serial Interface (TSI) to communicate with the DUT.
TSI protocol is an implementation of HTIF that is used to send commands to the RISC-V DUT. TSI protocol is an implementation of HTIF that is used to send commands to the RISC-V DUT.
These TSI commands are simple R/W commands that are able to access the DUT's memory space. These TSI commands are simple R/W commands that are able to access the DUT's memory space.
During simulation, the host sends TSI commands to a simulation stub in the test harness called ``SimSerial`` During simulation, the host sends TSI commands to a simulation stub in the test harness called ``SimTSI``
(C++ class) that resides in a ``SimSerial`` Verilog module (both are located in the ``generators/testchipip`` (C++ class) that resides in a ``SimTSI`` Verilog module (both are located in the ``generators/testchipip``
project). project).
This ``SimSerial`` Verilog module then sends the TSI command recieved by the simulation stub This ``SimTSI`` Verilog module then sends the TSI command recieved by the simulation stub
to an adapter that converts the TSI command into a TileLink request. to an adapter that converts the TSI command into a TileLink request.
This conversion is done by the ``SerialAdapter`` module (located in the ``generators/testchipip`` project). This conversion is done by the ``TSIToTileLink`` module (located in the ``generators/testchipip`` project).
After the transaction is converted to TileLink, the ``TLSerdesser`` (located in ``generators/testchipip``) serializes the After the transaction is converted to TileLink, the ``TLSerdesser`` (located in ``generators/testchipip``) serializes the
transaction and sends it to the chip (this ``TLSerdesser`` is sometimes also referred to as a digital serial-link or SerDes). transaction and sends it to the chip (this ``TLSerdesser`` is sometimes also referred to as a digital serial-link or SerDes).
Once the serialized transaction is received on the chip, it is deserialized and masters a TileLink bus on the chip Once the serialized transaction is received on the chip, it is deserialized and masters a TileLink bus on the chip
@@ -76,7 +76,7 @@ simulation stub called ``SimDTM`` (C++ class) that resides in a ``SimDTM`` Veril
sends the DMI command recieved by the simulation stub into the DUT which then converts the DMI sends the DMI command recieved by the simulation stub into the DUT which then converts the DMI
command into a TileLink request. This conversion is done by the DTM named ``DebugModule`` in the ``generators/rocket-chip`` project. command into a TileLink request. This conversion is done by the DTM named ``DebugModule`` in the ``generators/rocket-chip`` project.
When the DTM receives the program to load, it starts to write the binary byte-wise into memory. When the DTM receives the program to load, it starts to write the binary byte-wise into memory.
This is considerably slower than the TSI protocol communication pipeline (i.e. ``SimSerial``/``SerialAdapter``/TileLink) This is considerably slower than the TSI protocol communication pipeline (i.e. ``SimTSI``/``TSIToTileLink``/TileLink)
which directly writes the program binary to memory. which directly writes the program binary to memory.
Starting the TSI or DMI Simulation Starting the TSI or DMI Simulation
@@ -206,13 +206,17 @@ This type of simulation setup is done in the following multi-clock configuration
:start-after: DOC include start: MulticlockAXIOverSerialConfig :start-after: DOC include start: MulticlockAXIOverSerialConfig
:end-before: DOC include end: MulticlockAXIOverSerialConfig :end-before: DOC include end: MulticlockAXIOverSerialConfig
Bringup Setup of the Example Test Chip after Tapeout Softcore-driven Bringup Setup of the Example Test Chip after Tapeout
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. warning::
Bringing up test chips with a FPGA softcore as described here is discouraged.
An alternative approach using the FPGA to "bridge" between a host computer and the test chip is the preferred approach.
Assuming this example test chip is taped out and now ready to be tested, we can communicate with the chip using this serial-link. Assuming this example test chip is taped out and now ready to be tested, we can communicate with the chip using this serial-link.
For example, a common test setup used at Berkeley to evaluate Chipyard-based test-chips includes an FPGA running a RISC-V soft-core that is able to speak to the DUT (over an FMC). For example, a common test setup used at Berkeley to evaluate Chipyard-based test-chips includes an FPGA running a RISC-V soft-core that is able to speak to the DUT (over an FMC).
This RISC-V soft-core would serve as the host of the test that will run on the DUT. This RISC-V soft-core would serve as the host of the test that will run on the DUT.
This is done by the RISC-V soft-core running FESVR, sending TSI commands to a ``SerialAdapter`` / ``TLSerdesser`` programmed on the FPGA. This is done by the RISC-V soft-core running FESVR, sending TSI commands to a ``TSIToTileLink`` / ``TLSerdesser`` programmed on the FPGA.
Once the commands are converted to serialized TileLink, then they can be sent over some medium to the DUT Once the commands are converted to serialized TileLink, then they can be sent over some medium to the DUT
(like an FMC cable or a set of wires connecting FPGA outputs to the DUT board). (like an FMC cable or a set of wires connecting FPGA outputs to the DUT board).
Similar to simulation, if the chip requests offchip memory, it can then send the transaction back over the serial-link. Similar to simulation, if the chip requests offchip memory, it can then send the transaction back over the serial-link.
@@ -222,4 +226,4 @@ The following image shows this flow:
.. image:: ../_static/images/chip-bringup.png .. image:: ../_static/images/chip-bringup.png
In fact, this exact type of bringup setup is what the following section discusses: In fact, this exact type of bringup setup is what the following section discusses:
:ref:`Prototyping/VCU118:Introduction to the Bringup Design`. :ref:_legacy-vcu118-bringup.

View File

@@ -5,34 +5,20 @@ Creating Clocks in the Test Harness
Chipyard currently allows the SoC design (everything under ``ChipTop``) to Chipyard currently allows the SoC design (everything under ``ChipTop``) to
have independent clock domains through diplomacy. have independent clock domains through diplomacy.
This implies that some reference clock enters the ``ChipTop`` and then is divided down into ``ChipTop`` clock ports are driven by ``harnessClockInstantiator.requestClock(freq)``.
separate clock domains. ``ChipTop`` reset ports are driven by the ``referenceReset()`` function, which is intended to provide an asynchronous reset.
From the perspective of the ``TestHarness`` module, the ``ChipTop`` clock and reset is
provided from a clock and reset called ``buildtopClock`` and ``buildtopReset``.
In the default case, this ``buildtopClock`` and ``buildtopReset`` is directly wired to the
clock and reset IO's of the ``TestHarness`` module.
However, the ``TestHarness`` has the ability to generate a standalone clock and reset signal
that is separate from the reference clock/reset of ``ChipTop``.
This allows harness components (including harness binders) the ability to "request" a clock
for a new clock domain.
This is useful for simulating systems in which modules in the harness have independent clock domains
from the DUT.
Requests for a harness clock is done by the ``HarnessClockInstantiator`` class in ``generators/chipyard/src/main/scala/TestHarness.scala``. The ``HarnessBinder`` s in ``ChipTop`` are clocked by the ``HarnessBinderClockFrequencyKey`` value. The reset is provided as a synchronous reset, sync'd to the clock.
This class is accessed in harness components by referencing the Rocket Chip parameters key ``p(HarnessClockInstantiatorKey)``.
Then you can request a clock and syncronized reset at a particular frequency by invoking the ``requestClockBundle`` function.
Requests for a harness clock is done by the ``HarnessClockInstantiator`` class in ``generators/chipyard/src/main/scala/harness/HarnessClocks.scala``.
Then you can request a clock and syncronized reset at a particular frequency by invoking the ``requestClock`` function.
Take the following example: Take the following example:
.. literalinclude:: ../../generators/chipyard/src/main/scala/HarnessBinders.scala .. literalinclude:: ../../generators/chipyard/src/main/scala/harness/HarnessBinders.scala
:language: scala :language: scala
:start-after: DOC include start: HarnessClockInstantiatorEx :start-after: DOC include start: HarnessClockInstantiatorEx
:end-before: DOC include end: HarnessClockInstantiatorEx :end-before: DOC include end: HarnessClockInstantiatorEx
Here you can see the ``p(HarnessClockInstantiatorKey)`` is used to request a clock and reset at ``memFreq`` frequency. Here you can see the ``th.harnessClockInstantiator`` is used to request a clock and reset at ``memFreq`` frequency.
.. note::
In the case that the reference clock entering ``ChipTop`` is not the overall reference clock of the simulation
(i.e. the clock/reset coming into the ``TestHarness`` module), the ``buildtopClock`` and ``buildtopReset`` can
differ from the implicit ``TestHarness`` clock and reset. For example, if the ``ChipTop`` reference is 500MHz but an
extra harness clock is requested at 1GHz, the ``TestHarness`` implicit clock/reset will be at 1GHz while the ``buildtopClock``
and ``buildtopReset`` will be at 500MHz.

View File

@@ -2,24 +2,24 @@ Accessing Scala Resources
=============================== ===============================
A simple way to copy over a source file to the build directory to be used for a simulation compile or VLSI flow is to use the ``addResource`` function given by FIRRTL. A simple way to copy over a source file to the build directory to be used for a simulation compile or VLSI flow is to use the ``addResource`` function given by FIRRTL.
An example of its use can be seen in `generators/testchipip/src/main/scala/SerialAdapter.scala <https://github.com/ucb-bar/testchipip/blob/master/src/main/scala/SerialAdapter.scala>`_. An example of its use can be seen in `generators/testchipip/src/main/scala/SimTSI.scala <https://github.com/ucb-bar/testchipip/blob/master/src/main/scala/SimTSI.scala>`_.
Here is the example inlined: Here is the example inlined:
.. code-block:: scala .. code-block:: scala
class SimSerial(w: Int) extends BlackBox with HasBlackBoxResource { class SimTSI extends BlackBox with HasBlackBoxResource {
val io = IO(new Bundle { val io = IO(new Bundle {
val clock = Input(Clock()) val clock = Input(Clock())
val reset = Input(Bool()) val reset = Input(Bool())
val serial = Flipped(new SerialIO(w)) val tsi = Flipped(new TSIIO)
val exit = Output(Bool()) val exit = Output(Bool())
}) })
addResource("/testchipip/vsrc/SimSerial.v") addResource("/testchipip/vsrc/SimTSI.v")
addResource("/testchipip/csrc/SimSerial.cc") addResource("/testchipip/csrc/SimTSI.cc")
} }
In this example, the ``SimSerial`` files will be copied from a specific folder (in this case the ``path/to/testchipip/src/main/resources/testchipip/...``) to the build folder. In this example, the ``SimTSI`` files will be copied from a specific folder (in this case the ``path/to/testchipip/src/main/resources/testchipip/...``) to the build folder.
The ``addResource`` path retrieves resources from the ``src/main/resources`` directory. The ``addResource`` path retrieves resources from the ``src/main/resources`` directory.
So to get an item at ``src/main/resources/fileA.v`` you can use ``addResource("/fileA.v")``. So to get an item at ``src/main/resources/fileA.v`` you can use ``addResource("/fileA.v")``.
However, one caveat of this approach is that to retrieve the file during the FIRRTL compile, you must have that project in the FIRRTL compiler's classpath. However, one caveat of this approach is that to retrieve the file during the FIRRTL compile, you must have that project in the FIRRTL compiler's classpath.

View File

@@ -16,3 +16,4 @@ They expect you to know about Chisel, Parameters, configs, etc.
CDEs CDEs
Harness-Clocks Harness-Clocks
Managing-Published-Scala-Dependencies Managing-Published-Scala-Dependencies
Architectural-Checkpoints

View File

@@ -83,8 +83,8 @@ This example shows the Chipyard default top that composes multiple traits togeth
:end-before: DOC include end: DigitalTop :end-before: DOC include end: DigitalTop
There are two "cakes" or mixins here. One for the lazy module (ex. ``CanHavePeripherySerial``) and one for the lazy module There are two "cakes" or mixins here. One for the lazy module (ex. ``CanHavePeripheryTLSerial``) and one for the lazy module
implementation (ex. ``CanHavePeripherySerialModuleImp`` where ``Imp`` refers to implementation). The lazy module defines implementation (ex. ``CanHavePeripheryTLSerialModuleImp`` where ``Imp`` refers to implementation). The lazy module defines
all the logical connections between generators and exchanges configuration information among them, while the all the logical connections between generators and exchanges configuration information among them, while the
lazy module implementation performs the actual Chisel RTL elaboration. lazy module implementation performs the actual Chisel RTL elaboration.
@@ -93,19 +93,17 @@ In the ``DigitalTop`` example class, the "outer" ``DigitalTop`` instantiates the
of the module until all logical connections are determined and all configuration information is exchanged. of the module until all logical connections are determined and all configuration information is exchanged.
The ``System`` outer base class, as well as the The ``System`` outer base class, as well as the
``CanHavePeriphery<X>`` outer traits contain code to perform high-level logical ``CanHavePeriphery<X>`` outer traits contain code to perform high-level logical
connections. For example, the ``CanHavePeripherySerial`` outer trait contains code connections. For example, the ``CanHavePeripheryTLSerial`` outer trait contains code
to optionally lazily instantiate the ``SerialAdapter``, and connect the ``SerialAdapter``'s to optionally lazily instantiate the ``TLSerdesser``, and connect the ``TLSerdesser`` 's
TileLink node to the Front bus. TileLink node to the Front bus.
The ``ModuleImp`` classes and traits perform elaboration of real RTL. The ``ModuleImp`` classes and traits perform elaboration of real RTL.
For example, the ``CanHavePeripherySerialModuleImp`` trait optionally physically connects
the ``SerialAdapter`` module, and instantiates queues.
In the test harness, the SoC is elaborated with In the test harness, the SoC is elaborated with
``val dut = p(BuildTop)(p)``. ``val dut = p(BuildTop)(p)``.
After elaboration, the system submodule of ``ChipTop`` will be a ``DigitalTop`` module, which contains a After elaboration, the system submodule of ``ChipTop`` will be a ``DigitalTop`` module, which contains a
``SerialAdapter`` module (among others), if the config specified for that block to be instantiated. ``TLSerdesser`` module (among others), if the config specified for that block to be instantiated.
From a high level, classes which extend ``LazyModule`` *must* reference From a high level, classes which extend ``LazyModule`` *must* reference
their module implementation through ``lazy val module``, and they their module implementation through ``lazy val module``, and they
@@ -116,7 +114,7 @@ other normal modules OR lazy modules (for nested Diplomacy
graphs, for example). graphs, for example).
The naming convention for an additive mixin or trait is ``CanHave<YourMixin>``. The naming convention for an additive mixin or trait is ``CanHave<YourMixin>``.
This is shown in the ``Top`` class where things such as ``CanHavePeripherySerial`` connect a RTL component to a bus and expose signals to the top-level. This is shown in the ``Top`` class where things such as ``CanHavePeripheryTLSerial`` connect a RTL component to a bus and expose signals to the top-level.
Additional References Additional References
--------------------------- ---------------------------

View File

@@ -27,29 +27,28 @@ Conda allows users to create an "environment" that holds system dependencies lik
.. Note:: Chipyard can also run on systems without a Conda installation. However, users on these systems must manually install toolchains and dependencies. .. Note:: Chipyard can also run on systems without a Conda installation. However, users on these systems must manually install toolchains and dependencies.
First, Chipyard requires Conda to be installed on the system. First, Chipyard requires the latest Conda to be installed on the system.
Please refer to the `Conda installation instructions <https://github.com/conda-forge/miniforge/#download>`__ on how to install Conda with the **Miniforge** installer. Please refer to the `Conda installation instructions <https://github.com/conda-forge/miniforge/#download>`__ on how to install the latest Conda with the **Miniforge** installer.
Afterwards, verify that Conda is a sufficient version (we test on version 4.12.0 but higher is most likely fine).
.. Note:: If you have installed conda separately from this documentation (i.e. from miniconda or full Anaconda), please ensure you follow https://conda-forge.org/docs/user/introduction.html#how-can-i-install-packages-from-conda-forge to use ``conda-forge`` packages without any issues.
.. code-block:: shell
conda --version # must be version 4.12.0 or higher
After Conda is installed and is on your ``PATH``, we need to install a version of ``git`` to initially checkout the repository. After Conda is installed and is on your ``PATH``, we need to install a version of ``git`` to initially checkout the repository.
For this you can use the system package manager like ``yum`` or ``apt`` to install ``git``. For this you can use the system package manager like ``yum`` or ``apt`` to install ``git``.
This ``git`` is only used to first checkout the repository, we will later install a newer version of ``git`` with Conda. This ``git`` is only used to first checkout the repository, we will later install a newer version of ``git`` with Conda.
Next, we install `libmamba <https://www.anaconda.com/blog/a-faster-conda-for-a-growing-community>`__ for much faster dependency solving when initially setting up the repository.
.. code-block:: shell
conda install -n base conda-libmamba-solver
conda config --set solver libmamba
Finally we need to install ``conda-lock`` into the ``base`` conda environment. Finally we need to install ``conda-lock`` into the ``base`` conda environment.
This is done by the following: This is done by the following:
.. code-block:: shell .. code-block:: shell
conda install -n base conda-lock conda install -n base conda-lock=1.4
conda activate base conda activate base
.. Note:: We also recommended switching to `libmamba <https://www.anaconda.com/blog/a-faster-conda-for-a-growing-community>`__ for much faster dependency solving.
Setting up the Chipyard Repo Setting up the Chipyard Repo
------------------------------------------- -------------------------------------------
@@ -71,7 +70,27 @@ Run the following script based off which compiler you would like to use.
.. Note:: Prior versions of Chipyard recommended ``esp-tools`` for Gemmini development. Gemmini should now be used with the standard ``riscv-tools``. .. Note:: Prior versions of Chipyard recommended ``esp-tools`` for Gemmini development. Gemmini should now be used with the standard ``riscv-tools``.
.. Warning:: The following script will complete a "full" installation of Chipyard which may take a long time depending on the system. .. Warning:: The following script will complete a "full" installation of Chipyard which may take a long time depending on the system.
Ensure that this script completes fully (no interruptions) before continuing on. Ensure that this script completes fully (no interruptions) before continuing on. User can use the ``--skip`` or ``-s`` flag to skip steps:
``-s 1`` skips initializing Conda environment
``-s 2`` skips initializing Chipyard submodules
``-s 3`` skips initializing toolchain collateral (Spike, PK, tests, libgloss)
``-s 4`` skips initializing ctags
``-s 5`` skips pre-compiling Chipyard Scala sources
``-s 6`` skips initializing FireSim
``-s 7`` skips pre-compiling FireSim sources
``-s 8`` skips initializing FireMarshal
``-s 9`` skips pre-compiling FireMarshal default buildroot Linux sources
``-s 10`` skips running repository clean-up
.. code-block:: shell .. code-block:: shell
@@ -120,7 +139,7 @@ You can source this file in your ``.bashrc`` or equivalent environment setup fil
However, it is recommended that the final ``env.sh`` file sourced is the ``env.sh`` located in the However, it is recommended that the final ``env.sh`` file sourced is the ``env.sh`` located in the
Chipyard repo that you expect to run ``make`` commands in. Chipyard repo that you expect to run ``make`` commands in.
Pre-built Docker Image DEPRECATED: Pre-built Docker Image
------------------------------------------- -------------------------------------------
An alternative to setting up the Chipyard repository locally is to pull the pre-built Docker image from Docker Hub. The image comes with all dependencies installed, Chipyard cloned, and toolchains initialized. This image sets up baseline Chipyard (not including FireMarshal, FireSim, and Hammer initializations). Each image comes with a tag that corresponds to the version of Chipyard cloned/set-up in that image. Not including a tag during the pull will pull the image with the latest version of Chipyard. An alternative to setting up the Chipyard repository locally is to pull the pre-built Docker image from Docker Hub. The image comes with all dependencies installed, Chipyard cloned, and toolchains initialized. This image sets up baseline Chipyard (not including FireMarshal, FireSim, and Hammer initializations). Each image comes with a tag that corresponds to the version of Chipyard cloned/set-up in that image. Not including a tag during the pull will pull the image with the latest version of Chipyard.

View File

@@ -52,8 +52,22 @@ Then add ``yourproject`` to the Chipyard top-level build.sbt file.
You can then import the classes defined in the submodule in a new project if You can then import the classes defined in the submodule in a new project if
you add it as a dependency. For instance, if you want to use this code in you add it as a dependency. For instance, if you want to use this code in
the ``chipyard`` project, change the final line in build.sbt to the following. the ``chipyard`` project, add your project to the list of sub-projects in the
`.dependsOn()` for `lazy val chipyard`. The original code may change over time, but it
should look something like this:
.. code-block:: scala .. code-block:: scala
lazy val chipyard = (project in file(".")).settings(commonSettings).dependsOn(testchipip, yourproject) lazy val chipyard = (project in file("generators/chipyard"))
.dependsOn(testchipip, rocketchip, boom, hwacha, sifive_blocks, sifive_cache, iocell,
sha3, dsptools, `rocket-dsp-utils`,
gemmini, icenet, tracegen, cva6, nvdla, sodor, ibex, fft_generator,
yourproject, // <- added to the middle of the list for simplicity
constellation, mempress)
.settings(libraryDependencies ++= rocketLibDeps.value)
.settings(
libraryDependencies ++= Seq(
"org.reflections" % "reflections" % "0.10.2"
)
)
.settings(commonSettings)

View File

@@ -31,7 +31,7 @@ Like ``IOBinders``, ``HarnessBinders`` are defined using macros (``OverrideHarne
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. 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 .. literalinclude:: ../../generators/chipyard/src/main/scala/harness/HarnessBinders.scala
:language: scala :language: scala
:start-after: DOC include start: WithUARTAdapter :start-after: DOC include start: WithUARTAdapter
:end-before: DOC include end: WithUARTAdapter :end-before: DOC include end: WithUARTAdapter

View File

@@ -94,7 +94,7 @@ memory channel.
Instead of connecting to off-chip DRAM, you can instead connect a scratchpad Instead of connecting to off-chip DRAM, you can instead connect a scratchpad
and remove the off-chip link. This is done by adding a fragment like and remove the off-chip link. This is done by adding a fragment like
``testchipip.WithBackingScratchpad`` to your configuration and removing the ``testchipip.WithScratchpad`` to your configuration and removing the
memory port with ``freechips.rocketchip.subsystem.WithNoMemPort``. memory port with ``freechips.rocketchip.subsystem.WithNoMemPort``.
.. literalinclude:: ../../generators/chipyard/src/main/scala/config/RocketConfigs.scala .. literalinclude:: ../../generators/chipyard/src/main/scala/config/RocketConfigs.scala

View File

@@ -1,10 +1,15 @@
.. _rocc-accelerators: .. _rocc-accelerators:
Adding a RoCC Accelerator Adding a RoCC Accelerator
---------------------------- -------------------------
RoCC accelerators are lazy modules that extend the ``LazyRoCC`` class. A RoCC accelerator is a component that can be added into a particular Rocket or BooM tile.
Their implementation should extends the ``LazyRoCCModule`` class. It receives instructions that match a certain opcode, talks to other parts of the core or SoC (L1, L2, PTW, FPU), and then optionally writes back a value into the register corresponding with the ``rd`` field of the instruction.
RoCC accelerators are instantiated via modules that extend the ``LazyRoCC`` class.
These modules lazily instantiate another module which extends the ``LazyRoCCModule`` class.
This extra layer of indirection is used so that Diplomacy can figure out how to connect the RoCC module to the chip, without needing to instantiate the module ahead of time.
Lazy modules are further explained in the :ref:`Chipyard-Basics/Configs-Parameters-Mixins:Cake Pattern / Mixin` section.
Below is a minimal instantiation of a RoCC accelerator.
.. code-block:: scala .. code-block:: scala
@@ -31,7 +36,6 @@ Their implementation should extends the ``LazyRoCCModule`` class.
... ...
} }
The ``opcodes`` parameter for ``LazyRoCC`` is the set of custom opcodes that will map to this accelerator. The ``opcodes`` parameter for ``LazyRoCC`` is the set of custom opcodes that will map to this accelerator.
More on this in the next subsection. More on this in the next subsection.
@@ -46,6 +50,47 @@ the ``busy`` signal, which indicates when the accelerator is still handling an i
and the ``interrupt`` signal, which can be used to interrupt the CPU. and the ``interrupt`` signal, which can be used to interrupt the CPU.
Look at the examples in ``generators/rocket-chip/src/main/scala/tile/LazyRoCC.scala`` for detailed information on the different IOs. Look at the examples in ``generators/rocket-chip/src/main/scala/tile/LazyRoCC.scala`` for detailed information on the different IOs.
There is also more information about each of the signals in `the RoCC Documentation written by UCSD <https://docs.google.com/document/d/1CH2ep4YcL_ojsa3BVHEW-uwcKh1FlFTjH_kg5v8bxVw/edit>`_, although it is updated out of tree and may be out of date.
Accessing Memory via L1 Cache
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A RoCC accelerator can access memory through the L1 Cache of the core it is attached to.
This is a simpler interface for accelerator architects to implement, but will generally have lower achievable throughput than a dedicated TileLink port.
In your ``LazyRoCCModuleImp``, the signal ``io.mem`` is a ``HellaCacheIO``, which is defined in ``generators/rocket-chip/src/main/scala/rocket/HellaCache.scala``.
.. code-block:: scala
class HellaCacheIO(implicit p: Parameters) extends CoreBundle()(p) {
val req = Decoupled(new HellaCacheReq)
val s1_kill = Output(Bool()) // kill previous cycle's req
val s1_data = Output(new HellaCacheWriteData()) // data for previous cycle's req
val s2_nack = Input(Bool()) // req from two cycles ago is rejected
val s2_nack_cause_raw = Input(Bool()) // reason for nack is store-load RAW hazard (performance hint)
val s2_kill = Output(Bool()) // kill req from two cycles ago
val s2_uncached = Input(Bool()) // advisory signal that the access is MMIO
val s2_paddr = Input(UInt(paddrBits.W)) // translated address
val resp = Flipped(Valid(new HellaCacheResp))
val replay_next = Input(Bool())
val s2_xcpt = Input(new HellaCacheExceptions)
val s2_gpa = Input(UInt(vaddrBitsExtended.W))
val s2_gpa_is_pte = Input(Bool())
val uncached_resp = tileParams.dcache.get.separateUncachedResp.option(Flipped(Decoupled(new HellaCacheResp)))
val ordered = Input(Bool())
val perf = Input(new HellaCachePerfEvents())
val keep_clock_enabled = Output(Bool()) // should D$ avoid clock-gating itself?
val clock_enabled = Input(Bool()) // is D$ currently being clocked?
}
At a high level, you must tag requests that you send across this interface using the ``io.mem.req.tag``, and the tag will be returned to you when the data is ready.
Responses may come back out of order if you issue multiple requests, so you can use these tags to tell what data came back.
Note that the number of tag bits is controled by ``dcacheReqTagBits``, which is usually set to 6.
Using more than 6 bits will cause errors or hangs.
Adding RoCC accelerator to Config Adding RoCC accelerator to Config
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -67,3 +112,4 @@ For instance, if we wanted to add the previously defined accelerator and route c
new RocketConfig) new RocketConfig)
To add RoCC instructions in your program, use the RoCC C macros provided in ``tests/rocc.h``. You can find examples in the files ``tests/accum.c`` and ``charcount.c``. To add RoCC instructions in your program, use the RoCC C macros provided in ``tests/rocc.h``. You can find examples in the files ``tests/accum.c`` and ``charcount.c``.

View File

@@ -0,0 +1,9 @@
Prefetchers
====================================
The BAR-fetchers library is a collection of Chisel-implemented prefetchers, designed for compatibility with Chipyard and Rocket-Chip SoCs.
This package implements a generic prefetcher API, and example implementations of NextLine, Strided, and AMPM prefetchers.
Prefetchers can be instantiated in front of a L1D HellaCache, or as TileLink nodes in front of some TileLink bus.
An example configuration using prefetchers is found in the ``PrefetchingRocketConfig``

View File

@@ -0,0 +1,8 @@
Shuttle RISC-V Core
===================
Shuttle is a Rocket-based superscalar in-order RISC-V core, supporting the base RV64IMAFDC instruction set with supervisor and user-mode. Shuttle is a 6-stage core that can be configured to be dual, three, or quad-issue, although dual-issue is the most sensible design point. Shuttle is not designed to meet any power, performance, or area targets. It exists purely as a demonstrative example of another RISC-V CPU design point.
The superscalar microarchitecture presents the most advantages for 1) floating-point kernels and 2) RoCC accelerator kernels, as scalar control code can execute concurrently with floating point or RoCC instructions, maintaining high utilization of those units.
Shuttle is tape-out proven, and has similar physical design complexity as Rocket.

View File

@@ -2,16 +2,16 @@ Test Chip IP
============ ============
Chipyard includes a Test Chip IP library which provides various hardware Chipyard includes a Test Chip IP library which provides various hardware
widgets that may be useful when designing SoCs. This includes a :ref:`Generators/TestChipIP:Serial Adapter`, widgets that may be useful when designing SoCs. This includes a :ref:`Generators/TestChipIP:SimTSI`,
:ref:`Generators/TestChipIP:Block Device Controller`, :ref:`Generators/TestChipIP:TileLink SERDES`, :ref:`Generators/TestChipIP:TileLink Switcher`, :ref:`Generators/TestChipIP:Block Device Controller`, :ref:`Generators/TestChipIP:TileLink SERDES`, :ref:`Generators/TestChipIP:TileLink Switcher`,
:ref:`Generators/TestChipIP:TileLink Ring Network`, and :ref:`Generators/TestChipIP:UART Adapter`. :ref:`Generators/TestChipIP:TileLink Ring Network`, and :ref:`Generators/TestChipIP:UART Adapter`.
Serial Adapter SimTSI
-------------- --------------
The serial adapter is used by tethered test chips to communicate with the host The SimTSI and TSIToTileLink are used by tethered test chips to communicate with the host
processor. An instance of RISC-V frontend server running on the host CPU processor. An instance of RISC-V frontend server running on the host CPU
can send commands to the serial adapter to read and write data from the memory can send commands to the TSIToTileLink to read and write data from the memory
system. The frontend server uses this functionality to load the test program system. The frontend server uses this functionality to load the test program
into memory and to poll for completion of the program. More information on into memory and to poll for completion of the program. More information on
this can be found in :ref:`Customization/Boot-Process:Chipyard Boot Process`. this can be found in :ref:`Customization/Boot-Process:Chipyard Boot Process`.

View File

@@ -33,4 +33,6 @@ so changes to the generators themselves will automatically be used when building
fft fft
NVDLA NVDLA
Sodor Sodor
Shuttle
Mempress Mempress
Prefetchers

View File

@@ -1,18 +1,11 @@
General Setup and Usage General Setup and Usage
============================== ==============================
Sources and Submodule Setup Sources
--------------------------- ---------------------------
All FPGA prototyping-related collateral and sources are located in the ``fpga`` top-level Chipyard directory. All FPGA prototyping-related collateral and sources are located in the ``fpga`` top-level Chipyard directory.
This includes the ``fpga-shells`` submodule and the ``src`` directory that hold both Scala, TCL and other collateral. This includes the ``fpga-shells`` submodule and the ``src`` directory that hold both Scala, TCL and other collateral.
However, the ``fpga-shells`` submodule repository is not initialized by default.
To initialize the ``fpga-shells`` submodule repository, run the included initialization script from the Chipyard top-level directory:
.. code-block:: shell
# in the chipyard top level folder
./scripts/init-fpga.sh
Generating a Bitstream Generating a Bitstream
---------------------- ----------------------

View File

@@ -47,8 +47,14 @@ After the harness is created, the ``BundleBridgeSource``'s must be connected to
This is done with harness binders and io binders (see ``fpga/src/main/scala/vcu118/HarnessBinders.scala`` and ``fpga/src/main/scala/vcu118/IOBinders.scala``). This is done with harness binders and io binders (see ``fpga/src/main/scala/vcu118/HarnessBinders.scala`` and ``fpga/src/main/scala/vcu118/IOBinders.scala``).
For more information on harness binders and io binders, refer to :ref:`Customization/IOBinders:IOBinders and HarnessBinders`. For more information on harness binders and io binders, refer to :ref:`Customization/IOBinders:IOBinders and HarnessBinders`.
Introduction to the Bringup Design (Legacy) Introduction to the Legacy Bringup Design
---------------------------------- --------------------------------------------------
.. warning::
The bringup VCU118 design described here is designed for old versions of Chipyard SoCs, pre-1.9.1.
The key difference is that these designs rely on a clock generated on-chip to synchronize the slow serialized-TileLink interface.
After Chipyard 1.9.1, the FPGA host is expected to pass the clock to the chip, instead of the other way around.
A new bringup solution will be developed for post-1.9.1 Chipyard designs.
An example of a more complicated design used for Chipyard test chips can be viewed in ``fpga/src/main/scala/vcu118/bringup/``. An example of a more complicated design used for Chipyard test chips can be viewed in ``fpga/src/main/scala/vcu118/bringup/``.
This example extends the default test harness and creates new ``Overlays`` to connect to a DUT (connected to the FMC port). This example extends the default test harness and creates new ``Overlays`` to connect to a DUT (connected to the FMC port).

View File

@@ -26,9 +26,9 @@ Finally, source the following environment at the root of the FireSim directory:
cd sims/firesim cd sims/firesim
# (Recommended) The default manager environment (includes env.sh) # (Recommended) The default manager environment (includes env.sh)
source sourceme-f1-manager.sh source sourceme-manager.sh
.. Note:: Every time you want to use FireSim with a fresh shell, you must source this ``sourceme-f1-manager.sh`` .. Note:: Every time you want to use FireSim with a fresh shell, you must source ``sourceme-manager.sh``
At this point you're ready to use FireSim with Chipyard. If you're not already At this point you're ready to use FireSim with Chipyard. If you're not already
familiar with FireSim, please return to the :fsim_doc:`FireSim Docs <Initial-Setup/Setting-up-your-Manager-Instance.html#completing-setup-using-the-manager>`, familiar with FireSim, please return to the :fsim_doc:`FireSim Docs <Initial-Setup/Setting-up-your-Manager-Instance.html#completing-setup-using-the-manager>`,

View File

@@ -151,25 +151,17 @@ Fast Memory Loading
------------------- -------------------
The simulator loads the program binary over a simulated serial line. This can be quite slow if there is a lot of static data, so the simulator also allows data to be loaded from a file directly into the DRAM model. The simulator loads the program binary over a simulated serial line. This can be quite slow if there is a lot of static data, so the simulator also allows data to be loaded from a file directly into the DRAM model.
Loadmem files should be ELF files. In the most common use case, this can be the binary.
.. code-block:: shell .. code-block:: shell
make run-binary BINARY=test.riscv LOADMEM=testdata.hex LOADMEM_ADDR=81000000 make run-binary BINARY=test.riscv LOADMEM=test.riscv
The ``.hex`` file should be a text file with a hexadecimal number on each line. Usually the ``LOADMEM`` ELF is the same as the ``BINARY`` ELF, so ``LOADMEM=1`` can be used as a shortcut.
.. code-block:: text
deadbeef
0123
Each line uses little-endian order, so this file would produce the bytes "ef be ad de 01 23". ``LOADMEM_ADDR`` specifies which address in memory (in hexadecimal) to write the first byte to. The default is 0x81000000.
A special target that facilitates automatically generating a hex file for an entire elf RISC-V exectuable and then running the simulator with the appropriate flags is also available.
.. code-block:: shell .. code-block:: shell
make run-binary-hex BINARY=test.riscv make run-binary BINARY=test.riscv LOADMEM=1
Generating Waveforms Generating Waveforms
----------------------- -----------------------

View File

@@ -43,7 +43,7 @@ Spike-as-a-Tile can be configured with custom IPC, commit logging, and other beh
.. code-block:: shell .. code-block:: shell
make CONFIG=SpikeUltraFastConfig run-binary-hex BINARY=hello.riscv EXTRA_SPIKE_FLAGS="+spike-ipc=10000 +spike-fast-clint +spike-debug" make CONFIG=SpikeUltraFastConfig run-binary BINARY=hello.riscv EXTRA_SPIKE_FLAGS="+spike-ipc=10000 +spike-fast-clint +spike-debug" LOADMEM=1
* ``+spike-ipc=``: Sets the maximum number of instructions Spike can retire in a single "tick", or cycle of the uncore simulation. * ``+spike-ipc=``: Sets the maximum number of instructions Spike can retire in a single "tick", or cycle of the uncore simulation.

View File

@@ -66,6 +66,12 @@ In the Chipyard root, ensure that you have the Chipyard conda environment activa
to pull and install the plugin submodules. Note that for technologies other than ``sky130`` or ``asap7``, the tech submodule must be added in the ``vlsi`` folder first. to pull and install the plugin submodules. Note that for technologies other than ``sky130`` or ``asap7``, the tech submodule must be added in the ``vlsi`` folder first.
Now navigate to the ``vlsi`` directory. The remainder of the tutorial will assume you are in this directory.
.. code-block:: shell
cd ~chipyard/vlsi
Building the Design Building the Design
-------------------- --------------------
To elaborate the ``TinyRocketConfig`` and set up all prerequisites for the build system to push the design and SRAM macros through the flow: To elaborate the ``TinyRocketConfig`` and set up all prerequisites for the build system to push the design and SRAM macros through the flow:
@@ -115,7 +121,7 @@ Timing reports are found in ``build/par-rundir/timingReports``. They are gzipped
.. code-block:: shell .. code-block:: shell
./view_gds.py build/chipyard.TestHarness.TinyRocketConfig/par-rundir/ChipTop.gds ./view_gds.py build/chipyard.harness.TestHarness.TinyRocketConfig/par-rundir/ChipTop.gds
By default, this script only shows the M2 thru M4 routing. Layers can be toggled in the layout viewer's side pane and ``view_gds.py`` has a mapping of layer numbers to layer names. By default, this script only shows the M2 thru M4 routing. Layers can be toggled in the layout viewer's side pane and ``view_gds.py`` has a mapping of layer numbers to layer names.
@@ -126,9 +132,9 @@ To run DRC & LVS, and view the results in Calibre:
.. code-block:: shell .. code-block:: shell
make drc CONFIG=TinyRocketConfig make drc CONFIG=TinyRocketConfig
./build/chipyard.TestHarness.TinyRocketConfig-ChipTop/drc-rundir/generated-scripts/view-drc ./build/chipyard.harness.TestHarness.TinyRocketConfig-ChipTop/drc-rundir/generated-scripts/view-drc
make lvs CONFIG=TinyRocketConfig make lvs CONFIG=TinyRocketConfig
./build/chipyard.TestHarness.TinyRocketConfig-ChipTop/lvs-rundir/generated-scripts/view-lvs ./build/chipyard.harness.TestHarness.TinyRocketConfig-ChipTop/lvs-rundir/generated-scripts/view-lvs
Some DRC errors are expected from this PDK, as explained in the `ASAP7 plugin readme <https://github.com/ucb-bar/hammer/blob/master/hammer/technology/asap7>`__. Some DRC errors are expected from this PDK, as explained in the `ASAP7 plugin readme <https://github.com/ucb-bar/hammer/blob/master/hammer/technology/asap7>`__.
Furthermore, the dummy SRAMs that are provided in this tutorial and PDK do not have any geometry inside, so will certainly cause DRC errors. Furthermore, the dummy SRAMs that are provided in this tutorial and PDK do not have any geometry inside, so will certainly cause DRC errors.

View File

@@ -106,3 +106,22 @@ With the Synopsys plugin, hierarchical RTL and gate-level simulation is supporte
* ``-$(VLSI_TOP)`` suffixes denote simulations/power analysis on a submodule in a hierarchical flow (remember to override this variable). Note that you must provide the testbenches for these modules since the default testbench only simulates a Chipyard-based ``ChipTop`` DUT instance. * ``-$(VLSI_TOP)`` suffixes denote simulations/power analysis on a submodule in a hierarchical flow (remember to override this variable). Note that you must provide the testbenches for these modules since the default testbench only simulates a Chipyard-based ``ChipTop`` DUT instance.
The simulation configuration (e.g. binaries) can be edited for your design. See the ``Makefile`` and refer to Hammer's documentation for how to set up simulation parameters for your design. The simulation configuration (e.g. binaries) can be edited for your design. See the ``Makefile`` and refer to Hammer's documentation for how to set up simulation parameters for your design.
UPF Generation Flow
-------------------------------
This VLSI flow experimentally supports generating Chisel-based `UPF <https://vlsitutorials.com/upf-low-power-vlsi/>`__ files using `Chisel Aspects <https://javadoc.io/doc/edu.berkeley.cs/chisel3_2.13/latest/chisel3/aop/Aspect.html>`__.
To generate UPF for any design, first modify the ``UPFInputs`` object in ``generators/chipyard/src/main/scala/upf/UPFInputs.scala`` to fit your design power specifications.
This involves filling in the ``upfInfo`` list with ``PowerDomainInput`` objects representing all the power domains you want in your design, along with specifying hierarchy and domain attributes.
The given example in ``UPFInputs`` corresponds to a dual-core Rocket config with 3 power domains (1 parent domain with all uncore modules and 2 children corresponding to the Rocket tiles).
To run the flow:
.. code-block:: shell
cd chipyard/vlsi
make verilog ASPECTS=chipyard.upf.ChipTopUPFAspect
The output UPF files will be dumped in ``vlsi/generated-src/upf``.

View File

@@ -121,7 +121,7 @@ It is recommended that you edit these variables directly in the Makefile rather
The ``buildfile`` make target has dependencies on both (1) the Verilog that is elaborated from all Chisel sources The ``buildfile`` make target has dependencies on both (1) the Verilog that is elaborated from all Chisel sources
and (2) the mapping of memory instances in the design to SRAM macros; and (2) the mapping of memory instances in the design to SRAM macros;
all files related to these two steps reside in the ``generated-src/chipyard.TestHarness.TinyRocketConfig-ChipTop`` directory. all files related to these two steps reside in the ``generated-src/chipyard.harness.TestHarness.TinyRocketConfig-ChipTop`` directory.
Note that the files in ``generated-src`` vary for each tool/technology flow. Note that the files in ``generated-src`` vary for each tool/technology flow.
This especially applies to the Sky130 Commercial vs OpenROAD tutorial flows This especially applies to the Sky130 Commercial vs OpenROAD tutorial flows
(due to the ``ENABLE_YOSYS_FLOW`` flag present for the OpenROAD flow), so these flows should be run in separate (due to the ``ENABLE_YOSYS_FLOW`` flag present for the OpenROAD flow), so these flows should be run in separate
@@ -168,9 +168,9 @@ To run DRC & LVS, and view the results in Calibre:
.. code-block:: shell .. code-block:: shell
make drc tutorial=sky130-commercial make drc tutorial=sky130-commercial
./build/chipyard.TestHarness.TinyRocketConfig-ChipTop/drc-rundir/generated-scripts/view_drc ./build/chipyard.harness.TestHarness.TinyRocketConfig-ChipTop/drc-rundir/generated-scripts/view_drc
make lvs tutorial=sky130-commercial make lvs tutorial=sky130-commercial
./build/chipyard.TestHarness.TinyRocketConfig-ChipTop/lvs-rundir/generated-scripts/view_lvs ./build/chipyard.harness.TestHarness.TinyRocketConfig-ChipTop/lvs-rundir/generated-scripts/view_lvs
Some DRC errors are expected from this PDK, especially with regards to the SRAMs, as explained in the Some DRC errors are expected from this PDK, especially with regards to the SRAMs, as explained in the
`Sky130 Hammer plugin README <https://github.com/ucb-bar/hammer/blob/master/hammer/technology/sky130>`__. `Sky130 Hammer plugin README <https://github.com/ucb-bar/hammer/blob/master/hammer/technology/sky130>`__.

View File

@@ -149,7 +149,7 @@ It is recommended that you edit these variables directly in the Makefile rather
The ``buildfile`` make target has dependencies on both (1) the Verilog that is elaborated from all Chisel sources The ``buildfile`` make target has dependencies on both (1) the Verilog that is elaborated from all Chisel sources
and (2) the mapping of memory instances in the design to SRAM macros; and (2) the mapping of memory instances in the design to SRAM macros;
all files related to these two steps reside in the ``generated-src/chipyard.TestHarness.TinyRocketConfig-ChipTop`` directory. all files related to these two steps reside in the ``generated-src/chipyard.harness.TestHarness.TinyRocketConfig-ChipTop`` directory.
Note that the files in ``generated-src`` vary for each tool/technology flow. Note that the files in ``generated-src`` vary for each tool/technology flow.
This especially applies to the Sky130 Commercial vs OpenROAD tutorial flows This especially applies to the Sky130 Commercial vs OpenROAD tutorial flows
(due to the ``ENABLE_YOSYS_FLOW`` flag, explained below), so these flows should be run in separate (due to the ``ENABLE_YOSYS_FLOW`` flag, explained below), so these flows should be run in separate
@@ -197,7 +197,7 @@ Hammer generates a convenient script to launch these sessions
.. code-block:: shell .. code-block:: shell
cd ./build/chipyard.TestHarness.TinyRocketConfig-ChipTop/par-rundir cd ./build/chipyard.harness.TestHarness.TinyRocketConfig-ChipTop/par-rundir
./generated-scripts/open_chip ./generated-scripts/open_chip
Note that the conda OpenROAD package was compiled with the GUI disabled, so in order to view the layout, Note that the conda OpenROAD package was compiled with the GUI disabled, so in order to view the layout,
@@ -212,7 +212,7 @@ These databases can be restored using the same ``open_chip`` script for debuggin
.. code-block:: shell .. code-block:: shell
cd build/chipyard.TestHarness.TinyRocketConfig-ChipTop/par-rundir cd build/chipyard.harness.TestHarness.TinyRocketConfig-ChipTop/par-rundir
./generated_scripts/open_chip -h ./generated_scripts/open_chip -h
" "
Usage: ./generated-scripts/open_chip [-t] [openroad_db_name] Usage: ./generated-scripts/open_chip [-t] [openroad_db_name]
@@ -245,9 +245,9 @@ To run DRC & LVS in Magic & Netgen, respectively:
.. code-block:: shell .. code-block:: shell
make drc tutorial=sky130-openroad make drc tutorial=sky130-openroad
./build/chipyard.TestHarness.TinyRocketConfig-ChipTop/drc-rundir/generated-scripts/view_drc ./build/chipyard.harness.TestHarness.TinyRocketConfig-ChipTop/drc-rundir/generated-scripts/view_drc
make lvs tutorial=sky130-openroad make lvs tutorial=sky130-openroad
./build/chipyard.TestHarness.TinyRocketConfig-ChipTop/lvs-rundir/generated-scripts/view_lvs ./build/chipyard.harness.TestHarness.TinyRocketConfig-ChipTop/lvs-rundir/generated-scripts/view_lvs
Note that in ``sky130-openroad.yml`` we have set the following YAML keys: Note that in ``sky130-openroad.yml`` we have set the following YAML keys:

View File

@@ -22,7 +22,11 @@ class WithArtyTweaks extends Config(
new WithArtyUARTHarnessBinder ++ new WithArtyUARTHarnessBinder ++
new WithDebugResetPassthrough ++ new WithDebugResetPassthrough ++
new chipyard.config.WithDTSTimebase(32768) ++ new chipyard.harness.WithHarnessBinderClockFreqMHz(32) ++
new chipyard.harness.WithAllClocksFromHarnessClockInstantiator ++
new chipyard.config.WithDTSTimebase(32000) ++
new chipyard.config.WithSystemBusFrequency(32) ++
new chipyard.config.WithPeripheryBusFrequency(32) ++
new testchipip.WithNoSerialTL new testchipip.WithNoSerialTL
) )

View File

@@ -31,7 +31,7 @@ class WithArtyResetHarnessBinder extends ComposeHarnessBinder({
class WithArtyJTAGHarnessBinder extends OverrideHarnessBinder({ class WithArtyJTAGHarnessBinder extends OverrideHarnessBinder({
(system: HasPeripheryDebug, th: ArtyFPGATestHarness, ports: Seq[Data]) => { (system: HasPeripheryDebug, th: ArtyFPGATestHarness, ports: Seq[Data]) => {
ports.map { ports.map {
case j: JTAGChipIO => withClockAndReset(th.buildtopClock, th.hReset) { case j: JTAGChipIO => {
val jtag_wire = Wire(new JTAGIO) val jtag_wire = Wire(new JTAGIO)
jtag_wire.TDO.data := j.TDO jtag_wire.TDO.data := j.TDO
jtag_wire.TDO.driven := true.B jtag_wire.TDO.driven := true.B

View File

@@ -3,18 +3,15 @@ package chipyard.fpga.arty
import chisel3._ import chisel3._
import freechips.rocketchip.diplomacy.{LazyModule} import freechips.rocketchip.diplomacy.{LazyModule}
import freechips.rocketchip.prci.{ClockBundle, ClockBundleParameters}
import org.chipsalliance.cde.config.{Parameters} import org.chipsalliance.cde.config.{Parameters}
import sifive.fpgashells.shell.xilinx.artyshell.{ArtyShell} import sifive.fpgashells.shell.xilinx.artyshell.{ArtyShell}
import chipyard.{BuildTop, HasHarnessSignalReferences} import chipyard.harness.{HasHarnessInstantiators}
import chipyard.harness.{ApplyHarnessBinders}
import chipyard.iobinders.{HasIOBinders} import chipyard.iobinders.{HasIOBinders}
class ArtyFPGATestHarness(override implicit val p: Parameters) extends ArtyShell with HasHarnessSignalReferences { class ArtyFPGATestHarness(override implicit val p: Parameters) extends ArtyShell with HasHarnessInstantiators {
val lazyDut = LazyModule(p(BuildTop)(p)).suggestName("chiptop")
// Convert harness resets from Bool to Reset type. // Convert harness resets from Bool to Reset type.
val hReset = Wire(Reset()) val hReset = Wire(Reset())
hReset := ~ck_rst hReset := ~ck_rst
@@ -22,19 +19,11 @@ class ArtyFPGATestHarness(override implicit val p: Parameters) extends ArtyShell
val dReset = Wire(AsyncReset()) val dReset = Wire(AsyncReset())
dReset := reset_core.asAsyncReset dReset := reset_core.asAsyncReset
// default to 32MHz clock def success = {require(false, "Success not supported"); false.B }
withClockAndReset(clock_32MHz, hReset) {
val dut = Module(lazyDut.module)
}
val buildtopClock = clock_32MHz def referenceClockFreqMHz = 32.0
val buildtopReset = hReset def referenceClock = clock_32MHz
val success = false.B def referenceReset = hReset
val dutReset = dReset instantiateChipTops()
// must be after HasHarnessSignalReferences assignments
lazyDut match { case d: HasIOBinders =>
ApplyHarnessBinders(this, d.lazySystem, d.portMap)
}
} }

View File

@@ -25,6 +25,15 @@ class WithArty100TTweaks extends Config(
new WithArty100TUARTTSI ++ new WithArty100TUARTTSI ++
new WithArty100TDDRTL ++ new WithArty100TDDRTL ++
new WithNoDesignKey ++ new WithNoDesignKey ++
new testchipip.WithUARTTSIClient ++
new chipyard.harness.WithSerialTLTiedOff ++
new chipyard.harness.WithHarnessBinderClockFreqMHz(50) ++
new chipyard.config.WithMemoryBusFrequency(50.0) ++
new chipyard.config.WithFrontBusFrequency(50.0) ++
new chipyard.config.WithSystemBusFrequency(50.0) ++
new chipyard.config.WithPeripheryBusFrequency(50.0) ++
new chipyard.harness.WithAllClocksFromHarnessClockInstantiator ++
new chipyard.clocking.WithPassthroughClockGenerator ++
new chipyard.config.WithNoDebug ++ // no jtag new chipyard.config.WithNoDebug ++ // no jtag
new chipyard.config.WithNoUART ++ // use UART for the UART-TSI thing instad new chipyard.config.WithNoUART ++ // use UART for the UART-TSI thing instad
new chipyard.config.WithTLBackingMemory ++ // FPGA-shells converts the AXI to TL for us new chipyard.config.WithTLBackingMemory ++ // FPGA-shells converts the AXI to TL for us
@@ -33,8 +42,6 @@ class WithArty100TTweaks extends Config(
class RocketArty100TConfig extends Config( class RocketArty100TConfig extends Config(
new WithArty100TTweaks ++ new WithArty100TTweaks ++
new chipyard.config.WithMemoryBusFrequency(50.0) ++
new chipyard.config.WithPeripheryBusFrequency(50.0) ++ // Match the sbus and pbus frequency
new chipyard.config.WithBroadcastManager ++ // no l2 new chipyard.config.WithBroadcastManager ++ // no l2
new chipyard.RocketConfig) new chipyard.RocketConfig)

View File

@@ -4,7 +4,9 @@ import chisel3._
import chisel3.util._ import chisel3.util._
import freechips.rocketchip.diplomacy._ import freechips.rocketchip.diplomacy._
import org.chipsalliance.cde.config.{Parameters} import org.chipsalliance.cde.config.{Parameters}
import freechips.rocketchip.tilelink.{TLClientNode, TLBlockDuringReset} import freechips.rocketchip.tilelink._
import freechips.rocketchip.prci.{ClockBundle, ClockBundleParameters}
import freechips.rocketchip.subsystem.{SystemBusKey}
import sifive.fpgashells.shell.xilinx._ import sifive.fpgashells.shell.xilinx._
import sifive.fpgashells.shell._ import sifive.fpgashells.shell._
@@ -14,20 +16,18 @@ import sifive.fpgashells.ip.xilinx.{IBUF, PowerOnResetFPGAOnly}
import sifive.blocks.devices.uart._ import sifive.blocks.devices.uart._
import chipyard._ import chipyard._
import chipyard.harness.{ApplyHarnessBinders} import chipyard.harness._
import chipyard.iobinders.{HasIOBinders} import chipyard.iobinders.{HasIOBinders}
class Arty100THarness(override implicit val p: Parameters) extends Arty100TShell with HasHarnessSignalReferences class Arty100THarness(override implicit val p: Parameters) extends Arty100TShell {
{
def dp = designParameters def dp = designParameters
val chiptop = LazyModule(p(BuildTop)(p))
val clockOverlay = dp(ClockInputOverlayKey).map(_.place(ClockInputDesignInput())).head val clockOverlay = dp(ClockInputOverlayKey).map(_.place(ClockInputDesignInput())).head
val harnessSysPLL = dp(PLLFactoryKey) val harnessSysPLL = dp(PLLFactoryKey)
val harnessSysPLLNode = harnessSysPLL() val harnessSysPLLNode = harnessSysPLL()
println(s"Arty100T FPGA Base Clock Freq: ${dp(DefaultClockFrequencyKey)} MHz") val dutFreqMHz = (dp(SystemBusKey).dtsFrequency.get / (1000 * 1000)).toInt
val dutClock = ClockSinkNode(freqMHz = dp(DefaultClockFrequencyKey)) val dutClock = ClockSinkNode(freqMHz = dutFreqMHz)
println(s"Arty100T FPGA Base Clock Freq: ${dutFreqMHz} MHz")
val dutWrangler = LazyModule(new ResetWrangler()) val dutWrangler = LazyModule(new ResetWrangler())
val dutGroup = ClockGroup() val dutGroup = ClockGroup()
dutClock := dutWrangler.node := dutGroup := harnessSysPLLNode dutClock := dutWrangler.node := dutGroup := harnessSysPLLNode
@@ -38,12 +38,10 @@ class Arty100THarness(override implicit val p: Parameters) extends Arty100TShell
val uartOverlay = dp(UARTOverlayKey).head.place(UARTDesignInput(io_uart_bb)) val uartOverlay = dp(UARTOverlayKey).head.place(UARTDesignInput(io_uart_bb))
val ddrOverlay = dp(DDROverlayKey).head.place(DDRDesignInput(dp(ExtTLMem).get.master.base, dutWrangler.node, harnessSysPLLNode)).asInstanceOf[DDRArtyPlacedOverlay] val ddrOverlay = dp(DDROverlayKey).head.place(DDRDesignInput(dp(ExtTLMem).get.master.base, dutWrangler.node, harnessSysPLLNode)).asInstanceOf[DDRArtyPlacedOverlay]
val ddrInParams = chiptop match { case td: ChipTop => val ddrClient = TLClientNode(Seq(TLMasterPortParameters.v1(Seq(TLMasterParameters.v1(
td.lazySystem match { case lsys: CanHaveMasterTLMemPort => name = "chip_ddr",
lsys.memTLNode.edges.in(0) sourceId = IdRange(0, 1 << dp(ExtTLMem).get.master.idBits)
} )))))
}
val ddrClient = TLClientNode(Seq(ddrInParams.master))
val ddrBlockDuringReset = LazyModule(new TLBlockDuringReset(4)) val ddrBlockDuringReset = LazyModule(new TLBlockDuringReset(4))
ddrOverlay.overlayOutput.ddr := ddrBlockDuringReset.node := ddrClient ddrOverlay.overlayOutput.ddr := ddrBlockDuringReset.node := ddrClient
@@ -52,17 +50,16 @@ class Arty100THarness(override implicit val p: Parameters) extends Arty100TShell
val status_leds = all_leds.take(3) val status_leds = all_leds.take(3)
val other_leds = all_leds.drop(3) val other_leds = all_leds.drop(3)
def buildtopClock = dutClock.in.head._1.clock
def buildtopReset = dutClock.in.head._1.reset
def success = { require(false, "Unused"); false.B }
InModuleBody { override lazy val module = new HarnessLikeImpl
class HarnessLikeImpl extends Impl with HasHarnessInstantiators {
clockOverlay.overlayOutput.node.out(0)._1.reset := ~resetPin clockOverlay.overlayOutput.node.out(0)._1.reset := ~resetPin
val clk_100mhz = clockOverlay.overlayOutput.node.out.head._1.clock val clk_100mhz = clockOverlay.overlayOutput.node.out.head._1.clock
// Blink the status LEDs for sanity // Blink the status LEDs for sanity
withClock(clk_100mhz) { withClockAndReset(clk_100mhz, dutClock.in.head._1.reset) {
val period = (BigInt(100) << 20) / status_leds.size val period = (BigInt(100) << 20) / status_leds.size
val counter = RegInit(0.U(log2Ceil(period).W)) val counter = RegInit(0.U(log2Ceil(period).W))
val on = RegInit(0.U(log2Ceil(status_leds.size).W)) val on = RegInit(0.U(log2Ceil(status_leds.size).W))
@@ -77,16 +74,18 @@ class Arty100THarness(override implicit val p: Parameters) extends Arty100TShell
harnessSysPLL.plls.foreach(_._1.getReset.get := pllReset) harnessSysPLL.plls.foreach(_._1.getReset.get := pllReset)
ddrOverlay.mig.module.clock := buildtopClock def referenceClockFreqMHz = dutFreqMHz
ddrOverlay.mig.module.reset := buildtopReset def referenceClock = dutClock.in.head._1.clock
ddrBlockDuringReset.module.clock := buildtopClock def referenceReset = dutClock.in.head._1.reset
ddrBlockDuringReset.module.reset := buildtopReset || !ddrOverlay.mig.module.io.port.init_calib_complete def success = { require(false, "Unused"); false.B }
ddrOverlay.mig.module.clock := harnessBinderClock
ddrOverlay.mig.module.reset := harnessBinderReset
ddrBlockDuringReset.module.clock := harnessBinderClock
ddrBlockDuringReset.module.reset := harnessBinderReset.asBool || !ddrOverlay.mig.module.io.port.init_calib_complete
other_leds(6) := ddrOverlay.mig.module.io.port.init_calib_complete other_leds(6) := ddrOverlay.mig.module.io.port.init_calib_complete
chiptop match { case d: HasIOBinders => instantiateChipTops()
ApplyHarnessBinders(this, d.lazySystem, d.portMap)
}
} }
} }

View File

@@ -6,6 +6,7 @@ import freechips.rocketchip.jtag.{JTAGIO}
import freechips.rocketchip.subsystem.{PeripheryBusKey} import freechips.rocketchip.subsystem.{PeripheryBusKey}
import freechips.rocketchip.tilelink.{TLBundle} import freechips.rocketchip.tilelink.{TLBundle}
import freechips.rocketchip.util.{HeterogeneousBag} import freechips.rocketchip.util.{HeterogeneousBag}
import freechips.rocketchip.diplomacy.{LazyRawModuleImp}
import sifive.blocks.devices.uart.{UARTPortIO, HasPeripheryUARTModuleImp, UARTParams} import sifive.blocks.devices.uart.{UARTPortIO, HasPeripheryUARTModuleImp, UARTParams}
import sifive.blocks.devices.jtag.{JTAGPins, JTAGPinsFromPort} import sifive.blocks.devices.jtag.{JTAGPins, JTAGPinsFromPort}
@@ -20,38 +21,25 @@ import chipyard.iobinders.JTAGChipIO
import testchipip._ import testchipip._
class WithArty100TUARTTSI(uartBaudRate: BigInt = 115200) extends OverrideHarnessBinder({ class WithArty100TUARTTSI(uartBaudRate: BigInt = 115200) extends OverrideHarnessBinder({
(system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { (system: CanHavePeripheryUARTTSI, th: HasHarnessInstantiators, ports: Seq[UARTTSIIO]) => {
implicit val p = chipyard.iobinders.GetSystemParameters(system) implicit val p = chipyard.iobinders.GetSystemParameters(system)
require(ports.size <= 1)
val ath = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[Arty100THarness]
ports.map({ port => ports.map({ port =>
val ath = th.asInstanceOf[Arty100THarness] ath.io_uart_bb.bundle <> port.uart
val freq = p(PeripheryBusKey).dtsFrequency.get ath.other_leds(1) := port.dropped
val bits = SerialAdapter.asyncQueue(port, th.buildtopClock, th.buildtopReset) ath.other_leds(9) := port.tsi2tl_state(0)
withClockAndReset(th.buildtopClock, th.buildtopReset) { ath.other_leds(10) := port.tsi2tl_state(1)
val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, bits, th.buildtopReset) ath.other_leds(11) := port.tsi2tl_state(2)
val uart_to_serial = Module(new UARTToSerial( ath.other_leds(12) := port.tsi2tl_state(3)
freq, UARTParams(0, initBaudRate=uartBaudRate)))
val serial_width_adapter = Module(new SerialWidthAdapter(
narrowW = 8, wideW = SerialAdapter.SERIAL_TSI_WIDTH))
serial_width_adapter.io.narrow.flipConnect(uart_to_serial.io.serial)
ram.module.io.tsi_ser.flipConnect(serial_width_adapter.io.wide)
ath.io_uart_bb.bundle <> uart_to_serial.io.uart
ath.other_leds(1) := uart_to_serial.io.dropped
ath.other_leds(9) := ram.module.io.adapter_state(0)
ath.other_leds(10) := ram.module.io.adapter_state(1)
ath.other_leds(11) := ram.module.io.adapter_state(2)
ath.other_leds(12) := ram.module.io.adapter_state(3)
}
}) })
} }
}) })
class WithArty100TDDRTL extends OverrideHarnessBinder({ class WithArty100TDDRTL extends OverrideHarnessBinder({
(system: CanHaveMasterTLMemPort, th: HasHarnessSignalReferences, ports: Seq[HeterogeneousBag[TLBundle]]) => { (system: CanHaveMasterTLMemPort, th: HasHarnessInstantiators, ports: Seq[HeterogeneousBag[TLBundle]]) => {
require(ports.size == 1) require(ports.size == 1)
val artyTh = th.asInstanceOf[Arty100THarness] val artyTh = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[Arty100THarness]
val bundles = artyTh.ddrClient.out.map(_._1) val bundles = artyTh.ddrClient.out.map(_._1)
val ddrClientBundle = Wire(new HeterogeneousBag(bundles.map(_.cloneType))) val ddrClientBundle = Wire(new HeterogeneousBag(bundles.map(_.cloneType)))
bundles.zip(ddrClientBundle).foreach { case (bundle, io) => bundle <> io } bundles.zip(ddrClientBundle).foreach { case (bundle, io) => bundle <> io }

View File

@@ -17,7 +17,8 @@ import sifive.fpgashells.shell.xilinx.{VC7074GDDRSize}
import testchipip.{SerialTLKey} import testchipip.{SerialTLKey}
import chipyard.{BuildSystem, ExtTLMem, DefaultClockFrequencyKey} import chipyard.{BuildSystem, ExtTLMem}
import chipyard.harness._
class WithDefaultPeripherals extends Config((site, here, up) => { class WithDefaultPeripherals extends Config((site, here, up) => {
case PeripheryUARTKey => List(UARTParams(address = BigInt(0x64000000L))) case PeripheryUARTKey => List(UARTParams(address = BigInt(0x64000000L)))
@@ -28,7 +29,7 @@ class WithSystemModifications extends Config((site, here, up) => {
case DTSTimebase => BigInt{(1e6).toLong} case DTSTimebase => BigInt{(1e6).toLong}
case BootROMLocated(x) => up(BootROMLocated(x), site).map { p => case BootROMLocated(x) => up(BootROMLocated(x), site).map { p =>
// invoke makefile for sdboot // invoke makefile for sdboot
val freqMHz = (site(DefaultClockFrequencyKey) * 1e6).toLong val freqMHz = (site(SystemBusKey).dtsFrequency.get / (1000 * 1000)).toLong
val make = s"make -C fpga/src/main/resources/vc707/sdboot PBUS_CLK=${freqMHz} bin" val make = s"make -C fpga/src/main/resources/vc707/sdboot PBUS_CLK=${freqMHz} bin"
require (make.! == 0, "Failed to build bootrom") require (make.! == 0, "Failed to build bootrom")
p.copy(hang = 0x10000, contentFileName = s"./fpga/src/main/resources/vc707/sdboot/build/sdboot.bin") p.copy(hang = 0x10000, contentFileName = s"./fpga/src/main/resources/vc707/sdboot/build/sdboot.bin")
@@ -38,7 +39,17 @@ class WithSystemModifications extends Config((site, here, up) => {
}) })
class WithVC707Tweaks extends Config ( class WithVC707Tweaks extends Config (
// clocking
new chipyard.harness.WithAllClocksFromHarnessClockInstantiator ++
new chipyard.clocking.WithPassthroughClockGenerator ++
new chipyard.config.WithMemoryBusFrequency(50.0) ++
new chipyard.config.WithSystemBusFrequency(50.0) ++
new chipyard.config.WithPeripheryBusFrequency(50.0) ++
new chipyard.harness.WithHarnessBinderClockFreqMHz(50) ++
new WithFPGAFrequency(50) ++ // default 50MHz freq
// harness binders // harness binders
new chipyard.harness.WithAllClocksFromHarnessClockInstantiator ++
new WithVC707UARTHarnessBinder ++ new WithVC707UARTHarnessBinder ++
new WithVC707SPISDCardHarnessBinder ++ new WithVC707SPISDCardHarnessBinder ++
new WithVC707DDRMemHarnessBinder ++ new WithVC707DDRMemHarnessBinder ++
@@ -52,8 +63,7 @@ class WithVC707Tweaks extends Config (
new WithSystemModifications ++ // setup busses, use sdboot bootrom, setup ext. mem. size new WithSystemModifications ++ // setup busses, use sdboot bootrom, setup ext. mem. size
new chipyard.config.WithNoDebug ++ // remove debug module new chipyard.config.WithNoDebug ++ // remove debug module
new freechips.rocketchip.subsystem.WithoutTLMonitors ++ new freechips.rocketchip.subsystem.WithoutTLMonitors ++
new freechips.rocketchip.subsystem.WithNMemoryChannels(1) ++ new freechips.rocketchip.subsystem.WithNMemoryChannels(1)
new WithFPGAFrequency(50) // default 50MHz freq
) )
class RocketVC707Config extends Config ( class RocketVC707Config extends Config (

View File

@@ -1,24 +1,25 @@
package chipyard.fpga.vc707 package chipyard.fpga.vc707
import chisel3._ import chisel3._
import chisel3.experimental.{IO} import chisel3.experimental.{IO}
import freechips.rocketchip.diplomacy.{LazyModule, LazyRawModuleImp, BundleBridgeSource} import freechips.rocketchip.diplomacy.{LazyModule, LazyRawModuleImp, BundleBridgeSource}
import org.chipsalliance.cde.config.{Parameters} import org.chipsalliance.cde.config.{Parameters}
import freechips.rocketchip.tilelink.{TLClientNode} import freechips.rocketchip.tilelink._
import freechips.rocketchip.subsystem.{SystemBusKey}
import freechips.rocketchip.diplomacy.{IdRange, TransferSizes}
import sifive.fpgashells.shell.xilinx.{VC707Shell, UARTVC707ShellPlacer, PCIeVC707ShellPlacer, ChipLinkVC707PlacedOverlay} import sifive.fpgashells.shell.xilinx.{VC707Shell, UARTVC707ShellPlacer, PCIeVC707ShellPlacer, ChipLinkVC707PlacedOverlay}
import sifive.fpgashells.ip.xilinx.{IBUF, PowerOnResetFPGAOnly} import sifive.fpgashells.ip.xilinx.{IBUF, PowerOnResetFPGAOnly}
import sifive.fpgashells.shell.{ClockInputOverlayKey, ClockInputDesignInput, UARTOverlayKey, UARTDesignInput, UARTShellInput, LEDOverlayKey, LEDDesignInput, SwitchOverlayKey, SwitchDesignInput, ButtonOverlayKey, ButtonDesignInput, SPIOverlayKey, SPIDesignInput, ChipLinkOverlayKey, ChipLinkDesignInput, PCIeOverlayKey, PCIeDesignInput, PCIeShellInput, DDROverlayKey, DDRDesignInput, JTAGDebugOverlayKey, JTAGDebugDesignInput} import sifive.fpgashells.shell._
import sifive.fpgashells.clocks.{ClockGroup, ClockSinkNode, PLLFactoryKey, ResetWrangler} import sifive.fpgashells.clocks.{ClockGroup, ClockSinkNode, PLLFactoryKey, ResetWrangler}
import sifive.fpgashells.devices.xilinx.xilinxvc707pciex1.{XilinxVC707PCIeX1IO} import sifive.fpgashells.devices.xilinx.xilinxvc707pciex1.{XilinxVC707PCIeX1IO}
import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTPortIO} import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTPortIO}
import sifive.blocks.devices.spi.{PeripherySPIKey, SPIPortIO} import sifive.blocks.devices.spi.{PeripherySPIKey, SPIPortIO}
import chipyard.{HasHarnessSignalReferences, BuildTop, ChipTop, ExtTLMem, CanHaveMasterTLMemPort, DefaultClockFrequencyKey} import chipyard._
import chipyard.iobinders.{HasIOBinders} import chipyard.iobinders.{HasIOBinders}
import chipyard.harness.{ApplyHarnessBinders} import chipyard.harness._
class VC707FPGATestHarness(override implicit val p: Parameters) extends VC707Shell { outer => class VC707FPGATestHarness(override implicit val p: Parameters) extends VC707Shell { outer =>
@@ -27,8 +28,6 @@ class VC707FPGATestHarness(override implicit val p: Parameters) extends VC707She
// Order matters; ddr depends on sys_clock // Order matters; ddr depends on sys_clock
val uart = Overlay(UARTOverlayKey, new UARTVC707ShellPlacer(this, UARTShellInput())) val uart = Overlay(UARTOverlayKey, new UARTVC707ShellPlacer(this, UARTShellInput()))
val topDesign = LazyModule(p(BuildTop)(dp)).suggestName("chiptop")
// place all clocks in the shell // place all clocks in the shell
require(dp(ClockInputOverlayKey).size >= 1) require(dp(ClockInputOverlayKey).size >= 1)
val sysClkNode = dp(ClockInputOverlayKey).head.place(ClockInputDesignInput()).overlayOutput.node val sysClkNode = dp(ClockInputOverlayKey).head.place(ClockInputDesignInput()).overlayOutput.node
@@ -40,8 +39,9 @@ class VC707FPGATestHarness(override implicit val p: Parameters) extends VC707She
harnessSysPLL := sysClkNode harnessSysPLL := sysClkNode
// create and connect to the dutClock // create and connect to the dutClock
println(s"VC707 FPGA Base Clock Freq: ${dp(DefaultClockFrequencyKey)} MHz") val dutFreqMHz = (dp(SystemBusKey).dtsFrequency.get / (1000 * 1000)).toInt
val dutClock = ClockSinkNode(freqMHz = dp(DefaultClockFrequencyKey)) val dutClock = ClockSinkNode(freqMHz = dutFreqMHz)
println(s"VC707 FPGA Base Clock Freq: ${dutFreqMHz} MHz")
val dutWrangler = LazyModule(new ResetWrangler) val dutWrangler = LazyModule(new ResetWrangler)
val dutGroup = ClockGroup() val dutGroup = ClockGroup()
dutClock := dutWrangler.node := dutGroup := harnessSysPLL dutClock := dutWrangler.node := dutGroup := harnessSysPLL
@@ -76,22 +76,18 @@ class VC707FPGATestHarness(override implicit val p: Parameters) extends VC707She
// Modify the last field of `DDRDesignInput` for 1GB RAM size // Modify the last field of `DDRDesignInput` for 1GB RAM size
val ddrNode = dp(DDROverlayKey).head.place(DDRDesignInput(dp(ExtTLMem).get.master.base, dutWrangler.node, harnessSysPLL, true)).overlayOutput.ddr val ddrNode = dp(DDROverlayKey).head.place(DDRDesignInput(dp(ExtTLMem).get.master.base, dutWrangler.node, harnessSysPLL, true)).overlayOutput.ddr
val ddrClient = TLClientNode(Seq(TLMasterPortParameters.v1(Seq(TLMasterParameters.v1(
name = "chip_ddr",
sourceId = IdRange(0, 1 << dp(ExtTLMem).get.master.idBits)
)))))
// connect 1 mem. channel to the FPGA DDR
val inParams = topDesign match { case td: ChipTop =>
td.lazySystem match { case lsys: CanHaveMasterTLMemPort =>
lsys.memTLNode.edges.in(0)
}
}
val ddrClient = TLClientNode(Seq(inParams.master))
ddrNode := ddrClient ddrNode := ddrClient
// module implementation // module implementation
override lazy val module = new VC707FPGATestHarnessImp(this) override lazy val module = new VC707FPGATestHarnessImp(this)
} }
class VC707FPGATestHarnessImp(_outer: VC707FPGATestHarness) extends LazyRawModuleImp(_outer) with HasHarnessSignalReferences { class VC707FPGATestHarnessImp(_outer: VC707FPGATestHarness) extends LazyRawModuleImp(_outer) with HasHarnessInstantiators {
val vc707Outer = _outer val vc707Outer = _outer
val reset = IO(Input(Bool())) val reset = IO(Input(Bool()))
@@ -116,20 +112,13 @@ class VC707FPGATestHarnessImp(_outer: VC707FPGATestHarness) extends LazyRawModul
val hReset = Wire(Reset()) val hReset = Wire(Reset())
hReset := _outer.dutClock.in.head._1.reset hReset := _outer.dutClock.in.head._1.reset
val buildtopClock = _outer.dutClock.in.head._1.clock def referenceClockFreqMHz = _outer.dutFreqMHz
val buildtopReset = WireInit(hReset) def referenceClock = _outer.dutClock.in.head._1.clock
val dutReset = hReset.asAsyncReset def referenceReset = hReset
val success = false.B def success = { require(false, "Unused"); false.B }
childClock := buildtopClock childClock := referenceClock
childReset := buildtopReset childReset := referenceReset
// harness binders are non-lazy instantiateChipTops()
_outer.topDesign match { case d: HasIOBinders =>
ApplyHarnessBinders(this, d.lazySystem, d.portMap)
}
// check the top-level reference clock is equal to the default
// non-exhaustive since you need all ChipTop clocks to equal the default
require(getRefClockFreq == p(DefaultClockFrequencyKey))
} }

View File

@@ -17,7 +17,8 @@ import sifive.fpgashells.shell.xilinx.{VCU118ShellPMOD, VCU118DDRSize}
import testchipip.{SerialTLKey} import testchipip.{SerialTLKey}
import chipyard.{BuildSystem, ExtTLMem, DefaultClockFrequencyKey} import chipyard._
import chipyard.harness._
class WithDefaultPeripherals extends Config((site, here, up) => { class WithDefaultPeripherals extends Config((site, here, up) => {
case PeripheryUARTKey => List(UARTParams(address = BigInt(0x64000000L))) case PeripheryUARTKey => List(UARTParams(address = BigInt(0x64000000L)))
@@ -29,7 +30,7 @@ class WithSystemModifications extends Config((site, here, up) => {
case DTSTimebase => BigInt((1e6).toLong) case DTSTimebase => BigInt((1e6).toLong)
case BootROMLocated(x) => up(BootROMLocated(x), site).map { p => case BootROMLocated(x) => up(BootROMLocated(x), site).map { p =>
// invoke makefile for sdboot // invoke makefile for sdboot
val freqMHz = (site(DefaultClockFrequencyKey) * 1e6).toLong val freqMHz = (site(SystemBusKey).dtsFrequency.get / (1000 * 1000)).toLong
val make = s"make -C fpga/src/main/resources/vcu118/sdboot PBUS_CLK=${freqMHz} bin" val make = s"make -C fpga/src/main/resources/vcu118/sdboot PBUS_CLK=${freqMHz} bin"
require (make.! == 0, "Failed to build bootrom") require (make.! == 0, "Failed to build bootrom")
p.copy(hang = 0x10000, contentFileName = s"./fpga/src/main/resources/vcu118/sdboot/build/sdboot.bin") p.copy(hang = 0x10000, contentFileName = s"./fpga/src/main/resources/vcu118/sdboot/build/sdboot.bin")
@@ -40,6 +41,13 @@ class WithSystemModifications extends Config((site, here, up) => {
// DOC include start: AbstractVCU118 and Rocket // DOC include start: AbstractVCU118 and Rocket
class WithVCU118Tweaks extends Config( class WithVCU118Tweaks extends Config(
// clocking
new chipyard.harness.WithAllClocksFromHarnessClockInstantiator ++
new chipyard.clocking.WithPassthroughClockGenerator ++
new chipyard.config.WithMemoryBusFrequency(100) ++
new chipyard.config.WithSystemBusFrequency(100) ++
new chipyard.config.WithPeripheryBusFrequency(100) ++
new WithFPGAFrequency(100) ++ // default 100MHz freq
// harness binders // harness binders
new WithUART ++ new WithUART ++
new WithSPISDCard ++ new WithSPISDCard ++
@@ -53,8 +61,7 @@ class WithVCU118Tweaks extends Config(
new WithSystemModifications ++ // setup busses, use sdboot bootrom, setup ext. mem. size new WithSystemModifications ++ // setup busses, use sdboot bootrom, setup ext. mem. size
new chipyard.config.WithNoDebug ++ // remove debug module new chipyard.config.WithNoDebug ++ // remove debug module
new freechips.rocketchip.subsystem.WithoutTLMonitors ++ new freechips.rocketchip.subsystem.WithoutTLMonitors ++
new freechips.rocketchip.subsystem.WithNMemoryChannels(1) ++ new freechips.rocketchip.subsystem.WithNMemoryChannels(1)
new WithFPGAFrequency(100) // default 100MHz freq
) )
class RocketVCU118Config extends Config( class RocketVCU118Config extends Config(

View File

@@ -9,12 +9,12 @@ import freechips.rocketchip.tilelink.{TLBundle}
import sifive.blocks.devices.uart.{HasPeripheryUARTModuleImp, UARTPortIO} import sifive.blocks.devices.uart.{HasPeripheryUARTModuleImp, UARTPortIO}
import sifive.blocks.devices.spi.{HasPeripherySPI, SPIPortIO} import sifive.blocks.devices.spi.{HasPeripherySPI, SPIPortIO}
import chipyard.{HasHarnessSignalReferences, CanHaveMasterTLMemPort} import chipyard._
import chipyard.harness.{OverrideHarnessBinder} import chipyard.harness._
/*** UART ***/ /*** UART ***/
class WithUART extends OverrideHarnessBinder({ class WithUART extends OverrideHarnessBinder({
(system: HasPeripheryUARTModuleImp, th: BaseModule with HasHarnessSignalReferences, ports: Seq[UARTPortIO]) => { (system: HasPeripheryUARTModuleImp, th: BaseModule with HasHarnessInstantiators, ports: Seq[UARTPortIO]) => {
th match { case vcu118th: VCU118FPGATestHarnessImp => { th match { case vcu118th: VCU118FPGATestHarnessImp => {
vcu118th.vcu118Outer.io_uart_bb.bundle <> ports.head vcu118th.vcu118Outer.io_uart_bb.bundle <> ports.head
} } } }
@@ -23,7 +23,7 @@ class WithUART extends OverrideHarnessBinder({
/*** SPI ***/ /*** SPI ***/
class WithSPISDCard extends OverrideHarnessBinder({ class WithSPISDCard extends OverrideHarnessBinder({
(system: HasPeripherySPI, th: BaseModule with HasHarnessSignalReferences, ports: Seq[SPIPortIO]) => { (system: HasPeripherySPI, th: BaseModule with HasHarnessInstantiators, ports: Seq[SPIPortIO]) => {
th match { case vcu118th: VCU118FPGATestHarnessImp => { th match { case vcu118th: VCU118FPGATestHarnessImp => {
vcu118th.vcu118Outer.io_spi_bb.bundle <> ports.head vcu118th.vcu118Outer.io_spi_bb.bundle <> ports.head
} } } }
@@ -32,7 +32,7 @@ class WithSPISDCard extends OverrideHarnessBinder({
/*** Experimental DDR ***/ /*** Experimental DDR ***/
class WithDDRMem extends OverrideHarnessBinder({ class WithDDRMem extends OverrideHarnessBinder({
(system: CanHaveMasterTLMemPort, th: BaseModule with HasHarnessSignalReferences, ports: Seq[HeterogeneousBag[TLBundle]]) => { (system: CanHaveMasterTLMemPort, th: BaseModule with HasHarnessInstantiators, ports: Seq[HeterogeneousBag[TLBundle]]) => {
th match { case vcu118th: VCU118FPGATestHarnessImp => { th match { case vcu118th: VCU118FPGATestHarnessImp => {
require(ports.size == 1) require(ports.size == 1)

View File

@@ -5,7 +5,9 @@ import chisel3.experimental.{IO}
import freechips.rocketchip.diplomacy.{LazyModule, LazyRawModuleImp, BundleBridgeSource} import freechips.rocketchip.diplomacy.{LazyModule, LazyRawModuleImp, BundleBridgeSource}
import org.chipsalliance.cde.config.{Parameters} import org.chipsalliance.cde.config.{Parameters}
import freechips.rocketchip.tilelink.{TLClientNode} import freechips.rocketchip.tilelink._
import freechips.rocketchip.diplomacy.{IdRange, TransferSizes}
import freechips.rocketchip.subsystem.{SystemBusKey}
import sifive.fpgashells.shell.xilinx._ import sifive.fpgashells.shell.xilinx._
import sifive.fpgashells.ip.xilinx.{IBUF, PowerOnResetFPGAOnly} import sifive.fpgashells.ip.xilinx.{IBUF, PowerOnResetFPGAOnly}
@@ -17,7 +19,7 @@ import sifive.blocks.devices.spi.{PeripherySPIKey, SPIPortIO}
import chipyard._ import chipyard._
import chipyard.iobinders.{HasIOBinders} import chipyard.iobinders.{HasIOBinders}
import chipyard.harness.{ApplyHarnessBinders} import chipyard.harness._
class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118ShellBasicOverlays { class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118ShellBasicOverlays {
@@ -37,8 +39,6 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118S
val sys_clock2 = Overlay(ClockInputOverlayKey, new SysClock2VCU118ShellPlacer(this, ClockInputShellInput())) val sys_clock2 = Overlay(ClockInputOverlayKey, new SysClock2VCU118ShellPlacer(this, ClockInputShellInput()))
val ddr2 = Overlay(DDROverlayKey, new DDR2VCU118ShellPlacer(this, DDRShellInput())) val ddr2 = Overlay(DDROverlayKey, new DDR2VCU118ShellPlacer(this, DDRShellInput()))
val topDesign = LazyModule(p(BuildTop)(dp)).suggestName("chiptop")
// DOC include start: ClockOverlay // DOC include start: ClockOverlay
// place all clocks in the shell // place all clocks in the shell
require(dp(ClockInputOverlayKey).size >= 1) require(dp(ClockInputOverlayKey).size >= 1)
@@ -51,8 +51,9 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118S
harnessSysPLL := sysClkNode harnessSysPLL := sysClkNode
// create and connect to the dutClock // create and connect to the dutClock
println(s"VCU118 FPGA Base Clock Freq: ${dp(DefaultClockFrequencyKey)} MHz") val dutFreqMHz = (dp(SystemBusKey).dtsFrequency.get / (1000 * 1000)).toInt
val dutClock = ClockSinkNode(freqMHz = dp(DefaultClockFrequencyKey)) val dutClock = ClockSinkNode(freqMHz = dutFreqMHz)
println(s"VCU118 FPGA Base Clock Freq: ${dutFreqMHz} MHz")
val dutWrangler = LazyModule(new ResetWrangler) val dutWrangler = LazyModule(new ResetWrangler)
val dutGroup = ClockGroup() val dutGroup = ClockGroup()
dutClock := dutWrangler.node := dutGroup := harnessSysPLL dutClock := dutWrangler.node := dutGroup := harnessSysPLL
@@ -79,20 +80,17 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118S
val ddrNode = dp(DDROverlayKey).head.place(DDRDesignInput(dp(ExtTLMem).get.master.base, dutWrangler.node, harnessSysPLL)).overlayOutput.ddr val ddrNode = dp(DDROverlayKey).head.place(DDRDesignInput(dp(ExtTLMem).get.master.base, dutWrangler.node, harnessSysPLL)).overlayOutput.ddr
// connect 1 mem. channel to the FPGA DDR // connect 1 mem. channel to the FPGA DDR
val inParams = topDesign match { case td: ChipTop => val ddrClient = TLClientNode(Seq(TLMasterPortParameters.v1(Seq(TLMasterParameters.v1(
td.lazySystem match { case lsys: CanHaveMasterTLMemPort => name = "chip_ddr",
lsys.memTLNode.edges.in(0) sourceId = IdRange(0, 1 << dp(ExtTLMem).get.master.idBits)
} )))))
} ddrNode := TLWidthWidget(dp(ExtTLMem).get.master.beatBytes) := ddrClient
val ddrClient = TLClientNode(Seq(inParams.master))
ddrNode := ddrClient
// module implementation // module implementation
override lazy val module = new VCU118FPGATestHarnessImp(this) override lazy val module = new VCU118FPGATestHarnessImp(this)
} }
class VCU118FPGATestHarnessImp(_outer: VCU118FPGATestHarness) extends LazyRawModuleImp(_outer) with HasHarnessSignalReferences { class VCU118FPGATestHarnessImp(_outer: VCU118FPGATestHarness) extends LazyRawModuleImp(_outer) with HasHarnessInstantiators {
val vcu118Outer = _outer val vcu118Outer = _outer
val reset = IO(Input(Bool())) val reset = IO(Input(Bool()))
@@ -118,20 +116,13 @@ class VCU118FPGATestHarnessImp(_outer: VCU118FPGATestHarness) extends LazyRawMod
val hReset = Wire(Reset()) val hReset = Wire(Reset())
hReset := _outer.dutClock.in.head._1.reset hReset := _outer.dutClock.in.head._1.reset
val buildtopClock = _outer.dutClock.in.head._1.clock def referenceClockFreqMHz = _outer.dutFreqMHz
val buildtopReset = WireInit(hReset) def referenceClock = _outer.dutClock.in.head._1.clock
val dutReset = hReset.asAsyncReset def referenceReset = hReset
val success = false.B def success = { require(false, "Unused"); false.B }
childClock := buildtopClock childClock := referenceClock
childReset := buildtopReset childReset := referenceReset
// harness binders are non-lazy instantiateChipTops()
_outer.topDesign match { case d: HasIOBinders =>
ApplyHarnessBinders(this, d.lazySystem, d.portMap)
}
// check the top-level reference clock is equal to the default
// non-exhaustive since you need all ChipTop clocks to equal the default
require(getRefClockFreq == p(DefaultClockFrequencyKey))
} }

View File

@@ -13,12 +13,11 @@ import sifive.blocks.devices.gpio.{HasPeripheryGPIOModuleImp, GPIOPortIO}
import testchipip.{HasPeripheryTSIHostWidget, TSIHostWidgetIO} import testchipip.{HasPeripheryTSIHostWidget, TSIHostWidgetIO}
import chipyard.{HasHarnessSignalReferences} import chipyard.harness._
import chipyard.harness.{ComposeHarnessBinder, OverrideHarnessBinder}
/*** UART ***/ /*** UART ***/
class WithBringupUART extends ComposeHarnessBinder({ class WithBringupUART extends ComposeHarnessBinder({
(system: HasPeripheryUARTModuleImp, th: BaseModule with HasHarnessSignalReferences, ports: Seq[UARTPortIO]) => { (system: HasPeripheryUARTModuleImp, th: BaseModule with HasHarnessInstantiators, ports: Seq[UARTPortIO]) => {
th match { case vcu118th: BringupVCU118FPGATestHarnessImp => { th match { case vcu118th: BringupVCU118FPGATestHarnessImp => {
require(ports.size == 2) require(ports.size == 2)
@@ -29,7 +28,7 @@ class WithBringupUART extends ComposeHarnessBinder({
/*** I2C ***/ /*** I2C ***/
class WithBringupI2C extends OverrideHarnessBinder({ class WithBringupI2C extends OverrideHarnessBinder({
(system: HasPeripheryI2CModuleImp, th: BaseModule with HasHarnessSignalReferences, ports: Seq[I2CPort]) => { (system: HasPeripheryI2CModuleImp, th: BaseModule with HasHarnessInstantiators, ports: Seq[I2CPort]) => {
th match { case vcu118th: BringupVCU118FPGATestHarnessImp => { th match { case vcu118th: BringupVCU118FPGATestHarnessImp => {
require(ports.size == 1) require(ports.size == 1)
@@ -40,7 +39,7 @@ class WithBringupI2C extends OverrideHarnessBinder({
/*** GPIO ***/ /*** GPIO ***/
class WithBringupGPIO extends OverrideHarnessBinder({ class WithBringupGPIO extends OverrideHarnessBinder({
(system: HasPeripheryGPIOModuleImp, th: BaseModule with HasHarnessSignalReferences, ports: Seq[GPIOPortIO]) => { (system: HasPeripheryGPIOModuleImp, th: BaseModule with HasHarnessInstantiators, ports: Seq[GPIOPortIO]) => {
th match { case vcu118th: BringupVCU118FPGATestHarnessImp => { th match { case vcu118th: BringupVCU118FPGATestHarnessImp => {
(vcu118th.bringupOuter.io_gpio_bb zip ports).map { case (bb_io, dut_io) => (vcu118th.bringupOuter.io_gpio_bb zip ports).map { case (bb_io, dut_io) =>
bb_io.bundle <> dut_io bb_io.bundle <> dut_io
@@ -51,7 +50,7 @@ class WithBringupGPIO extends OverrideHarnessBinder({
/*** TSI Host Widget ***/ /*** TSI Host Widget ***/
class WithBringupTSIHost extends OverrideHarnessBinder({ class WithBringupTSIHost extends OverrideHarnessBinder({
(system: HasPeripheryTSIHostWidget, th: BaseModule with HasHarnessSignalReferences, ports: Seq[Data]) => { (system: HasPeripheryTSIHostWidget, th: BaseModule with HasHarnessInstantiators, ports: Seq[Data]) => {
th match { case vcu118th: BringupVCU118FPGATestHarnessImp => { th match { case vcu118th: BringupVCU118FPGATestHarnessImp => {
require(ports.size == 2) // 1st goes to the TL mem, 2nd goes to the serial link require(ports.size == 2) // 1st goes to the TL mem, 2nd goes to the serial link

View File

@@ -1,5 +1,4 @@
package chipyard.fpga.vcu118.bringup package chipyard.fpga.vcu118.bringup
import chisel3._ import chisel3._
import freechips.rocketchip.diplomacy._ import freechips.rocketchip.diplomacy._
@@ -22,6 +21,7 @@ import testchipip.{HasPeripheryTSIHostWidget, PeripheryTSIHostKey, TSIHostWidget
import chipyard.fpga.vcu118.{VCU118FPGATestHarness, VCU118FPGATestHarnessImp, DDR2VCU118ShellPlacer, SysClock2VCU118ShellPlacer} import chipyard.fpga.vcu118.{VCU118FPGATestHarness, VCU118FPGATestHarnessImp, DDR2VCU118ShellPlacer, SysClock2VCU118ShellPlacer}
import chipyard.{ChipTop} import chipyard.{ChipTop}
import chipyard.harness._
class BringupVCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118FPGATestHarness { class BringupVCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118FPGATestHarness {
@@ -78,12 +78,10 @@ class BringupVCU118FPGATestHarness(override implicit val p: Parameters) extends
dp(TSIHostOverlayKey).head.place(TSIHostDesignInput(dp(PeripheryTSIHostKey).head.offchipSerialIfWidth, io_tsi_serial_bb)) dp(TSIHostOverlayKey).head.place(TSIHostDesignInput(dp(PeripheryTSIHostKey).head.offchipSerialIfWidth, io_tsi_serial_bb))
// connect 1 mem. channel to the FPGA DDR // connect 1 mem. channel to the FPGA DDR
val inTsiParams = topDesign match { case td: ChipTop => val tsiDdrClient = TLClientNode(Seq(TLMasterPortParameters.v1(Seq(TLMasterParameters.v1(
td.lazySystem match { case lsys: HasPeripheryTSIHostWidget => name = "chip_ddr",
lsys.tsiMemTLNodes.head.edges.in(0) sourceId = IdRange(0, 64)
} )))))
}
val tsiDdrClient = TLClientNode(Seq(inTsiParams.master))
(ddr2Node (ddr2Node
:= TLFragmenter(8,64,holdFirstDeny=true) := TLFragmenter(8,64,holdFirstDeny=true)
:= TLCacheCork() := TLCacheCork()

View File

@@ -1,13 +1,44 @@
#include <cstdint>
#include <vector> #include <vector>
#include <string> #include <string>
#include <riscv/sim.h> #include <riscv/sim.h>
#include <riscv/mmu.h>
#include <riscv/encoding.h>
#include <vpi_user.h> #include <vpi_user.h>
#include <svdpi.h> #include <svdpi.h>
#include <sstream> #include <sstream>
#include <set> #include <set>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <fcntl.h>
#if __has_include ("cospike_dtm.h")
#define COSPIKE_DTM
#include "testchip_dtm.h"
extern testchip_dtm_t* dtm;
bool spike_loadarch_done = false;
#endif
#if __has_include ("mm.h")
#define COSPIKE_SIMDRAM
#include "mm.h"
extern std::map<long long int, backing_data_t> backing_mem_data;
#endif
#define CLINT_BASE (0x2000000) #define CLINT_BASE (0x2000000)
#define CLINT_SIZE (0x1000) #define CLINT_SIZE (0x10000)
#define UART_BASE (0x54000000)
#define UART_SIZE (0x1000)
#define PLIC_BASE (0xc000000)
#define PLIC_SIZE (0x4000000)
#define COSPIKE_PRINTF(...) { \
printf(__VA_ARGS__); \
fprintf(stderr, __VA_ARGS__); \
}
typedef struct system_info_t { typedef struct system_info_t {
std::string isa; std::string isa;
@@ -16,14 +47,37 @@ typedef struct system_info_t {
uint64_t mem0_size; uint64_t mem0_size;
int nharts; int nharts;
std::vector<char> bootrom; std::vector<char> bootrom;
std::string priv;
};
class read_override_device_t : public abstract_device_t {
public:
read_override_device_t(std::string n, reg_t sz) : was_read_from(false), size(sz), name(n) { };
virtual bool load(reg_t addr, size_t len, uint8_t* bytes) override {
if (addr + len > size) return false;
COSPIKE_PRINTF("Read from device %s at %lx\n", name.c_str(), addr);
was_read_from = true;
return true;
}
virtual bool store(reg_t addr, size_t len, const uint8_t* bytes) override {
COSPIKE_PRINTF("Store to device %s at %lx\n", name.c_str(), addr);
return (addr + len <= size);
}
bool was_read_from;
private:
reg_t size;
std::string name;
}; };
system_info_t* info = NULL; system_info_t* info = NULL;
sim_t* sim = NULL; sim_t* sim = NULL;
bool cospike_debug;
reg_t tohost_addr = 0; reg_t tohost_addr = 0;
reg_t fromhost_addr = 0; reg_t fromhost_addr = 0;
reg_t cospike_timeout = 0;
std::set<reg_t> magic_addrs; std::set<reg_t> magic_addrs;
cfg_t* cfg; cfg_t* cfg;
std::vector<std::shared_ptr<read_override_device_t>> read_override_devices;
static std::vector<std::pair<reg_t, mem_t*>> make_mems(const std::vector<mem_cfg_t> &layout) static std::vector<std::pair<reg_t, mem_t*>> make_mems(const std::vector<mem_cfg_t> &layout)
{ {
@@ -35,14 +89,16 @@ static std::vector<std::pair<reg_t, mem_t*>> make_mems(const std::vector<mem_cfg
return mems; return mems;
} }
extern "C" void cospike_set_sysinfo(char* isa, int pmpregions, extern "C" void cospike_set_sysinfo(char* isa, char* priv, int pmpregions,
long long int mem0_base, long long int mem0_size, long long int mem0_base, long long int mem0_size,
int nharts, int nharts,
char* bootrom char* bootrom
) { ) {
if (!info) { if (!info) {
info = new system_info_t; info = new system_info_t;
info->isa = std::string(isa); // technically the targets aren't zicntr compliant, but they implement the zicntr registers
info->isa = std::string(isa) + "_zicntr";
info->priv = std::string(priv);
info->pmpregions = pmpregions; info->pmpregions = pmpregions;
info->mem0_base = mem0_base; info->mem0_base = mem0_base;
info->mem0_size = mem0_size; info->mem0_size = mem0_size;
@@ -64,11 +120,13 @@ extern "C" void cospike_cosim(long long int cycle,
int raise_exception, int raise_exception,
int raise_interrupt, int raise_interrupt,
unsigned long long int cause, unsigned long long int cause,
unsigned long long int wdata) unsigned long long int wdata,
int priv)
{ {
assert(info); assert(info);
if (!sim) {
printf("Configuring spike cosim\n"); if (unlikely(!sim)) {
COSPIKE_PRINTF("Configuring spike cosim\n");
std::vector<mem_cfg_t> mem_cfg; std::vector<mem_cfg_t> mem_cfg;
std::vector<size_t> hartids; std::vector<size_t> hartids;
mem_cfg.push_back(mem_cfg_t(info->mem0_base, info->mem0_size)); mem_cfg.push_back(mem_cfg_t(info->mem0_base, info->mem0_size));
@@ -78,7 +136,7 @@ extern "C" void cospike_cosim(long long int cycle,
cfg = new cfg_t(std::make_pair(0, 0), cfg = new cfg_t(std::make_pair(0, 0),
nullptr, nullptr,
info->isa.c_str(), info->isa.c_str(),
"MSU", info->priv.c_str(),
"vlen:128,elen:64", "vlen:128,elen:64",
false, false,
endianness_little, endianness_little,
@@ -91,34 +149,48 @@ extern "C" void cospike_cosim(long long int cycle,
std::vector<std::pair<reg_t, mem_t*>> mems = make_mems(cfg->mem_layout()); std::vector<std::pair<reg_t, mem_t*>> mems = make_mems(cfg->mem_layout());
rom_device_t *boot_rom = new rom_device_t(info->bootrom); size_t default_boot_rom_size = 0x10000;
mem_t *boot_addr_reg = new mem_t(0x1000); size_t default_boot_rom_addr = 0x10000;
assert(info->bootrom.size() < default_boot_rom_size);
info->bootrom.resize(default_boot_rom_size);
std::shared_ptr<rom_device_t> boot_rom = std::make_shared<rom_device_t>(info->bootrom);
std::shared_ptr<mem_t> boot_addr_reg = std::make_shared<mem_t>(0x1000);
uint64_t default_boot_addr = 0x80000000; uint64_t default_boot_addr = 0x80000000;
boot_addr_reg->store(0, 8, (const uint8_t*)(&default_boot_addr)); boot_addr_reg.get()->store(0, 8, (const uint8_t*)(&default_boot_addr));
// Don't actually build a clint std::shared_ptr<read_override_device_t> clint = std::make_shared<read_override_device_t>("clint", CLINT_SIZE);
mem_t* clint_mem = new mem_t(CLINT_SIZE); std::shared_ptr<read_override_device_t> uart = std::make_shared<read_override_device_t>("uart", UART_SIZE);
std::shared_ptr<read_override_device_t> plic = std::make_shared<read_override_device_t>("plic", PLIC_SIZE);
std::vector<std::pair<reg_t, abstract_device_t*>> plugin_devices; read_override_devices.push_back(clint);
read_override_devices.push_back(uart);
read_override_devices.push_back(plic);
std::vector<std::pair<reg_t, std::shared_ptr<abstract_device_t>>> devices;
// The device map is hardcoded here for now // The device map is hardcoded here for now
plugin_devices.push_back(std::pair(0x4000, boot_addr_reg)); devices.push_back(std::pair(0x4000, boot_addr_reg));
plugin_devices.push_back(std::pair(0x10000, boot_rom)); devices.push_back(std::pair(default_boot_rom_addr, boot_rom));
plugin_devices.push_back(std::pair(CLINT_BASE, clint_mem)); devices.push_back(std::pair(CLINT_BASE, clint));
devices.push_back(std::pair(UART_BASE, uart));
devices.push_back(std::pair(PLIC_BASE, plic));
s_vpi_vlog_info vinfo; s_vpi_vlog_info vinfo;
if (!vpi_get_vlog_info(&vinfo)) if (!vpi_get_vlog_info(&vinfo))
abort(); abort();
std::vector<std::string> htif_args; std::vector<std::string> htif_args;
bool in_permissive = false; bool in_permissive = false;
bool cospike_debug = false; cospike_debug = false;
for (int i = 1; i < vinfo.argc; i++) { for (int i = 1; i < vinfo.argc; i++) {
std::string arg(vinfo.argv[i]); std::string arg(vinfo.argv[i]);
if (arg == "+permissive") { if (arg == "+permissive") {
in_permissive = true; in_permissive = true;
} else if (arg == "+permissive-off") { } else if (arg == "+permissive-off") {
in_permissive = false; in_permissive = false;
} else if (arg == "+cospike_debug") { } else if (arg == "+cospike_debug" || arg == "+cospike-debug") {
cospike_debug = true; cospike_debug = true;
} else if (arg.find("+cospike-timeout=") == 0) {
cospike_timeout = strtoull(arg.substr(17).c_str(), 0, 10);
} else if (!in_permissive) { } else if (!in_permissive) {
htif_args.push_back(arg); htif_args.push_back(arg);
} }
@@ -136,14 +208,17 @@ extern "C" void cospike_cosim(long long int cycle,
.support_impebreak = true .support_impebreak = true
}; };
printf("%s\n", info->isa.c_str()); COSPIKE_PRINTF("isa string: %s\n", info->isa.c_str());
COSPIKE_PRINTF("htif args: ");
for (int i = 0; i < htif_args.size(); i++) { for (int i = 0; i < htif_args.size(); i++) {
printf("%s\n", htif_args[i].c_str()); COSPIKE_PRINTF("%s", htif_args[i].c_str());
} }
COSPIKE_PRINTF("\n");
std::vector<const device_factory_t*> plugin_device_factories;
sim = new sim_t(cfg, false, sim = new sim_t(cfg, false,
mems, mems,
plugin_devices, plugin_device_factories,
htif_args, htif_args,
dm_config, dm_config,
nullptr, nullptr,
@@ -152,107 +227,274 @@ extern "C" void cospike_cosim(long long int cycle,
false, false,
nullptr nullptr
); );
for (auto &it : devices)
sim->add_device(it.first, it.second);
#ifdef COSPIKE_SIMDRAM
// match sim_t's backing memory with the SimDRAM memory
bus_t temp_mem_bus;
for (auto& pair : mems) temp_mem_bus.add_device(pair.first, pair.second);
for (auto& pair : backing_mem_data) {
size_t base = pair.first;
size_t size = pair.second.size;
COSPIKE_PRINTF("Matching spike memory initial state for region %lx-%lx\n", base, base + size);
if (!temp_mem_bus.store(base, size, pair.second.data)) {
COSPIKE_PRINTF("Error, unable to match memory at address %lx\n", base);
abort();
}
}
#endif
sim->configure_log(true, true); sim->configure_log(true, true);
// Use our own reset vector
for (int i = 0; i < info->nharts; i++) { for (int i = 0; i < info->nharts; i++) {
// Use our own reset vector
sim->get_core(hartid)->get_state()->pc = 0x10040; sim->get_core(hartid)->get_state()->pc = 0x10040;
// Set MMU to support up to sv39, as our normal hw configs do
sim->get_core(hartid)->set_impl(IMPL_MMU_SV48, false);
sim->get_core(hartid)->set_impl(IMPL_MMU_SV57, false);
// HACKS: Our processor's don't implement zicntr fully, they don't provide time
sim->get_core(hartid)->get_state()->csrmap.erase(CSR_TIME);
} }
sim->set_debug(cospike_debug); sim->set_debug(cospike_debug);
printf("Setting up htif for spike cosim\n"); sim->set_histogram(true);
sim->set_procs_debug(cospike_debug);
COSPIKE_PRINTF("Setting up htif for spike cosim\n");
((htif_t*)sim)->start(); ((htif_t*)sim)->start();
printf("Spike cosim started\n"); COSPIKE_PRINTF("Spike cosim started\n");
tohost_addr = ((htif_t*)sim)->get_tohost_addr(); tohost_addr = ((htif_t*)sim)->get_tohost_addr();
fromhost_addr = ((htif_t*)sim)->get_fromhost_addr(); fromhost_addr = ((htif_t*)sim)->get_fromhost_addr();
printf("Tohost : %lx\n", tohost_addr); COSPIKE_PRINTF("Tohost : %lx\n", tohost_addr);
printf("Fromhost: %lx\n", fromhost_addr); COSPIKE_PRINTF("Fromhost: %lx\n", fromhost_addr);
COSPIKE_PRINTF("BootROM base : %lx\n", default_boot_rom_addr);
COSPIKE_PRINTF("BootROM size : %lx\n", boot_rom->contents().size());
COSPIKE_PRINTF("Memory base : %lx\n", info->mem0_base);
COSPIKE_PRINTF("Memory size : %lx\n", info->mem0_size);
} }
if (priv & 0x4) { // debug
return;
}
if (cospike_timeout && cycle > cospike_timeout) {
if (sim) {
COSPIKE_PRINTF("Cospike reached timeout cycles = %ld, terminating\n", cospike_timeout);
delete sim;
}
exit(0);
}
processor_t* p = sim->get_core(hartid); processor_t* p = sim->get_core(hartid);
state_t* s = p->get_state(); state_t* s = p->get_state();
#ifdef COSPIKE_DTM
if (dtm && dtm->loadarch_done && !spike_loadarch_done) {
COSPIKE_PRINTF("Restoring spike state from testchip_dtm loadarch\n");
// copy the loadarch state into the cosim
loadarch_state_t &ls = dtm->loadarch_state[hartid];
s->pc = ls.pc;
s->prv = ls.prv;
s->csrmap[CSR_MSTATUS]->write(s->csrmap[CSR_MSTATUS]->read() | MSTATUS_VS | MSTATUS_XS | MSTATUS_FS);
#define RESTORE(CSRID, csr) s->csrmap[CSRID]->write(ls.csr);
RESTORE(CSR_FCSR , fcsr);
RESTORE(CSR_VSTART , vstart);
RESTORE(CSR_VXSAT , vxsat);
RESTORE(CSR_VXRM , vxrm);
RESTORE(CSR_VCSR , vcsr);
RESTORE(CSR_VTYPE , vtype);
RESTORE(CSR_STVEC , stvec);
RESTORE(CSR_SSCRATCH , sscratch);
RESTORE(CSR_SEPC , sepc);
RESTORE(CSR_SCAUSE , scause);
RESTORE(CSR_STVAL , stval);
RESTORE(CSR_SATP , satp);
RESTORE(CSR_MSTATUS , mstatus);
RESTORE(CSR_MEDELEG , medeleg);
RESTORE(CSR_MIDELEG , mideleg);
RESTORE(CSR_MIE , mie);
RESTORE(CSR_MTVEC , mtvec);
RESTORE(CSR_MSCRATCH , mscratch);
RESTORE(CSR_MEPC , mepc);
RESTORE(CSR_MCAUSE , mcause);
RESTORE(CSR_MTVAL , mtval);
RESTORE(CSR_MIP , mip);
RESTORE(CSR_MCYCLE , mcycle);
RESTORE(CSR_MINSTRET , minstret);
if (ls.VLEN != p->VU.VLEN) {
COSPIKE_PRINTF("VLEN mismatch loadarch: $d != spike: $d\n", ls.VLEN, p->VU.VLEN);
abort();
}
if (ls.ELEN != p->VU.ELEN) {
COSPIKE_PRINTF("ELEN mismatch loadarch: $d != spike: $d\n", ls.ELEN, p->VU.ELEN);
abort();
}
for (size_t i = 0; i < 32; i++) {
s->XPR.write(i, ls.XPR[i]);
s->FPR.write(i, { (uint64_t)ls.FPR[i], (uint64_t)-1 });
memcpy(p->VU.reg_file + i * ls.VLEN / 8, ls.VPR[i], ls.VLEN / 8);
}
spike_loadarch_done = true;
p->clear_waiting_for_interrupt();
}
#endif
uint64_t s_pc = s->pc; uint64_t s_pc = s->pc;
uint64_t interrupt_cause = cause & 0x7FFFFFFFFFFFFFFF;
bool ssip_interrupt = interrupt_cause == 0x1;
bool msip_interrupt = interrupt_cause == 0x3;
bool stip_interrupt = interrupt_cause == 0x5;
bool mtip_interrupt = interrupt_cause == 0x7;
bool debug_interrupt = interrupt_cause == 0xe;
if (raise_interrupt) { if (raise_interrupt) {
printf("%d interrupt %lx\n", cycle, cause); COSPIKE_PRINTF("%d interrupt %lx\n", cycle, cause);
uint64_t interrupt_cause = cause & 0x7FFFFFFFFFFFFFFF;
if (interrupt_cause == 3) { if (ssip_interrupt || stip_interrupt) {
// do nothing
} else if (msip_interrupt) {
s->mip->backdoor_write_with_mask(MIP_MSIP, MIP_MSIP); s->mip->backdoor_write_with_mask(MIP_MSIP, MIP_MSIP);
} else if (mtip_interrupt) {
s->mip->backdoor_write_with_mask(MIP_MTIP, MIP_MTIP);
} else if (debug_interrupt) {
return;
} else { } else {
printf("Unknown interrupt %lx\n", interrupt_cause); COSPIKE_PRINTF("Unknown interrupt %lx\n", interrupt_cause);
abort();
} }
} }
if (raise_exception) if (raise_exception)
printf("%d exception %lx\n", cycle, cause); COSPIKE_PRINTF("%d exception %lx\n", cycle, cause);
if (valid) { if (valid) {
printf("%d Cosim: %lx", cycle, iaddr); p->clear_waiting_for_interrupt();
if (has_wdata) { COSPIKE_PRINTF("%d Cosim: %lx", cycle, iaddr);
printf(" %lx", wdata); // if (has_wdata) {
} // COSPIKE_PRINTF(" s: %lx", wdata);
printf("\n"); // }
COSPIKE_PRINTF("\n");
} }
if (valid || raise_interrupt || raise_exception) if (valid || raise_interrupt || raise_exception) {
p->clear_waiting_for_interrupt();
for (auto& e : read_override_devices) e.get()->was_read_from = false;
p->step(1); p->step(1);
if (unlikely(cospike_debug)) {
COSPIKE_PRINTF("spike pc is %lx\n", s->pc);
COSPIKE_PRINTF("spike mstatus is %lx\n", s->mstatus->read());
COSPIKE_PRINTF("spike mip is %lx\n", s->mip->read());
COSPIKE_PRINTF("spike mie is %lx\n", s->mie->read());
COSPIKE_PRINTF("spike wfi state is %d\n", p->is_waiting_for_interrupt());
}
}
if (valid) { if (valid && !raise_exception) {
if (s_pc != iaddr) { if (s_pc != iaddr) {
printf("%d PC mismatch %lx != %lx\n", cycle, s_pc, iaddr); COSPIKE_PRINTF("%d PC mismatch spike %llx != DUT %llx\n", cycle, s_pc, iaddr);
if (unlikely(cospike_debug)) {
COSPIKE_PRINTF("spike mstatus is %lx\n", s->mstatus->read());
COSPIKE_PRINTF("spike mcause is %lx\n", s->mcause->read());
COSPIKE_PRINTF("spike mtval is %lx\n" , s->mtval->read());
COSPIKE_PRINTF("spike mtinst is %lx\n", s->mtinst->read());
}
exit(1); exit(1);
} }
// Try to remember magic_mem addrs, and ignore these in the future
auto& mem_write = s->log_mem_write; auto& mem_write = s->log_mem_write;
if (!mem_write.empty() && tohost_addr && std::get<0>(mem_write[0]) == tohost_addr) { auto& log = s->log_reg_write;
reg_t wdata = std::get<1>(mem_write[0]); auto& mem_read = s->log_mem_read;
if (wdata >= info->mem0_base && wdata < (info->mem0_base + info->mem0_size)) {
printf("Probable magic mem %x\n", wdata); for (auto memwrite : mem_write) {
magic_addrs.insert(wdata); reg_t waddr = std::get<0>(memwrite);
uint64_t w_data = std::get<1>(memwrite);
if ((waddr == CLINT_BASE + 4*hartid) && w_data == 0) {
s->mip->backdoor_write_with_mask(MIP_MSIP, 0);
}
if ((waddr == CLINT_BASE + 0x4000 + 4*hartid)) {
s->mip->backdoor_write_with_mask(MIP_MTIP, 0);
}
// Try to remember magic_mem addrs, and ignore these in the future
if ( waddr == tohost_addr && w_data >= info->mem0_base && w_data < (info->mem0_base + info->mem0_size)) {
COSPIKE_PRINTF("Probable magic mem %lx\n", w_data);
magic_addrs.insert(w_data);
} }
} }
if (has_wdata) { bool scalar_wb = false;
auto& log = s->log_reg_write; bool vector_wb = false;
auto& mem_read = s->log_mem_read; uint32_t vector_cnt = 0;
for (auto &regwrite : log) {
//TODO: scaling to multi issue reads?
reg_t mem_read_addr = mem_read.empty() ? 0 : std::get<0>(mem_read[0]); reg_t mem_read_addr = mem_read.empty() ? 0 : std::get<0>(mem_read[0]);
for (auto regwrite : log) {
int rd = regwrite.first >> 4; int rd = regwrite.first >> 4;
int type = regwrite.first & 0xf; int type = regwrite.first & 0xf;
// 0 => int
// 1 => fp // 0 => int
// 2 => vec // 1 => fp
// 3 => vec hint // 2 => vec
// 4 => csr // 3 => vec hint
if ((rd != 0 && type == 0) || type == 1) { // 4 => csr
// Override reads from some CSRs bool device_read = false;
uint64_t csr_addr = (insn >> 20) & 0xfff; for (auto& e : read_override_devices) if (e.get()->was_read_from) device_read = true;
bool csr_read = (insn & 0x7f) == 0x73;
if (csr_read) printf("CSR read %lx\n", csr_addr); bool lr_read = ((insn & MASK_LR_D) == MATCH_LR_D) || ((insn & MASK_LR_W) == MATCH_LR_W);
if (csr_read && ( bool sc_read = ((insn & MASK_SC_D) == MATCH_SC_D) || ((insn & MASK_SC_W) == MATCH_SC_W);
(csr_addr == 0x301) || // misa
(csr_addr == 0xf13) || // mimpid bool ignore_read = sc_read || (!mem_read.empty() &&
(csr_addr == 0xf12) || // marchid (magic_addrs.count(mem_read_addr) ||
(csr_addr == 0xf11) || // mvendorid device_read ||
(csr_addr == 0xb00) || // mcycle lr_read ||
(csr_addr == 0xb02) || // minstret (tohost_addr && mem_read_addr == tohost_addr) ||
(csr_addr >= 0x3b0 && csr_addr <= 0x3ef) // pmpaddr (fromhost_addr && mem_read_addr == fromhost_addr)));
)) { // check the type is compliant with writeback first
printf("CSR override\n"); if ((type == 0 || type == 1))
s->XPR.write(rd, wdata); scalar_wb = true;
} else if (!mem_read.empty() && ((magic_addrs.count(mem_read_addr) || if (type == 2) {
(tohost_addr && mem_read_addr == tohost_addr) || vector_wb = true;
(fromhost_addr && mem_read_addr == fromhost_addr) ||
(CLINT_BASE <= mem_read_addr && mem_read_addr < (CLINT_BASE + CLINT_SIZE))
))) {
// Don't check reads from tohost, reads from magic memory, or reads from clint
// Technically this could be buggy because log_mem_read only reports vaddrs, but
// no software ever should access tohost/fromhost/clint with vaddrs anyways
printf("Read override %lx\n", mem_read_addr);
s->XPR.write(rd, wdata);
} else if (wdata != regwrite.second.v[0]) {
printf("%d wdata mismatch reg %d %lx != %lx\n", cycle, rd, regwrite.second.v[0], wdata);
exit(1);
}
}
} }
if (type == 3) continue;
if ((rd != 0 && type == 0) || type == 1) {
// Override reads from some CSRs
uint64_t csr_addr = (insn >> 20) & 0xfff;
bool csr_read = (insn & 0x7f) == 0x73;
if (csr_read)
COSPIKE_PRINTF("CSR read %lx\n", csr_addr);
if (csr_read && ((csr_addr == 0x301) || // misa
(csr_addr == 0x306) || // mcounteren
(csr_addr == 0xf13) || // mimpid
(csr_addr == 0xf12) || // marchid
(csr_addr == 0xf11) || // mvendorid
(csr_addr == 0xb00) || // mcycle
(csr_addr == 0xb02) || // minstret
(csr_addr == 0xc00) || // cycle
(csr_addr == 0xc01) || // time
(csr_addr == 0xc02) || // instret
(csr_addr >= 0x7a0 && csr_addr <= 0x7aa) || // debug trigger registers
(csr_addr >= 0x3b0 && csr_addr <= 0x3ef) // pmpaddr
)) {
COSPIKE_PRINTF("CSR override\n");
s->XPR.write(rd, wdata);
} else if (ignore_read) {
// Don't check reads from tohost, reads from magic memory, or reads
// from clint Technically this could be buggy because log_mem_read
// only reports vaddrs, but no software ever should access
// tohost/fromhost/clint with vaddrs anyways
COSPIKE_PRINTF("Read override %lx = %lx\n", mem_read_addr, wdata);
s->XPR.write(rd, wdata);
} else if (wdata != regwrite.second.v[0]) {
COSPIKE_PRINTF("%d wdata mismatch reg %d %lx != %lx\n", cycle, rd,
regwrite.second.v[0], wdata);
exit(1);
}
}
// TODO FIX: Rocketchip TracedInstruction.wdata should be Valid(UInt)
// if (scalar_wb ^ has_wdata) {
// COSPIKE_PRINTF("Scalar wdata behavior divergence between spike and DUT\n");
// exit(-1);
// }
} }
} }
} }
// }

View File

@@ -1,394 +0,0 @@
// See LICENSE.SiFive for license details.
// See LICENSE.Berkeley for license details.
#if VM_TRACE
#include <memory>
#if CY_FST_TRACE
#include "verilated_fst_c.h"
#else
#include "verilated.h"
#include "verilated_vcd_c.h"
#endif // CY_FST_TRACE
#endif // VM_TRACE
#include <fesvr/dtm.h>
#include <fesvr/tsi.h>
#include "remote_bitbang.h"
#include <iostream>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
// For option parsing, which is split across this file, Verilog, and
// FESVR's HTIF, a few external files must be pulled in. The list of
// files and what they provide is enumerated:
//
// $RISCV/include/fesvr/htif.h:
// defines:
// - HTIF_USAGE_OPTIONS
// - HTIF_LONG_OPTIONS_OPTIND
// - HTIF_LONG_OPTIONS
// $(ROCKETCHIP_DIR)/generated-src(-debug)?/$(CONFIG).plusArgs:
// defines:
// - PLUSARG_USAGE_OPTIONS
// variables:
// - static const char * verilog_plusargs
extern tsi_t* tsi;
extern dtm_t* dtm;
extern remote_bitbang_t * jtag;
static uint64_t trace_count = 0;
bool verbose = false;
bool done_reset = false;
void handle_sigterm(int sig)
{
dtm->stop();
}
double sc_time_stamp()
{
return trace_count;
}
static void usage(const char * program_name)
{
printf("Usage: %s [EMULATOR OPTION]... [VERILOG PLUSARG]... [HOST OPTION]... BINARY [TARGET OPTION]...\n",
program_name);
fputs("\
Run a BINARY on the Rocket Chip emulator.\n\
\n\
Mandatory arguments to long options are mandatory for short options too.\n\
\n\
EMULATOR OPTIONS\n\
-c, --cycle-count Print the cycle count before exiting\n\
+cycle-count\n\
-h, --help Display this help and exit\n\
-m, --max-cycles=CYCLES Kill the emulation after CYCLES\n\
+max-cycles=CYCLES\n\
-s, --seed=SEED Use random number seed SEED\n\
-r, --rbb-port=PORT Use PORT for remote bit bang (with OpenOCD and GDB) \n\
If not specified, a random port will be chosen\n\
automatically.\n\
-V, --verbose Enable all Chisel printfs (cycle-by-cycle info)\n\
+verbose\n\
", stdout);
#if VM_TRACE == 0
fputs("\
\n\
EMULATOR DEBUG OPTIONS (only supported in debug build -- try `make debug`)\n",
stdout);
#endif
fputs("\
-v, --vcd=FILE, Write vcd trace to FILE (or '-' for stdout)\n\
-x, --dump-start=CYCLE Start VCD tracing at CYCLE\n\
+dump-start\n\
", stdout);
fputs("\n" PLUSARG_USAGE_OPTIONS, stdout);
fputs("\n" HTIF_USAGE_OPTIONS, stdout);
printf("\n"
"EXAMPLES\n"
" - run a bare metal test:\n"
" %s $RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-add\n"
" - run a bare metal test showing cycle-by-cycle information:\n"
" %s +verbose $RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-add 2>&1 | spike-dasm\n"
#if VM_TRACE
" - run a bare metal test to generate a VCD waveform:\n"
" %s -v rv64ui-p-add.vcd $RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-add\n"
#endif
" - run an ELF (you wrote, called 'hello') using the proxy kernel:\n"
" %s pk hello\n",
program_name, program_name, program_name
#if VM_TRACE
, program_name
#endif
);
}
int main(int argc, char** argv)
{
unsigned random_seed = (unsigned)time(NULL) ^ (unsigned)getpid();
uint64_t max_cycles = -1;
int ret = 0;
bool print_cycles = false;
// 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
int verilog_plusargs_legal = 1;
int verilated_argc = 1;
char** verilated_argv = new char*[argc];
verilated_argv[0] = argv[0];
opterr = 1;
while (1) {
static struct option long_options[] = {
{"cycle-count", no_argument, 0, 'c' },
{"help", no_argument, 0, 'h' },
{"max-cycles", required_argument, 0, 'm' },
{"seed", required_argument, 0, 's' },
{"rbb-port", required_argument, 0, 'r' },
{"verbose", no_argument, 0, 'V' },
{"permissive", no_argument, 0, 'p' },
{"permissive-off", no_argument, 0, 'o' },
#if VM_TRACE
{"vcd", required_argument, 0, 'v' },
{"dump-start", required_argument, 0, 'x' },
#endif
HTIF_LONG_OPTIONS
};
int option_index = 0;
#if VM_TRACE
int c = getopt_long(argc, argv, "-chm:s:r:v:Vx:po", long_options, &option_index);
#else
int c = getopt_long(argc, argv, "-chm:s:r:Vpo", long_options, &option_index);
#endif
if (c == -1) break;
retry:
switch (c) {
// Process long and short EMULATOR options
case '?': usage(argv[0]); return 1;
case 'c': print_cycles = true; break;
case 'h': usage(argv[0]); return 0;
case 'm': max_cycles = atoll(optarg); break;
case 's': random_seed = atoi(optarg); break;
case 'r': rbb_port = atoi(optarg); break;
case 'V': verbose = true; break;
case 'p': opterr = 0; break;
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";
return 1;
}
break;
}
case 'x': start = atoll(optarg); break;
#endif
// Process legacy '+' EMULATOR arguments by replacing them with
// their getopt equivalents
case 1: {
std::string arg = optarg;
if (arg.substr(0, 1) != "+") {
optind--;
goto done_processing;
}
if (arg == "+verbose")
c = 'V';
else if (arg.substr(0, 12) == "+max-cycles=") {
c = 'm';
optarg = optarg+12;
}
#if VM_TRACE
else if (arg.substr(0, 12) == "+dump-start=") {
c = 'x';
optarg = optarg+12;
}
#endif
else if (arg.substr(0, 12) == "+cycle-count")
c = 'c';
else if (arg == "+permissive")
{
c = 'p';
verilated_argv[verilated_argc++] = optarg;
}
else if (arg == "+permissive-off")
{
c = 'o';
verilated_argv[verilated_argc++] = optarg;
}
// If we don't find a legacy '+' EMULATOR argument, it still could be
// a VERILOG_PLUSARG and not an error.
else if (verilog_plusargs_legal) {
const char ** plusarg = &verilog_plusargs[0];
int legal_verilog_plusarg = 0;
while (*plusarg && (legal_verilog_plusarg == 0)){
if (arg.substr(1, strlen(*plusarg)) == *plusarg) {
legal_verilog_plusarg = 1;
}
plusarg ++;
}
if (!legal_verilog_plusarg) {
verilog_plusargs_legal = 0;
} else {
c = 'P';
}
goto retry;
}
// If we STILL don't find a legacy '+' argument, it still could be
// an HTIF (HOST) argument and not an error. If this is the case, then
// we're done processing EMULATOR and VERILOG arguments.
else {
static struct option htif_long_options [] = { HTIF_LONG_OPTIONS };
struct option * htif_option = &htif_long_options[0];
while (htif_option->name) {
if (arg.substr(1, strlen(htif_option->name)) == htif_option->name) {
optind--;
goto done_processing;
}
htif_option++;
}
if(opterr) {
std::cerr << argv[0] << ": invalid plus-arg (Verilog or HTIF) \""
<< arg << "\"\n";
c = '?';
} else {
c = 'P';
}
}
goto retry;
}
case 'P': // Verilog PlusArg, add to the argument list for verilator environment
verilated_argv[verilated_argc++] = optarg;
break;
// Realize that we've hit HTIF (HOST) arguments or error out
default:
if (c >= HTIF_LONG_OPTIONS_OPTIND) {
optind--;
goto done_processing;
}
c = '?';
goto retry;
}
}
done_processing:
if (optind == argc) {
std::cerr << "No binary specified for emulator\n";
usage(argv[0]);
return 1;
}
// Copy remaining HTIF arguments (if any) and the binary file name into the verilator argument stack
while (optind < argc) verilated_argv[verilated_argc++] = argv[optind++];
if (verbose)
fprintf(stderr, "using random seed %u\n", random_seed);
srand(random_seed);
srand48(random_seed);
Verilated::randReset(2);
Verilated::commandArgs(verilated_argc, verilated_argv);
TEST_HARNESS *tile = new TEST_HARNESS;
#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()));
#endif // CY_FST_TRACE
if (vcdfile_name) {
tile->trace(tfp.get(), 99); // Trace 99 levels of hierarchy
tfp->open(vcdfile_name);
}
#endif // VM_TRACE
// RocketChip currently only supports RBB port 0, so this needs to stay here
jtag = new remote_bitbang_t(rbb_port);
signal(SIGTERM, handle_sigterm);
bool dump;
// start reset off low so a rising edge triggers async reset
tile->reset = 0;
tile->clock = 0;
tile->eval();
// reset for several cycles to handle pipelined reset
for (int i = 0; i < 100; i++) {
tile->reset = 1;
tile->clock = 0;
tile->eval();
#if VM_TRACE
dump = tfp && trace_count >= start;
if (dump)
tfp->dump(static_cast<vluint64_t>(trace_count * 2));
#endif
tile->clock = 1;
tile->eval();
#if VM_TRACE
if (dump)
tfp->dump(static_cast<vluint64_t>(trace_count * 2 + 1));
#endif
trace_count ++;
}
tile->reset = 0;
done_reset = true;
do {
tile->clock = 0;
tile->eval();
#if VM_TRACE
dump = tfp && trace_count >= start;
if (dump)
tfp->dump(static_cast<vluint64_t>(trace_count * 2));
#endif
tile->clock = 1;
tile->eval();
#if VM_TRACE
if (dump)
tfp->dump(static_cast<vluint64_t>(trace_count * 2 + 1));
#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)
tfp->close();
if (vcdfile)
fclose(vcdfile);
#endif
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 && 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 && 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();
}
else if (trace_count == max_cycles)
{
fprintf(stderr, "*** FAILED *** via trace_count (timeout, seed %d) after %ld cycles\n", random_seed, trace_count);
ret = 2;
}
else if (verbose || print_cycles)
{
fprintf(stderr, "*** PASSED *** Completed after %ld cycles\n", trace_count);
}
if (dtm) delete dtm;
if (tsi) delete tsi;
if (jtag) delete jtag;
if (tile) delete tile;
if (verilated_argv) delete[] verilated_argv;
return ret;
}

View File

@@ -2,13 +2,22 @@
#include <riscv/processor.h> #include <riscv/processor.h>
#include <riscv/log_file.h> #include <riscv/log_file.h>
#include <fesvr/context.h> #include <fesvr/context.h>
#include <fesvr/htif.h>
#include <fesvr/memif.h>
#include <fesvr/elfloader.h>
#include <map> #include <map>
#include <sstream> #include <sstream>
#include <vpi_user.h> #include <vpi_user.h>
#include <svdpi.h> #include <svdpi.h>
#include "testchip_tsi.h"
extern testchip_tsi_t* tsi; #if __has_include("spiketile_tsi.h")
#define SPIKETILE_HTIF_TSI
extern htif_t* tsi;
#endif
#if __has_include("spiketile_dtm.h")
#define SPIKETILE_HTIF_DTM
extern htif_t* dtm;
#endif
enum transfer_t { enum transfer_t {
NToB, NToB,
@@ -80,10 +89,11 @@ public:
void tcm_a(uint64_t address, uint64_t data, uint32_t mask, uint32_t opcode, uint32_t size); void tcm_a(uint64_t address, uint64_t data, uint32_t mask, uint32_t opcode, uint32_t size);
bool tcm_d(uint64_t *data); bool tcm_d(uint64_t *data);
void loadmem(const char* fname); void loadmem(size_t base, const char* fname);
void drain_stq(); void drain_stq();
bool stq_empty() { return st_q.size() == 0; }; bool stq_empty() { return st_q.size() == 0; };
void flush_icache();
const cfg_t &get_cfg() const { return cfg; } const cfg_t &get_cfg() const { return cfg; }
const std::map<size_t, processor_t*>& get_harts() const { return harts; } const std::map<size_t, processor_t*>& get_harts() const { return harts; }
@@ -109,6 +119,7 @@ public:
bool fast_clint; bool fast_clint;
cfg_t cfg; cfg_t cfg;
std::map<size_t, processor_t*> harts; std::map<size_t, processor_t*> harts;
bool accessed_tofrom_host;
private: private:
bool handle_cache_access(reg_t addr, size_t len, bool handle_cache_access(reg_t addr, size_t len,
uint8_t* load_bytes, uint8_t* load_bytes,
@@ -324,7 +335,7 @@ extern "C" void spike_tile(int hartid, char* isa,
} }
} }
if (loadmem_file != "" && tcm_size > 0) if (loadmem_file != "" && tcm_size > 0)
simif->loadmem(loadmem_file.c_str()); simif->loadmem(tcm_base, loadmem_file.c_str());
p->reset(); p->reset();
p->get_state()->pc = reset_vector; p->get_state()->pc = reset_vector;
@@ -334,14 +345,22 @@ extern "C" void spike_tile(int hartid, char* isa,
tile_t* tile = tiles[hartid]; tile_t* tile = tiles[hartid];
chipyard_simif_t* simif = tile->simif; chipyard_simif_t* simif = tile->simif;
processor_t* proc = tile->proc; processor_t* proc = tile->proc;
if (!simif->htif && tsi) { #if defined(SPIKETILE_HTIF_TSI)
simif->htif = (htif_t*) tsi; if (!simif->htif && tsi)
} simif->htif = tsi;
#endif
#if defined(SPIKETILE_HTIF_DTM)
if (!simif->htif && dtm)
simif->htif = dtm;
#endif
simif->cycle = cycle; simif->cycle = cycle;
if (debug) { if (debug) {
proc->halt_request = proc->HR_REGULAR; proc->halt_request = proc->HR_REGULAR;
} }
if (!debug && proc->halt_request != proc->HR_NONE) {
proc->halt_request = proc->HR_NONE;
}
proc->get_state()->mip->backdoor_write_with_mask(MIP_MTIP, mtip ? MIP_MTIP : 0); proc->get_state()->mip->backdoor_write_with_mask(MIP_MTIP, mtip ? MIP_MTIP : 0);
proc->get_state()->mip->backdoor_write_with_mask(MIP_MSIP, msip ? MIP_MSIP : 0); proc->get_state()->mip->backdoor_write_with_mask(MIP_MSIP, msip ? MIP_MSIP : 0);
@@ -350,6 +369,7 @@ extern "C" void spike_tile(int hartid, char* isa,
tile->max_insns = ipc; tile->max_insns = ipc;
uint64_t pre_insns = proc->get_state()->minstret->read(); uint64_t pre_insns = proc->get_state()->minstret->read();
simif->accessed_tofrom_host = false;
tile->spike_context.switch_to(); tile->spike_context.switch_to();
*insns_retired = proc->get_state()->minstret->read() - pre_insns; *insns_retired = proc->get_state()->minstret->read() - pre_insns;
if (simif->use_stq) { if (simif->use_stq) {
@@ -439,6 +459,7 @@ chipyard_simif_t::chipyard_simif_t(size_t icache_ways,
std::vector<size_t>(), std::vector<size_t>(),
false, false,
0), 0),
accessed_tofrom_host(false),
icache_ways(icache_ways), icache_ways(icache_ways),
icache_sets(icache_sets), icache_sets(icache_sets),
dcache_ways(dcache_ways), dcache_ways(dcache_ways),
@@ -504,6 +525,12 @@ chipyard_simif_t::chipyard_simif_t(size_t icache_ways,
tcm = (uint8_t*)malloc(tcm_size); tcm = (uint8_t*)malloc(tcm_size);
} }
void chipyard_simif_t::flush_icache() {
for (auto &w : icache) {
for (size_t i = 0; i < icache_sets; i++) w[i].state = NONE;
}
}
bool chipyard_simif_t::reservable(reg_t addr) { bool chipyard_simif_t::reservable(reg_t addr) {
for (auto& r: cacheables) { for (auto& r: cacheables) {
if (addr >= r.base && addr < r.base + r.size) { if (addr >= r.base && addr < r.base + r.size) {
@@ -544,6 +571,12 @@ bool chipyard_simif_t::mmio_load(reg_t addr, size_t len, uint8_t* bytes) {
bool found = false; bool found = false;
bool cacheable = false; bool cacheable = false;
bool readonly = false; bool readonly = false;
reg_t tohost_addr = htif ? htif->get_tohost_addr() : 0;
reg_t fromhost_addr = htif ? htif->get_fromhost_addr() : 0;
if (addr == tohost_addr || addr == fromhost_addr) {
accessed_tofrom_host = true;
}
if (addr >= tcm_base && addr < tcm_base + tcm_size) { if (addr >= tcm_base && addr < tcm_base + tcm_size) {
memcpy(bytes, tcm + addr - tcm_base, len); memcpy(bytes, tcm + addr - tcm_base, len);
return true; return true;
@@ -579,6 +612,8 @@ bool chipyard_simif_t::mmio_load(reg_t addr, size_t len, uint8_t* bytes) {
while (!handle_cache_access(addr, len, bytes, nullptr, LOAD)) { while (!handle_cache_access(addr, len, bytes, nullptr, LOAD)) {
host->switch_to(); host->switch_to();
} }
uint64_t lddata = 0;
memcpy(&lddata, bytes, len);
} else { } else {
handle_mmio_access(addr, len, bytes, nullptr, LOAD, readonly); handle_mmio_access(addr, len, bytes, nullptr, LOAD, readonly);
} }
@@ -605,6 +640,7 @@ void chipyard_simif_t::handle_mmio_access(reg_t addr, size_t len,
mmio_st = type == STORE; mmio_st = type == STORE;
if (type == STORE) { if (type == STORE) {
assert(len <= 8); assert(len <= 8);
mmio_stdata = 0;
memcpy(&mmio_stdata, store_bytes, len); memcpy(&mmio_stdata, store_bytes, len);
} }
mmio_len = len; mmio_len = len;
@@ -911,6 +947,13 @@ bool chipyard_simif_t::dcache_c(uint64_t* address, uint64_t* source, int* param,
} }
bool chipyard_simif_t::mmio_store(reg_t addr, size_t len, const uint8_t* bytes) { bool chipyard_simif_t::mmio_store(reg_t addr, size_t len, const uint8_t* bytes) {
reg_t tohost_addr = htif ? htif->get_tohost_addr() : 0;
reg_t fromhost_addr = htif ? htif->get_fromhost_addr() : 0;
if (addr == tohost_addr || addr == fromhost_addr) {
accessed_tofrom_host = true;
}
if (addr >= tcm_base && addr < tcm_base + tcm_size) { if (addr >= tcm_base && addr < tcm_base + tcm_size) {
memcpy(tcm + addr - tcm_base, bytes, len); memcpy(tcm + addr - tcm_base, bytes, len);
return true; return true;
@@ -936,6 +979,8 @@ bool chipyard_simif_t::mmio_store(reg_t addr, size_t len, const uint8_t* bytes)
return false; return false;
} }
if (cacheable) { if (cacheable) {
uint64_t temp = 0;
memcpy(&temp, bytes, len);
if (use_stq) { if (use_stq) {
assert(len <= 8); assert(len <= 8);
uint64_t stdata; uint64_t stdata;
@@ -1009,30 +1054,28 @@ bool chipyard_simif_t::tcm_d(uint64_t* data) {
return true; return true;
} }
#define parse_nibble(c) ((c) >= 'a' ? (c)-'a'+10 : (c)-'0') void chipyard_simif_t::loadmem(size_t base, const char* fname) {
void chipyard_simif_t::loadmem(const char* fname) { class loadmem_memif_t : public memif_t {
std::ifstream in(fname); public:
std::string line; loadmem_memif_t(chipyard_simif_t* _simif, size_t _start) : memif_t(nullptr), simif(_simif), start(_start) {}
if (!in.is_open()) { void write(addr_t taddr, size_t len, const void* src) override
printf("SpikeTile couldn't open loadmem file %s\n", fname); {
abort(); addr_t addr = taddr - start;
} memcpy(simif->tcm + addr, src, len);
size_t fsize = 0;
size_t start = 0;
while (std::getline(in, line)) {
for (ssize_t i = line.length()-2, j = 0; i >= 0; i -= 2, j++) {
char byte = (parse_nibble(line[i]) << 4) | parse_nibble(line[i+1]);
ssize_t addr = (start + j) % tcm_size;
tcm[addr] = (uint8_t)byte;
} }
start += line.length()/2; void read(addr_t taddr, size_t len, void* bytes) override {
fsize += line.length()/2; assert(false);
}
endianness_t get_target_endianness() const override {
return endianness_little;
}
private:
chipyard_simif_t* simif;
size_t start;
} loadmem_memif(this, tcm_base);
if (fsize > tcm_size) { reg_t entry;
fprintf(stderr, "Loadmem file is too large\n"); load_elf(fname, &loadmem_memif, &entry);
abort();
}
}
} }
bool insn_should_fence(uint64_t bits) { bool insn_should_fence(uint64_t bits) {
@@ -1060,33 +1103,31 @@ void spike_thread_main(void* arg)
// if (insn_should_fence(last_bits) && !simif->stq_empty()) { // if (insn_should_fence(last_bits) && !simif->stq_empty()) {
// host->switch_to(); // host->switch_to();
// } // }
uint64_t old_minstret = state->minstret->read();
proc->step(1); proc->step(1);
tile->max_insns--; tile->max_insns--;
if (proc->is_waiting_for_interrupt()) { if (proc->is_waiting_for_interrupt()) {
if (simif->fast_clint) { if (simif->fast_clint) {
// uint64_t mip = state->mip->read();
// uint64_t mie = state->mie->read();
//printf("Setting MTIP %x %x %x %x %lx\n", simif->cycle, old_minstret, mip, mie,
// state->pc);
state->mip->backdoor_write_with_mask(MIP_MTIP, MIP_MTIP); state->mip->backdoor_write_with_mask(MIP_MTIP, MIP_MTIP);
tile->max_insns = tile->max_insns <= 1 ? 0 : 1; tile->max_insns = tile->max_insns <= 1 ? 0 : 1;
} else { } else {
//printf("SpikeTile in WFI\n");
tile->max_insns = 0; tile->max_insns = 0;
} }
} }
if (tile->max_insns % 100 == 0) { if (state->debug_mode) {
uint64_t old_minstret = state->minstret->read(); // TODO: Fix. This needs to apply the same hack as rocket-chip...
uint64_t tohost_addr = simif->htif ? simif->htif->get_tohost_addr() : 0; // JALRs in debug mode should flush the ICache.
uint64_t fromhost_addr = simif->htif ? simif->htif->get_fromhost_addr() : 0; // There is no API to determine if a JALR was executed, so hack the
auto& mem_read = state->log_mem_read; // pc of the JALR in the debug rom here instead.
reg_t mem_read_addr = mem_read.empty() ? 0 : std::get<0>(mem_read[0]); if (state->pc == 0x838) {
if ((old_minstret == state->minstret->read()) || simif->flush_icache();
(tohost_addr && mem_read_addr == tohost_addr) ||
(fromhost_addr && mem_read_addr == fromhost_addr)) {
tile->max_insns == 0;
} }
} }
// If we get stuck in WFI, or we start polling tohost/fromhost, switch to host thread
if ((old_minstret == state->minstret->read()) || simif->accessed_tofrom_host) {
tile->max_insns = 0;
}
state->mcycle->write(simif->cycle); state->mcycle->write(simif->cycle);
} }
} }

View File

@@ -1,5 +1,6 @@
import "DPI-C" function void cospike_set_sysinfo( import "DPI-C" function void cospike_set_sysinfo(
input string isa, input string isa,
input string priv,
input int pmpregions, input int pmpregions,
input longint mem0_base, input longint mem0_base,
input longint mem0_size, input longint mem0_size,
@@ -16,12 +17,14 @@ import "DPI-C" function void cospike_cosim(input longint cycle,
input bit raise_exception, input bit raise_exception,
input bit raise_interrupt, input bit raise_interrupt,
input longint cause, input longint cause,
input longint wdata input longint wdata,
input int priv
); );
module SpikeCosim #( module SpikeCosim #(
parameter ISA, parameter ISA,
parameter PRIV,
parameter PMPREGIONS, parameter PMPREGIONS,
parameter MEM0_BASE, parameter MEM0_BASE,
parameter MEM0_SIZE, parameter MEM0_SIZE,
@@ -42,6 +45,7 @@ module SpikeCosim #(
input [63:0] trace_0_cause, input [63:0] trace_0_cause,
input trace_0_has_wdata, input trace_0_has_wdata,
input [63:0] trace_0_wdata, input [63:0] trace_0_wdata,
input [2:0] trace_0_priv,
input trace_1_valid, input trace_1_valid,
input [63:0] trace_1_iaddr, input [63:0] trace_1_iaddr,
@@ -50,11 +54,12 @@ module SpikeCosim #(
input trace_1_interrupt, input trace_1_interrupt,
input [63:0] trace_1_cause, input [63:0] trace_1_cause,
input trace_1_has_wdata, input trace_1_has_wdata,
input [63:0] trace_1_wdata input [63:0] trace_1_wdata,
input [2:0] trace_1_priv
); );
initial begin initial begin
cospike_set_sysinfo(ISA, PMPREGIONS, MEM0_BASE, MEM0_SIZE, NHARTS, BOOTROM); cospike_set_sysinfo(ISA, PRIV, PMPREGIONS, MEM0_BASE, MEM0_SIZE, NHARTS, BOOTROM);
end; end;
always @(posedge clock) begin always @(posedge clock) begin
@@ -62,12 +67,12 @@ module SpikeCosim #(
if (trace_0_valid || trace_0_exception || trace_0_cause) begin if (trace_0_valid || trace_0_exception || trace_0_cause) begin
cospike_cosim(cycle, hartid, trace_0_has_wdata, trace_0_valid, trace_0_iaddr, cospike_cosim(cycle, hartid, trace_0_has_wdata, trace_0_valid, trace_0_iaddr,
trace_0_insn, trace_0_exception, trace_0_interrupt, trace_0_cause, trace_0_insn, trace_0_exception, trace_0_interrupt, trace_0_cause,
trace_0_wdata); trace_0_wdata, trace_0_priv);
end end
if (trace_1_valid || trace_1_exception || trace_1_cause) begin if (trace_1_valid || trace_1_exception || trace_1_cause) begin
cospike_cosim(cycle, hartid, trace_1_has_wdata, trace_1_valid, trace_1_iaddr, cospike_cosim(cycle, hartid, trace_1_has_wdata, trace_1_valid, trace_1_iaddr,
trace_1_insn, trace_1_exception, trace_1_interrupt, trace_1_cause, trace_1_insn, trace_1_exception, trace_1_interrupt, trace_1_cause,
trace_1_wdata); trace_1_wdata, trace_1_priv);
end end
end end
end end

View File

@@ -14,15 +14,18 @@ import testchipip.TileTraceIO
case class SpikeCosimConfig( case class SpikeCosimConfig(
isa: String, isa: String,
priv: String,
pmpregions: Int, pmpregions: Int,
mem0_base: BigInt, mem0_base: BigInt,
mem0_size: BigInt, mem0_size: BigInt,
nharts: Int, nharts: Int,
bootrom: String bootrom: String,
has_dtm: Boolean
) )
class SpikeCosim(cfg: SpikeCosimConfig) extends BlackBox(Map( class SpikeCosim(cfg: SpikeCosimConfig) extends BlackBox(Map(
"ISA" -> StringParam(cfg.isa), "ISA" -> StringParam(cfg.isa),
"PRIV" -> StringParam(cfg.priv),
"PMPREGIONS" -> IntParam(cfg.pmpregions), "PMPREGIONS" -> IntParam(cfg.pmpregions),
"MEM0_BASE" -> IntParam(cfg.mem0_base), "MEM0_BASE" -> IntParam(cfg.mem0_base),
"MEM0_SIZE" -> IntParam(cfg.mem0_size), "MEM0_SIZE" -> IntParam(cfg.mem0_size),
@@ -32,6 +35,7 @@ class SpikeCosim(cfg: SpikeCosimConfig) extends BlackBox(Map(
{ {
addResource("/csrc/cospike.cc") addResource("/csrc/cospike.cc")
addResource("/vsrc/cospike.v") addResource("/vsrc/cospike.v")
if (cfg.has_dtm) addResource("/csrc/cospike_dtm.h")
val io = IO(new Bundle { val io = IO(new Bundle {
val clock = Input(Clock()) val clock = Input(Clock())
val reset = Input(Bool()) val reset = Input(Bool())
@@ -46,6 +50,7 @@ class SpikeCosim(cfg: SpikeCosimConfig) extends BlackBox(Map(
val cause = UInt(64.W) val cause = UInt(64.W)
val has_wdata = Bool() val has_wdata = Bool()
val wdata = UInt(64.W) val wdata = UInt(64.W)
val priv = UInt(3.W)
})) }))
}) })
} }
@@ -64,25 +69,23 @@ object SpikeCosim
require(trace.numInsns <= 2) require(trace.numInsns <= 2)
cosim.io.cycle := cycle cosim.io.cycle := cycle
cosim.io.trace.map(t => { cosim.io.trace.map(t => {
t := DontCare
t.valid := false.B t.valid := false.B
t.iaddr := 0.U
t.insn := 0.U
t.exception := false.B
t.interrupt := false.B
t.cause := 0.U
}) })
cosim.io.hartid := hartid.U cosim.io.hartid := hartid.U
for (i <- 0 until trace.numInsns) { for (i <- 0 until trace.numInsns) {
cosim.io.trace(i).valid := trace.insns(i).valid val insn = trace.trace.insns(i)
cosim.io.trace(i).valid := insn.valid
val signed = Wire(SInt(64.W)) val signed = Wire(SInt(64.W))
signed := trace.insns(i).iaddr.asSInt signed := insn.iaddr.asSInt
cosim.io.trace(i).iaddr := signed.asUInt cosim.io.trace(i).iaddr := signed.asUInt
cosim.io.trace(i).insn := trace.insns(i).insn cosim.io.trace(i).insn := insn.insn
cosim.io.trace(i).exception := trace.insns(i).exception cosim.io.trace(i).exception := insn.exception
cosim.io.trace(i).interrupt := trace.insns(i).interrupt cosim.io.trace(i).interrupt := insn.interrupt
cosim.io.trace(i).cause := trace.insns(i).cause cosim.io.trace(i).cause := insn.cause
cosim.io.trace(i).has_wdata := trace.insns(i).wdata.isDefined.B cosim.io.trace(i).has_wdata := insn.wdata.isDefined.B
cosim.io.trace(i).wdata := trace.insns(i).wdata.getOrElse(0.U) cosim.io.trace(i).wdata := insn.wdata.getOrElse(0.U)
cosim.io.trace(i).priv := insn.priv
} }
} }
} }

View File

@@ -13,10 +13,11 @@ import freechips.rocketchip.devices.tilelink._
// DOC include start: DigitalTop // DOC include start: DigitalTop
class DigitalTop(implicit p: Parameters) extends ChipyardSystem class DigitalTop(implicit p: Parameters) extends ChipyardSystem
with testchipip.CanHavePeripheryUARTTSI // Enables optional UART-based TSI transport
with testchipip.CanHavePeripheryCustomBootPin // Enables optional custom boot pin with testchipip.CanHavePeripheryCustomBootPin // Enables optional custom boot pin
with testchipip.HasPeripheryBootAddrReg // Use programmable boot address register with testchipip.CanHavePeripheryBootAddrReg // Use programmable boot address register
with testchipip.CanHaveTraceIO // Enables optionally adding trace IO with testchipip.CanHaveTraceIO // Enables optionally adding trace IO
with testchipip.CanHaveBackingScratchpad // Enables optionally adding a backing scratchpad with testchipip.CanHaveBankedScratchpad // Enables optionally adding a banked scratchpad
with testchipip.CanHavePeripheryBlockDevice // Enables optionally adding the block device with testchipip.CanHavePeripheryBlockDevice // Enables optionally adding the block device
with testchipip.CanHavePeripheryTLSerial // Enables optionally adding the backing memory and serial adapter with testchipip.CanHavePeripheryTLSerial // Enables optionally adding the backing memory and serial adapter
with sifive.blocks.devices.i2c.HasPeripheryI2C // Enables optionally adding the sifive I2C with sifive.blocks.devices.i2c.HasPeripheryI2C // Enables optionally adding the sifive I2C

View File

@@ -1,96 +0,0 @@
package chipyard
import chisel3._
import scala.collection.mutable.{ArrayBuffer, LinkedHashMap}
import freechips.rocketchip.diplomacy.{LazyModule}
import org.chipsalliance.cde.config.{Field, Parameters, Config}
import freechips.rocketchip.util.{ResetCatchAndSync}
import freechips.rocketchip.prci._
import chipyard.harness.{ApplyHarnessBinders, HarnessBinders}
import chipyard.iobinders.HasIOBinders
import chipyard.clocking.{SimplePllConfiguration, ClockDividerN}
import chipyard.HarnessClockInstantiatorKey
// HarnessClockInstantiators are classes which generate clocks that drive
// TestHarness simulation models and any Clock inputs to the ChipTop
trait HarnessClockInstantiator {
val _clockMap: LinkedHashMap[String, (Double, ClockBundle)] = LinkedHashMap.empty
// request a clock bundle at a particular frequency
def requestClockBundle(name: String, freqRequested: Double): ClockBundle = {
val clockBundle = Wire(new ClockBundle(ClockBundleParameters()))
_clockMap(name) = (freqRequested, clockBundle)
clockBundle
}
// refClock is the clock generated by TestDriver that is
// passed to the TestHarness as its implicit clock
def instantiateHarnessClocks(refClock: ClockBundle): Unit
}
// The DividerOnlyHarnessClockInstantiator uses synthesizable clock divisors
// to approximate frequency ratios between the requested clocks
class DividerOnlyHarnessClockInstantiator extends HarnessClockInstantiator {
// connect all clock wires specified to a divider only PLL
def instantiateHarnessClocks(refClock: ClockBundle): Unit = {
val sinks = _clockMap.map({ case (name, (freq, bundle)) =>
ClockSinkParameters(take=Some(ClockParameters(freqMHz=freq / (1000 * 1000))), name=Some(name))
}).toSeq
val pllConfig = new SimplePllConfiguration("harnessDividerOnlyClockGenerator", sinks)
pllConfig.emitSummaries()
val dividedClocks = LinkedHashMap[Int, Clock]()
def instantiateDivider(div: Int): Clock = {
val divider = Module(new ClockDividerN(div))
divider.suggestName(s"ClockDivideBy${div}")
divider.io.clk_in := refClock.clock
dividedClocks(div) = divider.io.clk_out
divider.io.clk_out
}
// connect wires to clock source
for (sinkParams <- sinks) {
// bypass the reference freq. (don't create a divider + reset sync)
val (divClock, divReset) = if (sinkParams.take.get.freqMHz != pllConfig.referenceFreqMHz) {
val div = pllConfig.sinkDividerMap(sinkParams)
val divClock = dividedClocks.getOrElse(div, instantiateDivider(div))
(divClock, ResetCatchAndSync(divClock, refClock.reset.asBool))
} else {
(refClock.clock, refClock.reset)
}
_clockMap(sinkParams.name.get)._2.clock := divClock
_clockMap(sinkParams.name.get)._2.reset := divReset
}
}
}
// The AbsoluteFreqHarnessClockInstantiator uses a Verilog blackbox to
// provide the precise requested frequency.
// This ClockInstantiator cannot be synthesized, run in Verilator, or run in FireSim
// It is useful for VCS/Xcelium-driven RTL simulations
class AbsoluteFreqHarnessClockInstantiator extends HarnessClockInstantiator {
def instantiateHarnessClocks(refClock: ClockBundle): Unit = {
val sinks = _clockMap.map({ case (name, (freq, bundle)) =>
ClockSinkParameters(take=Some(ClockParameters(freqMHz=freq / (1000 * 1000))), name=Some(name))
}).toSeq
// connect wires to clock source
for (sinkParams <- sinks) {
val source = Module(new ClockSourceAtFreq(sinkParams.take.get.freqMHz))
source.io.power := true.B
source.io.gate := false.B
_clockMap(sinkParams.name.get)._2.clock := source.io.clk
_clockMap(sinkParams.name.get)._2.reset := refClock.reset
}
}
}
class WithAbsoluteFreqHarnessClockInstantiator extends Config((site, here, up) => {
case HarnessClockInstantiatorKey => () => new AbsoluteFreqHarnessClockInstantiator
})

View File

@@ -25,7 +25,6 @@ import barstools.iocell.chisel._
import testchipip._ import testchipip._
import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly} import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly}
import chipyard.{CanHaveMasterTLMemPort} import chipyard.{CanHaveMasterTLMemPort}
import chipyard.clocking.{HasChipyardPRCI, DividerOnlyClockGenerator}
import scala.reflect.{ClassTag} import scala.reflect.{ClassTag}
@@ -304,6 +303,15 @@ class WithSerialTLIOCells extends OverrideIOBinder({
}).getOrElse((Nil, Nil)) }).getOrElse((Nil, Nil))
}) })
class WithSerialTLPunchthrough extends OverrideIOBinder({
(system: CanHavePeripheryTLSerial) => system.serial_tl.map({ s =>
val sys = system.asInstanceOf[BaseSubsystem]
val port = IO(s.getWrappedValue.cloneType)
port <> s.getWrappedValue
(Seq(port), Nil)
}).getOrElse((Nil, Nil))
})
class WithAXI4MemPunchthrough extends OverrideLazyIOBinder({ class WithAXI4MemPunchthrough extends OverrideLazyIOBinder({
(system: CanHaveMasterAXI4MemPort) => { (system: CanHaveMasterAXI4MemPort) => {
implicit val p: Parameters = GetSystemParameters(system) implicit val p: Parameters = GetSystemParameters(system)
@@ -412,6 +420,15 @@ class WithCustomBootPin extends OverrideIOBinder({
}).getOrElse((Nil, Nil)) }).getOrElse((Nil, Nil))
}) })
class WithUARTTSIPunchthrough extends OverrideIOBinder({
(system: CanHavePeripheryUARTTSI) => system.uart_tsi.map({ p =>
val sys = system.asInstanceOf[BaseSubsystem]
val uart_tsi = IO(new UARTTSIIO(p.uartParams))
uart_tsi <> p
(Seq(uart_tsi), Nil)
}).getOrElse((Nil, Nil))
})
class WithTLMemPunchthrough extends OverrideIOBinder({ class WithTLMemPunchthrough extends OverrideIOBinder({
(system: CanHaveMasterTLMemPort) => { (system: CanHaveMasterTLMemPort) => {
val io_tl_mem_pins_temp = IO(DataMirror.internal.chiselTypeClone[HeterogeneousBag[TLBundle]](system.mem_tl)).suggestName("tl_slave") val io_tl_mem_pins_temp = IO(DataMirror.internal.chiselTypeClone[HeterogeneousBag[TLBundle]](system.mem_tl)).suggestName("tl_slave")

View File

@@ -7,6 +7,7 @@ import chisel3.experimental.{IntParam, StringParam, IO}
import org.chipsalliance.cde.config._ import org.chipsalliance.cde.config._
import freechips.rocketchip.subsystem._ import freechips.rocketchip.subsystem._
import freechips.rocketchip.devices.tilelink._ import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.devices.debug.{ExportDebug, DMI}
import freechips.rocketchip.diplomacy._ import freechips.rocketchip.diplomacy._
import freechips.rocketchip.rocket._ import freechips.rocketchip.rocket._
import freechips.rocketchip.tilelink._ import freechips.rocketchip.tilelink._
@@ -61,6 +62,7 @@ case class SpikeCoreParams() extends CoreParams {
val useBitManipCrypto = false val useBitManipCrypto = false
val useCryptoNIST = false val useCryptoNIST = false
val useCryptoSM = false val useCryptoSM = false
val useConditionalZero = false
override def vLen = 128 override def vLen = 128
override def vMemDataBits = 128 override def vMemDataBits = 128
@@ -189,7 +191,8 @@ class SpikeBlackBox(
readonly_uncacheable_regions: String, readonly_uncacheable_regions: String,
executable_regions: String, executable_regions: String,
tcm_base: BigInt, tcm_base: BigInt,
tcm_size: BigInt) extends BlackBox(Map( tcm_size: BigInt,
use_dtm: Boolean) extends BlackBox(Map(
"HARTID" -> IntParam(hartId), "HARTID" -> IntParam(hartId),
"ISA" -> StringParam(isa), "ISA" -> StringParam(isa),
"PMPREGIONS" -> IntParam(pmpregions), "PMPREGIONS" -> IntParam(pmpregions),
@@ -302,7 +305,11 @@ class SpikeBlackBox(
}) })
addResource("/vsrc/spiketile.v") addResource("/vsrc/spiketile.v")
addResource("/csrc/spiketile.cc") addResource("/csrc/spiketile.cc")
if (use_dtm) {
addResource("/csrc/spiketile_dtm.h")
} else {
addResource("/csrc/spiketile_tsi.h")
}
} }
class SpikeTileModuleImp(outer: SpikeTile) extends BaseTileModuleImp(outer) { class SpikeTileModuleImp(outer: SpikeTile) extends BaseTileModuleImp(outer) {
@@ -326,13 +333,18 @@ class SpikeTileModuleImp(outer: SpikeTile) extends BaseTileModuleImp(outer) {
val (dcache_tl, dcacheEdge) = outer.dcacheNode.out(0) val (dcache_tl, dcacheEdge) = outer.dcacheNode.out(0)
val (mmio_tl, mmioEdge) = outer.mmioNode.out(0) val (mmio_tl, mmioEdge) = outer.mmioNode.out(0)
// Note: This assumes that if the debug module exposes the ClockedDMI port,
// then the DTM-based bringup with SimDTM will be used. This isn't required to be
// true, but it usually is
val useDTM = p(ExportDebug).protocols.contains(DMI)
val spike = Module(new SpikeBlackBox(hartId, isaDTS, tileParams.core.nPMPs, val spike = Module(new SpikeBlackBox(hartId, isaDTS, tileParams.core.nPMPs,
tileParams.icache.get.nSets, tileParams.icache.get.nWays, tileParams.icache.get.nSets, tileParams.icache.get.nWays,
tileParams.dcache.get.nSets, tileParams.dcache.get.nWays, tileParams.dcache.get.nSets, tileParams.dcache.get.nWays,
tileParams.dcache.get.nMSHRs, tileParams.dcache.get.nMSHRs,
cacheable_regions, uncacheable_regions, readonly_uncacheable_regions, executable_regions, cacheable_regions, uncacheable_regions, readonly_uncacheable_regions, executable_regions,
outer.spikeTileParams.tcmParams.map(_.base).getOrElse(0), outer.spikeTileParams.tcmParams.map(_.base).getOrElse(0),
outer.spikeTileParams.tcmParams.map(_.size).getOrElse(0) outer.spikeTileParams.tcmParams.map(_.size).getOrElse(0),
useDTM
)) ))
spike.io.clock := clock.asBool spike.io.clock := clock.asBool
val cycle = RegInit(0.U(64.W)) val cycle = RegInit(0.U(64.W))
@@ -421,7 +433,7 @@ class SpikeTileModuleImp(outer: SpikeTile) extends BaseTileModuleImp(outer) {
spike.io.mmio.a.ready := mmio_tl.a.ready spike.io.mmio.a.ready := mmio_tl.a.ready
mmio_tl.a.valid := spike.io.mmio.a.valid mmio_tl.a.valid := spike.io.mmio.a.valid
val log_size = MuxCase(0.U, (0 until 3).map { i => (spike.io.mmio.a.size === (1 << i).U) -> i.U }) val log_size = (0 until 4).map { i => Mux(spike.io.mmio.a.size === (1 << i).U, i.U, 0.U) }.reduce(_|_)
mmio_tl.a.bits := Mux(spike.io.mmio.a.store, mmio_tl.a.bits := Mux(spike.io.mmio.a.store,
mmioEdge.Put(0.U, spike.io.mmio.a.address, log_size, spike.io.mmio.a.data)._2, mmioEdge.Put(0.U, spike.io.mmio.a.address, log_size, spike.io.mmio.a.data)._2,
mmioEdge.Get(0.U, spike.io.mmio.a.address, log_size)._2) mmioEdge.Get(0.U, spike.io.mmio.a.address, log_size)._2)

View File

@@ -1,63 +0,0 @@
package chipyard
import chisel3._
import scala.collection.mutable.{ArrayBuffer, LinkedHashMap}
import freechips.rocketchip.diplomacy.{LazyModule}
import org.chipsalliance.cde.config.{Field, Parameters}
import freechips.rocketchip.util.{ResetCatchAndSync}
import freechips.rocketchip.prci.{ClockBundle, ClockBundleParameters, ClockSinkParameters, ClockParameters}
import chipyard.harness.{ApplyHarnessBinders, HarnessBinders}
import chipyard.iobinders.HasIOBinders
import chipyard.clocking.{SimplePllConfiguration, ClockDividerN}
// -------------------------------
// Chipyard Test Harness
// -------------------------------
case object BuildTop extends Field[Parameters => LazyModule]((p: Parameters) => new ChipTop()(p))
case object DefaultClockFrequencyKey extends Field[Double](100.0) // MHz
case object HarnessClockInstantiatorKey extends Field[() => HarnessClockInstantiator](() => new DividerOnlyHarnessClockInstantiator)
trait HasHarnessSignalReferences {
implicit val p: Parameters
val harnessClockInstantiator = p(HarnessClockInstantiatorKey)()
// clock/reset of the chiptop reference clock (can be different than the implicit harness clock/reset)
var refClockFreq: Double = p(DefaultClockFrequencyKey)
def setRefClockFreq(freqMHz: Double) = { refClockFreq = freqMHz }
def getRefClockFreq: Double = refClockFreq
def buildtopClock: Clock
def buildtopReset: Reset
def success: Bool
}
class TestHarness(implicit val p: Parameters) extends Module with HasHarnessSignalReferences {
val io = IO(new Bundle {
val success = Output(Bool())
})
val buildtopClock = Wire(Clock())
val buildtopReset = Wire(Reset())
val lazyDut = LazyModule(p(BuildTop)(p)).suggestName("chiptop")
val dut = Module(lazyDut.module)
io.success := false.B
val success = io.success
lazyDut match { case d: HasIOBinders =>
ApplyHarnessBinders(this, d.lazySystem, d.portMap)
}
val refClkBundle = harnessClockInstantiator.requestClockBundle("buildtop_reference_clock", getRefClockFreq * (1000 * 1000))
buildtopClock := refClkBundle.clock
buildtopReset := WireInit(refClkBundle.reset)
val implicitHarnessClockBundle = Wire(new ClockBundle(ClockBundleParameters()))
implicitHarnessClockBundle.clock := clock
implicitHarnessClockBundle.reset := reset
harnessClockInstantiator.instantiateHarnessClocks(implicitHarnessClockBundle)
}

View File

@@ -13,53 +13,11 @@ class ClockWithFreq(val freqMHz: Double) extends Bundle {
val clock = Clock() val clock = Clock()
} }
// This uses synthesizable clock divisors to approximate frequency rations
// between the requested clocks. This is currently the defualt clock generator "model",
// as it can be used in VCS/Xcelium/Verilator/FireSim
class WithDividerOnlyClockGenerator extends OverrideLazyIOBinder({
(system: HasChipyardPRCI) => {
// Connect the implicit clock
implicit val p = GetSystemParameters(system)
val implicitClockSinkNode = ClockSinkNode(Seq(ClockSinkParameters(name = Some("implicit_clock"))))
system.connectImplicitClockSinkNode(implicitClockSinkNode)
InModuleBody {
val implicit_clock = implicitClockSinkNode.in.head._1.clock
val implicit_reset = implicitClockSinkNode.in.head._1.reset
system.asInstanceOf[BaseSubsystem].module match { case l: LazyModuleImp => {
l.clock := implicit_clock
l.reset := implicit_reset
}}
}
// Connect all other requested clocks
val referenceClockSource = ClockSourceNode(Seq(ClockSourceParameters()))
val dividerOnlyClockGen = LazyModule(new DividerOnlyClockGenerator("buildTopClockGenerator"))
(system.allClockGroupsNode
:= dividerOnlyClockGen.node
:= referenceClockSource)
InModuleBody {
val clock_wire = Wire(Input(new ClockWithFreq(dividerOnlyClockGen.module.referenceFreq)))
val reset_wire = Wire(Input(AsyncReset()))
val (clock_io, clockIOCell) = IOCell.generateIOFromSignal(clock_wire, "clock", p(IOCellKey))
val (reset_io, resetIOCell) = IOCell.generateIOFromSignal(reset_wire, "reset", p(IOCellKey))
referenceClockSource.out.unzip._1.map { o =>
o.clock := clock_wire.clock
o.reset := reset_wire
}
(Seq(clock_io, reset_io), clockIOCell ++ resetIOCell)
}
}
})
// This uses the FakePLL, which uses a ClockAtFreq Verilog blackbox to generate // This uses the FakePLL, which uses a ClockAtFreq Verilog blackbox to generate
// the requested clocks. This also adds TileLink ClockDivider and ClockSelector // the requested clocks. This also adds TileLink ClockDivider and ClockSelector
// blocks, which allow memory-mapped control of clock division, and clock muxing // blocks, which allow memory-mapped control of clock division, and clock muxing
// between the FakePLL and the slow off-chip clock // between the FakePLL and the slow off-chip clock
// Note: This will not simulate properly with verilator or firesim // Note: This will not simulate properly with firesim
class WithPLLSelectorDividerClockGenerator extends OverrideLazyIOBinder({ class WithPLLSelectorDividerClockGenerator extends OverrideLazyIOBinder({
(system: HasChipyardPRCI) => { (system: HasChipyardPRCI) => {
// Connect the implicit clock // Connect the implicit clock
@@ -80,9 +38,9 @@ class WithPLLSelectorDividerClockGenerator extends OverrideLazyIOBinder({
val clockSelector = system.prci_ctrl_domain { LazyModule(new TLClockSelector(baseAddress + 0x30000, tlbus.beatBytes)) } val clockSelector = system.prci_ctrl_domain { LazyModule(new TLClockSelector(baseAddress + 0x30000, tlbus.beatBytes)) }
val pllCtrl = system.prci_ctrl_domain { LazyModule(new FakePLLCtrl (baseAddress + 0x40000, tlbus.beatBytes)) } val pllCtrl = system.prci_ctrl_domain { LazyModule(new FakePLLCtrl (baseAddress + 0x40000, tlbus.beatBytes)) }
tlbus.toVariableWidthSlave(Some("clock-div-ctrl")) { clockDivider.tlNode := TLBuffer() } clockDivider.tlNode := system.prci_ctrl_domain { TLFragmenter(tlbus.beatBytes, tlbus.blockBytes) := system.prci_ctrl_bus.get }
tlbus.toVariableWidthSlave(Some("clock-sel-ctrl")) { clockSelector.tlNode := TLBuffer() } clockSelector.tlNode := system.prci_ctrl_domain { TLFragmenter(tlbus.beatBytes, tlbus.blockBytes) := system.prci_ctrl_bus.get }
tlbus.toVariableWidthSlave(Some("pll-ctrl")) { pllCtrl.tlNode := TLBuffer() } pllCtrl.tlNode := system.prci_ctrl_domain { TLFragmenter(tlbus.beatBytes, tlbus.blockBytes) := system.prci_ctrl_bus.get }
system.allClockGroupsNode := clockDivider.clockNode := clockSelector.clockNode system.allClockGroupsNode := clockDivider.clockNode := clockSelector.clockNode
@@ -100,7 +58,7 @@ class WithPLLSelectorDividerClockGenerator extends OverrideLazyIOBinder({
pllCtrlSink := pllCtrl.ctrlNode pllCtrlSink := pllCtrl.ctrlNode
InModuleBody { InModuleBody {
val clock_wire = Wire(Input(new ClockWithFreq(80))) val clock_wire = Wire(Input(new ClockWithFreq(100)))
val reset_wire = Wire(Input(AsyncReset())) val reset_wire = Wire(Input(AsyncReset()))
val (clock_io, clockIOCell) = IOCell.generateIOFromSignal(clock_wire, "clock", p(IOCellKey)) val (clock_io, clockIOCell) = IOCell.generateIOFromSignal(clock_wire, "clock", p(IOCellKey))
val (reset_io, resetIOCell) = IOCell.generateIOFromSignal(reset_wire, "reset", p(IOCellKey)) val (reset_io, resetIOCell) = IOCell.generateIOFromSignal(reset_wire, "reset", p(IOCellKey))
@@ -125,3 +83,43 @@ class WithPLLSelectorDividerClockGenerator extends OverrideLazyIOBinder({
} }
} }
}) })
// This passes all clocks through to the TestHarness
class WithPassthroughClockGenerator extends OverrideLazyIOBinder({
(system: HasChipyardPRCI) => {
// Connect the implicit clock
implicit val p = GetSystemParameters(system)
val implicitClockSinkNode = ClockSinkNode(Seq(ClockSinkParameters(name = Some("implicit_clock"))))
system.connectImplicitClockSinkNode(implicitClockSinkNode)
InModuleBody {
val implicit_clock = implicitClockSinkNode.in.head._1.clock
val implicit_reset = implicitClockSinkNode.in.head._1.reset
system.asInstanceOf[BaseSubsystem].module match { case l: LazyModuleImp => {
l.clock := implicit_clock
l.reset := implicit_reset
}}
}
// This aggregate node should do nothing
val clockGroupAggNode = ClockGroupAggregateNode("fake")
val clockGroupsSourceNode = ClockGroupSourceNode(Seq(ClockGroupSourceParameters()))
system.allClockGroupsNode := clockGroupAggNode := clockGroupsSourceNode
InModuleBody {
val reset_io = IO(Input(AsyncReset()))
require(clockGroupAggNode.out.size == 1)
val (bundle, edge) = clockGroupAggNode.out(0)
val clock_ios = (bundle.member.data zip edge.sink.members).map { case (b, m) =>
require(m.take.isDefined, s"""Clock ${m.name.get} has no requested frequency
|Clocks: ${edge.sink.members.map(_.name.get)}""".stripMargin)
val freq = m.take.get.freqMHz
val clock_io = IO(Input(new ClockWithFreq(freq))).suggestName(s"clock_${m.name.get}")
b.clock := clock_io.clock
b.reset := reset_io
clock_io
}.toSeq
((clock_ios :+ reset_io), Nil)
}
}
})

View File

@@ -23,10 +23,9 @@ object ClockGroupCombiner {
case object ClockGroupCombinerKey extends Field[Seq[(String, ClockSinkParameters => Boolean)]](Nil) case object ClockGroupCombinerKey extends Field[Seq[(String, ClockSinkParameters => Boolean)]](Nil)
// All clock groups with a name containing any substring in names will be combined into a single clock group // All clock groups with a name containing any substring in names will be combined into a single clock group
class WithClockGroupsCombinedByName(grouped_name: String, names: String*) extends Config((site, here, up) => { class WithClockGroupsCombinedByName(groups: (String, Seq[String], Seq[String])*) extends Config((site, here, up) => {
case ClockGroupCombinerKey => { case ClockGroupCombinerKey => groups.map { case (grouped_name, matched_names, unmatched_names) =>
val combiner: ClockSinkParameters => Boolean = { m => names.map(n => m.name.get.contains(n)).reduce(_||_) } (grouped_name, (m: ClockSinkParameters) => matched_names.exists(n => m.name.get.contains(n)) && !unmatched_names.exists(n => m.name.get.contains(n)))
up(ClockGroupCombinerKey) ++ Seq((grouped_name, combiner))
} }
}) })
@@ -49,9 +48,14 @@ class ClockGroupCombiner(implicit p: Parameters, v: ValName) extends LazyModule
val name = combiners(i)._1 val name = combiners(i)._1
i = i + 1 i = i + 1
require(g.size >= 1) require(g.size >= 1)
require(g.forall(_.take.get == g.head.take.get)) val takes = g.map(_.take).flatten
(grouped ++ Seq(ClockSinkParameters(take = g.head.take, name = Some(name))), r) require(takes.distinct.size <= 1,
s"Clock group $name has non-homogeneous requested ClockParameters $takes")
require(takes.size > 0,
s"Clock group $name has no inheritable frequencies")
(grouped ++ Seq(ClockSinkParameters(take = takes.headOption, name = Some(name))), r)
} }
ClockGroupSinkParameters( ClockGroupSinkParameters(
name = u.name, name = u.name,
members = grouped ++ rest members = grouped ++ rest

View File

@@ -60,23 +60,23 @@ object ClockGroupNamePrefixer {
* The default if all functions return None. * The default if all functions return None.
*/ */
object ClockGroupFrequencySpecifier { object ClockGroupFrequencySpecifier {
def apply( def apply(assigners: Seq[(String) => Option[Double]])(
assigners: Seq[(String) => Option[Double]], implicit p: Parameters, valName: ValName): ClockGroupAdapterNode = {
defaultFreq: Double)(
implicit p: Parameters, valName: ValName): ClockGroupAdapterNode = {
def lookupFrequencyForName(clock: ClockSinkParameters): ClockSinkParameters = { def lookupFrequencyForName(clock: ClockSinkParameters): ClockSinkParameters = clock.copy(take = clock.take match {
require(clock.name.nonEmpty, "All clocks in clock group must have an assigned name") case Some(cp) =>
val clockFreq = assigners.foldLeft(defaultFreq)( println(s"Clock ${clock.name.get}: using diplomatically specified frequency of ${cp.freqMHz}.")
(currentFreq, candidateFunc) => candidateFunc(clock.name.get).getOrElse(currentFreq)) Some(cp)
case None => {
clock.copy(take = clock.take match { val freqs = assigners.map { f => f(clock.name.get) }.flatten
case Some(cp) => if (freqs.size > 0) {
println(s"Clock ${clock.name.get}: using diplomatically specified frequency of ${cp.freqMHz}.") println(s"Clock ${clock.name.get}: using specified frequency of ${freqs.last}")
Some(cp) Some(ClockParameters(freqs.last))
case None => Some(ClockParameters(clockFreq)) } else {
}) None
} }
}
})
LazyModule(new ClockGroupParameterModifier(sinkFn = { s => s.copy(members = s.members.map(lookupFrequencyForName)) })).node LazyModule(new ClockGroupParameterModifier(sinkFn = { s => s.copy(members = s.members.map(lookupFrequencyForName)) })).node
} }

View File

@@ -92,57 +92,3 @@ class SimplePllConfiguration(
def referenceSinkParams(): ClockSinkParameters = sinkDividerMap.find(_._2 == 1).get._1 def referenceSinkParams(): ClockSinkParameters = sinkDividerMap.find(_._2 == 1).get._1
} }
case class DividerOnlyClockGeneratorNode(pllName: String)(implicit valName: ValName)
extends MixedNexusNode(ClockImp, ClockGroupImp)(
dFn = { _ => ClockGroupSourceParameters() },
uFn = { u =>
require(u.size == 1)
require(!u.head.members.contains(None),
"All output clocks in group must set their take parameters. Use a ClockGroupDealiaser")
ClockSinkParameters(
name = Some(s"${pllName}_reference_input"),
take = Some(ClockParameters(new SimplePllConfiguration(pllName, u.head.members).referenceFreqMHz))) }
)
/**
* Generates a digital-divider-only PLL model that verilator can simulate.
* Inspects all take-specified frequencies in the output ClockGroup, calculates a
* fast reference clock (roughly LCM(requested frequencies)) which is passed up the
* diplomatic graph, and then generates dividers for each unique requested
* frequency.
*
* Output resets are not synchronized to generated clocks and should be
* synchronized by the user in a manner they see fit.
*
*/
class DividerOnlyClockGenerator(pllName: String)(implicit p: Parameters, valName: ValName) extends LazyModule {
val node = DividerOnlyClockGeneratorNode(pllName)
lazy val module = new Impl
class Impl extends LazyRawModuleImp(this) {
require(node.out.size == 1, "Idealized PLL expects to generate a single output clock group. Use a ClockGroupAggregator")
val (refClock, ClockEdgeParameters(_, refSinkParam, _, _)) = node.in.head
val (outClocks, ClockGroupEdgeParameters(_, outSinkParams, _, _)) = node.out.head
val referenceFreq = refSinkParam.take.get.freqMHz
val pllConfig = new SimplePllConfiguration(pllName, outSinkParams.members)
pllConfig.emitSummaries()
val dividedClocks = mutable.HashMap[Int, Clock]()
def instantiateDivider(div: Int): Clock = {
val divider = Module(new ClockDividerN(div))
divider.suggestName(s"ClockDivideBy${div}")
divider.io.clk_in := refClock.clock
dividedClocks(div) = divider.io.clk_out
divider.io.clk_out
}
for (((sinkBName, sinkB), sinkP) <- outClocks.member.elements.zip(outSinkParams.members)) {
val div = pllConfig.sinkDividerMap(sinkP)
sinkB.clock := dividedClocks.getOrElse(div, instantiateDivider(div))
// Reset handling and synchronization is expected to be handled by a downstream node
sinkB.reset := refClock.reset
}
}
}

View File

@@ -14,15 +14,17 @@ import freechips.rocketchip.util._
import freechips.rocketchip.tile._ import freechips.rocketchip.tile._
import freechips.rocketchip.prci._ import freechips.rocketchip.prci._
import testchipip.{TLTileResetCtrl} import testchipip.{TLTileResetCtrl, ClockGroupFakeResetSynchronizer}
import chipyard.{DefaultClockFrequencyKey}
case class ChipyardPRCIControlParams( case class ChipyardPRCIControlParams(
slaveWhere: TLBusWrapperLocation = CBUS, slaveWhere: TLBusWrapperLocation = CBUS,
baseAddress: BigInt = 0x100000, baseAddress: BigInt = 0x100000,
enableTileClockGating: Boolean = true, enableTileClockGating: Boolean = true,
enableTileResetSetting: Boolean = true enableTileResetSetting: Boolean = true,
) enableResetSynchronizers: Boolean = true // this should only be disabled to work around verilator async-reset initialization problems
) {
def generatePRCIXBar = enableTileClockGating || enableTileResetSetting
}
case object ChipyardPRCIControlKey extends Field[ChipyardPRCIControlParams](ChipyardPRCIControlParams()) case object ChipyardPRCIControlKey extends Field[ChipyardPRCIControlParams](ChipyardPRCIControlParams())
@@ -37,6 +39,13 @@ trait HasChipyardPRCI { this: BaseSubsystem with InstantiatesTiles =>
val prci_ctrl_domain = LazyModule(new ClockSinkDomain(name=Some("chipyard-prci-control"))) val prci_ctrl_domain = LazyModule(new ClockSinkDomain(name=Some("chipyard-prci-control")))
prci_ctrl_domain.clockNode := tlbus.fixedClockNode prci_ctrl_domain.clockNode := tlbus.fixedClockNode
val prci_ctrl_bus = Option.when(prciParams.generatePRCIXBar) { prci_ctrl_domain { TLXbar() } }
prci_ctrl_bus.foreach(xbar => tlbus.coupleTo("prci_ctrl") { (xbar
:= TLFIFOFixer(TLFIFOFixer.all)
:= TLBuffer()
:= _)
})
// Aggregate all the clock groups into a single node // Aggregate all the clock groups into a single node
val aggregator = LazyModule(new ClockGroupAggregator("allClocks")).node val aggregator = LazyModule(new ClockGroupAggregator("allClocks")).node
val allClockGroupsNode = ClockGroupEphemeralNode() val allClockGroupsNode = ClockGroupEphemeralNode()
@@ -70,21 +79,47 @@ trait HasChipyardPRCI { this: BaseSubsystem with InstantiatesTiles =>
// 5. Add reset control registers to the tiles (if desired) // 5. Add reset control registers to the tiles (if desired)
// The final clock group here contains physically distinct clock domains, which some PRCI node in a // The final clock group here contains physically distinct clock domains, which some PRCI node in a
// diplomatic IOBinder should drive // diplomatic IOBinder should drive
val frequencySpecifier = ClockGroupFrequencySpecifier(p(ClockFrequencyAssignersKey), p(DefaultClockFrequencyKey)) val frequencySpecifier = ClockGroupFrequencySpecifier(p(ClockFrequencyAssignersKey))
val clockGroupCombiner = ClockGroupCombiner() val clockGroupCombiner = ClockGroupCombiner()
val resetSynchronizer = ClockGroupResetSynchronizer() val resetSynchronizer = prci_ctrl_domain {
val tileClockGater = if (prciParams.enableTileClockGating) { prci_ctrl_domain { if (prciParams.enableResetSynchronizers) ClockGroupResetSynchronizer() else ClockGroupFakeResetSynchronizer()
TileClockGater(prciParams.baseAddress + 0x00000, tlbus) }
} } else { ClockGroupEphemeralNode() } val tileClockGater = Option.when(prciParams.enableTileClockGating) { prci_ctrl_domain {
val tileResetSetter = if (prciParams.enableTileResetSetting) { prci_ctrl_domain { val clock_gater = LazyModule(new TileClockGater(prciParams.baseAddress + 0x00000, tlbus.beatBytes))
TileResetSetter(prciParams.baseAddress + 0x10000, tlbus, tile_prci_domains.map(_.tile_reset_domain.clockNode.portParams(0).name.get), Nil) clock_gater.tlNode := TLFragmenter(tlbus.beatBytes, tlbus.blockBytes) := prci_ctrl_bus.get
} } else { ClockGroupEphemeralNode() } clock_gater
} }
val tileResetSetter = Option.when(prciParams.enableTileResetSetting) { prci_ctrl_domain {
val reset_setter = LazyModule(new TileResetSetter(prciParams.baseAddress + 0x10000, tlbus.beatBytes,
tile_prci_domains.map(_.tile_reset_domain.clockNode.portParams(0).name.get), Nil))
reset_setter.tlNode := TLFragmenter(tlbus.beatBytes, tlbus.blockBytes) := prci_ctrl_bus.get
reset_setter
} }
if (!prciParams.enableResetSynchronizers) {
println(Console.RED + s"""
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
WARNING:
DISABLING THE RESET SYNCHRONIZERS RESULTS IN
A BROKEN DESIGN THAT WILL NOT BEHAVE
PROPERLY AS ASIC OR FPGA.
THESE SHOULD ONLY BE DISABLED TO WORK AROUND
LIMITATIONS IN ASYNC RESET INITIALIZATION IN
RTL SIMULATORS, NAMELY VERILATOR.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
""" + Console.RESET)
}
(aggregator (aggregator
:= frequencySpecifier := frequencySpecifier
:= clockGroupCombiner := clockGroupCombiner
:= resetSynchronizer := resetSynchronizer
:= tileClockGater := tileClockGater.map(_.clockNode).getOrElse(ClockGroupEphemeralNode()(ValName("temp")))
:= tileResetSetter := tileResetSetter.map(_.clockNode).getOrElse(ClockGroupEphemeralNode()(ValName("temp")))
:= allClockGroupsNode) := allClockGroupsNode)
} }

View File

@@ -26,20 +26,26 @@ class TLClockDivider(address: BigInt, beatBytes: Int, divBits: Int = 8)(implicit
val sinks = clockNode.out.head._1.member.elements.toSeq val sinks = clockNode.out.head._1.member.elements.toSeq
require (sources.size == sinks.size) require (sources.size == sinks.size)
val nSinks = sinks.size val nSinks = sinks.size
// The implicit clock of this module is the clock of the tilelink bus
// busReset is sync'd to that clock, and will be asserted longer than the
// resets coming in through the clockNode, since the busReset is derived from
// the clockNode resets in downstream PRCI nodes
val busReset = reset
val regs = (0 until nSinks) .map { i => val regs = (0 until nSinks) .map { i =>
val sinkName = sinks(i)._1 val sinkName = sinks(i)._1
val asyncReset = sources(i).reset val asyncReset = sources(i).reset
val reg = withReset (asyncReset) { val reg = Module(new AsyncResetRegVec(w=divBits, init=0))
Module(new AsyncResetRegVec(w=divBits, init=0))
}
println(s"${(address+i*4).toString(16)}: Clock domain $sinkName divider") println(s"${(address+i*4).toString(16)}: Clock domain $sinkName divider")
sinks(i)._2.clock := withClockAndReset(sources(i).clock, asyncReset) { val divider = Module(new testchipip.ClockDivideOrPass(divBits, depth = 3, genClockGate = p(ClockGateImpl)))
val divider = Module(new testchipip.ClockDivideOrPass(divBits, depth = 3, genClockGate = p(ClockGateImpl))) divider.io.clockIn := sources(i).clock
divider.io.divisor := reg.io.q // busReset is expected to be high for a long time, since reset will take a while to propagate
divider.io.resetAsync := ResetStretcher(sources(i).clock, asyncReset, 20).asAsyncReset // to the TL bus. While reset is propagating, make sure we propagate a fast, undivided clock
divider.io.clockOut // by setting divisor=0. The divisor signal into the ClockDividerOrPass is synchronized internally
} divider.io.divisor := Mux(busReset.asBool, 0.U, reg.io.q)
divider.io.resetAsync := ResetStretcher(sources(i).clock, asyncReset, 20).asAsyncReset
sinks(i)._2.clock := divider.io.clockOut
// Note this is not synchronized to the output clock, which takes time to appear // Note this is not synchronized to the output clock, which takes time to appear
// so this is still asyncreset // so this is still asyncreset

View File

@@ -13,23 +13,6 @@ import freechips.rocketchip.util.ElaborationArtefacts
import testchipip._ import testchipip._
object ResetStretcher {
def apply(clock: Clock, reset: Reset, cycles: Int): Reset = {
withClockAndReset(clock, reset) {
val n = log2Ceil(cycles)
val count = Module(new AsyncResetRegVec(w=n, init=0))
val resetout = Module(new AsyncResetRegVec(w=1, init=1))
count.io.en := resetout.io.q
count.io.d := count.io.q + 1.U
resetout.io.en := resetout.io.q
resetout.io.d := count.io.q < (cycles-1).U
resetout.io.q.asBool
}
}
}
case class ClockSelNode()(implicit valName: ValName) case class ClockSelNode()(implicit valName: ValName)
extends MixedNexusNode(ClockImp, ClockGroupImp)( extends MixedNexusNode(ClockImp, ClockGroupImp)(
dFn = { d => ClockGroupSourceParameters() }, dFn = { d => ClockGroupSourceParameters() },

View File

@@ -46,10 +46,3 @@ class TileClockGater(address: BigInt, beatBytes: Int)(implicit p: Parameters, va
} }
} }
object TileClockGater {
def apply(address: BigInt, tlbus: TLBusWrapper)(implicit p: Parameters, v: ValName) = {
val gater = LazyModule(new TileClockGater(address, tlbus.beatBytes))
tlbus.toVariableWidthSlave(Some("clock-gater")) { gater.tlNode := TLBuffer() }
gater.clockNode
}
}

View File

@@ -62,12 +62,3 @@ class TileResetSetter(address: BigInt, beatBytes: Int, tileNames: Seq[String], i
} }
} }
} }
object TileResetSetter {
def apply(address: BigInt, tlbus: TLBusWrapper, tileNames: Seq[String], initResetHarts: Seq[Int])(implicit p: Parameters, v: ValName) = {
val setter = LazyModule(new TileResetSetter(address, tlbus.beatBytes, tileNames, initResetHarts))
tlbus.toVariableWidthSlave(Some("tile-reset-setter")) { setter.tlNode := TLBuffer() }
setter.clockNode
}
}

View File

@@ -12,50 +12,58 @@ import org.chipsalliance.cde.config.{Config}
class AbstractConfig extends Config( class AbstractConfig extends Config(
// The HarnessBinders control generation of hardware in the TestHarness // 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.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.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.WithSimTSIOverSerialTL ++ // add external serial-adapter and RAM
new chipyard.harness.WithSimDebug ++ // add SimJTAG or SimDTM adapters if debug module is enabled 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.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.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.WithSimAXIMMIO ++ // add SimAXIMem for axi4 mmio port, if enabled
new chipyard.harness.WithTieOffInterrupts ++ // tie-off interrupt ports, if present new chipyard.harness.WithTieOffInterrupts ++ // tie-off interrupt ports, if present
new chipyard.harness.WithTieOffL2FBusAXI ++ // tie-off external AXI4 master, if present new chipyard.harness.WithTieOffL2FBusAXI ++ // tie-off external AXI4 master, if present
new chipyard.harness.WithCustomBootPinPlusArg ++ new chipyard.harness.WithCustomBootPinPlusArg ++ // drive custom-boot pin with a plusarg, if custom-boot-pin is present
new chipyard.harness.WithClockAndResetFromHarness ++ new chipyard.harness.WithSimUARTToUARTTSI ++ // connect a SimUART to the UART-TSI port
new chipyard.harness.WithClockAndResetFromHarness ++ // all Clock/Reset I/O in ChipTop should be driven by harnessClockInstantiator
new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++ // generate clocks in harness with unsynthesizable ClockSourceAtFreqMHz
// The IOBinders instantiate ChipTop IOs to match desired digital IOs // 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 // IOCells are generated for "Chip-like" IOs
new chipyard.iobinders.WithSerialTLIOCells ++
new chipyard.iobinders.WithDebugIOCells ++
new chipyard.iobinders.WithUARTIOCells ++
new chipyard.iobinders.WithGPIOCells ++
new chipyard.iobinders.WithSPIIOCells ++
new chipyard.iobinders.WithExtInterruptIOCells ++
new chipyard.iobinders.WithCustomBootPin ++
// The "punchthrough" IOBInders below don't generate IOCells, as these interfaces shouldn't really be mapped to ASIC IO
// Instead, they directly pass through the DigitalTop ports to ports in the ChipTop
new chipyard.iobinders.WithAXI4MemPunchthrough ++ new chipyard.iobinders.WithAXI4MemPunchthrough ++
new chipyard.iobinders.WithAXI4MMIOPunchthrough ++ new chipyard.iobinders.WithAXI4MMIOPunchthrough ++
new chipyard.iobinders.WithTLMemPunchthrough ++ new chipyard.iobinders.WithTLMemPunchthrough ++
new chipyard.iobinders.WithL2FBusAXI4Punchthrough ++ new chipyard.iobinders.WithL2FBusAXI4Punchthrough ++
new chipyard.iobinders.WithBlockDeviceIOPunchthrough ++ new chipyard.iobinders.WithBlockDeviceIOPunchthrough ++
new chipyard.iobinders.WithNICIOPunchthrough ++ new chipyard.iobinders.WithNICIOPunchthrough ++
new chipyard.iobinders.WithSerialTLIOCells ++
new chipyard.iobinders.WithDebugIOCells ++
new chipyard.iobinders.WithUARTIOCells ++
new chipyard.iobinders.WithGPIOCells ++
new chipyard.iobinders.WithSPIIOCells ++
new chipyard.iobinders.WithTraceIOPunchthrough ++ new chipyard.iobinders.WithTraceIOPunchthrough ++
new chipyard.iobinders.WithExtInterruptIOCells ++ new chipyard.iobinders.WithUARTTSIPunchthrough ++
new chipyard.iobinders.WithCustomBootPin ++
// Default behavior is to use a divider-only clock-generator // By default, punch out IOs to the Harness
// This works in VCS, Verilator, and FireSim/ new chipyard.clocking.WithPassthroughClockGenerator ++
// This should get replaced with a PLL-like config instead new chipyard.clocking.WithClockGroupsCombinedByName(("uncore", Seq("sbus", "mbus", "pbus", "fbus", "cbus", "implicit"), Seq("tile"))) ++
new chipyard.clocking.WithDividerOnlyClockGenerator ++ new chipyard.config.WithPeripheryBusFrequency(500.0) ++ // Default 500 MHz pbus
new chipyard.config.WithMemoryBusFrequency(500.0) ++ // Default 500 MHz mbus
new testchipip.WithCustomBootPin ++ // add a custom-boot-pin to support pin-driven boot address
new testchipip.WithBootAddrReg ++ // add a boot-addr-reg for configurable boot address
new testchipip.WithSerialTLClientIdBits(4) ++ // support up to 1 << 4 simultaneous requests from serialTL port
new testchipip.WithSerialTLWidth(32) ++ // fatten the serialTL interface to improve testing performance new testchipip.WithSerialTLWidth(32) ++ // fatten the serialTL interface to improve testing performance
new testchipip.WithDefaultSerialTL ++ // use serialized tilelink port to external serialadapter/harnessRAM new testchipip.WithDefaultSerialTL ++ // use serialized tilelink port to external serialadapter/harnessRAM
new chipyard.config.WithDebugModuleAbstractDataWords(8) ++ // increase debug module data capacity
new chipyard.config.WithBootROM ++ // use default bootrom new chipyard.config.WithBootROM ++ // use default bootrom
new chipyard.config.WithUART ++ // add a UART new chipyard.config.WithUART ++ // add a UART
new chipyard.config.WithL2TLBs(1024) ++ // use L2 TLBs 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 chipyard.config.WithNoSubsystemDrivenClocks ++ // drive the subsystem diplomatic clocks from ChipTop instead of using implicit clocks
new chipyard.config.WithInheritBusFrequencyAssignments ++ // Unspecified clocks within a bus will receive the bus frequency if set new chipyard.config.WithInheritBusFrequencyAssignments ++ // Unspecified clocks within a bus will receive the bus frequency if set
new chipyard.config.WithPeripheryBusFrequencyAsDefault ++ // Unspecified frequencies with match the pbus frequency (which is always set) new freechips.rocketchip.subsystem.WithNMemoryChannels(1) ++ // Default 1 memory channels
new chipyard.config.WithMemoryBusFrequency(100.0) ++ // Default 100 MHz mbus
new chipyard.config.WithPeripheryBusFrequency(100.0) ++ // Default 100 MHz pbus
new freechips.rocketchip.subsystem.WithClockGateModel ++ // add default EICG_wrapper clock gate model new freechips.rocketchip.subsystem.WithClockGateModel ++ // add default EICG_wrapper clock gate model
new freechips.rocketchip.subsystem.WithJtagDTM ++ // set the debug module to expose a JTAG port 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.WithNoMMIOPort ++ // no top-level MMIO master port (overrides default set in rocketchip)

View File

@@ -53,3 +53,18 @@ class MediumBoomCosimConfig extends Config(
new chipyard.config.WithTraceIO ++ // enable the traceio new chipyard.config.WithTraceIO ++ // enable the traceio
new boom.common.WithNMediumBooms(1) ++ new boom.common.WithNMediumBooms(1) ++
new chipyard.config.AbstractConfig) new chipyard.config.AbstractConfig)
class dmiMediumBoomConfig extends Config(
new chipyard.harness.WithSerialTLTiedOff ++ // don't attach anything to serial-tl
new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port
new boom.common.WithNMediumBooms(1) ++
new chipyard.config.AbstractConfig)
class dmiMediumBoomCosimConfig extends Config(
new chipyard.harness.WithCospike ++ // attach spike-cosim
new chipyard.config.WithTraceIO ++ // enable the traceio
new chipyard.harness.WithSerialTLTiedOff ++ // don't attach anythint to serial-tl
new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port
new boom.common.WithNMediumBooms(1) ++
new chipyard.config.AbstractConfig)

View File

@@ -13,7 +13,7 @@ class CVA6Config extends Config(
new chipyard.config.AbstractConfig) new chipyard.config.AbstractConfig)
class dmiCVA6Config extends Config( class dmiCVA6Config extends Config(
new chipyard.harness.WithSerialAdapterTiedOff ++ // Tie off the serial port, override default instantiation of SimSerial new chipyard.harness.WithSerialTLTiedOff ++ // Tie off the serial-tilelink port
new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port
new cva6.WithNCVA6Cores(1) ++ // single CVA6 core new cva6.WithNCVA6Cores(1) ++ // single CVA6 core
new chipyard.config.AbstractConfig) new chipyard.config.AbstractConfig)

View File

@@ -2,43 +2,106 @@ package chipyard
import org.chipsalliance.cde.config.{Config} import org.chipsalliance.cde.config.{Config}
import freechips.rocketchip.diplomacy._ import freechips.rocketchip.diplomacy._
import freechips.rocketchip.subsystem.{MBUS, SBUS}
import testchipip.{OBUS}
// A simple config demonstrating how to set up a basic chip in Chipyard // A simple config demonstrating how to set up a basic chip in Chipyard
class ChipLikeQuadRocketConfig extends Config( class ChipLikeRocketConfig extends Config(
//================================== //==================================
// Set up TestHarness // Set up TestHarness
//================================== //==================================
new chipyard.WithAbsoluteFreqHarnessClockInstantiator ++ // use absolute frequencies for simulations in the harness new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++ // use absolute frequencies for simulations in the harness
// NOTE: This only simulates properly in VCS // NOTE: This only simulates properly in VCS
new chipyard.harness.WithSimAXIMemOverSerialTL ++ // Attach SimDRAM to serial-tl port
//================================== //==================================
// Set up tiles // Set up tiles
//================================== //==================================
new freechips.rocketchip.subsystem.WithAsynchronousRocketTiles(3, 3) ++ // Add rational crossings between RocketTile and uncore new freechips.rocketchip.subsystem.WithAsynchronousRocketTiles(3, 3) ++ // Add rational crossings between RocketTile and uncore
new freechips.rocketchip.subsystem.WithNBigCores(4) ++ // quad-core (4 RocketTiles) new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // 1 RocketTile
//================================== //==================================
// Set up I/O // Set up I/O
//================================== //==================================
new testchipip.WithSerialTLWidth(4) ++ new testchipip.WithSerialTLWidth(4) ++
new chipyard.harness.WithSimAXIMemOverSerialTL ++ // Attach fast SimDRAM to TestHarness new testchipip.WithSerialTLBackingMemory ++ // Backing memory is over serial TL protocol
new chipyard.config.WithSerialTLBackingMemory ++ // Backing memory is over serial TL protocol
new freechips.rocketchip.subsystem.WithExtMemSize((1 << 30) * 4L) ++ // 4GB max external memory new freechips.rocketchip.subsystem.WithExtMemSize((1 << 30) * 4L) ++ // 4GB max external memory
new freechips.rocketchip.subsystem.WithNMemoryChannels(1) ++ // 1 memory channel
//==================================
// Set up buses
//==================================
new testchipip.WithOffchipBusClient(MBUS) ++
new testchipip.WithOffchipBus ++
//================================== //==================================
// Set up clock./reset // Set up clock./reset
//================================== //==================================
new chipyard.clocking.WithPLLSelectorDividerClockGenerator ++ // Use a PLL-based clock selector/divider generator structure new chipyard.clocking.WithPLLSelectorDividerClockGenerator ++ // Use a PLL-based clock selector/divider generator structure
// Create two clock groups, uncore and fbus, in addition to the tile clock groups // Create the uncore clock group
new chipyard.clocking.WithClockGroupsCombinedByName("uncore", "implicit", "sbus", "mbus", "cbus", "system_bus") ++ new chipyard.clocking.WithClockGroupsCombinedByName(("uncore", Seq("implicit", "sbus", "mbus", "cbus", "system_bus", "fbus", "pbus"), Nil)) ++
new chipyard.clocking.WithClockGroupsCombinedByName("fbus", "fbus", "pbus") ++
// Set up the crossings
new chipyard.config.WithFbusToSbusCrossingType(AsynchronousCrossing()) ++ // Add Async crossing between SBUS and FBUS
new chipyard.config.WithCbusToPbusCrossingType(AsynchronousCrossing()) ++ // Add Async crossing between PBUS and CBUS
new chipyard.config.WithSbusToMbusCrossingType(AsynchronousCrossing()) ++ // Add Async crossings between backside of L2 and MBUS
new testchipip.WithAsynchronousSerialSlaveCrossing ++ // Add Async crossing between serial and MBUS. Its master-side is tied to the FBUS
new chipyard.config.AbstractConfig) new chipyard.config.AbstractConfig)
// A simple config demonstrating a "bringup prototype" to bringup the ChipLikeRocketconfig
class ChipBringupHostConfig extends Config(
//=============================
// Set up TestHarness for standalone-sim
//=============================
new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++ // Generate absolute frequencies
new chipyard.harness.WithSerialTLTiedOff ++ // when doing standalone sim, tie off the serial-tl port
new chipyard.harness.WithSimTSIToUARTTSI ++ // Attach SimTSI-over-UART to the UART-TSI port
new chipyard.iobinders.WithSerialTLPunchthrough ++ // Don't generate IOCells for the serial TL (this design maps to FPGA)
//=============================
// Setup the SerialTL side on the bringup device
//=============================
new testchipip.WithSerialTLWidth(4) ++ // match width with the chip
new testchipip.WithSerialTLMem(base = 0x0, size = 0x80000000L, // accessible memory of the chip that doesn't come from the tethered host
idBits = 4, isMainMemory = false) ++ // This assumes off-chip mem starts at 0x8000_0000
new testchipip.WithSerialTLClockDirection(provideClockFreqMHz = Some(75)) ++ // bringup board drives the clock for the serial-tl receiver on the chip, use 75MHz clock
//============================
// Setup bus topology on the bringup system
//============================
new testchipip.WithOffchipBusClient(SBUS, // offchip bus hangs off the SBUS
blockRange = AddressSet.misaligned(0x80000000L, (BigInt(1) << 30) * 4)) ++ // offchip bus should not see the main memory of the testchip, since that can be accessed directly
new testchipip.WithOffchipBus ++ // offchip bus
//=============================
// Set up memory on the bringup system
//=============================
new freechips.rocketchip.subsystem.WithExtMemSize((1 << 30) * 4L) ++ // match what the chip believes the max size should be
//=============================
// Generate the TSI-over-UART side of the bringup system
//=============================
new testchipip.WithUARTTSIClient(initBaudRate = BigInt(921600)) ++ // nonstandard baud rate to improve performance
//=============================
// Set up clocks of the bringup system
//=============================
new chipyard.clocking.WithPassthroughClockGenerator ++ // pass all the clocks through, since this isn't a chip
new chipyard.config.WithFrontBusFrequency(75.0) ++ // run all buses of this system at 75 MHz
new chipyard.config.WithMemoryBusFrequency(75.0) ++
new chipyard.config.WithPeripheryBusFrequency(75.0) ++
// Base is the no-cores config
new chipyard.NoCoresConfig)
class TetheredChipLikeRocketConfig extends Config(
new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++ // use absolute freqs for sims in the harness
new chipyard.harness.WithMultiChipSerialTL(0, 1) ++ // connect the serial-tl ports of the chips together
new chipyard.harness.WithMultiChip(0, new ChipLikeRocketConfig) ++
new chipyard.harness.WithMultiChip(1, new ChipBringupHostConfig))
// Verilator does not initialize some of the async-reset reset-synchronizer
// flops properly, so this config disables them.
// This config should only be used for verilator simulations
class VerilatorCITetheredChipLikeRocketConfig extends Config(
new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++ // use absolute freqs for sims in the harness
new chipyard.harness.WithMultiChipSerialTL(0, 1) ++ // connect the serial-tl ports of the chips together
new chipyard.harness.WithMultiChip(0, new chipyard.config.WithNoResetSynchronizers ++ new ChipLikeRocketConfig) ++
new chipyard.harness.WithMultiChip(1, new ChipBringupHostConfig))

View File

@@ -61,7 +61,6 @@ class LargeNVDLARocketConfig extends Config(
class ManyMMIOAcceleratorRocketConfig extends Config( class ManyMMIOAcceleratorRocketConfig extends Config(
new chipyard.iobinders.WithDontTouchIOBinders(false) ++ // TODO: hack around dontTouch not working in SFC new chipyard.iobinders.WithDontTouchIOBinders(false) ++ // TODO: hack around dontTouch not working in SFC
new fftgenerator.WithFFTGenerator(numPoints=8, width=16, decPt=8) ++ // add 8-point mmio fft at the default addr (0x2400) with 16bit fixed-point numbers. new fftgenerator.WithFFTGenerator(numPoints=8, width=16, decPt=8) ++ // add 8-point mmio fft at the default addr (0x2400) with 16bit fixed-point numbers.
new nvidia.blocks.dla.WithNVDLA("small") ++ // add a small NVDLA
new chipyard.example.WithStreamingPassthrough ++ // use top with tilelink-controlled streaming passthrough new chipyard.example.WithStreamingPassthrough ++ // use top with tilelink-controlled streaming passthrough
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 freechips.rocketchip.subsystem.WithNBigCores(1) ++

View File

@@ -68,9 +68,9 @@ class MultiNoCConfig extends Config(
"serial-tl" -> 0), "serial-tl" -> 0),
outNodeMapping = ListMap( outNodeMapping = ListMap(
"error" -> 1, "l2[0]" -> 2, "pbus" -> 3, "plic" -> 4, "error" -> 1, "l2[0]" -> 2, "pbus" -> 3, "plic" -> 4,
"clint" -> 5, "dmInner" -> 6, "bootrom" -> 7, "tileClockGater" -> 8, "tileResetSetter" -> 9)), "clint" -> 5, "dmInner" -> 6, "bootrom" -> 7, "clock" -> 8)),
NoCParams( NoCParams(
topology = TerminalRouter(BidirectionalLine(10)), topology = TerminalRouter(BidirectionalLine(9)),
channelParamGen = (a, b) => UserChannelParams(Seq.fill(5) { UserVirtualChannelParams(4) }), channelParamGen = (a, b) => UserChannelParams(Seq.fill(5) { UserVirtualChannelParams(4) }),
routingRelation = NonblockingVirtualSubnetworksRouting(TerminalRouterRouting(BidirectionalLineRouting()), 5, 1)) routingRelation = NonblockingVirtualSubnetworksRouting(TerminalRouterRouting(BidirectionalLineRouting()), 5, 1))
)) ++ )) ++

View File

@@ -4,6 +4,15 @@ import org.chipsalliance.cde.config.{Config}
// A empty config with no cores. Useful for testing // A empty config with no cores. Useful for testing
class NoCoresConfig extends Config( class NoCoresConfig extends Config(
new testchipip.WithNoBootAddrReg ++
new testchipip.WithNoCustomBootPin ++
new chipyard.config.WithNoCLINT ++
new chipyard.config.WithNoBootROM ++
new chipyard.config.WithBroadcastManager ++
new chipyard.config.WithNoUART ++
new chipyard.config.WithNoTileClockGaters ++
new chipyard.config.WithNoTileResetSetters ++
new chipyard.config.WithNoBusErrorDevices ++
new chipyard.config.WithNoDebug ++ new chipyard.config.WithNoDebug ++
new chipyard.config.WithNoPLIC ++ new chipyard.config.WithNoPLIC ++
new chipyard.config.AbstractConfig) new chipyard.config.AbstractConfig)

View File

@@ -2,6 +2,7 @@ package chipyard
import org.chipsalliance.cde.config.{Config} import org.chipsalliance.cde.config.{Config}
import freechips.rocketchip.diplomacy.{AsynchronousCrossing} import freechips.rocketchip.diplomacy.{AsynchronousCrossing}
import freechips.rocketchip.subsystem.{MBUS}
// --------------------------------------------------------- // ---------------------------------------------------------
// Configs which add non-default peripheral devices or ports // Configs which add non-default peripheral devices or ports
@@ -58,20 +59,37 @@ class LBWIFRocketConfig extends Config(
// DOC include start: DmiRocket // DOC include start: DmiRocket
class dmiRocketConfig extends Config( class dmiRocketConfig extends Config(
new chipyard.harness.WithSerialAdapterTiedOff ++ // don't attach an external SimSerial new chipyard.harness.WithSerialTLTiedOff ++ // don't attach anything to serial-tl
new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port
new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig) new chipyard.config.AbstractConfig)
// DOC include end: DmiRocket // DOC include end: DmiRocket
class ManyPeripheralsRocketConfig extends Config( class ManyPeripheralsRocketConfig extends Config(
new testchipip.WithBlockDevice ++ // add block-device module to peripherybus
new testchipip.WithOffchipBusClient(MBUS) ++ // OBUS provides backing memory to the MBUS
new testchipip.WithOffchipBus ++ // OBUS must exist for serial-tl to master off-chip memory
new testchipip.WithSerialTLMem(isMainMemory=true) ++ // set lbwif memory base to DRAM_BASE, use as main memory
new chipyard.harness.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.harness.WithSimBlockDevice ++ // drive block-device IOs with SimBlockDevice new chipyard.harness.WithSimBlockDevice ++ // drive block-device IOs with SimBlockDevice
new chipyard.config.WithSPIFlash ++ // add the SPI flash controller new chipyard.config.WithSPIFlash ++ // add the SPI flash controller
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.WithDefaultSlavePort ++ // add default external slave port
new testchipip.WithBlockDevice ++ // add block-device module to peripherybus
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.WithNoMemPort ++ // remove AXI4 backing memory
new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig) new chipyard.config.AbstractConfig)
class QuadChannelRocketConfig extends Config(
new freechips.rocketchip.subsystem.WithNMemoryChannels(4) ++ // 4 AXI4 channels
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
new chipyard.config.AbstractConfig)
class UARTTSIRocketConfig extends Config(
new chipyard.harness.WithSerialTLTiedOff ++
new testchipip.WithUARTTSIClient ++
new chipyard.config.WithMemoryBusFrequency(10) ++
new chipyard.config.WithFrontBusFrequency(10) ++
new chipyard.config.WithPeripheryBusFrequency(10) ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // single rocket-core
new chipyard.config.AbstractConfig)

View File

@@ -29,14 +29,6 @@ class RocketGPUConfig extends Config(
new freechips.rocketchip.subsystem.WithNCustomSmallCores(2) ++ // multiple rocket-core new freechips.rocketchip.subsystem.WithNCustomSmallCores(2) ++ // multiple rocket-core
new chipyard.config.AbstractConfig) new chipyard.config.AbstractConfig)
class UARTTSIRocketConfig extends Config(
new chipyard.harness.WithUARTSerial ++
new chipyard.config.WithNoUART ++
new chipyard.config.WithMemoryBusFrequency(10) ++
new chipyard.config.WithPeripheryBusFrequency(10) ++
new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // single rocket-core
new chipyard.config.AbstractConfig)
class SimAXIRocketConfig extends Config( class SimAXIRocketConfig extends Config(
new chipyard.harness.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 freechips.rocketchip.subsystem.WithNBigCores(1) ++

View File

@@ -0,0 +1,32 @@
package chipyard
import org.chipsalliance.cde.config.{Config}
//-----------------
// Shuttle Configs
//-----------------
class ShuttleConfig extends Config(
new shuttle.common.WithNShuttleCores ++ // 1x dual-issue shuttle core
new chipyard.config.AbstractConfig)
class ShuttleCosimConfig extends Config(
new chipyard.harness.WithCospike ++ // attach spike-cosim
new chipyard.config.WithTraceIO ++ // enable trace-io for cosim
new shuttle.common.WithShuttleDebugROB ++ // enable shuttle debug ROB for cosim
new shuttle.common.WithNShuttleCores ++
new chipyard.config.AbstractConfig)
class dmiShuttleCosimConfig extends Config(
new chipyard.harness.WithSerialTLTiedOff ++ // don't attach anything to serial-tl
new chipyard.harness.WithCospike ++ // attach spike-cosim
new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port
new chipyard.config.WithTraceIO ++ // enable traceio for cosim
new shuttle.common.WithShuttleDebugROB ++ // enable shuttle debug ROB for cosim
new shuttle.common.WithNShuttleCores ++
new chipyard.config.AbstractConfig)
class GemminiShuttleConfig extends Config(
new gemmini.DefaultGemminiConfig ++ // use Gemmini systolic array GEMM accel
new shuttle.common.WithNShuttleCores ++
new chipyard.config.AbstractConfig)

View File

@@ -8,7 +8,6 @@ class Sodor1StageConfig extends Config(
// Create a Sodor 1-stage core // Create a Sodor 1-stage core
new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage1Factory) ++ new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage1Factory) ++
new testchipip.WithSerialTLWidth(32) ++ new testchipip.WithSerialTLWidth(32) ++
new testchipip.WithSerialPBusMem ++
new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad
new freechips.rocketchip.subsystem.WithNoMemPort ++ // use no external memory new freechips.rocketchip.subsystem.WithNoMemPort ++ // use no external memory
new freechips.rocketchip.subsystem.WithNBanks(0) ++ new freechips.rocketchip.subsystem.WithNBanks(0) ++
@@ -18,7 +17,6 @@ class Sodor2StageConfig extends Config(
// Create a Sodor 2-stage core // Create a Sodor 2-stage core
new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage2Factory) ++ new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage2Factory) ++
new testchipip.WithSerialTLWidth(32) ++ new testchipip.WithSerialTLWidth(32) ++
new testchipip.WithSerialPBusMem ++
new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad
new freechips.rocketchip.subsystem.WithNoMemPort ++ // use no external memory new freechips.rocketchip.subsystem.WithNoMemPort ++ // use no external memory
new freechips.rocketchip.subsystem.WithNBanks(0) ++ new freechips.rocketchip.subsystem.WithNBanks(0) ++
@@ -28,7 +26,6 @@ class Sodor3StageConfig extends Config(
// Create a Sodor 1-stage core with two ports // Create a Sodor 1-stage core with two ports
new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage3Factory(ports = 2)) ++ new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage3Factory(ports = 2)) ++
new testchipip.WithSerialTLWidth(32) ++ new testchipip.WithSerialTLWidth(32) ++
new testchipip.WithSerialPBusMem ++
new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad
new freechips.rocketchip.subsystem.WithNoMemPort ++ // use no external memory new freechips.rocketchip.subsystem.WithNoMemPort ++ // use no external memory
new freechips.rocketchip.subsystem.WithNBanks(0) ++ new freechips.rocketchip.subsystem.WithNBanks(0) ++
@@ -38,7 +35,6 @@ class Sodor3StageSinglePortConfig extends Config(
// Create a Sodor 3-stage core with one ports (instruction and data memory access controlled by arbiter) // Create a Sodor 3-stage core with one ports (instruction and data memory access controlled by arbiter)
new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage3Factory(ports = 1)) ++ new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage3Factory(ports = 1)) ++
new testchipip.WithSerialTLWidth(32) ++ new testchipip.WithSerialTLWidth(32) ++
new testchipip.WithSerialPBusMem ++
new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad
new freechips.rocketchip.subsystem.WithNoMemPort ++ // use no external memory new freechips.rocketchip.subsystem.WithNoMemPort ++ // use no external memory
new freechips.rocketchip.subsystem.WithNBanks(0) ++ new freechips.rocketchip.subsystem.WithNBanks(0) ++
@@ -48,7 +44,6 @@ class Sodor5StageConfig extends Config(
// Create a Sodor 5-stage core // Create a Sodor 5-stage core
new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage5Factory) ++ new sodor.common.WithNSodorCores(1, internalTile = sodor.common.Stage5Factory) ++
new testchipip.WithSerialTLWidth(32) ++ new testchipip.WithSerialTLWidth(32) ++
new testchipip.WithSerialPBusMem ++
new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad
new freechips.rocketchip.subsystem.WithNoMemPort ++ // use no external memory new freechips.rocketchip.subsystem.WithNoMemPort ++ // use no external memory
new freechips.rocketchip.subsystem.WithNBanks(0) ++ new freechips.rocketchip.subsystem.WithNBanks(0) ++
@@ -58,7 +53,6 @@ class SodorUCodeConfig extends Config(
// Construct a Sodor microcode-based single-bus core // Construct a Sodor microcode-based single-bus core
new sodor.common.WithNSodorCores(1, internalTile = sodor.common.UCodeFactory) ++ new sodor.common.WithNSodorCores(1, internalTile = sodor.common.UCodeFactory) ++
new testchipip.WithSerialTLWidth(32) ++ new testchipip.WithSerialTLWidth(32) ++
new testchipip.WithSerialPBusMem ++
new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad new freechips.rocketchip.subsystem.WithScratchpadsOnly ++ // use sodor tile-internal scratchpad
new freechips.rocketchip.subsystem.WithNoMemPort ++ // use no external memory new freechips.rocketchip.subsystem.WithNoMemPort ++ // use no external memory
new freechips.rocketchip.subsystem.WithNBanks(0) ++ new freechips.rocketchip.subsystem.WithNBanks(0) ++

View File

@@ -10,6 +10,11 @@ class SpikeConfig extends Config(
new chipyard.WithNSpikeCores(1) ++ new chipyard.WithNSpikeCores(1) ++
new chipyard.config.AbstractConfig) new chipyard.config.AbstractConfig)
class dmiSpikeConfig extends Config(
new chipyard.harness.WithSerialTLTiedOff ++ // don't attach anything to serial-tilelink
new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port
new SpikeConfig)
// Avoids polling on the UART registers // Avoids polling on the UART registers
class SpikeFastUARTConfig extends Config( class SpikeFastUARTConfig extends Config(
new chipyard.WithNSpikeCores(1) ++ new chipyard.WithNSpikeCores(1) ++
@@ -22,13 +27,17 @@ class SpikeFastUARTConfig extends Config(
class SpikeUltraFastConfig extends Config( class SpikeUltraFastConfig extends Config(
new chipyard.WithSpikeTCM ++ new chipyard.WithSpikeTCM ++
new chipyard.WithNSpikeCores(1) ++ new chipyard.WithNSpikeCores(1) ++
new testchipip.WithSerialPBusMem ++
new chipyard.config.WithUARTFIFOEntries(128, 128) ++ new chipyard.config.WithUARTFIFOEntries(128, 128) ++
new chipyard.config.WithMemoryBusFrequency(2) ++ new chipyard.config.WithMemoryBusFrequency(2) ++
new chipyard.config.WithPeripheryBusFrequency(2) ++ new chipyard.config.WithPeripheryBusFrequency(2) ++
new chipyard.config.WithBroadcastManager ++ new chipyard.config.WithBroadcastManager ++
new chipyard.config.AbstractConfig) new chipyard.config.AbstractConfig)
class dmiSpikeUltraFastConfig extends Config(
new chipyard.harness.WithSerialTLTiedOff ++ // don't attach anything to serial-tilelink
new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port
new SpikeUltraFastConfig)
// Add the default firechip devices // Add the default firechip devices
class SpikeUltraFastDevicesConfig extends Config( class SpikeUltraFastDevicesConfig extends Config(
new chipyard.harness.WithSimBlockDevice ++ new chipyard.harness.WithSimBlockDevice ++
@@ -38,7 +47,6 @@ class SpikeUltraFastDevicesConfig extends Config(
new chipyard.WithSpikeTCM ++ new chipyard.WithSpikeTCM ++
new chipyard.WithNSpikeCores(1) ++ new chipyard.WithNSpikeCores(1) ++
new testchipip.WithSerialPBusMem ++
new chipyard.config.WithUARTFIFOEntries(128, 128) ++ new chipyard.config.WithUARTFIFOEntries(128, 128) ++
new chipyard.config.WithMemoryBusFrequency(2) ++ new chipyard.config.WithMemoryBusFrequency(2) ++
new chipyard.config.WithPeripheryBusFrequency(2) ++ new chipyard.config.WithPeripheryBusFrequency(2) ++

View File

@@ -4,21 +4,24 @@ import org.chipsalliance.cde.config.{Config}
import freechips.rocketchip.rocket.{DCacheParams} import freechips.rocketchip.rocket.{DCacheParams}
class AbstractTraceGenConfig extends Config( class AbstractTraceGenConfig extends Config(
new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++
new chipyard.harness.WithBlackBoxSimMem ++ new chipyard.harness.WithBlackBoxSimMem ++
new chipyard.harness.WithTraceGenSuccess ++ new chipyard.harness.WithTraceGenSuccess ++
new chipyard.harness.WithClockAndResetFromHarness ++ new chipyard.harness.WithClockAndResetFromHarness ++
new chipyard.iobinders.WithAXI4MemPunchthrough ++ new chipyard.iobinders.WithAXI4MemPunchthrough ++
new chipyard.iobinders.WithTraceGenSuccessPunchthrough ++ new chipyard.iobinders.WithTraceGenSuccessPunchthrough ++
new chipyard.clocking.WithDividerOnlyClockGenerator ++ new chipyard.clocking.WithPassthroughClockGenerator ++
new chipyard.clocking.WithClockGroupsCombinedByName(("uncore", Seq("sbus", "implicit"), Nil)) ++
new chipyard.config.WithTracegenSystem ++ new chipyard.config.WithTracegenSystem ++
new chipyard.config.WithNoSubsystemDrivenClocks ++ new chipyard.config.WithNoSubsystemDrivenClocks ++
new chipyard.config.WithPeripheryBusFrequencyAsDefault ++ new chipyard.config.WithMemoryBusFrequency(1000.0) ++
new chipyard.config.WithMemoryBusFrequency(100.0) ++ new chipyard.config.WithSystemBusFrequency(1000.0) ++
new chipyard.config.WithPeripheryBusFrequency(100.0) ++ new chipyard.config.WithPeripheryBusFrequency(1000.0) ++
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ new freechips.rocketchip.subsystem.WithCoherentBusTopology ++
new freechips.rocketchip.groundtest.GroundTestBaseConfig) new freechips.rocketchip.groundtest.GroundTestBaseConfig)
class TraceGenConfig extends Config( class TraceGenConfig extends Config(
new tracegen.WithTraceGen()(List.fill(2) { DCacheParams(nMSHRs = 0, nSets = 16, nWays = 2) }) ++ new tracegen.WithTraceGen()(List.fill(2) { DCacheParams(nMSHRs = 0, nSets = 16, nWays = 2) }) ++
new AbstractTraceGenConfig) new AbstractTraceGenConfig)

View File

@@ -14,7 +14,6 @@ import freechips.rocketchip.tilelink.{HasTLBusParams}
import chipyard._ import chipyard._
import chipyard.clocking._ import chipyard.clocking._
// The default RocketChip BaseSubsystem drives its diplomatic clock graph // The default RocketChip BaseSubsystem drives its diplomatic clock graph
// with the implicit clocks of Subsystem. Don't do that, instead we extend // 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 // the diplomacy graph upwards into the ChipTop, where we connect it to
@@ -37,14 +36,6 @@ class WithTileFrequency(fMHz: Double, hartId: Option[Int] = None) extends ClockN
}, },
fMHz) fMHz)
class WithPeripheryBusFrequencyAsDefault extends Config((site, here, up) => {
case DefaultClockFrequencyKey => (site(PeripheryBusKey).dtsFrequency.get.toDouble / (1000 * 1000))
})
class WithSystemBusFrequencyAsDefault extends Config((site, here, up) => {
case DefaultClockFrequencyKey => (site(SystemBusKey).dtsFrequency.get.toDouble / (1000 * 1000))
})
class BusFrequencyAssignment[T <: HasTLBusParams](re: Regex, key: Field[T]) extends Config((site, here, up) => { class BusFrequencyAssignment[T <: HasTLBusParams](re: Regex, key: Field[T]) extends Config((site, here, up) => {
case ClockFrequencyAssignersKey => up(ClockFrequencyAssignersKey, site) ++ case ClockFrequencyAssignersKey => up(ClockFrequencyAssignersKey, site) ++
Seq((cName: String) => site(key).dtsFrequency.flatMap { f => Seq((cName: String) => site(key).dtsFrequency.flatMap { f =>
@@ -116,17 +107,14 @@ class WithControlBusFrequency(freqMHz: Double) extends Config((site, here, up) =
class WithRationalMemoryBusCrossing extends WithSbusToMbusCrossingType(RationalCrossing(Symmetric)) class WithRationalMemoryBusCrossing extends WithSbusToMbusCrossingType(RationalCrossing(Symmetric))
class WithAsynchrousMemoryBusCrossing extends WithSbusToMbusCrossingType(AsynchronousCrossing()) class WithAsynchrousMemoryBusCrossing extends WithSbusToMbusCrossingType(AsynchronousCrossing())
class WithTestChipBusFreqs extends Config( class WithNoTileClockGaters extends Config((site, here, up) => {
// Frequency specifications case ChipyardPRCIControlKey => up(ChipyardPRCIControlKey).copy(enableTileClockGating = false)
new chipyard.config.WithTileFrequency(1600.0) ++ // Matches the maximum frequency of U540 })
new chipyard.config.WithSystemBusFrequency(800.0) ++ // Put the system bus at a lower freq, representative of ncore working at a lower frequency than the tiles. Same freq as U540
new chipyard.config.WithMemoryBusFrequency(1000.0) ++ // 2x the U540 freq (appropriate for a 128b Mbus) class WithNoTileResetSetters extends Config((site, here, up) => {
new chipyard.config.WithPeripheryBusFrequency(800.0) ++ // Match the sbus and pbus frequency case ChipyardPRCIControlKey => up(ChipyardPRCIControlKey).copy(enableTileResetSetting = false)
new chipyard.config.WithSystemBusFrequencyAsDefault ++ // All unspecified clock frequencies, notably the implicit clock, will use the sbus freq (800 MHz) })
// Crossing specifications
new chipyard.config.WithCbusToPbusCrossingType(AsynchronousCrossing()) ++ // Add Async crossing between PBUS and CBUS class WithNoResetSynchronizers extends Config((site, here, up) => {
new chipyard.config.WithSbusToMbusCrossingType(AsynchronousCrossing()) ++ // Add Async crossings between backside of L2 and MBUS case ChipyardPRCIControlKey => up(ChipyardPRCIControlKey).copy(enableResetSynchronizers = false)
new freechips.rocketchip.subsystem.WithRationalRocketTiles ++ // Add rational crossings between RocketTile and uncore })
new boom.common.WithRationalBoomTiles ++ // Add rational crossings between BoomTile and uncore
new testchipip.WithAsynchronousSerialSlaveCrossing // Add Async crossing between serial and MBUS. Its master-side is tied to the FBUS
)

View File

@@ -5,8 +5,9 @@ import chisel3._
import chisel3.util.{log2Up} import chisel3.util.{log2Up}
import org.chipsalliance.cde.config.{Config} import org.chipsalliance.cde.config.{Config}
import freechips.rocketchip.devices.tilelink.{BootROMLocated, PLICKey} import freechips.rocketchip.devices.tilelink.{BootROMLocated, PLICKey, CLINTKey}
import freechips.rocketchip.devices.debug.{Debug, ExportDebug, DebugModuleKey, DMI} import freechips.rocketchip.devices.debug.{Debug, ExportDebug, DebugModuleKey, DMI, JtagDTMKey, JtagDTMConfig}
import freechips.rocketchip.diplomacy.{AsynchronousCrossing}
import freechips.rocketchip.stage.phases.TargetDirKey import freechips.rocketchip.stage.phases.TargetDirKey
import freechips.rocketchip.subsystem._ import freechips.rocketchip.subsystem._
import freechips.rocketchip.tile.{XLen} import freechips.rocketchip.tile.{XLen}
@@ -14,53 +15,125 @@ import freechips.rocketchip.tile.{XLen}
import sifive.blocks.devices.gpio._ import sifive.blocks.devices.gpio._
import sifive.blocks.devices.uart._ import sifive.blocks.devices.uart._
import sifive.blocks.devices.spi._ import sifive.blocks.devices.spi._
import sifive.blocks.devices.i2c._
import testchipip._ import testchipip._
import chipyard.{ExtTLMem} import chipyard.{ExtTLMem}
// Set the bootrom to the Chipyard bootrom /**
class WithBootROM extends Config((site, here, up) => { * Config fragment for adding a BootROM to the SoC
*
* @param address the address of the BootROM device
* @param size the size of the BootROM
* @param hang the power-on reset vector, i.e. the program counter will be set to this value on reset
* @param contentFileName the path to the BootROM image
*/
class WithBootROM(address: BigInt = 0x10000, size: Int = 0x10000, hang: BigInt = 0x10040) extends Config((site, here, up) => {
case BootROMLocated(x) => up(BootROMLocated(x), site) case BootROMLocated(x) => up(BootROMLocated(x), site)
.map(_.copy(contentFileName = s"${site(TargetDirKey)}/bootrom.rv${site(XLen)}.img")) .map(_.copy(
address = address,
size = size,
hang = hang,
contentFileName = s"${site(TargetDirKey)}/bootrom.rv${site(XLen)}.img"
))
}) })
// DOC include start: gpio config fragment // DOC include start: gpio config fragment
class WithGPIO extends Config((site, here, up) => { /**
case PeripheryGPIOKey => Seq( * Config fragment for adding a GPIO peripheral device to the SoC
GPIOParams(address = 0x10012000, width = 4, includeIOF = false)) *
* @param address the address of the GPIO device
* @param width the number of pins of the GPIO device
*/
class WithGPIO(address: BigInt = 0x10010000, width: Int = 4) extends Config ((site, here, up) => {
case PeripheryGPIOKey => up(PeripheryGPIOKey) ++ Seq(
GPIOParams(address = address, width = width, includeIOF = false))
}) })
// DOC include end: gpio config fragment // DOC include end: gpio config fragment
class WithUART(baudrate: BigInt = 115200) extends Config((site, here, up) => { /**
case PeripheryUARTKey => Seq( * Config fragment for removing all UART peripheral devices from the SoC
UARTParams(address = 0x54000000L, nTxEntries = 256, nRxEntries = 256, initBaudRate = baudrate)) */
})
class WithNoUART extends Config((site, here, up) => { class WithNoUART extends Config((site, here, up) => {
case PeripheryUARTKey => Nil case PeripheryUARTKey => Nil
}) })
/**
* Config fragment for adding a UART peripheral device to the SoC
*
* @param address the address of the UART device
* @param baudrate the baudrate of the UART device
*/
class WithUART(baudrate: BigInt = 115200, address: BigInt = 0x10020000) extends Config ((site, here, up) => {
case PeripheryUARTKey => up(PeripheryUARTKey) ++ Seq(
UARTParams(address = address, nTxEntries = 256, nRxEntries = 256, initBaudRate = baudrate))
})
class WithUARTFIFOEntries(txEntries: Int, rxEntries: Int) extends Config((site, here, up) => { class WithUARTFIFOEntries(txEntries: Int, rxEntries: Int) extends Config((site, here, up) => {
case PeripheryUARTKey => up(PeripheryUARTKey).map(_.copy(nTxEntries = txEntries, nRxEntries = rxEntries)) case PeripheryUARTKey => up(PeripheryUARTKey).map(_.copy(nTxEntries = txEntries, nRxEntries = rxEntries))
}) })
class WithSPIFlash(size: BigInt = 0x10000000) extends Config((site, here, up) => { class WithUARTInitBaudRate(baudrate: BigInt = 115200) extends Config ((site, here, up) => {
// Note: the default size matches freedom with the addresses below case PeripheryUARTKey => up(PeripheryUARTKey).map(_.copy(initBaudRate=baudrate))
case PeripherySPIFlashKey => Seq(
SPIFlashParams(rAddress = 0x10040000, fAddress = 0x20000000, fSize = size))
}) })
class WithDMIDTM extends Config((site, here, up) => { /**
case ExportDebug => up(ExportDebug, site).copy(protocols = Set(DMI)) * Config fragment for adding a SPI peripheral device with Execute-in-Place capability to the SoC
*
* @param address the address of the SPI controller
* @param fAddress the address of the Execute-in-Place (XIP) region of the SPI flash memory
* @param size the size of the Execute-in-Place (XIP) region of the SPI flash memory
*/
class WithSPIFlash(size: BigInt = 0x10000000, address: BigInt = 0x10030000, fAddress: BigInt = 0x20000000) extends Config((site, here, up) => {
// Note: the default size matches freedom with the addresses below
case PeripherySPIFlashKey => up(PeripherySPIFlashKey) ++ Seq(
SPIFlashParams(rAddress = address, fAddress = fAddress, fSize = size))
})
/**
* Config fragment for adding a SPI peripheral device to the SoC
*
* @param address the address of the SPI controller
*/
class WithSPI(address: BigInt = 0x10031000) extends Config((site, here, up) => {
case PeripherySPIKey => up(PeripherySPIKey) ++ Seq(
SPIParams(rAddress = address))
})
/**
* Config fragment for adding a I2C peripheral device to the SoC
*
* @param address the address of the I2C controller
*/
class WithI2C(address: BigInt = 0x10040000) extends Config((site, here, up) => {
case PeripheryI2CKey => up(PeripheryI2CKey) ++ Seq(
I2CParams(address = address, controlXType = AsynchronousCrossing(), intXType = AsynchronousCrossing())
)
}) })
class WithNoDebug extends Config((site, here, up) => { class WithNoDebug extends Config((site, here, up) => {
case DebugModuleKey => None case DebugModuleKey => None
}) })
class WithTLSerialLocation(masterWhere: TLBusWrapperLocation, slaveWhere: TLBusWrapperLocation) extends Config((site, here, up) => { class WithDMIDTM extends Config((site, here, up) => {
case SerialTLAttachKey => up(SerialTLAttachKey, site).copy(masterWhere = masterWhere, slaveWhere = slaveWhere) case ExportDebug => up(ExportDebug, site).copy(protocols = Set(DMI))
})
/**
* Config fragment for adding a JTAG Debug Module to the SoC
*
* @param idcodeVersion the version of the JTAG protocol the Debug Module supports
* @param partNum the part number of the Debug Module
* @param manufId the 11-bit JEDEC Designer ID of the chip manufacturer
* @param debugIdleCycles the number of cycles the Debug Module waits before responding to a request
*/
class WithJTAGDTMKey(idcodeVersion: Int = 2, partNum: Int = 0x000, manufId: Int = 0x489, debugIdleCycles: Int = 5) extends Config((site, here, up) => {
case JtagDTMKey => new JtagDTMConfig (
idcodeVersion = idcodeVersion,
idcodePartNum = partNum,
idcodeManufId = manufId,
debugIdleCycles = debugIdleCycles)
}) })
class WithTLBackingMemory extends Config((site, here, up) => { class WithTLBackingMemory extends Config((site, here, up) => {
@@ -68,18 +141,6 @@ class WithTLBackingMemory extends Config((site, here, up) => {
case ExtTLMem => up(ExtMem, site) // enable TL backing memory case ExtTLMem => up(ExtMem, site) // enable TL backing memory
}) })
class WithSerialTLBackingMemory extends Config((site, here, up) => {
case ExtMem => None
case SerialTLKey => up(SerialTLKey, site).map { k => k.copy(
memParams = {
val memPortParams = up(ExtMem, site).get
require(memPortParams.nMemoryChannels == 1)
memPortParams.master
},
isMemoryDevice = true
)}
})
class WithExtMemIdBits(n: Int) extends Config((site, here, up) => { class WithExtMemIdBits(n: Int) extends Config((site, here, up) => {
case ExtMem => up(ExtMem, site).map(x => x.copy(master = x.master.copy(idBits = n))) case ExtMem => up(ExtMem, site).map(x => x.copy(master = x.master.copy(idBits = n)))
}) })
@@ -87,3 +148,23 @@ class WithExtMemIdBits(n: Int) extends Config((site, here, up) => {
class WithNoPLIC extends Config((site, here, up) => { class WithNoPLIC extends Config((site, here, up) => {
case PLICKey => None case PLICKey => None
}) })
class WithDebugModuleAbstractDataWords(words: Int = 16) extends Config((site, here, up) => {
case DebugModuleKey => up(DebugModuleKey).map(_.copy(nAbstractDataWords=words))
})
class WithNoCLINT extends Config((site, here, up) => {
case CLINTKey => None
})
class WithNoBootROM extends Config((site, here, up) => {
case BootROMLocated(_) => None
})
class WithNoBusErrorDevices extends Config((site, here, up) => {
case SystemBusKey => up(SystemBusKey).copy(errorDevice = None)
case ControlBusKey => up(ControlBusKey).copy(errorDevice = None)
case PeripheryBusKey => up(PeripheryBusKey).copy(errorDevice = None)
case MemoryBusKey => up(MemoryBusKey).copy(errorDevice = None)
case FrontBusKey => up(FrontBusKey).copy(errorDevice = None)
})

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