Merge remote-tracking branch 'origin/main' into bump-verilator
This commit is contained in:
2
.github/actions/cleanup-conda/action.yml
vendored
2
.github/actions/cleanup-conda/action.yml
vendored
@@ -15,7 +15,7 @@ runs:
|
||||
conda env remove -n $env
|
||||
done
|
||||
fi
|
||||
IS_NUMBER_REGEX='[0-9]+$'
|
||||
IS_NUMBER_REGEX='^[0-9]+$'
|
||||
conda env list | awk '{print $1}' | tail -n +4 | while read envname; do
|
||||
ENV_DATE=$(echo $envname | sed "s/cy-[[:digit:]]\+-\(.*\)-\(riscv\|esp\)-tools/\1/")
|
||||
if ! [[ $ENV_DATE =~ $IS_NUMBER_REGEX ]]; then
|
||||
|
||||
2
.github/scripts/check-commit.sh
vendored
2
.github/scripts/check-commit.sh
vendored
@@ -12,9 +12,7 @@ source $SCRIPT_DIR/defaults.sh
|
||||
cd $LOCAL_CHIPYARD_DIR
|
||||
|
||||
# ignore the private vlsi submodules
|
||||
git config submodule.vlsi/hammer-cadence-plugins.update none
|
||||
git config submodule.vlsi/hammer-mentor-plugins.update none
|
||||
git config submodule.vlsi/hammer-synopsys-plugins.update none
|
||||
|
||||
# initialize submodules and get the hashes
|
||||
git submodule update --init
|
||||
|
||||
4
.github/scripts/defaults.sh
vendored
4
.github/scripts/defaults.sh
vendored
@@ -29,7 +29,7 @@ REMOTE_COURSIER_CACHE=$REMOTE_WORK_DIR/.coursier-cache
|
||||
# key value store to get the build groups
|
||||
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-peripherals"]="chipyard-dmirocket chipyard-spiflashwrite chipyard-mmios chipyard-nocores chipyard-manyperipherals"
|
||||
grouping["group-peripherals"]="chipyard-dmirocket chipyard-dmiboom chipyard-spiflashwrite chipyard-mmios chipyard-nocores chipyard-manyperipherals chipyard-chiplike"
|
||||
grouping["group-accels"]="chipyard-mempress chipyard-sha3 chipyard-hwacha chipyard-gemmini chipyard-manymmioaccels"
|
||||
grouping["group-constellation"]="chipyard-constellation"
|
||||
grouping["group-tracegen"]="tracegen tracegen-boom"
|
||||
@@ -46,6 +46,7 @@ mapping["chipyard-digitaltop"]=" TOP=DigitalTop"
|
||||
mapping["chipyard-manymmioaccels"]=" CONFIG=ManyMMIOAcceleratorRocketConfig"
|
||||
mapping["chipyard-hetero"]=" CONFIG=LargeBoomAndRocketConfig"
|
||||
mapping["chipyard-boom"]=" CONFIG=MediumBoomCosimConfig"
|
||||
mapping["chipyard-dmiboom"]=" CONFIG=dmiMediumBoomCosimConfig"
|
||||
mapping["chipyard-spike"]=" CONFIG=SpikeFastUARTConfig EXTRA_SIM_FLAGS='+spike-ipc=10'"
|
||||
mapping["chipyard-hwacha"]=" CONFIG=HwachaRocketConfig"
|
||||
mapping["chipyard-gemmini"]=" CONFIG=GemminiRocketConfig"
|
||||
@@ -53,6 +54,7 @@ mapping["chipyard-cva6"]=" CONFIG=CVA6Config"
|
||||
mapping["chipyard-ibex"]=" CONFIG=IbexConfig"
|
||||
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-chiplike"]=" CONFIG=ChipLikeQuadRocketConfig MODEL=FlatTestHarness MODEL_PACKAGE=chipyard.example verilog"
|
||||
mapping["chipyard-cloneboom"]=" CONFIG=Cloned64MegaBoomConfig verilog"
|
||||
mapping["chipyard-nocores"]=" CONFIG=NoCoresConfig verilog"
|
||||
mapping["tracegen"]=" CONFIG=NonBlockingTraceGenL2Config"
|
||||
|
||||
2
.github/scripts/remote-do-rtl-build.sh
vendored
2
.github/scripts/remote-do-rtl-build.sh
vendored
@@ -16,8 +16,6 @@ source $SCRIPT_DIR/defaults.sh
|
||||
|
||||
cd $REMOTE_CHIPYARD_DIR
|
||||
./scripts/init-submodules-no-riscv-tools.sh --force
|
||||
./scripts/init-fpga.sh
|
||||
|
||||
|
||||
# Constellation can run without espresso, but this improves
|
||||
# elaboration time drastically
|
||||
|
||||
7
.github/scripts/run-tests.sh
vendored
7
.github/scripts/run-tests.sh
vendored
@@ -33,11 +33,16 @@ case $1 in
|
||||
run_bmark ${mapping[$1]}
|
||||
;;
|
||||
chipyard-dmirocket)
|
||||
run_bmark ${mapping[$1]}
|
||||
$LOCAL_CHIPYARD_DIR/scripts/generate-ckpt.sh -b $RISCV/riscv64-unknown-elf/share/riscv-tests/benchmarks/dhrystone.riscv -i 10000
|
||||
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} run-binary LOADARCH=$PWD/dhrystone.riscv.0x80000000.10000.loadarch
|
||||
;;
|
||||
chipyard-boom)
|
||||
run_bmark ${mapping[$1]}
|
||||
;;
|
||||
chipyard-dmiboom)
|
||||
$LOCAL_CHIPYARD_DIR/scripts/generate-ckpt.sh -b $RISCV/riscv64-unknown-elf/share/riscv-tests/benchmarks/dhrystone.riscv -i 10000
|
||||
make -C $LOCAL_SIM_DIR $DISABLE_SIM_PREREQ ${mapping[$1]} run-binary LOADARCH=$PWD/dhrystone.riscv.0x80000000.10000.loadarch
|
||||
;;
|
||||
chipyard-spike)
|
||||
run_bmark ${mapping[$1]}
|
||||
;;
|
||||
|
||||
53
.github/workflows/chipyard-run-tests.yml
vendored
53
.github/workflows/chipyard-run-tests.yml
vendored
@@ -390,6 +390,35 @@ jobs:
|
||||
|
||||
##########################################################################
|
||||
|
||||
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
|
||||
runs-on: ferry
|
||||
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: Build Gemmini FireMarshal
|
||||
run: |
|
||||
conda activate ${{ env.conda-env-name-no-time }}-$(date --date "${{ env.workflow-timestamp }}" +%Y%m%d)-riscv-tools
|
||||
cd ${{ github.workspace }} && ./scripts/init-submodules-no-riscv-tools.sh --force
|
||||
cd ${{ github.workspace }} && source ./scripts/fix-open-files.sh
|
||||
git submodule update --init software/firemarshal && cd software/firemarshal && ./init-submodules.sh
|
||||
cd ${{ github.workspace }}/generators/gemmini/software && ${{ github.workspace }}/software/firemarshal/marshal -v -d build gemmini-smoke.json
|
||||
- name: Running Gemmini FireMarshal smoke test
|
||||
run: |
|
||||
conda activate ${{ env.conda-env-name-no-time }}-$(date --date "${{ env.workflow-timestamp }}" +%Y%m%d)-riscv-tools
|
||||
cd ${{ github.workspace }}/generators/gemmini/software && ${{ github.workspace }}/software/firemarshal/marshal -v -d launch -s gemmini-smoke.json
|
||||
|
||||
chipyard-rocket-run-tests:
|
||||
name: chipyard-rocket-run-tests
|
||||
needs: prepare-chipyard-cores
|
||||
@@ -574,6 +603,29 @@ jobs:
|
||||
group-key: "group-peripherals"
|
||||
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:
|
||||
name: chipyard-spiflashwrite-run-tests
|
||||
needs: prepare-chipyard-peripherals
|
||||
@@ -915,6 +967,7 @@ jobs:
|
||||
chipyard-cva6-run-tests,
|
||||
chipyard-ibex-run-tests,
|
||||
chipyard-sodor-run-tests,
|
||||
chipyard-dmiboom-run-tests,
|
||||
chipyard-dmirocket-run-tests,
|
||||
chipyard-spiflashwrite-run-tests,
|
||||
chipyard-manyperipherals-run-tests,
|
||||
|
||||
12
.gitmodules
vendored
12
.gitmodules
vendored
@@ -34,12 +34,6 @@
|
||||
[submodule "generators/sha3"]
|
||||
path = generators/sha3
|
||||
url = https://github.com/ucb-bar/sha3.git
|
||||
[submodule "vlsi/hammer-cadence-plugins"]
|
||||
path = vlsi/hammer-cadence-plugins
|
||||
url = https://github.com/ucb-bar/hammer-cadence-plugins.git
|
||||
[submodule "vlsi/hammer-synopsys-plugins"]
|
||||
path = vlsi/hammer-synopsys-plugins
|
||||
url = https://github.com/ucb-bar/hammer-synopsys-plugins.git
|
||||
[submodule "vlsi/hammer-mentor-plugins"]
|
||||
path = vlsi/hammer-mentor-plugins
|
||||
url = https://github.com/ucb-bar/hammer-mentor-plugins.git
|
||||
@@ -79,9 +73,6 @@
|
||||
[submodule "fpga/fpga-shells"]
|
||||
path = fpga/fpga-shells
|
||||
url = https://github.com/chipsalliance/rocket-chip-fpga-shells.git
|
||||
[submodule "tools/api-config-chipsalliance"]
|
||||
path = tools/api-config-chipsalliance
|
||||
url = https://github.com/chipsalliance/api-config-chipsalliance.git
|
||||
[submodule "tools/rocket-dsp-utils"]
|
||||
path = tools/rocket-dsp-utils
|
||||
url = https://github.com/ucb-bar/rocket-dsp-utils
|
||||
@@ -127,3 +118,6 @@
|
||||
[submodule "generators/mempress"]
|
||||
path = generators/mempress
|
||||
url = https://github.com/ucb-bar/mempress.git
|
||||
[submodule "tools/cde"]
|
||||
path = tools/cde
|
||||
url = https://github.com/chipsalliance/cde.git
|
||||
|
||||
@@ -5,8 +5,6 @@ build:
|
||||
tools:
|
||||
python: "mambaforge-4.10"
|
||||
|
||||
formats: all
|
||||
|
||||
sphinx:
|
||||
configuration: docs/conf.py
|
||||
|
||||
|
||||
109
CHANGELOG.md
109
CHANGELOG.md
@@ -2,6 +2,115 @@
|
||||
|
||||
This changelog follows the format defined here: https://keepachangelog.com/en/1.0.0/
|
||||
|
||||
## [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
|
||||
|
||||
Faster FIRRTL build support work CIRCT. New software support for RISC-V GCC12 and Linux 6.2. Various bumps and fixes of all submodules.
|
||||
|
||||
### Added
|
||||
* Add example ring-only NoC Config by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1325
|
||||
* Bump Gemmini by @hngenc, @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1276 https://github.com/ucb-bar/chipyard/pull/1326
|
||||
* Bump FireMarshal, Bump to newer RV toolchain (deprecate use of esp-tools for Gemmini) by @abejgonzalez, @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1284 https://github.com/ucb-bar/chipyard/pull/1304 https://github.com/ucb-bar/chipyard/pull/1306 https://github.com/ucb-bar/chipyard/pull/1327 https://github.com/ucb-bar/chipyard/pull/1334 https://github.com/ucb-bar/chipyard/pull/1335 https://github.com/ucb-bar/chipyard/pull/1344 https://github.com/ucb-bar/chipyard/pull/1394 https://github.com/ucb-bar/chipyard/pull/1403 https://github.com/ucb-bar/chipyard/pull/1415
|
||||
* Add support for VC707 FPGA board by @Lorilandly in https://github.com/ucb-bar/chipyard/pull/1278
|
||||
* Fail simulations on TSI errors by @tymcauley in https://github.com/ucb-bar/chipyard/pull/1288
|
||||
* Add pre-commit support by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1294 https://github.com/ucb-bar/chipyard/pull/1310
|
||||
* Bump mempress by @joey0320 in https://github.com/ucb-bar/chipyard/pull/1305
|
||||
* CIRCT Integration by @abejgonzalez, @joey0320 in https://github.com/ucb-bar/chipyard/pull/1239 https://github.com/ucb-bar/chipyard/pull/1312 https://github.com/ucb-bar/chipyard/pull/1372 https://github.com/ucb-bar/chipyard/pull/1396
|
||||
* Bump to scala 2.13.10/chisel 3.5.5/latest rocketchip by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1303
|
||||
* Spike-as-a-Tile and use for co-simulation by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1307 https://github.com/ucb-bar/chipyard/pull/1323 https://github.com/ucb-bar/chipyard/pull/1360
|
||||
* Add clone-tile configs by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1322
|
||||
* New Hammer by @harrisonliew in https://github.com/ucb-bar/chipyard/pull/1324 https://github.com/ucb-bar/chipyard/pull/1368 https://github.com/ucb-bar/chipyard/pull/1374 https://github.com/ucb-bar/chipyard/pull/1369 https://github.com/ucb-bar/chipyard/pull/1410
|
||||
* Config finder `make` target by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1328 https://github.com/ucb-bar/chipyard/pull/1381
|
||||
* Arty100T board + TSI-over-UART by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1345
|
||||
* Add graphml visualization section to docs by @schwarz-em in https://github.com/ucb-bar/chipyard/pull/1387
|
||||
* Add a frag./config for MMIO only FireSim bridges by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1393
|
||||
* Add log of chisel elaboration to generated src by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1400
|
||||
* Xcelium support by @sagark in https://github.com/ucb-bar/chipyard/pull/1386
|
||||
* Bump Sodor @a0u in https://github.com/ucb-bar/chipyard/pull/1338
|
||||
* Bump Constellation by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1339
|
||||
|
||||
### Changed
|
||||
* remove RocketTilesKey by @SingularityKChen in https://github.com/ucb-bar/chipyard/pull/1264
|
||||
* Move setup script to scripts/, use a symlink at top-level by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1271
|
||||
* Decoupled sbus width from boom|hwacha|gemmini memory interface widths by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1273
|
||||
* Remove conda from build-toolchains-extra.sh by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1266
|
||||
* Rework build-setup | Add single-node CI by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1282
|
||||
* Switch simulators to C++17. by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1285
|
||||
* Init FPGA submodules in build-setup.sh by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1292
|
||||
* Stripped down rocket configs for FireSim testing by @t14916 in https://github.com/ucb-bar/chipyard/pull/1302
|
||||
* Add more minimal firesim configs for testing by @t14916 in https://github.com/ucb-bar/chipyard/pull/1313
|
||||
* Add workshop info to README.md by @sagark in https://github.com/ucb-bar/chipyard/pull/1314
|
||||
* Removed FireSim tests and harnesses by @nandor in https://github.com/ucb-bar/chipyard/pull/1317
|
||||
* Move boom's tracegen interface to boom submodule by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1331
|
||||
* Split up RocketConfigs.scala by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1340
|
||||
* Sky130/Openroad Tutorial Fixes by @nayiri-k in https://github.com/ucb-bar/chipyard/pull/1392
|
||||
* Testing VLSI commands for chipyard tutorial by @nayiri-k in https://github.com/ucb-bar/chipyard/pull/1395
|
||||
* Reduce test cases for noc-config in CI by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1359
|
||||
* Remove TLHelper, directly use tilelink node constructors by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1358
|
||||
* Remove chisel-testers submodule by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1378
|
||||
* Cache `.ivy2` and `.sbt` within Chipyard root directory by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1362
|
||||
|
||||
### Fixed
|
||||
* Remove extra parenthesis by @odxa20 in https://github.com/ucb-bar/chipyard/pull/1261
|
||||
* Fixed typo in Initial-Repo-Setup.rst by @PisonJay in https://github.com/ucb-bar/chipyard/pull/1269
|
||||
* fix: S-interpolator for assert, assume and printf by @SingularityKChen in https://github.com/ucb-bar/chipyard/pull/1242
|
||||
* Revert "fix: S-interpolator for assert, assume and printf" by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1272
|
||||
* changelog: fixed TinyRocketArtyConfig FPGA reset signal polarity (Please Backport) by @T-K-233 in https://github.com/ucb-bar/chipyard/pull/1257
|
||||
* Fix CY logo in README by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1295
|
||||
* More files to gitignore by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1297
|
||||
* Bump rocket-dsp-utils for ShiftRegisterMem fix. by @milovanovic in https://github.com/ucb-bar/chipyard/pull/1298
|
||||
* Set VLOGMODEL=MODEL by default in variables.mk by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1337
|
||||
* Fix compile breaking due to merge conflict by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1321
|
||||
* Makefile bug fixes by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1336
|
||||
* Fix Verilog Prerequisites + Ignore `mv` stdout by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1406
|
||||
* Fix Chisel hierarchy API - Fixes #1356 by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1361
|
||||
* Remove gen-collateral when rebuilding by @joey0320 in https://github.com/ucb-bar/chipyard/pull/1342
|
||||
* Fix VLSI input files list emission to avoid bash "too many arguments" error by @sagark in https://github.com/ucb-bar/chipyard/pull/1348
|
||||
* Small build system improvements by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1349
|
||||
* Fix socket name length issues on CI by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1353
|
||||
* Fix TestDriver.v missing from gen-collateral after recompiling by @joey0320 in https://github.com/ucb-bar/chipyard/pull/1354
|
||||
* Consolidate CI testing configs to improve CI runtime by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1352
|
||||
* Remove Duplicate Compiler Flags by @joey0320 in https://github.com/ucb-bar/chipyard/pull/1351
|
||||
* fpga makefile clean fix by @joey0320 in https://github.com/ucb-bar/chipyard/pull/1357
|
||||
* Fix newline in message in build-setup.sh by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1365
|
||||
* Update assert message if configs can't be split by `:` by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1373
|
||||
* Remove Duplicate Compiler Flags by @joey0320 in https://github.com/ucb-bar/chipyard/pull/1367
|
||||
* Move more tmp/ folders to a unique location by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1382
|
||||
* Remove stale conda env's after 2 days by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1389
|
||||
* Match CY/FireSim deps | Unpin deps | Update lockfiles by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1391
|
||||
* Only support HTML docs by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1401
|
||||
* Only HTML docs v2 by @abejgonzalez in https://github.com/ucb-bar/chipyard/pull/1402
|
||||
* Fix ANSI color output by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1407
|
||||
* Fix chisel elab errors not causing flow to stop by @jerryz123 in https://github.com/ucb-bar/chipyard/pull/1409
|
||||
* lean gemmini tutorial by @sagark in https://github.com/ucb-bar/chipyard/pull/1413
|
||||
|
||||
## [1.8.1] - 2022-10-18
|
||||
|
||||
Various fixes and improvements, bump FireSim to 1.15.1.
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
|
||||
# Chipyard Framework [](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
|
||||
|
||||
* **Stable Documentation**: https://chipyard.readthedocs.io/
|
||||
|
||||
33
build.sbt
33
build.sbt
@@ -62,7 +62,7 @@ def isolateAllTests(tests: Seq[TestDefinition]) = tests map { test =>
|
||||
new Group(test.name, Seq(test), SubProcess(options))
|
||||
} toSeq
|
||||
|
||||
val chiselVersion = "3.5.5"
|
||||
val chiselVersion = "3.5.6"
|
||||
|
||||
lazy val chiselSettings = Seq(
|
||||
libraryDependencies ++= Seq("edu.berkeley.cs" %% "chisel3" % chiselVersion,
|
||||
@@ -102,18 +102,8 @@ lazy val rocketMacros = (project in rocketChipDir / "macros")
|
||||
)
|
||||
)
|
||||
|
||||
lazy val rocketConfig = (project in rocketChipDir / "api-config-chipsalliance/build-rules/sbt")
|
||||
.settings(commonSettings)
|
||||
.settings(
|
||||
libraryDependencies ++= Seq(
|
||||
"org.scala-lang" % "scala-reflect" % scalaVersion.value,
|
||||
"org.json4s" %% "json4s-jackson" % "3.6.6",
|
||||
"org.scalatest" %% "scalatest" % "3.2.0" % "test"
|
||||
)
|
||||
)
|
||||
|
||||
lazy val rocketchip = freshProject("rocketchip", rocketChipDir)
|
||||
.dependsOn(hardfloat, rocketMacros, rocketConfig)
|
||||
.dependsOn(hardfloat, rocketMacros, cde)
|
||||
.settings(commonSettings)
|
||||
.settings(chiselSettings)
|
||||
.settings(
|
||||
@@ -149,7 +139,12 @@ lazy val chipyard = (project in file("generators/chipyard"))
|
||||
gemmini, icenet, tracegen, cva6, nvdla, sodor, ibex, fft_generator,
|
||||
constellation, mempress)
|
||||
.settings(libraryDependencies ++= rocketLibDeps.value)
|
||||
.settings(commonSettings)
|
||||
.settings(
|
||||
libraryDependencies ++= Seq(
|
||||
"org.reflections" % "reflections" % "0.10.2"
|
||||
)
|
||||
)
|
||||
.settings(commonSettings)
|
||||
|
||||
lazy val mempress = (project in file("generators/mempress"))
|
||||
.dependsOn(rocketchip, midasTargetUtils)
|
||||
@@ -246,16 +241,12 @@ lazy val dsptools = freshProject("dsptools", file("./tools/dsptools"))
|
||||
"org.scalacheck" %% "scalacheck" % "1.14.3" % "test",
|
||||
))
|
||||
|
||||
lazy val `api-config-chipsalliance` = freshProject("api-config-chipsalliance", file("./tools/api-config-chipsalliance"))
|
||||
.settings(
|
||||
commonSettings,
|
||||
libraryDependencies ++= Seq(
|
||||
"org.scalatest" %% "scalatest" % "3.0.+" % "test",
|
||||
"org.scalacheck" %% "scalacheck" % "1.14.3" % "test",
|
||||
))
|
||||
lazy val cde = (project in file("tools/cde"))
|
||||
.settings(commonSettings)
|
||||
.settings(Compile / scalaSource := baseDirectory.value / "cde/src/chipsalliance/rocketchip")
|
||||
|
||||
lazy val `rocket-dsp-utils` = freshProject("rocket-dsp-utils", file("./tools/rocket-dsp-utils"))
|
||||
.dependsOn(rocketchip, `api-config-chipsalliance`, dsptools)
|
||||
.dependsOn(rocketchip, cde, dsptools)
|
||||
.settings(libraryDependencies ++= rocketLibDeps.value)
|
||||
.settings(commonSettings)
|
||||
|
||||
|
||||
77
common.mk
77
common.mk
@@ -18,7 +18,7 @@ HELP_COMPILATION_VARIABLES += \
|
||||
" 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_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_FIRRTL_OPTIONS = additional options to pass to the FIRRTL compiler"
|
||||
|
||||
@@ -50,13 +50,14 @@ HELP_COMMANDS += \
|
||||
" run-tests = run all assembly and benchmark tests" \
|
||||
" 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 and their locations (recursive up to CONFIG_FRAG_LEVELS=$(CONFIG_FRAG_LEVELS))"
|
||||
" find-config-fragments = list all config. fragments"
|
||||
|
||||
#########################################################################################
|
||||
# include additional subproject make fragments
|
||||
# see HELP_COMPILATION_VARIABLES
|
||||
#########################################################################################
|
||||
include $(base_dir)/generators/cva6/cva6.mk
|
||||
include $(base_dir)/generators/ibex/ibex.mk
|
||||
include $(base_dir)/generators/tracegen/tracegen.mk
|
||||
include $(base_dir)/generators/nvdla/nvdla.mk
|
||||
include $(base_dir)/tools/dromajo/dromajo.mk
|
||||
@@ -104,14 +105,14 @@ $(BOOTROM_TARGETS): $(build_dir)/bootrom.%.img: $(TESTCHIP_RSRCS_DIR)/testchipip
|
||||
# create firrtl file rule and variables
|
||||
#########################################################################################
|
||||
# AG: must re-elaborate if cva6 sources have changed... otherwise just run firrtl compile
|
||||
$(FIRRTL_FILE) $(ANNO_FILE) &: $(SCALA_SOURCES) $(SCALA_BUILDTOOL_DEPS) $(EXTRA_GENERATOR_REQS)
|
||||
$(FIRRTL_FILE) $(ANNO_FILE) $(CHISEL_LOG_FILE) &: $(SCALA_SOURCES) $(SCALA_BUILDTOOL_DEPS) $(EXTRA_GENERATOR_REQS)
|
||||
mkdir -p $(build_dir)
|
||||
$(call run_scala_main,$(SBT_PROJECT),$(GENERATOR_PACKAGE).Generator,\
|
||||
(set -o pipefail && $(call run_scala_main,$(SBT_PROJECT),$(GENERATOR_PACKAGE).Generator,\
|
||||
--target-dir $(build_dir) \
|
||||
--name $(long_name) \
|
||||
--top-module $(MODEL_PACKAGE).$(MODEL) \
|
||||
--legacy-configs $(CONFIG_PACKAGE):$(CONFIG) \
|
||||
$(EXTRA_CHISEL_OPTIONS))
|
||||
$(EXTRA_CHISEL_OPTIONS)) | tee $(CHISEL_LOG_FILE))
|
||||
|
||||
define mfc_extra_anno_contents
|
||||
[
|
||||
@@ -174,7 +175,7 @@ MFC_BASE_LOWERING_OPTIONS = emittedLineLength=2048,noAlwaysComb,disallowLocalVar
|
||||
# hack: lower to low firrtl if Fixed types are found
|
||||
# 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
|
||||
$(SFC_LEVEL) $(EXTRA_FIRRTL_OPTIONS) $(FINAL_ANNO_FILE) $(MFC_LOWERING_OPTIONS) &: $(FIRRTL_FILE) $(EXTRA_ANNO_FILE) $(SFC_EXTRA_ANNO_FILE)
|
||||
$(SFC_LEVEL) $(EXTRA_FIRRTL_OPTIONS) $(FINAL_ANNO_FILE) $(MFC_LOWERING_OPTIONS) &: $(FIRRTL_FILE) $(EXTRA_ANNO_FILE) $(SFC_EXTRA_ANNO_FILE) $(VLOG_SOURCES)
|
||||
ifeq (,$(ENABLE_CUSTOM_FIRRTL_PASS))
|
||||
$(eval SFC_LEVEL := $(if $(shell grep "Fixed<" $(FIRRTL_FILE)), low, none))
|
||||
$(eval EXTRA_FIRRTL_OPTIONS += $(if $(shell grep "Fixed<" $(FIRRTL_FILE)), $(SFC_REPL_SEQ_MEM),))
|
||||
@@ -191,7 +192,7 @@ endif
|
||||
if [ $(SFC_LEVEL) = none ]; then cat $(EXTRA_ANNO_FILE) > $(FINAL_ANNO_FILE); fi
|
||||
|
||||
$(SFC_MFC_TARGETS) &: private TMP_DIR := $(shell mktemp -d -t cy-XXXXXXXX)
|
||||
$(SFC_MFC_TARGETS) &: $(FIRRTL_FILE) $(FINAL_ANNO_FILE) $(VLOG_SOURCES) $(SFC_LEVEL) $(EXTRA_FIRRTL_OPTIONS)
|
||||
$(SFC_MFC_TARGETS) &: $(FIRRTL_FILE) $(FINAL_ANNO_FILE) $(SFC_LEVEL) $(EXTRA_FIRRTL_OPTIONS)
|
||||
rm -rf $(GEN_COLLATERAL_DIR)
|
||||
$(call run_scala_main,tapeout,barstools.tapeout.transforms.GenerateModelStageMain,\
|
||||
--no-dedup \
|
||||
@@ -204,7 +205,7 @@ $(SFC_MFC_TARGETS) &: $(FIRRTL_FILE) $(FINAL_ANNO_FILE) $(VLOG_SOURCES) $(SFC_LE
|
||||
--allow-unrecognized-annotations \
|
||||
-X $(SFC_LEVEL) \
|
||||
$(EXTRA_FIRRTL_OPTIONS))
|
||||
-mv $(SFC_FIRRTL_BASENAME).lo.fir $(SFC_FIRRTL_FILE) # 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 [ $(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
|
||||
@@ -226,36 +227,32 @@ $(SFC_MFC_TARGETS) &: $(FIRRTL_FILE) $(FINAL_ANNO_FILE) $(VLOG_SOURCES) $(SFC_LE
|
||||
--split-verilog \
|
||||
-o $(GEN_COLLATERAL_DIR) \
|
||||
$(SFC_FIRRTL_FILE)
|
||||
-mv $(SFC_SMEMS_CONF) $(MFC_SMEMS_CONF)
|
||||
-mv $(SFC_SMEMS_CONF) $(MFC_SMEMS_CONF) 2> /dev/null
|
||||
$(SED) -i 's/.*/& /' $(MFC_SMEMS_CONF) # need trailing space for SFC macrocompiler
|
||||
# DOC include end: FirrtlCompiler
|
||||
|
||||
$(TOP_MODS_FILELIST) $(MODEL_MODS_FILELIST) $(ALL_MODS_FILELIST) $(BB_MODS_FILELIST) &: $(MFC_MODEL_HRCHY_JSON) $(MFC_FILELIST) $(MFC_BB_MODS_FILELIST)
|
||||
$(base_dir)/scripts/split-module-files.py \
|
||||
$(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/uniquify-module-names.py \
|
||||
--model-hier-json $(MFC_MODEL_HRCHY_JSON) \
|
||||
--top-hier-json $(MFC_TOP_HRCHY_JSON) \
|
||||
--in-all-filelist $(MFC_FILELIST) \
|
||||
--dut $(TOP) \
|
||||
--model $(MODEL) \
|
||||
--target-dir $(GEN_COLLATERAL_DIR) \
|
||||
--out-dut-filelist $(TOP_MODS_FILELIST) \
|
||||
--out-model-filelist $(MODEL_MODS_FILELIST) \
|
||||
--in-all-filelist $(MFC_FILELIST) \
|
||||
--target-dir $(GEN_COLLATERAL_DIR)
|
||||
--out-model-hier-json $(MFC_MODEL_HRCHY_JSON_UNIQUIFIED) \
|
||||
--gcpath $(GEN_COLLATERAL_DIR)
|
||||
$(SED) -e 's;^;$(GEN_COLLATERAL_DIR)/;' $(MFC_BB_MODS_FILELIST) > $(BB_MODS_FILELIST)
|
||||
$(SED) -i 's/\.\///' $(TOP_MODS_FILELIST)
|
||||
$(SED) -i 's/\.\///' $(MODEL_MODS_FILELIST)
|
||||
$(SED) -i 's/\.\///' $(BB_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)
|
||||
$(TOP_SMEMS_CONF) $(MODEL_SMEMS_CONF) &: $(MFC_SMEMS_CONF) $(MFC_MODEL_HRCHY_JSON_UNIQUIFIED)
|
||||
$(base_dir)/scripts/split-mems-conf.py \
|
||||
--in-smems-conf $(MFC_SMEMS_CONF) \
|
||||
--in-model-hrchy-json $(MFC_MODEL_HRCHY_JSON) \
|
||||
--in-model-hrchy-json $(MFC_MODEL_HRCHY_JSON_UNIQUIFIED) \
|
||||
--dut-module-name $(TOP) \
|
||||
--model-module-name $(MODEL) \
|
||||
--out-dut-smems-conf $(TOP_SMEMS_CONF) \
|
||||
@@ -275,7 +272,7 @@ $(MODEL_SMEMS_FILE) $(MODEL_SMEMS_FIR) &: $(MODEL_SMEMS_CONF) | $(TOP_SMEMS_FILE
|
||||
# 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
|
||||
########################################################################################
|
||||
$(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\)$$' > $@
|
||||
echo "$(TOP_SMEMS_FILE)" >> $@
|
||||
echo "$(MODEL_SMEMS_FILE)" >> $@
|
||||
@@ -317,29 +314,15 @@ run-binary-debug: $(SIM_DEBUG_PREREQ) check-binary | $(output_dir)
|
||||
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)
|
||||
$(base_dir)/scripts/smartelf2hex.sh $(firstword $(BINARY)) > $(binary_hex)
|
||||
|
||||
run-binary-hex: check-binary
|
||||
run-binary-hex: $(SIM_PREREQ) $(binary_hex) | $(output_dir)
|
||||
run-binary-hex: run-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-hex: override SIM_FLAGS += +loadmem=$(BINARY)
|
||||
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-debug-hex: override SIM_FLAGS += +loadmem=$(BINARY)
|
||||
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-binary-fast-hex: override SIM_FLAGS += +loadmem=$(BINARY)
|
||||
|
||||
#########################################################################################
|
||||
# run assembly/benchmarks rules
|
||||
@@ -405,13 +388,9 @@ define \n
|
||||
|
||||
endef
|
||||
|
||||
CONFIG_FRAG_LEVELS ?= 3
|
||||
.PHONY: find-config-fragments
|
||||
find-config-fragments: private IN_F := $(shell mktemp -d -t cy-XXXXXXXX)/scala_files.f
|
||||
find-config-fragments: $(SCALA_SOURCES)
|
||||
@$(foreach file,$(SCALA_SOURCES),echo $(file) >> $(IN_F)${\n})
|
||||
$(base_dir)/scripts/config-finder.py -l $(CONFIG_FRAG_LEVELS) $(IN_F)
|
||||
@rm -rf $(dir $(IN_F))
|
||||
find-config-fragments:
|
||||
$(call run_scala_main,chipyard,chipyard.ConfigFinder,)
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
channels:
|
||||
- ucb-bar
|
||||
- litex-hub
|
||||
- conda-forge
|
||||
- litex-hub
|
||||
- nodefaults
|
||||
|
||||
platforms:
|
||||
@@ -103,7 +103,7 @@ dependencies:
|
||||
- sty
|
||||
- open_pdks.sky130a
|
||||
- pip:
|
||||
- hammer-vlsi[asap7]==1.0.5
|
||||
- hammer-vlsi[asap7]==1.1.1
|
||||
|
||||
# doc requirements
|
||||
- sphinx
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
channels:
|
||||
- ucb-bar
|
||||
- litex-hub
|
||||
- conda-forge
|
||||
- litex-hub
|
||||
- nodefaults
|
||||
|
||||
platforms:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
channels:
|
||||
- ucb-bar
|
||||
- litex-hub
|
||||
- conda-forge
|
||||
- litex-hub
|
||||
- nodefaults
|
||||
|
||||
platforms:
|
||||
|
||||
39
docs/Advanced-Concepts/Architectural-Checkpoints.rst
Normal file
39
docs/Advanced-Concepts/Architectural-Checkpoints.rst
Normal 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
|
||||
|
||||
@@ -206,8 +206,12 @@ This type of simulation setup is done in the following multi-clock configuration
|
||||
:start-after: DOC include start: 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.
|
||||
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).
|
||||
@@ -222,4 +226,4 @@ The following image shows this flow:
|
||||
.. image:: ../_static/images/chip-bringup.png
|
||||
|
||||
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.
|
||||
|
||||
@@ -18,12 +18,12 @@ 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``.
|
||||
Requests for a harness clock is done by the ``HarnessClockInstantiator`` class in ``generators/chipyard/src/main/scala/harness/TestHarness.scala``.
|
||||
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.
|
||||
Take the following example:
|
||||
|
||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/HarnessBinders.scala
|
||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/harness/HarnessBinders.scala
|
||||
:language: scala
|
||||
:start-after: DOC include start: HarnessClockInstantiatorEx
|
||||
:end-before: DOC include end: HarnessClockInstantiatorEx
|
||||
|
||||
@@ -18,6 +18,13 @@ The ``IOBinders`` are responsible for instantiating the IO cells for ``ChipTop``
|
||||
The ``HarnessBinders`` are responsible for instantiating test harness collateral that connects to the ``ChipTop`` ports.
|
||||
Most types of devices and testing collateral can be instantiated using custom ``IOBinders`` and ``HarnessBinders``.
|
||||
|
||||
Custom ChipTops
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The default standard ``ChipTop`` provides a mimimal, barebones template for ``IOBinders`` to generate IOCells around ``DigitalTop`` traits.
|
||||
For tapeouts, integrating Analog IP, or other non-standard use cases, Chipyard supports specifying a custom ``ChipTop`` using the ``BuildTop`` key.
|
||||
An example of a custom ChipTop which uses non-standard IOCells is provided in `generators/chipyard/src/main/scala/example/CustomChipTop.scala <https://github.com/ucb-bar/chipyard/blob/main/generators/chipyard/src/main/scala/example/CustomChipTop.scala>`__
|
||||
|
||||
|
||||
System/DigitalTop
|
||||
-------------------------
|
||||
|
||||
@@ -16,3 +16,4 @@ They expect you to know about Chisel, Parameters, configs, etc.
|
||||
CDEs
|
||||
Harness-Clocks
|
||||
Managing-Published-Scala-Dependencies
|
||||
Architectural-Checkpoints
|
||||
|
||||
@@ -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.
|
||||
|
||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/HarnessBinders.scala
|
||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/harness/HarnessBinders.scala
|
||||
:language: scala
|
||||
:start-after: DOC include start: WithUARTAdapter
|
||||
:end-before: DOC include end: WithUARTAdapter
|
||||
|
||||
@@ -79,5 +79,4 @@ We can use this config fragment when composing our configs.
|
||||
Chipyard Config Fragments
|
||||
-------------------------
|
||||
|
||||
For discoverability, users can run ``make find-config-fragments`` to see a list of config. fragments
|
||||
(config. fragments that match "class NAME extends CONFIG\n" on a single line and a subset of their children) and their file path in a fully initialized Chipyard repository.
|
||||
For discoverability, users can run ``make find-config-fragments`` to see a list of config. fragments.
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
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.
|
||||
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
|
||||
----------------------
|
||||
|
||||
@@ -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``).
|
||||
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/``.
|
||||
This example extends the default test harness and creates new ``Overlays`` to connect to a DUT (connected to the FMC port).
|
||||
|
||||
@@ -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.
|
||||
Loadmem files should be ELF files. In the most common use case, this can be the binary.
|
||||
|
||||
.. 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.
|
||||
|
||||
.. 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.
|
||||
Usually the ``LOADMEM`` ELF is the same as the ``BINARY`` ELF, so ``LOADMEM=1`` can be used as a shortcut.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
make run-binary-hex BINARY=test.riscv
|
||||
make run-binary BINARY=test.riscv LOADMEM=1
|
||||
|
||||
Generating Waveforms
|
||||
-----------------------
|
||||
|
||||
@@ -32,4 +32,21 @@ In this configuration, Spike is cache-coherent, and communicates with the uncore
|
||||
|
||||
make CONFIG=SpikeConfig run-binary BINARY=hello.riscv
|
||||
|
||||
Spike-as-a-Tile also supports Tightly-Coupled-Memory (TCM) for the SpikeTile, in which the main system memory is entirely modeled
|
||||
within the Spike tile, allowing for very fast simulatoin performance.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
make CONFIG=SpikeUltraFastConfig run-binary BINARY=hello.riscv
|
||||
|
||||
Spike-as-a-Tile can be configured with custom IPC, commit logging, and other behaviors. Spike-specific flags can be added as plusargs to ``EXTRA_SIM_FLAGS``
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
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-fast-clint``: Enables fast-forwarding through WFI stalls by generating fake timer interrupts
|
||||
* ``+spike-debug``: Enables debug Spike logging
|
||||
* ``+spike-verbose``: Enables Spike commit-log generation
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
ASAP7 Tutorial
|
||||
==============
|
||||
The ``vlsi`` folder of this repository contains an example Hammer flow with the SHA-3 accelerator and a dummy hard macro. This example tutorial uses the built-in ASAP7 technology plugin and requires access to the included Cadence and Mentor tool plugin submodules. Cadence is necessary for synthesis & place-and-route, while Mentor is needed for DRC & LVS.
|
||||
The ``vlsi`` folder of this repository contains an example Hammer flow with the SHA-3 accelerator and a dummy hard macro. This example tutorial uses the built-in ASAP7 technology plugin and requires access to the included Mentor tool plugin submodule, which is needed for DRC & LVS.
|
||||
|
||||
Project Structure
|
||||
-----------------
|
||||
@@ -115,7 +115,7 @@ Timing reports are found in ``build/par-rundir/timingReports``. They are gzipped
|
||||
|
||||
.. 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.
|
||||
|
||||
@@ -126,9 +126,9 @@ To run DRC & LVS, and view the results in Calibre:
|
||||
.. code-block:: shell
|
||||
|
||||
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
|
||||
./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>`__.
|
||||
Furthermore, the dummy SRAMs that are provided in this tutorial and PDK do not have any geometry inside, so will certainly cause DRC errors.
|
||||
|
||||
@@ -162,7 +162,7 @@ Simulation-exacted power estimation often requires a dedicated testharness for t
|
||||
The simulation-extracted power estimation flow implicitly uses Hammer's gate-level simulation flow (in order to generate the ``saif`` activity data file). This gate-level simulation flow can also be run independantly from the power estimation flow using the ``make sim-par`` command.
|
||||
|
||||
|
||||
.. Note:: The gate-level simulation flow (and there the simulation-extracted power-estimation) is currently integrated only with the Synopsys VCS simulation (Verilator does not support gate-level simulation. Support for Cadence Incisive is work-in-progress)
|
||||
.. Note:: The gate-level simulation flow (and there the simulation-extracted power-estimation) is currently integrated only with the Synopsys VCS simulation (Verilator does not support gate-level simulation. Support for Cadence Xcelium is work-in-progress)
|
||||
|
||||
|
||||
Signoff
|
||||
|
||||
@@ -46,7 +46,7 @@ The current set of all available Hammer APIs is codified `here <https://github.c
|
||||
Tool Plugins
|
||||
============
|
||||
|
||||
Hammer supports separately managed plugins for different CAD tool vendors. You may be able to acquire access to the included Cadence, Synopsys, and Mentor plugins repositories with permission from the respective CAD tool vendor.
|
||||
Hammer supports separately managed plugins for different CAD tool vendors. You may be able to acquire access to the included Mentor plugins submodule with permission from the respective CAD tool vendor.
|
||||
The types of tools (by Hammer names) supported currently include:
|
||||
|
||||
* synthesis
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Sky130 Commercial Tutorial
|
||||
==========================
|
||||
The ``vlsi`` folder of this repository contains an example Hammer flow with the TinyRocketConfig from Chipyard. This example tutorial uses the built-in Sky130 technology plugin and requires access to the included Cadence and Mentor tool plugin submodules. Cadence is necessary for synthesis & place-and-route, while Mentor is needed for DRC & LVS.
|
||||
The ``vlsi`` folder of this repository contains an example Hammer flow with the TinyRocketConfig from Chipyard. This example tutorial uses the built-in Sky130 technology plugin and requires access to the included Mentor tool plugin submodule, which is needed for DRC & LVS.
|
||||
|
||||
Project Structure
|
||||
-----------------
|
||||
@@ -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
|
||||
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.
|
||||
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
|
||||
@@ -168,9 +168,9 @@ To run DRC & LVS, and view the results in Calibre:
|
||||
.. code-block:: shell
|
||||
|
||||
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
|
||||
./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
|
||||
`Sky130 Hammer plugin README <https://github.com/ucb-bar/hammer/blob/master/hammer/technology/sky130>`__.
|
||||
|
||||
@@ -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
|
||||
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.
|
||||
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
|
||||
@@ -197,7 +197,7 @@ Hammer generates a convenient script to launch these sessions
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
cd ./build/chipyard.TestHarness.TinyRocketConfig-ChipTop/par-rundir
|
||||
cd ./build/chipyard.harness.TestHarness.TinyRocketConfig-ChipTop/par-rundir
|
||||
./generated-scripts/open_chip
|
||||
|
||||
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
|
||||
|
||||
cd build/chipyard.TestHarness.TinyRocketConfig-ChipTop/par-rundir
|
||||
cd build/chipyard.harness.TestHarness.TinyRocketConfig-ChipTop/par-rundir
|
||||
./generated_scripts/open_chip -h
|
||||
"
|
||||
Usage: ./generated-scripts/open_chip [-t] [openroad_db_name]
|
||||
@@ -245,9 +245,9 @@ To run DRC & LVS in Magic & Netgen, respectively:
|
||||
.. code-block:: shell
|
||||
|
||||
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
|
||||
./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:
|
||||
|
||||
|
||||
Submodule fpga/fpga-shells updated: b6cd1bb7fe...9f4c6ac571
@@ -1,7 +1,7 @@
|
||||
// See LICENSE for license details.
|
||||
package chipyard.fpga.arty
|
||||
|
||||
import freechips.rocketchip.config._
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.devices.debug._
|
||||
import freechips.rocketchip.devices.tilelink._
|
||||
@@ -17,9 +17,9 @@ import chipyard.{BuildSystem}
|
||||
|
||||
// DOC include start: AbstractArty and Rocket
|
||||
class WithArtyTweaks extends Config(
|
||||
new WithArtyResetHarnessBinder ++
|
||||
new WithArtyJTAGHarnessBinder ++
|
||||
new WithArtyUARTHarnessBinder ++
|
||||
new WithArtyResetHarnessBinder ++
|
||||
new WithDebugResetPassthrough ++
|
||||
|
||||
new chipyard.config.WithDTSTimebase(32768) ++
|
||||
|
||||
@@ -2,7 +2,7 @@ package chipyard.fpga.arty
|
||||
|
||||
import chisel3._
|
||||
|
||||
import freechips.rocketchip.devices.debug.{HasPeripheryDebug, HasPeripheryDebugModuleImp}
|
||||
import freechips.rocketchip.devices.debug.{HasPeripheryDebug}
|
||||
import freechips.rocketchip.jtag.{JTAGIO}
|
||||
|
||||
import sifive.blocks.devices.uart.{UARTPortIO, HasPeripheryUARTModuleImp}
|
||||
@@ -15,15 +15,15 @@ import chipyard.harness.{ComposeHarnessBinder, OverrideHarnessBinder}
|
||||
import chipyard.iobinders.JTAGChipIO
|
||||
|
||||
class WithArtyResetHarnessBinder extends ComposeHarnessBinder({
|
||||
(system: HasPeripheryDebugModuleImp, th: ArtyFPGATestHarness, ports: Seq[Bool]) => {
|
||||
require(ports.size == 2)
|
||||
|
||||
(system: HasPeripheryDebug, th: ArtyFPGATestHarness, ports: Seq[Data]) => {
|
||||
val resetPorts = ports.collect { case b: Bool => b }
|
||||
require(resetPorts.size == 2)
|
||||
withClockAndReset(th.clock_32MHz, th.ck_rst) {
|
||||
// Debug module reset
|
||||
th.dut_ndreset := ports(0)
|
||||
th.dut_ndreset := resetPorts(0)
|
||||
|
||||
// JTAG reset
|
||||
ports(1) := PowerOnResetFPGAOnly(th.clock_32MHz)
|
||||
resetPorts(1) := PowerOnResetFPGAOnly(th.clock_32MHz)
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -63,6 +63,7 @@ class WithArtyJTAGHarnessBinder extends OverrideHarnessBinder({
|
||||
io_jtag.TMS.i.po.map(_ := DontCare)
|
||||
io_jtag.TDO.i.po.map(_ := DontCare)
|
||||
}
|
||||
case b: Bool =>
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -3,12 +3,12 @@ package chipyard.fpga.arty
|
||||
import chisel3._
|
||||
import chisel3.experimental.{IO}
|
||||
|
||||
import freechips.rocketchip.devices.debug.{HasPeripheryDebugModuleImp}
|
||||
import freechips.rocketchip.devices.debug.{HasPeripheryDebug}
|
||||
|
||||
import chipyard.iobinders.{ComposeIOBinder}
|
||||
|
||||
class WithDebugResetPassthrough extends ComposeIOBinder({
|
||||
(system: HasPeripheryDebugModuleImp) => {
|
||||
(system: HasPeripheryDebug) => {
|
||||
// Debug module reset
|
||||
val io_ndreset: Bool = IO(Output(Bool())).suggestName("ndreset")
|
||||
io_ndreset := system.debug.get.ndreset
|
||||
|
||||
@@ -3,12 +3,11 @@ package chipyard.fpga.arty
|
||||
import chisel3._
|
||||
|
||||
import freechips.rocketchip.diplomacy.{LazyModule}
|
||||
import freechips.rocketchip.config.{Parameters}
|
||||
import org.chipsalliance.cde.config.{Parameters}
|
||||
|
||||
import sifive.fpgashells.shell.xilinx.artyshell.{ArtyShell}
|
||||
|
||||
import chipyard.{BuildTop, HasHarnessSignalReferences}
|
||||
import chipyard.harness.{ApplyHarnessBinders}
|
||||
import chipyard.harness.{ApplyHarnessBinders, BuildTop, HasHarnessSignalReferences}
|
||||
import chipyard.iobinders.{HasIOBinders}
|
||||
|
||||
class ArtyFPGATestHarness(override implicit val p: Parameters) extends ArtyShell with HasHarnessSignalReferences {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// See LICENSE for license details.
|
||||
package chipyard.fpga.arty100t
|
||||
|
||||
import freechips.rocketchip.config._
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.devices.debug._
|
||||
import freechips.rocketchip.devices.tilelink._
|
||||
|
||||
@@ -3,7 +3,7 @@ package chipyard.fpga.arty100t
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.config.{Parameters}
|
||||
import org.chipsalliance.cde.config.{Parameters}
|
||||
import freechips.rocketchip.tilelink.{TLClientNode, TLBlockDuringReset}
|
||||
|
||||
import sifive.fpgashells.shell.xilinx._
|
||||
@@ -13,8 +13,8 @@ import sifive.fpgashells.ip.xilinx.{IBUF, PowerOnResetFPGAOnly}
|
||||
|
||||
import sifive.blocks.devices.uart._
|
||||
|
||||
import chipyard._
|
||||
import chipyard.harness.{ApplyHarnessBinders}
|
||||
import chipyard.{ChipTop, CanHaveMasterTLMemPort, ExtTLMem}
|
||||
import chipyard.harness._
|
||||
import chipyard.iobinders.{HasIOBinders}
|
||||
|
||||
class Arty100THarness(override implicit val p: Parameters) extends Arty100TShell with HasHarnessSignalReferences
|
||||
|
||||
@@ -2,7 +2,6 @@ package chipyard.fpga.arty100t
|
||||
|
||||
import chisel3._
|
||||
|
||||
import freechips.rocketchip.devices.debug.{HasPeripheryDebug, HasPeripheryDebugModuleImp}
|
||||
import freechips.rocketchip.jtag.{JTAGIO}
|
||||
import freechips.rocketchip.subsystem.{PeripheryBusKey}
|
||||
import freechips.rocketchip.tilelink.{TLBundle}
|
||||
@@ -26,7 +25,8 @@ class WithArty100TUARTTSI(uartBaudRate: BigInt = 115200) extends OverrideHarness
|
||||
ports.map({ port =>
|
||||
val ath = th.asInstanceOf[Arty100THarness]
|
||||
val freq = p(PeripheryBusKey).dtsFrequency.get
|
||||
val bits = SerialAdapter.asyncQueue(port, th.buildtopClock, th.buildtopReset)
|
||||
val bits = port.bits
|
||||
port.clock := th.buildtopClock
|
||||
withClockAndReset(th.buildtopClock, th.buildtopReset) {
|
||||
val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, bits, th.buildtopReset)
|
||||
val uart_to_serial = Module(new UARTToSerial(
|
||||
|
||||
@@ -2,7 +2,7 @@ package chipyard.fpga.vc707
|
||||
|
||||
import sys.process._
|
||||
|
||||
import freechips.rocketchip.config.{Config, Parameters}
|
||||
import org.chipsalliance.cde.config.{Config, Parameters}
|
||||
import freechips.rocketchip.subsystem.{SystemBusKey, PeripheryBusKey, ControlBusKey, ExtMem}
|
||||
import freechips.rocketchip.devices.debug.{DebugModuleKey, ExportDebug, JTAG}
|
||||
import freechips.rocketchip.devices.tilelink.{DevNullParams, BootROMLocated}
|
||||
@@ -17,7 +17,8 @@ import sifive.fpgashells.shell.xilinx.{VC7074GDDRSize}
|
||||
|
||||
import testchipip.{SerialTLKey}
|
||||
|
||||
import chipyard.{BuildSystem, ExtTLMem, DefaultClockFrequencyKey}
|
||||
import chipyard.{BuildSystem, ExtTLMem}
|
||||
import chipyard.harness.{DefaultClockFrequencyKey}
|
||||
|
||||
class WithDefaultPeripherals extends Config((site, here, up) => {
|
||||
case PeripheryUARTKey => List(UARTParams(address = BigInt(0x64000000L)))
|
||||
|
||||
@@ -4,7 +4,7 @@ import chisel3._
|
||||
import chisel3.experimental.{IO}
|
||||
|
||||
import freechips.rocketchip.diplomacy.{LazyModule, LazyRawModuleImp, BundleBridgeSource}
|
||||
import freechips.rocketchip.config.{Parameters}
|
||||
import org.chipsalliance.cde.config.{Parameters}
|
||||
import freechips.rocketchip.tilelink.{TLClientNode}
|
||||
|
||||
import sifive.fpgashells.shell.xilinx.{VC707Shell, UARTVC707ShellPlacer, PCIeVC707ShellPlacer, ChipLinkVC707PlacedOverlay}
|
||||
@@ -16,9 +16,9 @@ import sifive.fpgashells.devices.xilinx.xilinxvc707pciex1.{XilinxVC707PCIeX1IO}
|
||||
import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTPortIO}
|
||||
import sifive.blocks.devices.spi.{PeripherySPIKey, SPIPortIO}
|
||||
|
||||
import chipyard.{HasHarnessSignalReferences, BuildTop, ChipTop, ExtTLMem, CanHaveMasterTLMemPort, DefaultClockFrequencyKey}
|
||||
import chipyard.{ChipTop, ExtTLMem, CanHaveMasterTLMemPort}
|
||||
import chipyard.iobinders.{HasIOBinders}
|
||||
import chipyard.harness.{ApplyHarnessBinders}
|
||||
import chipyard.harness.{ApplyHarnessBinders, HasHarnessSignalReferences, BuildTop, DefaultClockFrequencyKey}
|
||||
|
||||
class VC707FPGATestHarness(override implicit val p: Parameters) extends VC707Shell { outer =>
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package chipyard.fpga.vcu118
|
||||
|
||||
import sys.process._
|
||||
|
||||
import freechips.rocketchip.config.{Config, Parameters}
|
||||
import org.chipsalliance.cde.config.{Config, Parameters}
|
||||
import freechips.rocketchip.subsystem.{SystemBusKey, PeripheryBusKey, ControlBusKey, ExtMem}
|
||||
import freechips.rocketchip.devices.debug.{DebugModuleKey, ExportDebug, JTAG}
|
||||
import freechips.rocketchip.devices.tilelink.{DevNullParams, BootROMLocated}
|
||||
@@ -17,7 +17,8 @@ import sifive.fpgashells.shell.xilinx.{VCU118ShellPMOD, VCU118DDRSize}
|
||||
|
||||
import testchipip.{SerialTLKey}
|
||||
|
||||
import chipyard.{BuildSystem, ExtTLMem, DefaultClockFrequencyKey}
|
||||
import chipyard.{BuildSystem, ExtTLMem}
|
||||
import chipyard.harness.{DefaultClockFrequencyKey}
|
||||
|
||||
class WithDefaultPeripherals extends Config((site, here, up) => {
|
||||
case PeripheryUARTKey => List(UARTParams(address = BigInt(0x64000000L)))
|
||||
|
||||
@@ -3,7 +3,7 @@ package chipyard.fpga.vcu118
|
||||
import chisel3._
|
||||
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.config.{Parameters, Field}
|
||||
import org.chipsalliance.cde.config.{Parameters, Field}
|
||||
import freechips.rocketchip.tilelink.{TLInwardNode, TLAsyncCrossingSink}
|
||||
|
||||
import sifive.fpgashells.shell._
|
||||
|
||||
@@ -9,8 +9,8 @@ import freechips.rocketchip.tilelink.{TLBundle}
|
||||
import sifive.blocks.devices.uart.{HasPeripheryUARTModuleImp, UARTPortIO}
|
||||
import sifive.blocks.devices.spi.{HasPeripherySPI, SPIPortIO}
|
||||
|
||||
import chipyard.{HasHarnessSignalReferences, CanHaveMasterTLMemPort}
|
||||
import chipyard.harness.{OverrideHarnessBinder}
|
||||
import chipyard.{CanHaveMasterTLMemPort}
|
||||
import chipyard.harness.{HasHarnessSignalReferences, OverrideHarnessBinder}
|
||||
|
||||
/*** UART ***/
|
||||
class WithUART extends OverrideHarnessBinder({
|
||||
|
||||
@@ -4,7 +4,7 @@ import chisel3._
|
||||
import chisel3.experimental.{IO}
|
||||
|
||||
import freechips.rocketchip.diplomacy.{LazyModule, LazyRawModuleImp, BundleBridgeSource}
|
||||
import freechips.rocketchip.config.{Parameters}
|
||||
import org.chipsalliance.cde.config.{Parameters}
|
||||
import freechips.rocketchip.tilelink.{TLClientNode}
|
||||
|
||||
import sifive.fpgashells.shell.xilinx._
|
||||
@@ -17,7 +17,7 @@ import sifive.blocks.devices.spi.{PeripherySPIKey, SPIPortIO}
|
||||
|
||||
import chipyard._
|
||||
import chipyard.iobinders.{HasIOBinders}
|
||||
import chipyard.harness.{ApplyHarnessBinders}
|
||||
import chipyard.harness._
|
||||
|
||||
class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118ShellBasicOverlays {
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package chipyard.fpga.vcu118.bringup
|
||||
|
||||
import math.min
|
||||
|
||||
import freechips.rocketchip.config.{Config, Parameters}
|
||||
import org.chipsalliance.cde.config.{Config, Parameters}
|
||||
import freechips.rocketchip.diplomacy.{DTSModel, DTSTimebase, RegionType, AddressSet, ResourceBinding, Resource, ResourceAddress}
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
|
||||
@@ -4,7 +4,7 @@ import chisel3._
|
||||
import chisel3.experimental.{attach}
|
||||
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.config.{Parameters, Field}
|
||||
import org.chipsalliance.cde.config.{Parameters, Field}
|
||||
import freechips.rocketchip.tilelink.{TLInwardNode, TLAsyncCrossingSink}
|
||||
|
||||
import sifive.fpgashells.shell._
|
||||
|
||||
@@ -4,7 +4,7 @@ import chisel3._
|
||||
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.system._
|
||||
import freechips.rocketchip.config.Parameters
|
||||
import org.chipsalliance.cde.config.Parameters
|
||||
import freechips.rocketchip.devices.tilelink._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
|
||||
@@ -13,8 +13,7 @@ import sifive.blocks.devices.gpio.{HasPeripheryGPIOModuleImp, GPIOPortIO}
|
||||
|
||||
import testchipip.{HasPeripheryTSIHostWidget, TSIHostWidgetIO}
|
||||
|
||||
import chipyard.{HasHarnessSignalReferences}
|
||||
import chipyard.harness.{ComposeHarnessBinder, OverrideHarnessBinder}
|
||||
import chipyard.harness.{ComposeHarnessBinder, OverrideHarnessBinder, HasHarnessSignalReferences}
|
||||
|
||||
/*** UART ***/
|
||||
class WithBringupUART extends ComposeHarnessBinder({
|
||||
|
||||
@@ -3,7 +3,7 @@ package chipyard.fpga.vcu118.bringup
|
||||
import chisel3._
|
||||
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.config._
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.tilelink._
|
||||
|
||||
|
||||
Submodule generators/boom updated: deae9f7046...679f358755
@@ -1,3 +1,4 @@
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <riscv/sim.h>
|
||||
@@ -5,6 +6,25 @@
|
||||
#include <svdpi.h>
|
||||
#include <sstream>
|
||||
#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_SIZE (0x1000)
|
||||
@@ -20,6 +40,7 @@ typedef struct system_info_t {
|
||||
|
||||
system_info_t* info = NULL;
|
||||
sim_t* sim = NULL;
|
||||
bool cospike_debug;
|
||||
reg_t tohost_addr = 0;
|
||||
reg_t fromhost_addr = 0;
|
||||
std::set<reg_t> magic_addrs;
|
||||
@@ -64,13 +85,14 @@ extern "C" void cospike_cosim(long long int cycle,
|
||||
int raise_exception,
|
||||
int raise_interrupt,
|
||||
unsigned long long int cause,
|
||||
unsigned long long int wdata)
|
||||
unsigned long long int wdata,
|
||||
int priv)
|
||||
{
|
||||
assert(info);
|
||||
if (!sim) {
|
||||
if (unlikely(!sim)) {
|
||||
printf("Configuring spike cosim\n");
|
||||
std::vector<mem_cfg_t> mem_cfg;
|
||||
std::vector<int> hartids;
|
||||
std::vector<size_t> hartids;
|
||||
mem_cfg.push_back(mem_cfg_t(info->mem0_base, info->mem0_size));
|
||||
for (int i = 0; i < info->nharts; i++)
|
||||
hartids.push_back(i);
|
||||
@@ -110,7 +132,7 @@ extern "C" void cospike_cosim(long long int cycle,
|
||||
abort();
|
||||
std::vector<std::string> htif_args;
|
||||
bool in_permissive = false;
|
||||
bool cospike_debug = false;
|
||||
cospike_debug = false;
|
||||
for (int i = 1; i < vinfo.argc; i++) {
|
||||
std::string arg(vinfo.argv[i]);
|
||||
if (arg == "+permissive") {
|
||||
@@ -136,7 +158,7 @@ extern "C" void cospike_cosim(long long int cycle,
|
||||
.support_impebreak = true
|
||||
};
|
||||
|
||||
printf("%s\n", info->isa.c_str());
|
||||
printf("isa string is %s\n", info->isa.c_str());
|
||||
for (int i = 0; i < htif_args.size(); i++) {
|
||||
printf("%s\n", htif_args[i].c_str());
|
||||
}
|
||||
@@ -146,13 +168,29 @@ extern "C" void cospike_cosim(long long int cycle,
|
||||
plugin_devices,
|
||||
htif_args,
|
||||
dm_config,
|
||||
nullptr,
|
||||
"cospike.log",
|
||||
false,
|
||||
nullptr,
|
||||
false,
|
||||
nullptr
|
||||
);
|
||||
|
||||
#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;
|
||||
printf("Matching spike memory initial state for region %lx-%lx\n", base, base + size);
|
||||
if (!temp_mem_bus.store(base, size, pair.second.data)) {
|
||||
printf("Error, unable to match memory at address %lx\n", base);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
sim->configure_log(true, true);
|
||||
// Use our own reset vector
|
||||
for (int i = 0; i < info->nharts; i++) {
|
||||
@@ -166,18 +204,80 @@ extern "C" void cospike_cosim(long long int cycle,
|
||||
fromhost_addr = ((htif_t*)sim)->get_fromhost_addr();
|
||||
printf("Tohost : %lx\n", tohost_addr);
|
||||
printf("Fromhost: %lx\n", fromhost_addr);
|
||||
printf("Memory base : %lx\n", info->mem0_base);
|
||||
printf("Memory Size : %lx\n", info->mem0_size);
|
||||
}
|
||||
|
||||
if (priv & 0x4) { // debug
|
||||
return;
|
||||
}
|
||||
|
||||
processor_t* p = sim->get_core(hartid);
|
||||
state_t* s = p->get_state();
|
||||
#ifdef COSPIKE_DTM
|
||||
if (dtm && dtm->loadarch_done && !spike_loadarch_done) {
|
||||
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) {
|
||||
printf("VLEN mismatch loadarch: $d != spike: $d\n", ls.VLEN, p->VU.VLEN);
|
||||
abort();
|
||||
}
|
||||
if (ls.ELEN != p->VU.ELEN) {
|
||||
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 interrupt_cause = cause & 0x7FFFFFFFFFFFFFFF;
|
||||
bool msip_interrupt = interrupt_cause == 0x3;
|
||||
bool debug_interrupt = interrupt_cause == 0xe;
|
||||
if (raise_interrupt) {
|
||||
printf("%d interrupt %lx\n", cycle, cause);
|
||||
uint64_t interrupt_cause = cause & 0x7FFFFFFFFFFFFFFF;
|
||||
if (interrupt_cause == 3) {
|
||||
|
||||
if (msip_interrupt) {
|
||||
s->mip->backdoor_write_with_mask(MIP_MSIP, MIP_MSIP);
|
||||
} else if (debug_interrupt) {
|
||||
return;
|
||||
} else {
|
||||
printf("Unknown interrupt %lx\n", interrupt_cause);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
if (raise_exception)
|
||||
@@ -185,74 +285,122 @@ extern "C" void cospike_cosim(long long int cycle,
|
||||
if (valid) {
|
||||
printf("%d Cosim: %lx", cycle, iaddr);
|
||||
if (has_wdata) {
|
||||
printf(" %lx", wdata);
|
||||
printf(" s: %lx", wdata);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
if (valid || raise_interrupt || raise_exception)
|
||||
if (valid || raise_interrupt || raise_exception) {
|
||||
p->step(1);
|
||||
if (unlikely(cospike_debug)) {
|
||||
printf("spike pc is %lx\n", s->pc);
|
||||
printf("spike mstatus is %lx\n", s->mstatus->read());
|
||||
printf("spike mip is %lx\n", s->mip->read());
|
||||
printf("spike mie is %lx\n", s->mie->read());
|
||||
}
|
||||
}
|
||||
|
||||
if (valid) {
|
||||
if (s_pc != iaddr) {
|
||||
printf("%d PC mismatch %lx != %lx\n", cycle, s_pc, iaddr);
|
||||
printf("%d PC mismatch spike %llx != DUT %llx\n", cycle, s_pc, iaddr);
|
||||
if (unlikely(cospike_debug)) {
|
||||
printf("spike mstatus is %lx\n", s->mstatus->read());
|
||||
printf("spike mcause is %lx\n", s->mcause->read());
|
||||
printf("spike mtval is %lx\n" , s->mtval->read());
|
||||
printf("spike mtinst is %lx\n", s->mtinst->read());
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Try to remember magic_mem addrs, and ignore these in the future
|
||||
|
||||
auto& mem_write = s->log_mem_write;
|
||||
if (!mem_write.empty() && tohost_addr && std::get<0>(mem_write[0]) == tohost_addr) {
|
||||
reg_t wdata = std::get<1>(mem_write[0]);
|
||||
if (wdata >= info->mem0_base && wdata < (info->mem0_base + info->mem0_size)) {
|
||||
printf("Probable magic mem %x\n", wdata);
|
||||
magic_addrs.insert(wdata);
|
||||
auto& log = s->log_reg_write;
|
||||
auto& mem_read = s->log_mem_read;
|
||||
|
||||
for (auto memwrite : mem_write) {
|
||||
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);
|
||||
}
|
||||
// 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)) {
|
||||
printf("Probable magic mem %lx\n", w_data);
|
||||
magic_addrs.insert(w_data);
|
||||
}
|
||||
// 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)) {
|
||||
printf("Probable magic mem %lx\n", w_data);
|
||||
magic_addrs.insert(w_data);
|
||||
}
|
||||
}
|
||||
|
||||
if (has_wdata) {
|
||||
auto& log = s->log_reg_write;
|
||||
auto& mem_read = s->log_mem_read;
|
||||
bool scalar_wb = false;
|
||||
bool vector_wb = false;
|
||||
uint32_t vector_cnt = 0;
|
||||
|
||||
for (auto ®write : log) {
|
||||
|
||||
//TODO: scaling to multi issue reads?
|
||||
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 type = regwrite.first & 0xf;
|
||||
// 0 => int
|
||||
// 1 => fp
|
||||
// 2 => vec
|
||||
// 3 => vec hint
|
||||
// 4 => csr
|
||||
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) printf("CSR read %lx\n", csr_addr);
|
||||
if (csr_read && (
|
||||
(csr_addr == 0x301) || // misa
|
||||
(csr_addr == 0xf13) || // mimpid
|
||||
(csr_addr == 0xf12) || // marchid
|
||||
(csr_addr == 0xf11) || // mvendorid
|
||||
(csr_addr == 0xb00) || // mcycle
|
||||
(csr_addr == 0xb02) || // minstret
|
||||
(csr_addr >= 0x3b0 && csr_addr <= 0x3ef) // pmpaddr
|
||||
)) {
|
||||
printf("CSR override\n");
|
||||
s->XPR.write(rd, wdata);
|
||||
} else if (!mem_read.empty() && ((magic_addrs.count(mem_read_addr) ||
|
||||
(tohost_addr && mem_read_addr == tohost_addr) ||
|
||||
(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);
|
||||
}
|
||||
}
|
||||
|
||||
int rd = regwrite.first >> 4;
|
||||
int type = regwrite.first & 0xf;
|
||||
|
||||
// 0 => int
|
||||
// 1 => fp
|
||||
// 2 => vec
|
||||
// 3 => vec hint
|
||||
// 4 => csr
|
||||
|
||||
bool ignore_read = (!mem_read.empty() &&
|
||||
((magic_addrs.count(mem_read_addr) ||
|
||||
(tohost_addr && mem_read_addr == tohost_addr) ||
|
||||
(fromhost_addr && mem_read_addr == fromhost_addr) ||
|
||||
(CLINT_BASE <= mem_read_addr && mem_read_addr < (CLINT_BASE + CLINT_SIZE)))));
|
||||
|
||||
// check the type is compliant with writeback first
|
||||
if ((type == 0 || type == 1))
|
||||
scalar_wb = true;
|
||||
if (type == 2) {
|
||||
vector_wb = true;
|
||||
}
|
||||
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)
|
||||
printf("CSR read %lx\n", csr_addr);
|
||||
if (csr_read && ((csr_addr == 0xf13) || // mimpid
|
||||
(csr_addr == 0xf12) || // marchid
|
||||
(csr_addr == 0xf11) || // mvendorid
|
||||
(csr_addr == 0xb00) || // mcycle
|
||||
(csr_addr == 0xb02) || // minstret
|
||||
(csr_addr >= 0x3b0 && csr_addr <= 0x3ef) // pmpaddr
|
||||
)) {
|
||||
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
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO FIX: Rocketchip TracedInstruction.wdata should be Valid(UInt)
|
||||
// if (scalar_wb ^ has_wdata) {
|
||||
// printf("Scalar wdata behavior divergence between spike and DUT\n");
|
||||
// exit(-1);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
|
||||
@@ -2,11 +2,23 @@
|
||||
#include <riscv/processor.h>
|
||||
#include <riscv/log_file.h>
|
||||
#include <fesvr/context.h>
|
||||
#include <fesvr/htif.h>
|
||||
#include <fesvr/memif.h>
|
||||
#include <fesvr/elfloader.h>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <vpi_user.h>
|
||||
#include <svdpi.h>
|
||||
|
||||
#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 {
|
||||
NToB,
|
||||
NToT,
|
||||
@@ -73,9 +85,19 @@ public:
|
||||
void dcache_b(uint64_t address, uint64_t source, int param);
|
||||
bool dcache_c(uint64_t *address, uint64_t* source, int* param, unsigned char* voluntary, unsigned char* has_data, uint64_t* data[8]);
|
||||
void dcache_d(uint64_t sourceid, uint64_t data[8], unsigned char has_data, unsigned char grantack);
|
||||
|
||||
void tcm_a(uint64_t address, uint64_t data, uint32_t mask, uint32_t opcode, uint32_t size);
|
||||
bool tcm_d(uint64_t *data);
|
||||
|
||||
void loadmem(size_t base, const char* fname);
|
||||
|
||||
void drain_stq();
|
||||
bool stq_empty() { return st_q.size() == 0; };
|
||||
|
||||
void flush_icache();
|
||||
|
||||
const cfg_t &get_cfg() const { return cfg; }
|
||||
const std::map<size_t, processor_t*>& get_harts() const { return harts; }
|
||||
|
||||
~chipyard_simif_t() { };
|
||||
chipyard_simif_t(size_t icache_ways,
|
||||
size_t icache_sets,
|
||||
@@ -86,9 +108,18 @@ public:
|
||||
char* readonly_uncacheable,
|
||||
char* executable,
|
||||
size_t icache_sourceids,
|
||||
size_t dcache_sourceids);
|
||||
size_t dcache_sourceids,
|
||||
size_t tcm_base,
|
||||
size_t tcm_size,
|
||||
const char* isastr,
|
||||
size_t pmpregions);
|
||||
uint64_t cycle;
|
||||
bool use_stq;
|
||||
htif_t *htif;
|
||||
bool fast_clint;
|
||||
cfg_t cfg;
|
||||
std::map<size_t, processor_t*> harts;
|
||||
bool accessed_tofrom_host;
|
||||
private:
|
||||
bool handle_cache_access(reg_t addr, size_t len,
|
||||
uint8_t* load_bytes,
|
||||
@@ -133,6 +164,11 @@ private:
|
||||
uint64_t mmio_stdata;
|
||||
size_t mmio_len;
|
||||
uint64_t mmio_lddata;
|
||||
|
||||
uint64_t tcm_base;
|
||||
uint64_t tcm_size;
|
||||
uint8_t* tcm;
|
||||
std::vector<uint64_t> tcm_q;
|
||||
};
|
||||
|
||||
class tile_t {
|
||||
@@ -163,6 +199,7 @@ extern "C" void spike_tile(int hartid, char* isa,
|
||||
int dcache_sets, int dcache_ways,
|
||||
char* cacheable, char* uncacheable, char* readonly_uncacheable, char* executable,
|
||||
int icache_sourceids, int dcache_sourceids,
|
||||
long long int tcm_base, long long int tcm_size,
|
||||
long long int reset_vector,
|
||||
long long int ipc,
|
||||
long long int cycle,
|
||||
@@ -237,7 +274,18 @@ extern "C" void spike_tile(int hartid, char* isa,
|
||||
int* mmio_a_size,
|
||||
|
||||
unsigned char mmio_d_valid,
|
||||
long long int mmio_d_data
|
||||
long long int mmio_d_data,
|
||||
|
||||
unsigned char tcm_a_valid,
|
||||
long long int tcm_a_address,
|
||||
long long int tcm_a_data,
|
||||
int tcm_a_mask,
|
||||
int tcm_a_opcode,
|
||||
int tcm_a_size,
|
||||
|
||||
unsigned char* tcm_d_valid,
|
||||
unsigned char tcm_d_ready,
|
||||
long long int* tcm_d_data
|
||||
)
|
||||
{
|
||||
if (!host) {
|
||||
@@ -248,36 +296,26 @@ extern "C" void spike_tile(int hartid, char* isa,
|
||||
if (tiles.find(hartid) == tiles.end()) {
|
||||
printf("Constructing spike processor_t\n");
|
||||
isa_parser_t *isa_parser = new isa_parser_t(isa, "MSU");
|
||||
std::string* isastr = new std::string(isa);
|
||||
chipyard_simif_t* simif = new chipyard_simif_t(icache_ways, icache_sets,
|
||||
dcache_ways, dcache_sets,
|
||||
cacheable, uncacheable, readonly_uncacheable, executable,
|
||||
icache_sourceids, dcache_sourceids);
|
||||
std::string* isastr = new std::string(isa);
|
||||
cfg_t* cfg = new cfg_t(std::make_pair(0, 0),
|
||||
nullptr,
|
||||
isastr->c_str(),
|
||||
"MSU",
|
||||
"vlen:128,elen:64",
|
||||
false,
|
||||
endianness_little,
|
||||
pmpregions,
|
||||
std::vector<mem_cfg_t>(),
|
||||
std::vector<int>(),
|
||||
false,
|
||||
0);
|
||||
icache_sourceids, dcache_sourceids,
|
||||
tcm_base, tcm_size,
|
||||
isastr->c_str(), pmpregions);
|
||||
processor_t* p = new processor_t(isa_parser,
|
||||
cfg,
|
||||
&simif->get_cfg(),
|
||||
simif,
|
||||
hartid,
|
||||
false,
|
||||
log_file->get(),
|
||||
sout);
|
||||
|
||||
p->enable_log_commits();
|
||||
simif->harts[hartid] = p;
|
||||
|
||||
s_vpi_vlog_info vinfo;
|
||||
if (!vpi_get_vlog_info(&vinfo))
|
||||
abort();
|
||||
std::string loadmem_file = "";
|
||||
for (int i = 1; i < vinfo.argc; i++) {
|
||||
std::string arg(vinfo.argv[i]);
|
||||
if (arg == "+spike-debug") {
|
||||
@@ -286,7 +324,18 @@ extern "C" void spike_tile(int hartid, char* isa,
|
||||
if (arg == "+spike-stq") {
|
||||
simif->use_stq = true;
|
||||
}
|
||||
if (arg.find("+loadmem=") == 0) {
|
||||
loadmem_file = arg.substr(strlen("+loadmem="));
|
||||
}
|
||||
if (arg == "+spike-fast-clint") {
|
||||
simif->fast_clint = true;
|
||||
}
|
||||
if (arg == "+spike-verbose") {
|
||||
p->enable_log_commits();
|
||||
}
|
||||
}
|
||||
if (loadmem_file != "" && tcm_size > 0)
|
||||
simif->loadmem(tcm_base, loadmem_file.c_str());
|
||||
|
||||
p->reset();
|
||||
p->get_state()->pc = reset_vector;
|
||||
@@ -296,11 +345,22 @@ extern "C" void spike_tile(int hartid, char* isa,
|
||||
tile_t* tile = tiles[hartid];
|
||||
chipyard_simif_t* simif = tile->simif;
|
||||
processor_t* proc = tile->proc;
|
||||
#if defined(SPIKETILE_HTIF_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;
|
||||
if (debug) {
|
||||
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_MSIP, msip ? MIP_MSIP : 0);
|
||||
@@ -309,6 +369,7 @@ extern "C" void spike_tile(int hartid, char* isa,
|
||||
|
||||
tile->max_insns = ipc;
|
||||
uint64_t pre_insns = proc->get_state()->minstret->read();
|
||||
simif->accessed_tofrom_host = false;
|
||||
tile->spike_context.switch_to();
|
||||
*insns_retired = proc->get_state()->minstret->read() - pre_insns;
|
||||
if (simif->use_stq) {
|
||||
@@ -357,6 +418,13 @@ extern "C" void spike_tile(int hartid, char* isa,
|
||||
if (mmio_d_valid) {
|
||||
simif->mmio_d(mmio_d_data);
|
||||
}
|
||||
|
||||
if (tcm_a_valid) {
|
||||
simif->tcm_a(tcm_a_address, tcm_a_data, tcm_a_mask, tcm_a_opcode, tcm_a_size);
|
||||
}
|
||||
if (tcm_d_ready) {
|
||||
*tcm_d_valid = simif->tcm_d((uint64_t*)tcm_d_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -369,14 +437,35 @@ chipyard_simif_t::chipyard_simif_t(size_t icache_ways,
|
||||
char* readonly_uncacheable,
|
||||
char* executable,
|
||||
size_t ic_sourceids,
|
||||
size_t dc_sourceids
|
||||
size_t dc_sourceids,
|
||||
size_t tcm_base,
|
||||
size_t tcm_size,
|
||||
const char* isastr,
|
||||
size_t pmpregions
|
||||
) :
|
||||
cycle(0),
|
||||
use_stq(false),
|
||||
htif(nullptr),
|
||||
fast_clint(false),
|
||||
cfg(std::make_pair(0, 0),
|
||||
nullptr,
|
||||
isastr,
|
||||
"MSU",
|
||||
"vlen:128,elen:64",
|
||||
false,
|
||||
endianness_little,
|
||||
pmpregions,
|
||||
std::vector<mem_cfg_t>(),
|
||||
std::vector<size_t>(),
|
||||
false,
|
||||
0),
|
||||
accessed_tofrom_host(false),
|
||||
icache_ways(icache_ways),
|
||||
icache_sets(icache_sets),
|
||||
dcache_ways(dcache_ways),
|
||||
dcache_sets(dcache_sets),
|
||||
tcm_base(tcm_base),
|
||||
tcm_size(tcm_size),
|
||||
mmio_valid(false),
|
||||
mmio_inflight(false)
|
||||
{
|
||||
@@ -432,6 +521,14 @@ chipyard_simif_t::chipyard_simif_t(size_t icache_ways,
|
||||
uint64_t size_int = std::stoul(size);
|
||||
executables.push_back(mem_region_t { base_int, size_int });
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -440,12 +537,20 @@ bool chipyard_simif_t::reservable(reg_t addr) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (addr >= tcm_base && addr < tcm_base + tcm_size) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool chipyard_simif_t::mmio_fetch(reg_t addr, size_t len, uint8_t* bytes) {
|
||||
bool executable = false;
|
||||
|
||||
if (addr >= tcm_base && addr < tcm_base + tcm_size) {
|
||||
memcpy(bytes, tcm + addr - tcm_base, len);
|
||||
return true;
|
||||
}
|
||||
|
||||
for (auto& r: executables) {
|
||||
if (addr >= r.base && addr + len <= r.base + r.size) {
|
||||
executable = true;
|
||||
@@ -466,6 +571,16 @@ bool chipyard_simif_t::mmio_load(reg_t addr, size_t len, uint8_t* bytes) {
|
||||
bool found = false;
|
||||
bool cacheable = 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) {
|
||||
memcpy(bytes, tcm + addr - tcm_base, len);
|
||||
return true;
|
||||
}
|
||||
for (auto& r: cacheables) {
|
||||
if (addr >= r.base && addr + len <= r.base + r.size) {
|
||||
cacheable = true;
|
||||
@@ -488,7 +603,7 @@ bool chipyard_simif_t::mmio_load(reg_t addr, size_t len, uint8_t* bytes) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!found) {
|
||||
return false;
|
||||
}
|
||||
@@ -497,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)) {
|
||||
host->switch_to();
|
||||
}
|
||||
uint64_t lddata = 0;
|
||||
memcpy(&lddata, bytes, len);
|
||||
} else {
|
||||
handle_mmio_access(addr, len, bytes, nullptr, LOAD, readonly);
|
||||
}
|
||||
@@ -523,6 +640,7 @@ void chipyard_simif_t::handle_mmio_access(reg_t addr, size_t len,
|
||||
mmio_st = type == STORE;
|
||||
if (type == STORE) {
|
||||
assert(len <= 8);
|
||||
mmio_stdata = 0;
|
||||
memcpy(&mmio_stdata, store_bytes, len);
|
||||
}
|
||||
mmio_len = len;
|
||||
@@ -576,7 +694,7 @@ bool chipyard_simif_t::handle_cache_access(reg_t addr, size_t len,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define SETIDX(ADDR) ((ADDR >> 6) & (n_sets - 1))
|
||||
uint64_t setidx = SETIDX(addr);
|
||||
uint64_t offset = addr & (64 - 1);
|
||||
@@ -829,9 +947,21 @@ 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) {
|
||||
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) {
|
||||
memcpy(tcm + addr - tcm_base, bytes, len);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
bool cacheable = false;
|
||||
for (auto& r: cacheables) {
|
||||
for (auto& r: cacheables) {
|
||||
if (addr >= r.base && addr + len <= r.base + r.size) {
|
||||
cacheable = true;
|
||||
found = true;
|
||||
@@ -849,6 +979,8 @@ bool chipyard_simif_t::mmio_store(reg_t addr, size_t len, const uint8_t* bytes)
|
||||
return false;
|
||||
}
|
||||
if (cacheable) {
|
||||
uint64_t temp = 0;
|
||||
memcpy(&temp, bytes, len);
|
||||
if (use_stq) {
|
||||
assert(len <= 8);
|
||||
uint64_t stdata;
|
||||
@@ -899,27 +1031,104 @@ void chipyard_simif_t::dcache_d(uint64_t sourceid, uint64_t data[8], unsigned ch
|
||||
}
|
||||
}
|
||||
|
||||
void chipyard_simif_t::tcm_a(uint64_t address, uint64_t data, uint32_t mask, uint32_t opcode, uint32_t size) {
|
||||
bool load = opcode == 4;
|
||||
uint64_t rdata = 0;
|
||||
memcpy(&rdata, tcm + address - tcm_base, 8);
|
||||
tcm_q.push_back(rdata);
|
||||
|
||||
if (!load) {
|
||||
for (size_t i = 0; i < 8; i++) {
|
||||
if ((mask >> i) & 1) {
|
||||
memcpy(tcm + address - tcm_base + i, ((uint8_t*)&data) + i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool chipyard_simif_t::tcm_d(uint64_t* data) {
|
||||
if (tcm_q.size() == 0)
|
||||
return false;
|
||||
*data = tcm_q[0];
|
||||
tcm_q.erase(tcm_q.begin());
|
||||
return true;
|
||||
}
|
||||
|
||||
void chipyard_simif_t::loadmem(size_t base, const char* fname) {
|
||||
class loadmem_memif_t : public memif_t {
|
||||
public:
|
||||
loadmem_memif_t(chipyard_simif_t* _simif, size_t _start) : memif_t(nullptr), simif(_simif), start(_start) {}
|
||||
void write(addr_t taddr, size_t len, const void* src) override
|
||||
{
|
||||
addr_t addr = taddr - start;
|
||||
memcpy(simif->tcm + addr, src, len);
|
||||
}
|
||||
void read(addr_t taddr, size_t len, void* bytes) override {
|
||||
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);
|
||||
|
||||
reg_t entry;
|
||||
load_elf(fname, &loadmem_memif, &entry);
|
||||
}
|
||||
|
||||
bool insn_should_fence(uint64_t bits) {
|
||||
uint8_t opcode = bits & 0x7f;
|
||||
return opcode == 0b0101111 || opcode == 0b0001111;
|
||||
}
|
||||
|
||||
bool insn_is_wfi(uint64_t bits) {
|
||||
return bits == 0x10500073;
|
||||
}
|
||||
|
||||
void spike_thread_main(void* arg)
|
||||
{
|
||||
tile_t* tile = (tile_t*) arg;
|
||||
processor_t* proc = tile->proc;
|
||||
chipyard_simif_t* simif = tile->simif;
|
||||
state_t* state = proc->get_state();
|
||||
while (true) {
|
||||
while (tile->max_insns == 0) {
|
||||
host->switch_to();
|
||||
}
|
||||
while (tile->max_insns != 0) {
|
||||
// TODO: Fences don't work
|
||||
// uint64_t last_bits = tile->proc->get_last_bits();
|
||||
// if (insn_should_fence(last_bits) && !tile->simif->stq_empty()) {
|
||||
//uint64_t last_bits = proc->get_last_bits();
|
||||
// if (insn_should_fence(last_bits) && !simif->stq_empty()) {
|
||||
// host->switch_to();
|
||||
// }
|
||||
tile->proc->step(1);
|
||||
uint64_t old_minstret = state->minstret->read();
|
||||
proc->step(1);
|
||||
tile->max_insns--;
|
||||
tile->proc->get_state()->mcycle->write(tile->simif->cycle);
|
||||
if (proc->is_waiting_for_interrupt()) {
|
||||
if (simif->fast_clint) {
|
||||
state->mip->backdoor_write_with_mask(MIP_MTIP, MIP_MTIP);
|
||||
tile->max_insns = tile->max_insns <= 1 ? 0 : 1;
|
||||
} else {
|
||||
tile->max_insns = 0;
|
||||
}
|
||||
}
|
||||
if (state->debug_mode) {
|
||||
// TODO: Fix. This needs to apply the same hack as rocket-chip...
|
||||
// JALRs in debug mode should flush the ICache.
|
||||
// There is no API to determine if a JALR was executed, so hack the
|
||||
// pc of the JALR in the debug rom here instead.
|
||||
if (state->pc == 0x838) {
|
||||
simif->flush_icache();
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,8 @@ import "DPI-C" function void cospike_cosim(input longint cycle,
|
||||
input bit raise_exception,
|
||||
input bit raise_interrupt,
|
||||
input longint cause,
|
||||
input longint wdata
|
||||
input longint wdata,
|
||||
input int priv
|
||||
);
|
||||
|
||||
|
||||
@@ -42,6 +43,7 @@ module SpikeCosim #(
|
||||
input [63:0] trace_0_cause,
|
||||
input trace_0_has_wdata,
|
||||
input [63:0] trace_0_wdata,
|
||||
input [2:0] trace_0_priv,
|
||||
|
||||
input trace_1_valid,
|
||||
input [63:0] trace_1_iaddr,
|
||||
@@ -50,7 +52,8 @@ module SpikeCosim #(
|
||||
input trace_1_interrupt,
|
||||
input [63:0] trace_1_cause,
|
||||
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
|
||||
@@ -62,12 +65,12 @@ module SpikeCosim #(
|
||||
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,
|
||||
trace_0_insn, trace_0_exception, trace_0_interrupt, trace_0_cause,
|
||||
trace_0_wdata);
|
||||
trace_0_wdata, trace_0_priv);
|
||||
end
|
||||
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,
|
||||
trace_1_insn, trace_1_exception, trace_1_interrupt, trace_1_cause,
|
||||
trace_1_wdata);
|
||||
trace_1_wdata, trace_1_priv);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,6 +13,8 @@ import "DPI-C" function void spike_tile(input int hartid,
|
||||
input string executable,
|
||||
input int icache_sourceids,
|
||||
input int dcache_sourceids,
|
||||
input longint tcm_base,
|
||||
input longint tcm_size,
|
||||
input longint reset_vector,
|
||||
input longint ipc,
|
||||
input longint cycle,
|
||||
@@ -89,7 +91,18 @@ import "DPI-C" function void spike_tile(input int hartid,
|
||||
output int mmio_a_size,
|
||||
|
||||
input bit mmio_d_valid,
|
||||
input longint mmio_d_data
|
||||
input longint mmio_d_data,
|
||||
|
||||
input bit tcm_a_valid,
|
||||
input longint tcm_a_address,
|
||||
input longint tcm_a_data,
|
||||
input int tcm_a_mask,
|
||||
input int tcm_a_opcode,
|
||||
input int tcm_a_size,
|
||||
|
||||
output bit tcm_d_valid,
|
||||
input bit tcm_d_ready,
|
||||
output longint tcm_d_data
|
||||
);
|
||||
|
||||
|
||||
@@ -106,7 +119,9 @@ module SpikeBlackBox #(
|
||||
parameter READONLY_UNCACHEABLE,
|
||||
parameter EXECUTABLE,
|
||||
parameter ICACHE_SOURCEIDS,
|
||||
parameter DCACHE_SOURCEIDS )(
|
||||
parameter DCACHE_SOURCEIDS,
|
||||
parameter TCM_BASE,
|
||||
parameter TCM_SIZE)(
|
||||
input clock,
|
||||
input reset,
|
||||
input [63:0] reset_vector,
|
||||
@@ -185,7 +200,18 @@ module SpikeBlackBox #(
|
||||
output [31:0] mmio_a_size,
|
||||
|
||||
input mmio_d_valid,
|
||||
input [63:0] mmio_d_data
|
||||
input [63:0] mmio_d_data,
|
||||
|
||||
input tcm_a_valid,
|
||||
input [63:0] tcm_a_address,
|
||||
input [63:0] tcm_a_data,
|
||||
input [31:0] tcm_a_mask,
|
||||
input [31:0] tcm_a_opcode,
|
||||
input [31:0] tcm_a_size,
|
||||
|
||||
output tcm_d_valid,
|
||||
input tcm_d_ready,
|
||||
output [63:0] tcm_d_data
|
||||
);
|
||||
|
||||
longint __insns_retired;
|
||||
@@ -257,7 +283,13 @@ module SpikeBlackBox #(
|
||||
reg [63:0] __dcache_c_data_6_reg;
|
||||
reg [63:0] __dcache_c_data_7_reg;
|
||||
|
||||
|
||||
wire __tcm_d_ready;
|
||||
bit __tcm_d_valid;
|
||||
longint __tcm_d_data;
|
||||
|
||||
reg __tcm_d_valid_reg;
|
||||
reg [63:0] __tcm_d_data_reg;
|
||||
|
||||
|
||||
|
||||
always @(posedge clock) begin
|
||||
@@ -322,12 +354,18 @@ module SpikeBlackBox #(
|
||||
__dcache_c_data_6_reg <= 64'h0;
|
||||
__dcache_c_data_7 = 64'h0;
|
||||
__dcache_c_data_7_reg <= 64'h0;
|
||||
|
||||
__tcm_d_valid = 1'b0;
|
||||
__tcm_d_valid_reg <= 1'b0;
|
||||
__tcm_d_data = 64'h0;
|
||||
__tcm_d_data_reg <= 64'h0;
|
||||
spike_tile_reset(HARTID);
|
||||
end else begin
|
||||
spike_tile(HARTID, ISA, PMPREGIONS,
|
||||
ICACHE_SETS, ICACHE_WAYS, DCACHE_SETS, DCACHE_WAYS,
|
||||
CACHEABLE, UNCACHEABLE, READONLY_UNCACHEABLE, EXECUTABLE,
|
||||
ICACHE_SOURCEIDS, DCACHE_SOURCEIDS,
|
||||
TCM_BASE, TCM_SIZE,
|
||||
reset_vector, ipc, cycle, __insns_retired,
|
||||
debug, mtip, msip, meip, seip,
|
||||
|
||||
@@ -350,7 +388,10 @@ module SpikeBlackBox #(
|
||||
dcache_d_data_4, dcache_d_data_5, dcache_d_data_6, dcache_d_data_7,
|
||||
|
||||
__mmio_a_ready, __mmio_a_valid, __mmio_a_address, __mmio_a_data, __mmio_a_store, __mmio_a_size,
|
||||
mmio_d_valid, mmio_d_data
|
||||
mmio_d_valid, mmio_d_data,
|
||||
|
||||
tcm_a_valid, tcm_a_address, tcm_a_data, tcm_a_mask, tcm_a_opcode, tcm_a_size,
|
||||
__tcm_d_valid, __tcm_d_ready, __tcm_d_data
|
||||
);
|
||||
__insns_retired_reg <= __insns_retired;
|
||||
|
||||
@@ -385,6 +426,10 @@ module SpikeBlackBox #(
|
||||
__mmio_a_data_reg <= __mmio_a_data;
|
||||
__mmio_a_store_reg <= __mmio_a_store;
|
||||
__mmio_a_size_reg <= __mmio_a_size;
|
||||
|
||||
__tcm_d_valid_reg <= __tcm_d_valid;
|
||||
__tcm_d_data_reg <= __tcm_d_data;
|
||||
|
||||
end
|
||||
end // always @ (posedge clock)
|
||||
assign insns_retired = __insns_retired_reg;
|
||||
@@ -424,6 +469,8 @@ module SpikeBlackBox #(
|
||||
assign mmio_a_size = __mmio_a_size_reg;
|
||||
assign __mmio_a_ready = mmio_a_ready;
|
||||
|
||||
|
||||
assign tcm_d_valid = __tcm_d_valid_reg;
|
||||
assign tcm_d_data = __tcm_d_data_reg;
|
||||
assign __tcm_d_ready = tcm_d_ready;
|
||||
|
||||
endmodule;
|
||||
|
||||
@@ -6,7 +6,7 @@ import scala.collection.mutable.{ArrayBuffer}
|
||||
|
||||
import freechips.rocketchip.prci.{ClockGroupIdentityNode, ClockSinkParameters, ClockSinkNode, ClockGroup}
|
||||
import freechips.rocketchip.subsystem.{BaseSubsystem, SubsystemDriveAsyncClockGroupsKey}
|
||||
import freechips.rocketchip.config.{Parameters, Field}
|
||||
import org.chipsalliance.cde.config.{Parameters, Field}
|
||||
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, LazyRawModuleImp, LazyModuleImpLike, BindingScope}
|
||||
import freechips.rocketchip.util.{ResetCatchAndSync}
|
||||
import chipyard.iobinders._
|
||||
|
||||
19
generators/chipyard/src/main/scala/ConfigFinder.scala
Normal file
19
generators/chipyard/src/main/scala/ConfigFinder.scala
Normal file
@@ -0,0 +1,19 @@
|
||||
package chipyard
|
||||
|
||||
import org.reflections.Reflections
|
||||
import org.reflections.scanners.Scanners.SubTypes
|
||||
import scala.jdk.CollectionConverters._
|
||||
import scala.collection.{SortedSet}
|
||||
|
||||
import org.chipsalliance.cde.config.{Config}
|
||||
|
||||
object ConfigFinder {
|
||||
def main(args: Array[String]) = {
|
||||
val reflections = new Reflections()
|
||||
val classes = reflections.get(SubTypes.of(classOf[Config]).asClass()).asScala
|
||||
val sortedClasses = SortedSet[String]() ++ classes.map(_.getName)
|
||||
for (cls <- sortedClasses) {
|
||||
println(cls)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import chisel3._
|
||||
import chisel3.experimental.{IntParam, StringParam, IO}
|
||||
import chisel3.util._
|
||||
|
||||
import freechips.rocketchip.config.{Parameters, Field, Config}
|
||||
import org.chipsalliance.cde.config.{Parameters, Field, Config}
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.devices.tilelink._
|
||||
@@ -18,7 +18,8 @@ case class SpikeCosimConfig(
|
||||
mem0_base: BigInt,
|
||||
mem0_size: BigInt,
|
||||
nharts: Int,
|
||||
bootrom: String
|
||||
bootrom: String,
|
||||
has_dtm: Boolean
|
||||
)
|
||||
|
||||
class SpikeCosim(cfg: SpikeCosimConfig) extends BlackBox(Map(
|
||||
@@ -32,6 +33,7 @@ class SpikeCosim(cfg: SpikeCosimConfig) extends BlackBox(Map(
|
||||
{
|
||||
addResource("/csrc/cospike.cc")
|
||||
addResource("/vsrc/cospike.v")
|
||||
if (cfg.has_dtm) addResource("/csrc/cospike_dtm.h")
|
||||
val io = IO(new Bundle {
|
||||
val clock = Input(Clock())
|
||||
val reset = Input(Bool())
|
||||
@@ -46,6 +48,7 @@ class SpikeCosim(cfg: SpikeCosimConfig) extends BlackBox(Map(
|
||||
val cause = UInt(64.W)
|
||||
val has_wdata = Bool()
|
||||
val wdata = UInt(64.W)
|
||||
val priv = UInt(3.W)
|
||||
}))
|
||||
})
|
||||
}
|
||||
@@ -64,12 +67,8 @@ object SpikeCosim
|
||||
require(trace.numInsns <= 2)
|
||||
cosim.io.cycle := cycle
|
||||
cosim.io.trace.map(t => {
|
||||
t := DontCare
|
||||
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
|
||||
for (i <- 0 until trace.numInsns) {
|
||||
@@ -83,6 +82,7 @@ object SpikeCosim
|
||||
cosim.io.trace(i).cause := trace.insns(i).cause
|
||||
cosim.io.trace(i).has_wdata := trace.insns(i).wdata.isDefined.B
|
||||
cosim.io.trace(i).wdata := trace.insns(i).wdata.getOrElse(0.U)
|
||||
cosim.io.trace(i).priv := trace.insns(i).priv
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import chisel3._
|
||||
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.system._
|
||||
import freechips.rocketchip.config.Parameters
|
||||
import org.chipsalliance.cde.config.Parameters
|
||||
import freechips.rocketchip.devices.tilelink._
|
||||
|
||||
// ------------------------------------
|
||||
|
||||
@@ -3,7 +3,7 @@ package chipyard.iobinders
|
||||
import chisel3._
|
||||
import chisel3.experimental.{Analog, IO, DataMirror}
|
||||
|
||||
import freechips.rocketchip.config._
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.devices.debug._
|
||||
import freechips.rocketchip.jtag.{JTAGIO}
|
||||
@@ -51,6 +51,12 @@ case object IOBinders extends Field[Map[String, Seq[IOBinderFunction]]](
|
||||
Map[String, Seq[IOBinderFunction]]().withDefaultValue(Nil)
|
||||
)
|
||||
|
||||
case object DontTouchIOBindersPorts extends Field[Boolean](true)
|
||||
|
||||
class WithDontTouchIOBinders(b: Boolean = true) extends Config((site, here, up) => {
|
||||
case DontTouchIOBindersPorts => b
|
||||
})
|
||||
|
||||
abstract trait HasIOBinders { this: LazyModule =>
|
||||
val lazySystem: LazyModule
|
||||
private val iobinders = p(IOBinders)
|
||||
@@ -67,10 +73,33 @@ abstract trait HasIOBinders { this: LazyModule =>
|
||||
})
|
||||
|
||||
// A publicly accessible list of IO cells (useful for a floorplanning tool, for example)
|
||||
lazy val iocells = (lzyFlattened.values ++ impFlattened.values).unzip._2.flatten.toBuffer
|
||||
val iocells = InModuleBody { (lzyFlattened.values ++ impFlattened.values).unzip._2.flatten.toBuffer }
|
||||
|
||||
// A mapping between stringified DigitalSystem traits and their corresponding ChipTop ports
|
||||
lazy val portMap = iobinders.keys.map(k => k -> (lzyFlattened(k)._1 ++ impFlattened(k)._1)).toMap
|
||||
val portMap = InModuleBody { iobinders.keys.map(k => k -> (lzyFlattened(k)._1 ++ impFlattened(k)._1)).toMap }
|
||||
|
||||
// A mapping between stringified DigitalSystem traits and their corresponding ChipTop iocells
|
||||
val iocellMap = InModuleBody { iobinders.keys.map(k => k -> (lzyFlattened(k)._2 ++ impFlattened(k)._2)).toMap }
|
||||
|
||||
InModuleBody {
|
||||
if (p(DontTouchIOBindersPorts)) {
|
||||
portMap.values.foreach(_.foreach(dontTouch(_)))
|
||||
}
|
||||
|
||||
println("IOCells generated by IOBinders:")
|
||||
for ((k, v) <- iocellMap) {
|
||||
if (!v.isEmpty) {
|
||||
val cells = v.map(_.getClass.getSimpleName).groupBy(identity).mapValues(_.size)
|
||||
|
||||
println(s" IOBinder for $k generated:")
|
||||
for ((t, c) <- cells) { println(s" $c X $t") }
|
||||
}
|
||||
}
|
||||
println()
|
||||
val totals = iocells.map(_.getClass.getSimpleName).groupBy(identity).mapValues(_.size)
|
||||
println(s" Total generated ${iocells.size} IOCells:")
|
||||
for ((t, c) <- totals) { println(s" $c X $t") }
|
||||
}
|
||||
}
|
||||
|
||||
// Note: The parameters instance is accessible only through LazyModule
|
||||
@@ -219,7 +248,7 @@ class WithDebugIOCells extends OverrideLazyIOBinder({
|
||||
def clockBundle = clockSinkNode.get.in.head._1
|
||||
|
||||
|
||||
InModuleBody { system.asInstanceOf[BaseSubsystem].module match { case system: HasPeripheryDebugModuleImp => {
|
||||
InModuleBody { system.asInstanceOf[BaseSubsystem] match { case system: HasPeripheryDebug => {
|
||||
system.debug.map({ debug =>
|
||||
// We never use the PSDIO, so tie it off on-chip
|
||||
system.psd.psd.foreach { _ <> 0.U.asTypeOf(new PSDTestMode) }
|
||||
@@ -396,45 +425,4 @@ class WithDontTouchPorts extends OverrideIOBinder({
|
||||
(system: DontTouch) => system.dontTouchPorts(); (Nil, Nil)
|
||||
})
|
||||
|
||||
class ClockWithFreq(val freqMHz: Double) extends Bundle {
|
||||
val clock = Clock()
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -4,9 +4,10 @@ import chisel3._
|
||||
import chisel3.util._
|
||||
import chisel3.experimental.{IntParam, StringParam, IO}
|
||||
|
||||
import freechips.rocketchip.config._
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.devices.tilelink._
|
||||
import freechips.rocketchip.devices.debug.{ExportDebug, DMI}
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.rocket._
|
||||
import freechips.rocketchip.tilelink._
|
||||
@@ -15,8 +16,7 @@ import freechips.rocketchip.util._
|
||||
import freechips.rocketchip.tile._
|
||||
import freechips.rocketchip.prci.ClockSinkParameters
|
||||
|
||||
case class SpikeCoreParams(
|
||||
) extends CoreParams {
|
||||
case class SpikeCoreParams() extends CoreParams {
|
||||
val useVM = true
|
||||
val useHypervisor = false
|
||||
val useSupervisor = true
|
||||
@@ -79,7 +79,8 @@ case class SpikeTileParams(
|
||||
hartId: Int = 0,
|
||||
val core: SpikeCoreParams = SpikeCoreParams(),
|
||||
icacheParams: ICacheParams = ICacheParams(nWays = 32),
|
||||
dcacheParams: DCacheParams = DCacheParams(nWays = 32)
|
||||
dcacheParams: DCacheParams = DCacheParams(nWays = 32),
|
||||
tcmParams: Option[MasterPortParams] = None // tightly coupled memory
|
||||
) extends InstantiableTileParams[SpikeTile]
|
||||
{
|
||||
val name = Some("spike_tile")
|
||||
@@ -145,6 +146,27 @@ class SpikeTile(
|
||||
sourceId = IdRange(0, 1),
|
||||
requestFifo = true))))))
|
||||
|
||||
tlSlaveXbar.node :*= slaveNode
|
||||
val tcmNode = spikeTileParams.tcmParams.map { tcmP =>
|
||||
val device = new MemoryDevice
|
||||
val base = AddressSet.misaligned(tcmP.base, tcmP.size)
|
||||
val tcmNode = TLManagerNode(Seq(TLSlavePortParameters.v1(
|
||||
managers = Seq(TLSlaveParameters.v1(
|
||||
address = base,
|
||||
resources = device.reg,
|
||||
regionType = RegionType.IDEMPOTENT, // not cacheable
|
||||
executable = true,
|
||||
supportsGet = TransferSizes(1, 8),
|
||||
supportsPutFull = TransferSizes(1, 8),
|
||||
supportsPutPartial = TransferSizes(1, 8),
|
||||
fifoId = Some(0)
|
||||
)),
|
||||
beatBytes = 8
|
||||
)))
|
||||
connectTLSlave(tcmNode := TLBuffer(), 8)
|
||||
tcmNode
|
||||
}
|
||||
|
||||
tlOtherMastersNode := TLBuffer() := tlMasterXbar.node
|
||||
masterNode :=* tlOtherMastersNode
|
||||
tlMasterXbar.node := TLWidthWidget(64) := TLBuffer():= icacheNode
|
||||
@@ -166,7 +188,10 @@ class SpikeBlackBox(
|
||||
cacheable_regions: String,
|
||||
uncacheable_regions: String,
|
||||
readonly_uncacheable_regions: String,
|
||||
executable_regions: String) extends BlackBox(Map(
|
||||
executable_regions: String,
|
||||
tcm_base: BigInt,
|
||||
tcm_size: BigInt,
|
||||
use_dtm: Boolean) extends BlackBox(Map(
|
||||
"HARTID" -> IntParam(hartId),
|
||||
"ISA" -> StringParam(isa),
|
||||
"PMPREGIONS" -> IntParam(pmpregions),
|
||||
@@ -179,7 +204,9 @@ class SpikeBlackBox(
|
||||
"UNCACHEABLE" -> StringParam(uncacheable_regions),
|
||||
"READONLY_UNCACHEABLE" -> StringParam(readonly_uncacheable_regions),
|
||||
"CACHEABLE" -> StringParam(cacheable_regions),
|
||||
"EXECUTABLE" -> StringParam(executable_regions)
|
||||
"EXECUTABLE" -> StringParam(executable_regions),
|
||||
"TCM_BASE" -> IntParam(tcm_base),
|
||||
"TCM_SIZE" -> IntParam(tcm_size)
|
||||
)) with HasBlackBoxResource {
|
||||
|
||||
val io = IO(new Bundle {
|
||||
@@ -258,10 +285,30 @@ class SpikeBlackBox(
|
||||
val data = Input(UInt(64.W))
|
||||
}
|
||||
}
|
||||
|
||||
val tcm = new Bundle {
|
||||
val a = new Bundle {
|
||||
val valid = Input(Bool())
|
||||
val address = Input(UInt(64.W))
|
||||
val data = Input(UInt(64.W))
|
||||
val mask = Input(UInt(32.W))
|
||||
val opcode = Input(UInt(32.W))
|
||||
val size = Input(UInt(32.W))
|
||||
}
|
||||
val d = new Bundle {
|
||||
val valid = Output(Bool())
|
||||
val ready = Input(Bool())
|
||||
val data = Output(UInt(64.W))
|
||||
}
|
||||
}
|
||||
})
|
||||
addResource("/vsrc/spiketile.v")
|
||||
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) {
|
||||
@@ -285,11 +332,19 @@ class SpikeTileModuleImp(outer: SpikeTile) extends BaseTileModuleImp(outer) {
|
||||
val (dcache_tl, dcacheEdge) = outer.dcacheNode.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,
|
||||
tileParams.icache.get.nSets, tileParams.icache.get.nWays,
|
||||
tileParams.dcache.get.nSets, tileParams.dcache.get.nWays,
|
||||
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(_.size).getOrElse(0),
|
||||
useDTM
|
||||
))
|
||||
spike.io.clock := clock.asBool
|
||||
val cycle = RegInit(0.U(64.W))
|
||||
cycle := cycle + 1.U
|
||||
@@ -304,64 +359,63 @@ class SpikeTileModuleImp(outer: SpikeTile) extends BaseTileModuleImp(outer) {
|
||||
spike.io.msip := int_bundle.msip
|
||||
spike.io.meip := int_bundle.meip
|
||||
spike.io.seip := int_bundle.seip.get
|
||||
spike.io.ipc := PlusArg("spike-ipc", 10000, width=64)
|
||||
spike.io.ipc := PlusArg("spike-ipc", width=32, default=10000)
|
||||
|
||||
val blockBits = log2Ceil(p(CacheBlockBytes))
|
||||
|
||||
val icache_a_q = Module(new Queue(new TLBundleA(icacheEdge.bundle), 1, flow=true, pipe=true))
|
||||
spike.io.icache.a.ready := icache_a_q.io.enq.ready && icache_a_q.io.count === 0.U
|
||||
icache_tl.a <> icache_a_q.io.deq
|
||||
icache_a_q.io.enq.valid := spike.io.icache.a.valid
|
||||
icache_a_q.io.enq.bits := icacheEdge.Get(
|
||||
spike.io.icache.a.ready := icache_tl.a.ready
|
||||
icache_tl.a.valid := spike.io.icache.a.valid
|
||||
icache_tl.a.bits := icacheEdge.Get(
|
||||
fromSource = spike.io.icache.a.sourceid,
|
||||
toAddress = (spike.io.icache.a.address >> blockBits) << blockBits,
|
||||
lgSize = blockBits.U)._2
|
||||
|
||||
icache_tl.d.ready := true.B
|
||||
spike.io.icache.d.valid := icache_tl.d.valid
|
||||
spike.io.icache.d.sourceid := icache_tl.d.bits.source
|
||||
spike.io.icache.d.data := icache_tl.d.bits.data.asTypeOf(Vec(8, UInt(64.W)))
|
||||
|
||||
val dcache_a_q = Module(new Queue(new TLBundleA(dcacheEdge.bundle), 1, flow=true, pipe=true))
|
||||
spike.io.dcache.a.ready := dcache_a_q.io.enq.ready && dcache_a_q.io.count === 0.U
|
||||
dcache_tl.a <> dcache_a_q.io.deq
|
||||
dcache_a_q.io.enq.valid := spike.io.dcache.a.valid
|
||||
dcache_a_q.io.enq.bits := dcacheEdge.AcquireBlock(
|
||||
fromSource = spike.io.dcache.a.sourceid,
|
||||
toAddress = (spike.io.dcache.a.address >> blockBits) << blockBits,
|
||||
lgSize = blockBits.U,
|
||||
growPermissions = Mux(spike.io.dcache.a.state_old, 2.U, Mux(spike.io.dcache.a.state_new, 1.U, 0.U)))._2
|
||||
|
||||
spike.io.dcache.a.ready := dcache_tl.a.ready
|
||||
dcache_tl.a.valid := spike.io.dcache.a.valid
|
||||
if (dcacheEdge.manager.anySupportAcquireB) {
|
||||
dcache_tl.a.bits := dcacheEdge.AcquireBlock(
|
||||
fromSource = spike.io.dcache.a.sourceid,
|
||||
toAddress = (spike.io.dcache.a.address >> blockBits) << blockBits,
|
||||
lgSize = blockBits.U,
|
||||
growPermissions = Mux(spike.io.dcache.a.state_old, 2.U, Mux(spike.io.dcache.a.state_new, 1.U, 0.U)))._2
|
||||
} else {
|
||||
dcache_tl.a.bits := DontCare
|
||||
}
|
||||
dcache_tl.b.ready := true.B
|
||||
spike.io.dcache.b.valid := dcache_tl.b.valid
|
||||
spike.io.dcache.b.address := dcache_tl.b.bits.address
|
||||
spike.io.dcache.b.source := dcache_tl.b.bits.source
|
||||
spike.io.dcache.b.param := dcache_tl.b.bits.param
|
||||
|
||||
val dcache_c_q = Module(new Queue(new TLBundleC(dcacheEdge.bundle), 1, flow=true, pipe=true))
|
||||
spike.io.dcache.c.ready := dcache_c_q.io.enq.ready && dcache_c_q.io.count === 0.U
|
||||
dcache_tl.c <> dcache_c_q.io.deq
|
||||
dcache_c_q.io.enq.valid := spike.io.dcache.c.valid
|
||||
dcache_c_q.io.enq.bits := Mux(spike.io.dcache.c.voluntary,
|
||||
dcacheEdge.Release(
|
||||
fromSource = spike.io.dcache.c.sourceid,
|
||||
toAddress = spike.io.dcache.c.address,
|
||||
lgSize = blockBits.U,
|
||||
shrinkPermissions = spike.io.dcache.c.param,
|
||||
data = spike.io.dcache.c.data.asUInt)._2,
|
||||
Mux(spike.io.dcache.c.has_data,
|
||||
dcacheEdge.ProbeAck(
|
||||
spike.io.dcache.c.ready := dcache_tl.c.ready
|
||||
dcache_tl.c.valid := spike.io.dcache.c.valid
|
||||
if (dcacheEdge.manager.anySupportAcquireB) {
|
||||
dcache_tl.c.bits := Mux(spike.io.dcache.c.voluntary,
|
||||
dcacheEdge.Release(
|
||||
fromSource = spike.io.dcache.c.sourceid,
|
||||
toAddress = spike.io.dcache.c.address,
|
||||
lgSize = blockBits.U,
|
||||
reportPermissions = spike.io.dcache.c.param,
|
||||
data = spike.io.dcache.c.data.asUInt),
|
||||
dcacheEdge.ProbeAck(
|
||||
fromSource = spike.io.dcache.c.sourceid,
|
||||
toAddress = spike.io.dcache.c.address,
|
||||
lgSize = blockBits.U,
|
||||
reportPermissions = spike.io.dcache.c.param)
|
||||
))
|
||||
shrinkPermissions = spike.io.dcache.c.param,
|
||||
data = spike.io.dcache.c.data.asUInt)._2,
|
||||
Mux(spike.io.dcache.c.has_data,
|
||||
dcacheEdge.ProbeAck(
|
||||
fromSource = spike.io.dcache.c.sourceid,
|
||||
toAddress = spike.io.dcache.c.address,
|
||||
lgSize = blockBits.U,
|
||||
reportPermissions = spike.io.dcache.c.param,
|
||||
data = spike.io.dcache.c.data.asUInt),
|
||||
dcacheEdge.ProbeAck(
|
||||
fromSource = spike.io.dcache.c.sourceid,
|
||||
toAddress = spike.io.dcache.c.address,
|
||||
lgSize = blockBits.U,
|
||||
reportPermissions = spike.io.dcache.c.param)
|
||||
))
|
||||
} else {
|
||||
dcache_tl.c.bits := DontCare
|
||||
}
|
||||
|
||||
val has_data = dcacheEdge.hasData(dcache_tl.d.bits)
|
||||
val should_finish = dcacheEdge.isRequest(dcache_tl.d.bits)
|
||||
@@ -376,12 +430,10 @@ class SpikeTileModuleImp(outer: SpikeTile) extends BaseTileModuleImp(outer) {
|
||||
dcache_tl.e.valid := dcache_tl.d.valid && should_finish
|
||||
dcache_tl.e.bits := dcacheEdge.GrantAck(dcache_tl.d.bits)
|
||||
|
||||
val mmio_a_q = Module(new Queue(new TLBundleA(mmioEdge.bundle), 1, flow=true, pipe=true))
|
||||
spike.io.mmio.a.ready := mmio_a_q.io.enq.ready && mmio_a_q.io.count === 0.U
|
||||
mmio_tl.a <> mmio_a_q.io.deq
|
||||
mmio_a_q.io.enq.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 })
|
||||
mmio_a_q.io.enq.bits := Mux(spike.io.mmio.a.store,
|
||||
spike.io.mmio.a.ready := mmio_tl.a.ready
|
||||
mmio_tl.a.valid := spike.io.mmio.a.valid
|
||||
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,
|
||||
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)
|
||||
|
||||
@@ -389,9 +441,33 @@ class SpikeTileModuleImp(outer: SpikeTile) extends BaseTileModuleImp(outer) {
|
||||
spike.io.mmio.d.valid := mmio_tl.d.valid
|
||||
spike.io.mmio.d.data := mmio_tl.d.bits.data
|
||||
|
||||
spike.io.tcm := DontCare
|
||||
spike.io.tcm.a.valid := false.B
|
||||
spike.io.tcm.d.ready := true.B
|
||||
outer.tcmNode.map { tcmNode =>
|
||||
val (tcm_tl, tcmEdge) = tcmNode.in(0)
|
||||
val debug_tcm_tl = WireInit(tcm_tl)
|
||||
dontTouch(debug_tcm_tl)
|
||||
tcm_tl.a.ready := true.B
|
||||
spike.io.tcm.a.valid := tcm_tl.a.valid
|
||||
spike.io.tcm.a.address := tcm_tl.a.bits.address
|
||||
spike.io.tcm.a.data := tcm_tl.a.bits.data
|
||||
spike.io.tcm.a.mask := tcm_tl.a.bits.mask
|
||||
spike.io.tcm.a.opcode := tcm_tl.a.bits.opcode
|
||||
spike.io.tcm.a.size := tcm_tl.a.bits.size
|
||||
|
||||
spike.io.tcm.d.ready := tcm_tl.d.ready
|
||||
tcm_tl.d.bits := tcmEdge.AccessAck(RegNext(tcm_tl.a.bits))
|
||||
when (RegNext(tcm_tl.a.bits.opcode === TLMessages.Get)) {
|
||||
tcm_tl.d.bits.opcode := TLMessages.AccessAckData
|
||||
}
|
||||
tcm_tl.d.valid := spike.io.tcm.d.valid
|
||||
tcm_tl.d.bits.data := spike.io.tcm.d.data
|
||||
}
|
||||
}
|
||||
|
||||
class WithNSpikeCores(n: Int = 1, overrideIdOffset: Option[Int] = None) extends Config((site, here, up) => {
|
||||
class WithNSpikeCores(n: Int = 1, tileParams: SpikeTileParams = SpikeTileParams(),
|
||||
overrideIdOffset: Option[Int] = None) extends Config((site, here, up) => {
|
||||
case TilesLocated(InSubsystem) => {
|
||||
// Calculate the next available hart ID (since hart ID cannot be duplicated)
|
||||
val prev = up(TilesLocated(InSubsystem), site)
|
||||
@@ -399,8 +475,21 @@ class WithNSpikeCores(n: Int = 1, overrideIdOffset: Option[Int] = None) extends
|
||||
// Create TileAttachParams for every core to be instantiated
|
||||
(0 until n).map { i =>
|
||||
SpikeTileAttachParams(
|
||||
tileParams = SpikeTileParams(hartId = i + idOffset)
|
||||
tileParams = tileParams.copy(hartId = i + idOffset)
|
||||
)
|
||||
} ++ prev
|
||||
}
|
||||
})
|
||||
|
||||
class WithSpikeTCM extends Config((site, here, up) => {
|
||||
case TilesLocated(InSubsystem) => {
|
||||
val prev = up(TilesLocated(InSubsystem))
|
||||
require(prev.size == 1)
|
||||
val spike = prev(0).asInstanceOf[SpikeTileAttachParams]
|
||||
Seq(spike.copy(tileParams = spike.tileParams.copy(
|
||||
tcmParams = Some(up(ExtMem).get.master)
|
||||
)))
|
||||
}
|
||||
case ExtMem => None
|
||||
case BankedL2Key => up(BankedL2Key).copy(nBanks = 0)
|
||||
})
|
||||
|
||||
@@ -9,9 +9,10 @@ import chisel3._
|
||||
import chisel3.internal.sourceinfo.{SourceInfo}
|
||||
|
||||
import freechips.rocketchip.prci._
|
||||
import freechips.rocketchip.config.{Field, Parameters}
|
||||
import org.chipsalliance.cde.config.{Field, Parameters}
|
||||
import freechips.rocketchip.devices.tilelink._
|
||||
import freechips.rocketchip.devices.debug.{HasPeripheryDebug, HasPeripheryDebugModuleImp, ExportDebug, DebugModuleKey}
|
||||
import freechips.rocketchip.devices.debug.{HasPeripheryDebug, ExportDebug, DebugModuleKey}
|
||||
import sifive.blocks.devices.uart.{HasPeripheryUART, PeripheryUARTKey}
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tile._
|
||||
import freechips.rocketchip.tilelink._
|
||||
@@ -45,9 +46,35 @@ trait CanHaveHTIF { this: BaseSubsystem =>
|
||||
}
|
||||
}
|
||||
|
||||
// This trait adds the "chosen" node to DTS, which
|
||||
// can be used to pass information to OS about the earlycon
|
||||
case object ChosenInDTS extends Field[Boolean](true)
|
||||
trait CanHaveChosenInDTS { this: BaseSubsystem =>
|
||||
if (p(ChosenInDTS)) {
|
||||
this match {
|
||||
case t: HasPeripheryUART if (!p(PeripheryUARTKey).isEmpty) => {
|
||||
val chosen = new Device {
|
||||
def describe(resources: ResourceBindings): Description = {
|
||||
val stdout = resources("stdout").map(_.value)
|
||||
Description("chosen", resources("uart").headOption.map { case Binding(_, value) =>
|
||||
"stdout-path" -> Seq(value)
|
||||
}.toMap)
|
||||
}
|
||||
}
|
||||
ResourceBinding {
|
||||
t.uarts.foreach(u => Resource(chosen, "uart").bind(ResourceAlias(u.device.label)))
|
||||
}
|
||||
}
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ChipyardSubsystem(implicit p: Parameters) extends BaseSubsystem
|
||||
with HasTiles
|
||||
with HasPeripheryDebug
|
||||
with CanHaveHTIF
|
||||
with CanHaveChosenInDTS
|
||||
{
|
||||
def coreMonitorBundles = tiles.map {
|
||||
case r: RocketTile => r.module.core.rocketImpl.coreMonitorBundle
|
||||
|
||||
@@ -7,7 +7,7 @@ package chipyard
|
||||
|
||||
import chisel3._
|
||||
|
||||
import freechips.rocketchip.config.{Parameters, Field}
|
||||
import org.chipsalliance.cde.config.{Parameters, Field}
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.devices.tilelink._
|
||||
@@ -31,6 +31,14 @@ class ChipyardSystem(implicit p: Parameters) extends ChipyardSubsystem
|
||||
|
||||
val bootROM = p(BootROMLocated(location)).map { BootROM.attach(_, this, CBUS) }
|
||||
val maskROMs = p(MaskROMLocated(location)).map { MaskROM.attach(_, this, CBUS) }
|
||||
|
||||
// If there is no bootrom, the tile reset vector bundle will be tied to zero
|
||||
if (bootROM.isEmpty) {
|
||||
val fakeResetVectorSourceNode = BundleBridgeSource[UInt]()
|
||||
InModuleBody { fakeResetVectorSourceNode.bundle := 0.U }
|
||||
tileResetVectorNexusNode := fakeResetVectorSourceNode
|
||||
}
|
||||
|
||||
override lazy val module = new ChipyardSystemModule(this)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
package chipyard
|
||||
|
||||
import chisel3._
|
||||
|
||||
import scala.collection.mutable.{ArrayBuffer, LinkedHashMap}
|
||||
import freechips.rocketchip.diplomacy.{LazyModule}
|
||||
import freechips.rocketchip.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
|
||||
|
||||
trait HasHarnessSignalReferences {
|
||||
implicit val p: Parameters
|
||||
// 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 HarnessClockInstantiator {
|
||||
private 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
|
||||
}
|
||||
|
||||
// connect all clock wires specified to a divider only PLL
|
||||
def instantiateHarnessDividerPLL(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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case object HarnessClockInstantiatorKey extends Field[HarnessClockInstantiator](new HarnessClockInstantiator)
|
||||
|
||||
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 = p(HarnessClockInstantiatorKey).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
|
||||
p(HarnessClockInstantiatorKey).instantiateHarnessDividerPLL(implicitHarnessClockBundle)
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import scala.collection.mutable.{LinkedHashSet}
|
||||
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.tile.{XLen, TileParams}
|
||||
import freechips.rocketchip.config.{Parameters, Field, Config}
|
||||
import org.chipsalliance.cde.config.{Parameters, Field, Config}
|
||||
import freechips.rocketchip.system.{TestGeneration, RegressionTestSuite, RocketTestSuite}
|
||||
|
||||
/**
|
||||
|
||||
127
generators/chipyard/src/main/scala/clocking/ClockBinders.scala
Normal file
127
generators/chipyard/src/main/scala/clocking/ClockBinders.scala
Normal file
@@ -0,0 +1,127 @@
|
||||
package chipyard.clocking
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import chipyard.iobinders.{OverrideLazyIOBinder, GetSystemParameters, IOCellKey}
|
||||
import freechips.rocketchip.prci._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import barstools.iocell.chisel._
|
||||
|
||||
class ClockWithFreq(val freqMHz: Double) extends Bundle {
|
||||
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
|
||||
// the requested clocks. This also adds TileLink ClockDivider and ClockSelector
|
||||
// blocks, which allow memory-mapped control of clock division, and clock muxing
|
||||
// between the FakePLL and the slow off-chip clock
|
||||
// Note: This will not simulate properly with verilator or firesim
|
||||
class WithPLLSelectorDividerClockGenerator 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
|
||||
}}
|
||||
}
|
||||
val tlbus = system.asInstanceOf[BaseSubsystem].locateTLBusWrapper(system.prciParams.slaveWhere)
|
||||
val baseAddress = system.prciParams.baseAddress
|
||||
val clockDivider = system.prci_ctrl_domain { LazyModule(new TLClockDivider (baseAddress + 0x20000, 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)) }
|
||||
|
||||
tlbus.toVariableWidthSlave(Some("clock-div-ctrl")) { clockDivider.tlNode := TLBuffer() }
|
||||
tlbus.toVariableWidthSlave(Some("clock-sel-ctrl")) { clockSelector.tlNode := TLBuffer() }
|
||||
tlbus.toVariableWidthSlave(Some("pll-ctrl")) { pllCtrl.tlNode := TLBuffer() }
|
||||
|
||||
system.allClockGroupsNode := clockDivider.clockNode := clockSelector.clockNode
|
||||
|
||||
// Connect all other requested clocks
|
||||
val slowClockSource = ClockSourceNode(Seq(ClockSourceParameters()))
|
||||
val pllClockSource = ClockSourceNode(Seq(ClockSourceParameters()))
|
||||
|
||||
// The order of the connections to clockSelector.clockNode configures the inputs
|
||||
// of the clockSelector's clockMux. Default to using the slowClockSource,
|
||||
// software should enable the PLL, then switch to the pllClockSource
|
||||
clockSelector.clockNode := slowClockSource
|
||||
clockSelector.clockNode := pllClockSource
|
||||
|
||||
val pllCtrlSink = BundleBridgeSink[FakePLLCtrlBundle]()
|
||||
pllCtrlSink := pllCtrl.ctrlNode
|
||||
|
||||
InModuleBody {
|
||||
val clock_wire = Wire(Input(new ClockWithFreq(80)))
|
||||
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))
|
||||
|
||||
slowClockSource.out.unzip._1.map { o =>
|
||||
o.clock := clock_wire.clock
|
||||
o.reset := reset_wire
|
||||
}
|
||||
|
||||
// For a real chip you should replace this ClockSourceAtFreqFromPlusArg
|
||||
// with a blackbox of whatever PLL is being integrated
|
||||
val fake_pll = Module(new ClockSourceAtFreqFromPlusArg("pll_freq_mhz"))
|
||||
fake_pll.io.power := pllCtrlSink.in(0)._1.power
|
||||
fake_pll.io.gate := pllCtrlSink.in(0)._1.gate
|
||||
|
||||
pllClockSource.out.unzip._1.map { o =>
|
||||
o.clock := fake_pll.io.clk
|
||||
o.reset := reset_wire
|
||||
}
|
||||
|
||||
(Seq(clock_io, reset_io), clockIOCell ++ resetIOCell)
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -4,7 +4,7 @@ import chisel3._
|
||||
import chisel3.util._
|
||||
import chisel3.experimental.{Analog, IO}
|
||||
|
||||
import freechips.rocketchip.config._
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.prci._
|
||||
|
||||
@@ -2,7 +2,7 @@ package chipyard.clocking
|
||||
|
||||
import chisel3._
|
||||
|
||||
import freechips.rocketchip.config.{Parameters, Config, Field}
|
||||
import org.chipsalliance.cde.config.{Parameters, Config, Field}
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.prci._
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package chipyard.clocking
|
||||
|
||||
import chisel3._
|
||||
|
||||
import freechips.rocketchip.config.{Parameters}
|
||||
import org.chipsalliance.cde.config.{Parameters}
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.prci._
|
||||
import freechips.rocketchip.util.ElaborationArtefacts
|
||||
|
||||
36
generators/chipyard/src/main/scala/clocking/FakePLL.scala
Normal file
36
generators/chipyard/src/main/scala/clocking/FakePLL.scala
Normal file
@@ -0,0 +1,36 @@
|
||||
package chipyard.clocking
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import org.chipsalliance.cde.config.Parameters
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.devices.tilelink._
|
||||
import freechips.rocketchip.regmapper._
|
||||
import freechips.rocketchip.util._
|
||||
|
||||
class FakePLLCtrlBundle extends Bundle {
|
||||
val gate = Bool()
|
||||
val power = Bool()
|
||||
}
|
||||
|
||||
class FakePLLCtrl(address: BigInt, beatBytes: Int)(implicit p: Parameters) extends LazyModule
|
||||
{
|
||||
val device = new SimpleDevice(s"pll", Nil)
|
||||
val tlNode = TLRegisterNode(Seq(AddressSet(address, 4096-1)), device, "reg/control", beatBytes=beatBytes)
|
||||
val ctrlNode = BundleBridgeSource(() => Output(new FakePLLCtrlBundle))
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
// This PLL only has 2 address, the gate and power
|
||||
// Both should be set to turn on the PLL
|
||||
// TODO: Should these be reset by the top level reset pin?
|
||||
val gate_reg = Module(new AsyncResetRegVec(w=1, init=0))
|
||||
val power_reg = Module(new AsyncResetRegVec(w=1, init=0))
|
||||
|
||||
ctrlNode.out(0)._1.gate := gate_reg.io.q
|
||||
ctrlNode.out(0)._1.power := power_reg.io.q
|
||||
tlNode.regmap(
|
||||
0 -> Seq(RegField.rwReg(1, gate_reg.io)),
|
||||
4 -> Seq(RegField.rwReg(1, power_reg.io))
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import chisel3._
|
||||
|
||||
import scala.collection.mutable.{ArrayBuffer}
|
||||
|
||||
import freechips.rocketchip.config.{Parameters, Field, Config}
|
||||
import org.chipsalliance.cde.config.{Parameters, Field, Config}
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.devices.tilelink._
|
||||
@@ -15,12 +15,13 @@ import freechips.rocketchip.tile._
|
||||
import freechips.rocketchip.prci._
|
||||
|
||||
import testchipip.{TLTileResetCtrl}
|
||||
import chipyard.{DefaultClockFrequencyKey}
|
||||
import chipyard.harness.{DefaultClockFrequencyKey}
|
||||
|
||||
case class ChipyardPRCIControlParams(
|
||||
slaveWhere: TLBusWrapperLocation = CBUS,
|
||||
baseAddress: BigInt = 0x100000,
|
||||
enableTileClockGating: Boolean = true
|
||||
enableTileClockGating: Boolean = true,
|
||||
enableTileResetSetting: Boolean = true
|
||||
)
|
||||
|
||||
|
||||
@@ -72,12 +73,13 @@ trait HasChipyardPRCI { this: BaseSubsystem with InstantiatesTiles =>
|
||||
val frequencySpecifier = ClockGroupFrequencySpecifier(p(ClockFrequencyAssignersKey), p(DefaultClockFrequencyKey))
|
||||
val clockGroupCombiner = ClockGroupCombiner()
|
||||
val resetSynchronizer = ClockGroupResetSynchronizer()
|
||||
val tileClockGater = prci_ctrl_domain {
|
||||
TileClockGater(prciParams.baseAddress + 0x00000, tlbus, prciParams.enableTileClockGating)
|
||||
}
|
||||
val tileResetSetter = prci_ctrl_domain {
|
||||
val tileClockGater = if (prciParams.enableTileClockGating) { prci_ctrl_domain {
|
||||
TileClockGater(prciParams.baseAddress + 0x00000, tlbus)
|
||||
} } else { ClockGroupEphemeralNode() }
|
||||
val tileResetSetter = if (prciParams.enableTileResetSetting) { prci_ctrl_domain {
|
||||
TileResetSetter(prciParams.baseAddress + 0x10000, tlbus, tile_prci_domains.map(_.tile_reset_domain.clockNode.portParams(0).name.get), Nil)
|
||||
}
|
||||
} } else { ClockGroupEphemeralNode() }
|
||||
|
||||
(aggregator
|
||||
:= frequencySpecifier
|
||||
:= clockGroupCombiner
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package chipyard.clocking
|
||||
|
||||
import chisel3._
|
||||
|
||||
import org.chipsalliance.cde.config.Parameters
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.devices.tilelink._
|
||||
import freechips.rocketchip.regmapper._
|
||||
import freechips.rocketchip.util._
|
||||
import freechips.rocketchip.prci._
|
||||
import freechips.rocketchip.util.ElaborationArtefacts
|
||||
|
||||
import testchipip._
|
||||
|
||||
// This module adds a TileLink memory-mapped clock divider to the clock graph
|
||||
// The output clock/reset pairs from this module should be synchronized later
|
||||
class TLClockDivider(address: BigInt, beatBytes: Int, divBits: Int = 8)(implicit p: Parameters) extends LazyModule {
|
||||
val device = new SimpleDevice(s"clk-div-ctrl", Nil)
|
||||
val clockNode = ClockGroupIdentityNode()
|
||||
val tlNode = TLRegisterNode(Seq(AddressSet(address, 4096-1)), device, "reg/control", beatBytes=beatBytes)
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
require (clockNode.out.size == 1)
|
||||
val sources = clockNode.in.head._1.member.data.toSeq
|
||||
val sinks = clockNode.out.head._1.member.elements.toSeq
|
||||
require (sources.size == sinks.size)
|
||||
val nSinks = sinks.size
|
||||
|
||||
val regs = (0 until nSinks) .map { i =>
|
||||
val sinkName = sinks(i)._1
|
||||
val asyncReset = sources(i).reset
|
||||
val reg = withReset (asyncReset) {
|
||||
Module(new AsyncResetRegVec(w=divBits, init=0))
|
||||
}
|
||||
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)))
|
||||
divider.io.divisor := reg.io.q
|
||||
divider.io.resetAsync := ResetStretcher(sources(i).clock, asyncReset, 20).asAsyncReset
|
||||
divider.io.clockOut
|
||||
}
|
||||
|
||||
// Note this is not synchronized to the output clock, which takes time to appear
|
||||
// so this is still asyncreset
|
||||
// Stretch the reset for 40 cycles, to give enough time to reset any downstream
|
||||
// digital logic
|
||||
sinks(i)._2.reset := ResetStretcher(sources(i).clock, asyncReset, 40).asAsyncReset
|
||||
reg
|
||||
}
|
||||
|
||||
tlNode.regmap((0 until nSinks).map { i =>
|
||||
i * 4 -> Seq(RegField.rwReg(divBits, regs(i).io))
|
||||
}: _*)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package chipyard.clocking
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import org.chipsalliance.cde.config.Parameters
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.devices.tilelink._
|
||||
import freechips.rocketchip.regmapper._
|
||||
import freechips.rocketchip.util._
|
||||
import freechips.rocketchip.prci._
|
||||
import freechips.rocketchip.util.ElaborationArtefacts
|
||||
|
||||
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)
|
||||
extends MixedNexusNode(ClockImp, ClockGroupImp)(
|
||||
dFn = { d => ClockGroupSourceParameters() },
|
||||
uFn = { u => ClockSinkParameters() }
|
||||
)
|
||||
|
||||
// This module adds a TileLink memory-mapped clock mux for each downstream clock domain
|
||||
// in the clock graph. The output clock/reset should be synchronized downstream
|
||||
class TLClockSelector(address: BigInt, beatBytes: Int)(implicit p: Parameters) extends LazyModule {
|
||||
val device = new SimpleDevice("clk-sel-ctrl", Nil)
|
||||
val tlNode = TLRegisterNode(Seq(AddressSet(address, 4096-1)), device, "reg/control", beatBytes=beatBytes)
|
||||
|
||||
val clockNode = ClockSelNode()
|
||||
|
||||
lazy val module = new LazyModuleImp(this) {
|
||||
val asyncReset = clockNode.in.map(_._1).map(_.reset).toSeq(0)
|
||||
val clocks = clockNode.in.map(_._1).map(_.clock)
|
||||
val (outClocks, _) = clockNode.out.head
|
||||
val (sinkNames, sinks) = outClocks.member.elements.toSeq.unzip
|
||||
|
||||
val regs = (0 until sinks.size).map { i =>
|
||||
val sinkName = sinkNames(i)
|
||||
val sel = Wire(UInt(log2Ceil(clocks.size).W))
|
||||
val reg = withReset(asyncReset) { Module(new AsyncResetRegVec(w=log2Ceil(clocks.size), init=0)) }
|
||||
sel := reg.io.q
|
||||
println(s"${(address+i*4).toString(16)}: Clock domain $sinkName clock mux")
|
||||
|
||||
val mux = testchipip.ClockMutexMux(clocks).suggestName(s"${sinkName}_clkmux")
|
||||
mux.io.sel := sel
|
||||
mux.io.resetAsync := asyncReset.asAsyncReset
|
||||
sinks(i).clock := mux.io.clockOut
|
||||
// Stretch the reset for 20 cycles, to give time to reset any downstream digital logic
|
||||
sinks(i).reset := ResetStretcher(clocks(0), asyncReset, 20).asAsyncReset
|
||||
|
||||
reg
|
||||
}
|
||||
tlNode.regmap((0 until sinks.size).map { i =>
|
||||
i * 4 -> Seq(RegField.rwReg(log2Ceil(clocks.size), regs(i).io))
|
||||
}: _*)
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import chisel3._
|
||||
import chisel3.util._
|
||||
import chisel3.experimental.{Analog, IO}
|
||||
|
||||
import freechips.rocketchip.config._
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.prci._
|
||||
@@ -19,7 +19,7 @@ import freechips.rocketchip.subsystem._
|
||||
* flag will generate the registers, preserving the same memory map and behavior, but will not
|
||||
* generate any gaters
|
||||
*/
|
||||
class TileClockGater(address: BigInt, beatBytes: Int, enable: Boolean)(implicit p: Parameters, valName: ValName) extends LazyModule
|
||||
class TileClockGater(address: BigInt, beatBytes: Int)(implicit p: Parameters, valName: ValName) extends LazyModule
|
||||
{
|
||||
val device = new SimpleDevice(s"clock-gater", Nil)
|
||||
val clockNode = ClockGroupIdentityNode()
|
||||
@@ -31,8 +31,8 @@ class TileClockGater(address: BigInt, beatBytes: Int, enable: Boolean)(implicit
|
||||
val regs = (0 until nSinks).map({i =>
|
||||
val sinkName = sinks(i)._1
|
||||
val reg = withReset(sources(i).reset) { Module(new AsyncResetRegVec(w=1, init=1)) }
|
||||
if (sinkName.contains("tile") && enable) {
|
||||
println(s"ClockGate for ${sinkName} regmapped at ${(address+i*4).toString(16)}")
|
||||
if (sinkName.contains("tile")) {
|
||||
println(s"${(address+i*4).toString(16)}: Tile $sinkName clock gate")
|
||||
sinks(i)._2.clock := ClockGate(sources(i).clock, reg.io.q.asBool)
|
||||
sinks(i)._2.reset := sources(i).reset
|
||||
} else {
|
||||
@@ -47,8 +47,8 @@ class TileClockGater(address: BigInt, beatBytes: Int, enable: Boolean)(implicit
|
||||
}
|
||||
|
||||
object TileClockGater {
|
||||
def apply(address: BigInt, tlbus: TLBusWrapper, enable: Boolean)(implicit p: Parameters, v: ValName) = {
|
||||
val gater = LazyModule(new TileClockGater(address, tlbus.beatBytes, enable))
|
||||
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
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import chisel3._
|
||||
import chisel3.util._
|
||||
import chisel3.experimental.{Analog, IO}
|
||||
|
||||
import freechips.rocketchip.config._
|
||||
import org.chipsalliance.cde.config._
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.prci._
|
||||
@@ -39,16 +39,16 @@ class TileResetSetter(address: BigInt, beatBytes: Int, tileNames: Seq[String], i
|
||||
}): _*)
|
||||
|
||||
val tileMap = tileNames.zipWithIndex.map({ case (n, i) =>
|
||||
n -> (tile_async_resets(i), r_tile_resets(i).io.q)
|
||||
n -> (tile_async_resets(i), r_tile_resets(i).io.q, address + i * 4)
|
||||
})
|
||||
|
||||
(clockNode.out zip clockNode.in).map { case ((o, _), (i, _)) =>
|
||||
(o.member.elements zip i.member.elements).foreach { case ((name, oD), (_, iD)) =>
|
||||
oD.clock := iD.clock
|
||||
oD.reset := iD.reset
|
||||
for ((n, (rIn, rOut)) <- tileMap) {
|
||||
for ((n, (rIn, rOut, addr)) <- tileMap) {
|
||||
if (name.contains(n)) {
|
||||
println(name, n)
|
||||
println(s"${addr.toString(16)}: Tile $name reset control")
|
||||
// Async because the reset coming out of the AsyncResetRegVec is
|
||||
// clocked to the bus this is attached to, not the clock in this
|
||||
// clock bundle. We expect a ClockGroupResetSynchronizer downstream
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package chipyard.config
|
||||
|
||||
import freechips.rocketchip.config.{Config}
|
||||
import org.chipsalliance.cde.config.{Config}
|
||||
|
||||
// --------------
|
||||
// Chipyard abstract ("base") configuration
|
||||
@@ -40,10 +40,15 @@ class AbstractConfig extends Config(
|
||||
new chipyard.iobinders.WithTraceIOPunchthrough ++
|
||||
new chipyard.iobinders.WithExtInterruptIOCells ++
|
||||
new chipyard.iobinders.WithCustomBootPin ++
|
||||
new chipyard.iobinders.WithDividerOnlyClockGenerator ++
|
||||
|
||||
// Default behavior is to use a divider-only clock-generator
|
||||
// This works in VCS, Verilator, and FireSim/
|
||||
// This should get replaced with a PLL-like config instead
|
||||
new chipyard.clocking.WithDividerOnlyClockGenerator ++
|
||||
|
||||
new testchipip.WithSerialTLWidth(32) ++ // fatten the serialTL interface to improve testing performance
|
||||
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.WithUART ++ // add a UART
|
||||
new chipyard.config.WithL2TLBs(1024) ++ // use L2 TLBs
|
||||
@@ -52,6 +57,7 @@ class AbstractConfig extends Config(
|
||||
new chipyard.config.WithPeripheryBusFrequencyAsDefault ++ // Unspecified frequencies with match the pbus frequency (which is always set)
|
||||
new chipyard.config.WithMemoryBusFrequency(100.0) ++ // Default 100 MHz mbus
|
||||
new chipyard.config.WithPeripheryBusFrequency(100.0) ++ // Default 100 MHz pbus
|
||||
new freechips.rocketchip.subsystem.WithNMemoryChannels(2) ++ // Default 2 memory channels
|
||||
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.WithNoMMIOPort ++ // no top-level MMIO master port (overrides default set in rocketchip)
|
||||
@@ -60,4 +66,5 @@ class AbstractConfig extends Config(
|
||||
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ // no external interrupts
|
||||
new freechips.rocketchip.subsystem.WithDontDriveBusClocksFromSBus ++ // leave the bus clocks undriven by sbus
|
||||
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ // hierarchical buses including sbus/mbus/pbus/fbus/cbus/l2
|
||||
new freechips.rocketchip.subsystem.WithDTS("ucb-bar,chipyard", Nil) ++ // custom device name for DTS
|
||||
new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package chipyard
|
||||
|
||||
import freechips.rocketchip.config.{Config}
|
||||
import org.chipsalliance.cde.config.{Config}
|
||||
|
||||
// ---------------------
|
||||
// BOOM Configs
|
||||
@@ -53,3 +53,18 @@ class MediumBoomCosimConfig extends Config(
|
||||
new chipyard.config.WithTraceIO ++ // enable the traceio
|
||||
new boom.common.WithNMediumBooms(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class dmiMediumBoomConfig extends Config(
|
||||
new chipyard.harness.WithSerialAdapterTiedOff ++ // don't attach an external SimSerial
|
||||
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.WithSerialAdapterTiedOff ++ // don't attach an external SimSerial
|
||||
new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port
|
||||
new boom.common.WithNMediumBooms(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ package chipyard
|
||||
|
||||
import chisel3._
|
||||
|
||||
import freechips.rocketchip.config.{Config}
|
||||
import org.chipsalliance.cde.config.{Config}
|
||||
|
||||
// ---------------------
|
||||
// CVA6 Configs
|
||||
|
||||
38
generators/chipyard/src/main/scala/config/ChipConfigs.scala
Normal file
38
generators/chipyard/src/main/scala/config/ChipConfigs.scala
Normal file
@@ -0,0 +1,38 @@
|
||||
package chipyard
|
||||
|
||||
import org.chipsalliance.cde.config.{Config}
|
||||
import freechips.rocketchip.diplomacy._
|
||||
|
||||
// A simple config demonstrating how to set up a basic chip in Chipyard
|
||||
class ChipLikeQuadRocketConfig extends Config(
|
||||
//==================================
|
||||
// Set up TestHarness
|
||||
//==================================
|
||||
new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++ // use absolute frequencies for simulations in the harness
|
||||
// NOTE: This only simulates properly in VCS
|
||||
|
||||
//==================================
|
||||
// Set up tiles
|
||||
//==================================
|
||||
new freechips.rocketchip.subsystem.WithAsynchronousRocketTiles(3, 3) ++ // Add rational crossings between RocketTile and uncore
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(4) ++ // quad-core (4 RocketTiles)
|
||||
|
||||
//==================================
|
||||
// Set up I/O
|
||||
//==================================
|
||||
new testchipip.WithSerialTLWidth(4) ++
|
||||
new chipyard.harness.WithSimAXIMemOverSerialTL ++ // Attach fast SimDRAM to TestHarness
|
||||
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.WithNMemoryChannels(1) ++ // 1 memory channel
|
||||
|
||||
//==================================
|
||||
// Set up clock./reset
|
||||
//==================================
|
||||
new chipyard.clocking.WithPLLSelectorDividerClockGenerator ++ // Use a PLL-based clock selector/divider generator structure
|
||||
|
||||
// Create the uncore clock group
|
||||
new chipyard.clocking.WithClockGroupsCombinedByName("uncore", "implicit", "sbus", "mbus", "cbus", "system_bus", "fbus", "pbus") ++
|
||||
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package chipyard
|
||||
|
||||
import freechips.rocketchip.config.{Config}
|
||||
import org.chipsalliance.cde.config.{Config}
|
||||
|
||||
// ---------------------
|
||||
// Heterogenous Configs
|
||||
|
||||
@@ -2,7 +2,7 @@ package chipyard
|
||||
|
||||
import chisel3._
|
||||
|
||||
import freechips.rocketchip.config.{Config}
|
||||
import org.chipsalliance.cde.config.{Config}
|
||||
|
||||
// ---------------------
|
||||
// Ibex Configs
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package chipyard
|
||||
|
||||
import freechips.rocketchip.config.{Config}
|
||||
import org.chipsalliance.cde.config.{Config}
|
||||
import freechips.rocketchip.diplomacy.{AsynchronousCrossing}
|
||||
|
||||
// ------------------------------
|
||||
@@ -9,6 +9,7 @@ import freechips.rocketchip.diplomacy.{AsynchronousCrossing}
|
||||
|
||||
// DOC include start: FFTRocketConfig
|
||||
class FFTRocketConfig extends Config(
|
||||
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 freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
@@ -58,6 +59,7 @@ class LargeNVDLARocketConfig extends Config(
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class ManyMMIOAcceleratorRocketConfig extends Config(
|
||||
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 nvidia.blocks.dla.WithNVDLA("small") ++ // add a small NVDLA
|
||||
new chipyard.example.WithStreamingPassthrough ++ // use top with tilelink-controlled streaming passthrough
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package chipyard
|
||||
|
||||
import freechips.rocketchip.config.{Config}
|
||||
import org.chipsalliance.cde.config.{Config}
|
||||
import freechips.rocketchip.diplomacy.{AsynchronousCrossing}
|
||||
import freechips.rocketchip.subsystem.{SBUS, MBUS}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package chipyard
|
||||
|
||||
import freechips.rocketchip.config.{Config}
|
||||
import org.chipsalliance.cde.config.{Config}
|
||||
|
||||
// A empty config with no cores. Useful for testing
|
||||
class NoCoresConfig extends Config(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package chipyard
|
||||
|
||||
import freechips.rocketchip.config.{Config}
|
||||
import org.chipsalliance.cde.config.{Config}
|
||||
import freechips.rocketchip.diplomacy.{AsynchronousCrossing}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package chipyard
|
||||
|
||||
import freechips.rocketchip.config.{Config}
|
||||
import org.chipsalliance.cde.config.{Config}
|
||||
import freechips.rocketchip.diplomacy.{AsynchronousCrossing}
|
||||
|
||||
// ------------------------------
|
||||
@@ -27,6 +27,12 @@ class LeanGemminiRocketConfig extends Config(
|
||||
new chipyard.config.WithSystemBusWidth(128) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class LeanGemminiPrintfRocketConfig extends Config(
|
||||
new gemmini.LeanGemminiPrintfConfig ++ // use Lean Gemmini systolic array GEMM accelerator
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
new chipyard.config.WithSystemBusWidth(128) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class HwachaRocketConfig extends Config(
|
||||
new chipyard.config.WithHwachaTest ++
|
||||
new hwacha.DefaultHwachaConfig ++ // use Hwacha vector accelerator
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package chipyard
|
||||
|
||||
import freechips.rocketchip.config.{Config}
|
||||
import org.chipsalliance.cde.config.{Config}
|
||||
import freechips.rocketchip.diplomacy.{AsynchronousCrossing}
|
||||
|
||||
// --------------
|
||||
@@ -12,6 +12,7 @@ class RocketConfig extends Config(
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class TinyRocketConfig extends Config(
|
||||
new chipyard.iobinders.WithDontTouchIOBinders(false) ++ // TODO FIX: Don't dontTouch the ports
|
||||
new chipyard.config.WithTLSerialLocation(
|
||||
freechips.rocketchip.subsystem.FBUS,
|
||||
freechips.rocketchip.subsystem.PBUS) ++ // attach TL serial adapter to f/p busses
|
||||
@@ -85,6 +86,7 @@ class MbusScratchpadRocketConfig extends Config(
|
||||
// DOC include end: mbusscratchpadrocket
|
||||
|
||||
class MulticlockRocketConfig extends Config(
|
||||
new freechips.rocketchip.subsystem.WithRationalRocketTiles ++ // Add rational crossings between RocketTile and uncore
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||
// Frequency specifications
|
||||
new chipyard.config.WithTileFrequency(1600.0) ++ // Matches the maximum frequency of U540
|
||||
@@ -95,7 +97,6 @@ class MulticlockRocketConfig extends Config(
|
||||
// Crossing specifications
|
||||
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 freechips.rocketchip.subsystem.WithRationalRocketTiles ++ // Add rational crossings between RocketTile and uncore
|
||||
new testchipip.WithAsynchronousSerialSlaveCrossing ++ // Add Async crossing between serial and MBUS. Its master-side is tied to the FBUS
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
@@ -124,5 +125,12 @@ class MulticlockAXIOverSerialConfig extends Config(
|
||||
new chipyard.config.WithSerialTLBackingMemory ++ // remove axi4 mem port in favor of SerialTL memory
|
||||
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(2) ++
|
||||
new freechips.rocketchip.subsystem.WithNMemoryChannels(1) ++ // 1 memory channel
|
||||
new chipyard.config.AbstractConfig)
|
||||
// DOC include end: MulticlockAXIOverSerialConfig
|
||||
|
||||
class CustomIOChipTopRocketConfig extends Config(
|
||||
new chipyard.example.WithCustomChipTop ++
|
||||
new chipyard.example.WithCustomIOCells ++
|
||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // single rocket-core
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package chipyard
|
||||
|
||||
import freechips.rocketchip.config.{Config}
|
||||
import org.chipsalliance.cde.config.{Config}
|
||||
import freechips.rocketchip.diplomacy.{AsynchronousCrossing}
|
||||
|
||||
// --------------
|
||||
|
||||
@@ -2,7 +2,7 @@ package chipyard
|
||||
|
||||
import chisel3._
|
||||
|
||||
import freechips.rocketchip.config.{Config}
|
||||
import org.chipsalliance.cde.config.{Config}
|
||||
|
||||
class Sodor1StageConfig extends Config(
|
||||
// Create a Sodor 1-stage core
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package chipyard
|
||||
|
||||
import freechips.rocketchip.config.{Config}
|
||||
import org.chipsalliance.cde.config.{Config}
|
||||
|
||||
// Configs which instantiate a Spike-simulated
|
||||
// tile that interacts with the Chipyard SoC
|
||||
@@ -10,10 +10,47 @@ class SpikeConfig extends Config(
|
||||
new chipyard.WithNSpikeCores(1) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class dmiSpikeConfig extends Config(
|
||||
new chipyard.harness.WithSerialAdapterTiedOff ++ // don't attach an external SimSerial
|
||||
new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port
|
||||
new SpikeConfig)
|
||||
|
||||
// Avoids polling on the UART registers
|
||||
class SpikeFastUARTConfig extends Config(
|
||||
new chipyard.WithNSpikeCores(1) ++
|
||||
new chipyard.config.WithUARTFIFOEntries(128, 128) ++
|
||||
new chipyard.config.WithMemoryBusFrequency(1) ++
|
||||
new chipyard.config.WithPeripheryBusFrequency(1) ++
|
||||
new chipyard.config.WithMemoryBusFrequency(2) ++
|
||||
new chipyard.config.WithPeripheryBusFrequency(2) ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
// Makes the UART fast, also builds no L2 and a ludicrous L1D
|
||||
class SpikeUltraFastConfig extends Config(
|
||||
new chipyard.WithSpikeTCM ++
|
||||
new chipyard.WithNSpikeCores(1) ++
|
||||
new testchipip.WithSerialPBusMem ++
|
||||
new chipyard.config.WithUARTFIFOEntries(128, 128) ++
|
||||
new chipyard.config.WithMemoryBusFrequency(2) ++
|
||||
new chipyard.config.WithPeripheryBusFrequency(2) ++
|
||||
new chipyard.config.WithBroadcastManager ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
class dmiSpikeUltraFastConfig extends Config(
|
||||
new chipyard.harness.WithSerialAdapterTiedOff ++ // don't attach an external SimSerial
|
||||
new chipyard.config.WithDMIDTM ++ // have debug module expose a clocked DMI port
|
||||
new SpikeUltraFastConfig)
|
||||
|
||||
// Add the default firechip devices
|
||||
class SpikeUltraFastDevicesConfig extends Config(
|
||||
new chipyard.harness.WithSimBlockDevice ++
|
||||
new chipyard.harness.WithLoopbackNIC ++
|
||||
new icenet.WithIceNIC ++
|
||||
new testchipip.WithBlockDevice ++
|
||||
|
||||
new chipyard.WithSpikeTCM ++
|
||||
new chipyard.WithNSpikeCores(1) ++
|
||||
new testchipip.WithSerialPBusMem ++
|
||||
new chipyard.config.WithUARTFIFOEntries(128, 128) ++
|
||||
new chipyard.config.WithMemoryBusFrequency(2) ++
|
||||
new chipyard.config.WithPeripheryBusFrequency(2) ++
|
||||
new chipyard.config.WithBroadcastManager ++
|
||||
new chipyard.config.AbstractConfig)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package chipyard
|
||||
|
||||
import freechips.rocketchip.config.{Config}
|
||||
import org.chipsalliance.cde.config.{Config}
|
||||
import freechips.rocketchip.rocket.{DCacheParams}
|
||||
|
||||
class AbstractTraceGenConfig extends Config(
|
||||
@@ -9,7 +9,7 @@ class AbstractTraceGenConfig extends Config(
|
||||
new chipyard.harness.WithClockAndResetFromHarness ++
|
||||
new chipyard.iobinders.WithAXI4MemPunchthrough ++
|
||||
new chipyard.iobinders.WithTraceGenSuccessPunchthrough ++
|
||||
new chipyard.iobinders.WithDividerOnlyClockGenerator ++
|
||||
new chipyard.clocking.WithDividerOnlyClockGenerator ++
|
||||
new chipyard.config.WithTracegenSystem ++
|
||||
new chipyard.config.WithNoSubsystemDrivenClocks ++
|
||||
new chipyard.config.WithPeripheryBusFrequencyAsDefault ++
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package chipyard
|
||||
|
||||
import freechips.rocketchip.config.{Config}
|
||||
import org.chipsalliance.cde.config.{Config}
|
||||
import constellation.channel._
|
||||
import constellation.routing._
|
||||
import constellation.topology._
|
||||
@@ -77,6 +77,7 @@ class TutorialSha3BlackBoxConfig extends Config(
|
||||
|
||||
// Tutorial Phase 5: Map a multicore heterogeneous SoC with multiple cores and memory-mapped accelerators
|
||||
class TutorialNoCConfig extends Config(
|
||||
new chipyard.iobinders.WithDontTouchIOBinders(false) ++
|
||||
// Try changing the dimensions of the Mesh topology
|
||||
new constellation.soc.WithGlobalNoC(constellation.soc.GlobalNoCParams(
|
||||
NoCParams(
|
||||
|
||||
@@ -4,7 +4,7 @@ import scala.util.matching.Regex
|
||||
import chisel3._
|
||||
import chisel3.util.{log2Up}
|
||||
|
||||
import freechips.rocketchip.config.{Field, Parameters, Config}
|
||||
import org.chipsalliance.cde.config.{Field, Parameters, Config}
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.prci._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
@@ -13,7 +13,7 @@ import freechips.rocketchip.tilelink.{HasTLBusParams}
|
||||
|
||||
import chipyard._
|
||||
import chipyard.clocking._
|
||||
|
||||
import chipyard.harness.{DefaultClockFrequencyKey}
|
||||
|
||||
// The default RocketChip BaseSubsystem drives its diplomatic clock graph
|
||||
// with the implicit clocks of Subsystem. Don't do that, instead we extend
|
||||
|
||||
@@ -4,7 +4,7 @@ import scala.util.matching.Regex
|
||||
import chisel3._
|
||||
import chisel3.util.{log2Up}
|
||||
|
||||
import freechips.rocketchip.config.{Config}
|
||||
import org.chipsalliance.cde.config.{Config}
|
||||
import freechips.rocketchip.devices.tilelink.{BootROMLocated, PLICKey}
|
||||
import freechips.rocketchip.devices.debug.{Debug, ExportDebug, DebugModuleKey, DMI}
|
||||
import freechips.rocketchip.stage.phases.TargetDirKey
|
||||
@@ -87,3 +87,7 @@ class WithExtMemIdBits(n: Int) extends Config((site, here, up) => {
|
||||
class WithNoPLIC extends Config((site, here, up) => {
|
||||
case PLICKey => None
|
||||
})
|
||||
|
||||
class WithDebugModuleAbstractDataWords(words: Int = 16) extends Config((site, here, up) => {
|
||||
case DebugModuleKey => up(DebugModuleKey).map(_.copy(nAbstractDataWords=words))
|
||||
})
|
||||
|
||||
@@ -2,7 +2,7 @@ package chipyard.config
|
||||
|
||||
import chisel3._
|
||||
|
||||
import freechips.rocketchip.config.{Field, Parameters, Config}
|
||||
import org.chipsalliance.cde.config.{Field, Parameters, Config}
|
||||
import freechips.rocketchip.tile._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user