diff --git a/.github/actions/ibex-rtl-ci-steps/action.yml b/.github/actions/ibex-rtl-ci-steps/action.yml
new file mode 100644
index 00000000..e31d6779
--- /dev/null
+++ b/.github/actions/ibex-rtl-ci-steps/action.yml
@@ -0,0 +1,102 @@
+name: Ibex RTL CI Steps
+description: Ibex RTL CI Steps
+
+inputs:
+ ibex_config:
+ required: true
+ description: Ibex configuration to run CI for
+
+runs:
+ using: "composite"
+ steps:
+ # ibex_config.py will exit with error code 1 on any error which will cause
+ # the CI to fail if there's an issue with the configuration file or an
+ # incorrect configuration name being used
+ - name: Test and display fusesoc config for ${{ inputs.ibex_config }}
+ shell: bash
+ run: |
+ IBEX_CONFIG_OPTS=`./util/ibex_config.py ${{ inputs.ibex_config }} fusesoc_opts`
+ echo $IBEX_CONFIG_OPTS
+ echo "IBEX_CONFIG_OPTS=$IBEX_CONFIG_OPTS" >> $GITHUB_ENV
+
+ - name: Lint Verilog source files with Verilator for ${{ inputs.ibex_config }}
+ shell: bash
+ run: |
+ set +e
+ fusesoc --cores-root . run --target=lint --tool=verilator lowrisc:ibex:ibex_top_tracing $IBEX_CONFIG_OPTS
+ if [ $? != 0 ]; then
+ echo -n "::error::"
+ echo "Verilog lint failed. Run 'fusesoc --cores-root . run --target=lint --tool=verilator lowrisc:ibex:ibex_top_tracing $IBEX_CONFIG_OPTS' to check and fix all errors."
+ exit 1
+ fi
+
+ - name: Lint Verilog source files with Verible Verilog Lint for ${{ inputs.ibex_config }}
+ shell: bash
+ run: |
+ set +e
+ fusesoc --cores-root . run --target=lint --tool=veriblelint lowrisc:ibex:ibex_top_tracing $IBEX_CONFIG_OPTS
+ if [ $? != 0 ]; then
+ echo -n "::error::"
+ echo "Verilog lint failed. Run 'fusesoc --cores-root . run --target=lint --tool=veriblelint lowrisc:ibex:ibex_top_tracing $IBEX_CONFIG_OPTS' to check and fix all errors."
+ exit 1
+ fi
+
+ - name: Run RISC-V Compliance test for Ibex RV32IMC for ${{ inputs.ibex_config }}
+ shell: bash
+ run: |
+ set +e
+ # Build simulation model of Ibex
+ fusesoc --cores-root=. run --target=sim --setup --build lowrisc:ibex:ibex_riscv_compliance $IBEX_CONFIG_OPTS
+ if [ $? != 0 ]; then
+ echo -n "::error::"
+ echo "Unable to build Verilator model of Ibex for compliance testing."
+ exit 1
+ fi
+
+ # Run compliance test suite
+ export TARGET_SIM=$PWD/build/lowrisc_ibex_ibex_riscv_compliance_0.1/sim-verilator/Vibex_riscv_compliance
+ export RISCV_PREFIX=riscv32-unknown-elf-
+ export RISCV_TARGET=ibex
+ export RISCV_DEVICE=rv32imc
+ fail=0
+ for isa in rv32i rv32im rv32imc rv32Zicsr rv32Zifencei; do
+ make -C build/riscv-compliance RISCV_ISA=$isa 2>&1 | tee run.log
+ if [ ${PIPESTATUS[0]} != 0 ]; then
+ echo -n "::error::"
+ echo "The RISC-V compliance test suite failed for $isa"
+
+ # There's no easy way to get the test results in machine-readable
+ # form to properly exclude known-failing tests. Going with an
+ # approximate solution for now.
+ if [ $isa == rv32i ] && grep -q 'FAIL: 4/48' run.log; then
+ echo -n "::error::"
+ echo "Expected failure for rv32i, see lowrisc/ibex#100 more more information."
+ else
+ fail=1
+ fi
+ fi
+ done
+ exit $fail
+
+ - name: Run Verilator co-sim tests for for ${{ inputs.ibex_config }}
+ shell: bash
+ run: |
+ source ci/setup-cosim.sh
+ # Build simple system with co-simulation
+ fusesoc --cores-root=. run --target=sim --setup --build lowrisc:ibex:ibex_simple_system_cosim $IBEX_CONFIG_OPTS
+
+ # Run directed tests against simple system co-simulation
+ ./ci/run-cosim-test.sh --skip-pass-check CoreMark examples/sw/benchmarks/coremark/coremark.elf
+
+ if ./util/ibex_config.py ${{ inputs.ibex_config }} query_fields PMPEnable | grep -q 'PMPEnable=1'; then
+ ./ci/run-cosim-test.sh --skip-pass-check pmp_smoke examples/sw/simple_system/pmp_smoke_test/pmp_smoke_test.elf
+ else
+ echo "PMP not supported on ${{ inputs.ibex_config }}, skipping pmp_smoke_test"
+ fi
+
+ if ./util/ibex_config.py ${{ inputs.ibex_config }} query_fields SecureIbex | grep -q 'SecureIbex=1'; then
+ ./ci/run-cosim-test.sh dit_test examples/sw/simple_system/dit_test/dit_test.elf
+ ./ci/run-cosim-test.sh dummy_instr_test examples/sw/simple_system/dummy_instr_test/dummy_instr_test.elf
+ else
+ echo "Security features not supported on ${{ inputs.ibex_config }}, skipping security feature tests"
+ fi
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 00000000..9fbbe8cc
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,151 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+# GitHub Actions CI build configuration
+
+name: Ibex CI
+
+on:
+ push:
+ tags:
+ - "*"
+ merge_group:
+ types:
+ - checks_requested
+ pull_request:
+ branches:
+ - "*"
+
+# Note: All tests run as part of one job to avoid copying intermediate build
+# artifacts around (e.g. Verilator and toolchain builds). Once more builds/tests
+# are added, we need to re-evaluate this decision to parallelize jobs and
+# improve end-to-end CI times.
+
+jobs:
+ lint_dv:
+ name: Run quality checks (Lint and DV)
+ runs-on: ubuntu-22.04
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ # Fetch all history so that we can run git diff on the base branch
+ fetch-depth: 0
+
+ - name: Setup environment variables
+ run: |
+ # Filter out empty lines or comments
+ grep -v '^\(#\|$\)' ci/vars.env >> $GITHUB_ENV
+
+ - name: Install build dependencies
+ run: |
+ ci/install-build-deps.sh
+
+ - name: Display environment
+ run: |
+ echo $PATH
+ python3 --version
+ echo -n "fusesoc "
+ fusesoc --version
+ verilator --version
+ riscv32-unknown-elf-gcc --version
+ verible-verilog-lint --version
+
+ # Verible format is experimental so only run on default config for now,
+ # will eventually become part of the per-config CI
+ - name: Format all source code with Verible format (experimental)
+ run: |
+ set +e
+ fusesoc --cores-root . run --no-export --target=format --tool=veribleformat lowrisc:ibex:ibex_top_tracing
+ if [ $? != 0 ]; then
+ echo -n "::error::"
+ echo "Verilog format with Verible failed. Run 'fusesoc --cores-root . run --no-export --target=format --tool=veribleformat lowrisc:ibex:ibex_top_tracing' to check and fix all errors."
+ echo "This flow is currently experimental and failures can be ignored."
+ fi
+ # Show diff of what verilog_format would have changed, and then revert.
+ git diff --no-pager
+ git reset --hard HEAD
+ continue-on-error: true
+
+ - name: Use clang-format to check C/C++ coding style
+ # This check is not idempotent, but checks changes to a base branch.
+ # Run it only on pull requests.
+ if: github.event_name == 'pull_request'
+ run: |
+ set +e
+ fork_origin=${{ github.event.pull_request.base.sha }}
+ changed_files=$(git diff --name-only $fork_origin | grep -v '^vendor' | grep -E '\.(cpp|cc|c|h)$')
+ test -z "$changed_files" || git diff -U0 $fork_origin $changed_files | clang-format-diff -p1 | tee clang-format-output
+ if [ -s clang-format-output ]; then
+ echo -n "::error::"
+ echo "C/C++ lint failed. Use 'git clang-format' with appropriate options to reformat the changed code."
+ exit 1
+ fi
+
+ - name: Build and run CSR testbench with Verilator
+ run: |
+ # Build and run CSR testbench, chosen Ibex configuration does not effect
+ # this so doesn't need to be part of per-config CI
+ fusesoc --cores-root=. run --target=sim --tool=verilator lowrisc:ibex:tb_cs_registers
+
+ - name: Get RISC-V Compliance test suite
+ run: |
+ cd build
+ git clone https://github.com/riscv/riscv-compliance.git
+ cd riscv-compliance
+ git checkout "$RISCV_COMPLIANCE_GIT_VERSION"
+
+ - name: Build tests for verilator co-simulation
+ run: |
+ # Build CoreMark without performance counter dump for co-simulation testing
+ make -C ./examples/sw/benchmarks/coremark SUPPRESS_PCOUNT_DUMP=1
+ make -C ./examples/sw/simple_system/pmp_smoke_test
+ make -C ./examples/sw/simple_system/dit_test
+ make -C ./examples/sw/simple_system/dummy_instr_test
+
+ # Run Ibex RTL CI per supported configuration
+ - name: Run Ibex RTL CI for small configuration
+ uses: ./.github/actions/ibex-rtl-ci-steps
+ with:
+ ibex_config: small
+ - name: Run Ibex RTL CI for opentitan configuration
+ uses: ./.github/actions/ibex-rtl-ci-steps
+ with:
+ ibex_config: opentitan
+ - name: Run Ibex RTL CI for maxperf configuration
+ uses: ./.github/actions/ibex-rtl-ci-steps
+ with:
+ ibex_config: maxperf
+ - name: Run Ibex RTL CI for maxperf-pmp-bmbalanced configuration
+ uses: ./.github/actions/ibex-rtl-ci-steps
+ with:
+ ibex_config: maxperf-pmp-bmbalanced
+ - name: Run Ibex RTL CI for maxperf-pmp-bmfull configuration
+ uses: ./.github/actions/ibex-rtl-ci-steps
+ with:
+ ibex_config: maxperf-pmp-bmfull
+ - name: Run Ibex RTL CI for experimental-branch-predictor configuration
+ uses: ./.github/actions/ibex-rtl-ci-steps
+ with:
+ ibex_config: experimental-branch-predictor
+
+ # Run lint on simple system
+ - name: Run Verilator lint on simple system
+ run: |
+ set +e
+ fusesoc --cores-root . run --target=lint --tool=verilator lowrisc:ibex:ibex_simple_system
+ if [ $? != 0 ]; then
+ echo -n "::error::"
+ echo "Verilog lint with Verilator failed. Run 'fusesoc --cores-root . run --target=lint --tool=verilator lowrisc:ibex:ibex_simple_system' to check and fix all errors."
+ exit 1
+ fi
+
+ - name: Run Verible lint on simple system
+ run: |
+ set +e
+ fusesoc --cores-root . run --target=lint --tool=veriblelint lowrisc:ibex:ibex_simple_system
+ if [ $? != 0 ]; then
+ echo -n "::error::"
+ echo "Verilog lint with Verible failed. Run 'fusesoc --cores-root . run --target=lint --tool=veriblelint lowrisc:ibex:ibex_simple_system' to check and fix all errors."
+ exit 1
+ fi
diff --git a/.github/workflows/pr_lint.yml b/.github/workflows/pr_lint.yml
new file mode 100644
index 00000000..91eeb1e4
--- /dev/null
+++ b/.github/workflows/pr_lint.yml
@@ -0,0 +1,38 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+# GitHub Action to run Verible linting on pull requests and add review comments.
+#
+# See https://github.com/chipsalliance/verible-linter-action.
+
+name: pr-lint
+
+# Triggers when there is any activity on a pull request, e.g. opened, updated.
+on:
+ merge_group:
+ types:
+ - checks_requested
+ pull_request:
+ branches:
+ - "*"
+
+jobs:
+ verible-lint:
+ runs-on: ubuntu-latest
+ env:
+ verible_config: "vendor/lowrisc_ip/lint/tools/veriblelint/lowrisc-styleguide.rules.verible_lint"
+ steps:
+ - uses: actions/checkout@v4
+ - name: Display Verible config
+ run: |
+ echo "::group::Verible config"
+ cat "$verible_config"
+ echo "::endgroup::"
+ - name: Run Verible linter action
+ uses: chipsalliance/verible-linter-action@main
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ reviewdog_reporter: github-pr-check
+ suggest_fixes: "false"
+ config_file: ${{ env.verible_config }}
diff --git a/.github/workflows/private-ci.yml b/.github/workflows/private-ci.yml
new file mode 100644
index 00000000..22430b03
--- /dev/null
+++ b/.github/workflows/private-ci.yml
@@ -0,0 +1,38 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+name: Ibex Private CI
+
+on:
+ push:
+ tags:
+ - "*"
+ merge_group:
+ types:
+ - checks_requested
+ pull_request_target:
+ branches:
+ - "*"
+
+permissions:
+ contents: write # For repository dispatch
+
+jobs:
+ trigger:
+ name: Trigger Private CI
+ runs-on: ubuntu-latest
+ steps:
+ - name: Trigger Private CI
+ run: |
+ PAYLOAD='"target":"${{ github.repository_owner }}/lowrisc-private-ci/master/ibex-private-ci.yml","sha":"${{ github.event.pull_request.head.sha || github.sha }}"'
+ if ${{ github.event_name == 'pull_request_target' }}; then
+ PAYLOAD+=',"pull_request":${{ github.event.pull_request.number }}'
+ fi
+ curl -fL \
+ -X POST \
+ -H "Accept: application/vnd.github+json" \
+ -H "Authorization: Bearer ${{ github.token }}" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ https://api.github.com/repos/${{ github.repository }}/dispatches \
+ -d '{"event_type":"cross-repo-ci","client_payload":{'"$PAYLOAD"'}}'
diff --git a/.gitignore b/.gitignore
index 65915375..177ca105 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,19 +18,6 @@ ibex_simple_system_pcount.csv
# Python cache files
__pycache__
-# This is generated by VCS when running DV simulations with WAVE=1.
-/dv/uvm/core_ibex/ucli.key
-
-# This is generated by UVM when running simulations and doesn't seem
-# to be something you can disable.
-/dv/uvm/core_ibex/tr_db.log
-
-# This is the default output directory in dv/uvm/core_ibex and
-# contains auto-generated files from building and running tests.
-/dv/uvm/core_ibex/out
-
# This is generated by Questa tool when running DV simulations
modelsim.ini
-# This is generated by Xcelium when running DV simulations, even with WAVE=0
-/dv/uvm/core_ibex/waves.shm
diff --git a/.readthedocs.yml b/.readthedocs.yml
new file mode 100644
index 00000000..b6da63d9
--- /dev/null
+++ b/.readthedocs.yml
@@ -0,0 +1,20 @@
+# .readthedocs.yaml
+# Read the Docs configuration file
+# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
+
+# Required
+version: 2
+
+# Set the version of Python and other tools you might need
+build:
+ os: ubuntu-22.04
+ tools:
+ python: "3.11"
+
+# Build documentation in the docs/ directory with Sphinx
+sphinx:
+ configuration: doc/conf.py
+
+python:
+ install:
+ - requirements: doc/requirements.txt
diff --git a/.svlint.toml b/.svlint.toml
index 29bbeb09..50dd4fc4 100644
--- a/.svlint.toml
+++ b/.svlint.toml
@@ -5,7 +5,7 @@
# Rules for svlint, a SystemVerilog linter commonly used in editors.
# The configuration matches the lowRISC SystemVerilog style guide at
# https://github.com/lowRISC/style-guides/blob/master/VerilogCodingStyle.md.
-# See https://github.com/dalance/svlint/blob/master/RULES.md for a list of rules.
+# See https://github.com/dalance/svlint/blob/master/MANUAL.md for a list of rules.
[option]
exclude_paths = ["build.*", "sw/.*", ".sv.tpl$", "vendor/.*"]
diff --git a/CREDITS.md b/CREDITS.md
index f98e6900..c1d249a2 100644
--- a/CREDITS.md
+++ b/CREDITS.md
@@ -13,34 +13,68 @@ in the form of source code, bug reports, testing, marketing, or any other form,
please feel free to open a pull request to get your name added to this file.
- Alex Bradbury
+- Andreas Kurth
- Andreas Traber
- Antonio Pullini
+- Bryan Cantrill
+- Canberk Topal
+- Cathal Minnock
+- Daniel Mlynek
+- Dawid Zimonczyk
- Eunchan Kim
+- Felix Yan
+- Flavian Solt
- Florian Zaruba
- Francesco Conti
+- Gary Guo
- Germain Haugou
- Greg Chadwick
+- Harry Callahan
+- Hai Hoang Dang
+- Henner Zeller
+- Hodjat Asghari Esfeden
- Igor Loi
- Ioannis Karageorgos
-- Markus Wegmann
- Ivan Ribeiro
+- Karol Gugala
+- Leon Woestenberg
+- Luís Marques
+- Marek Pikuła
+- Markus Wegmann
+- Marno van der Maas
- Matthias Baer
+- Mehmet Burak Aykenar
- Michael Gautschi
+- Michael Gielda
+- Michael Munday
+- Michael Platzer
- Michael Schaffner
- Nils Graf
- Noah Huesser
- Noam Gallmann
- Pasquale Davide Schiavone
+- Paul O'Keeffe
- Philipp Wagner
- Pirmin Vogel
+- Prajwala Puttappa
- Rahul Behl
- Rhys Thomas
- Renzo Andri
- Robert Schilling
+- Rupert Swarbick
+- Sam Elliott
- Scott Johnson
+- Stefan Mach
+- Stefan Tauner
- Stefan Wallentowitz
- Sven Stucki
- Tao Liu
- Tobias Wölfel
- Tom Roberts
+- Tudor Timi
- Udi Jonnalagadda
+- Vladimir Rozic
+- Yuichi Sugiyama
+- Yusef Karim
+- Zachary Snow
+- Zeeshan Rafique
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 00000000..f6898e32
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,10 @@
+The Ibex Project
+Copyright 2024 lowRISC contributors.
+
+This product includes hardware and/or software developed as part of the
+Ibex(R) (https://github.com/lowRISC/ibex) and OpenTitan(R) projects.
+
+Ibex was originally developed by the PULP team at ETH Zurich and University of
+Bologna under the name zero-riscy. Ibex verification, performance enhancement
+and security hardening have been supported by the OpenTitan project
+(https://www.opentitan.org).
diff --git a/README.md b/README.md
index 1a4256d5..06c5603e 100644
--- a/README.md
+++ b/README.md
@@ -1,17 +1,23 @@
-[](https://dev.azure.com/lowrisc/ibex/_build/latest?definitionId=3&branchName=master)
+[Ibex OpenTitan configuration Nightly Regression](https://ibex.reports.lowrisc.org/opentitan/latest/report.html)
+
+
+
# Ibex RISC-V Core
-Ibex is a small and efficient, 32-bit, in-order RISC-V core with a 2-stage pipeline that implements
-the RV32IMC instruction set architecture.
+Ibex is a production-quality open source 32-bit RISC-V CPU core written in
+SystemVerilog. The CPU core is heavily parametrizable and well suited for
+embedded control applications. Ibex is being extensively verified and has
+seen multiple tape-outs. Ibex supports the Integer (I) or Embedded (E),
+Integer Multiplication and Division (M), Compressed (C), and B (Bit
+Manipulation) extensions.
-This core was initially developed as part of the [PULP platform](https://www.pulp-platform.org)
-under the name "Zero-riscy" \[[1](https://doi.org/10.1109/PATMOS.2017.8106976)\], and has been
+Ibex was initially developed as part of the [PULP platform](https://www.pulp-platform.org)
+under the name ["Zero-riscy"](https://doi.org/10.1109/PATMOS.2017.8106976), and has been
contributed to [lowRISC](https://www.lowrisc.org) who maintains it and develops it further. It is
-under active development, with further code cleanups, feature additions, and test and verification
-planned for the future.
+under active development.
## Configuration
@@ -23,17 +29,16 @@ These are configurations on which lowRISC is focusing for performance evaluation
| Config | "micro" | "small" | "maxperf" | "maxperf-pmp-bmfull" |
| ------ | ------- | --------| ----------| -------------------- |
| Features | RV32EC | RV32IMC, 3 cycle mult | RV32IMC, 1 cycle mult, Branch target ALU, Writeback stage | RV32IMCB, 1 cycle mult, Branch target ALU, Writeback stage, 16 PMP regions |
-| Performance (CoreMark/MHz) | 0.904 | 2.47 | 3.13 | 3.05 |
-| Area - Yosys (kGE) | 17.44 | 26.06 | 35.64 | 58.74 |
-| Area - Commercial (estimated kGE) | ~16 | ~24 | ~33 | ~54 |
-| Verification status | Red | Green | Amber | Amber |
+| Performance (CoreMark/MHz) | 0.904 | 2.47 | 3.13 | 3.13 |
+| Area - Yosys (kGE) | 16.85 | 26.60 | 32.48 | 66.02 |
+| Area - Commercial (estimated kGE) | ~15 | ~24 | ~30 | ~61 |
+| Verification status | Red | Green | Green | Green |
Notes:
* Performance numbers are based on CoreMark running on the Ibex Simple System [platform](examples/simple_system/README.md).
Note that different ISAs (use of B and C extensions) give the best results for different configurations.
See the [Benchmarks README](examples/sw/benchmarks/README.md) for more information.
- The "maxperf-pmp-bmfull" configuration sets a `SpecBranch` parameter in `ibex_core.sv`; this helps timing but has a small negative performance impact.
* Yosys synthesis area numbers are based on the Ibex basic synthesis [flow](syn/README.md) using the latch-based register file.
* Commercial synthesis area numbers are a rough estimate of what might be achievable with a commercial synthesis flow and technology library.
* For comparison, the original "Zero-riscy" core yields an area of 23.14kGE using our Yosys synthesis flow.
@@ -42,8 +47,8 @@ Notes:
Amber indicates that some verification has been performed, but the configuration is still experimental.
Red indicates a configuration with minimal/no verification.
Users must make their own assessment of verification readiness for any tapeout.
-* v0.92 of the RISC-V Bit Manipulation Extension is supported.
- This is *not ratified* and there may be changes for the v1.0 ratified version.
+* v.1.0.0 of the RISC-V Bit-Manipulation Extension is supported as well as the remaining sub-extensions of draft v.0.93 of the bitmanip spec.
+ The latter are *not ratified* and there may be changes before ratification.
See [Standards Compliance](https://ibex-core.readthedocs.io/en/latest/01_overview/compliance.html) in the Ibex documentation for more information.
## Documentation
@@ -52,6 +57,17 @@ The Ibex user manual can be
[read online at ReadTheDocs](https://ibex-core.readthedocs.io/en/latest/). It is also contained in
the `doc` folder of this repository.
+## Examples
+
+The Ibex repository includes [Simple System](examples/simple_system/README.md).
+This is an intentionally simple integration of Ibex with a basic system that targets simulation.
+It is intended to provide an easy way to get bare metal binaries running on Ibex in simulation.
+
+A more complete example can be found in the [Ibex Demo System repository](https://github.com/lowrisc/ibex-demo-system).
+In particular it includes a integration of the [PULP RISC-V debug module](https://github.com/pulp-platform/riscv-dbg).
+It targets the [Arty A7 FPGA board from Digilent](https://digilent.com/shop/arty-a7-artix-7-fpga-development-board/) and supports debugging via OpenOCD and GDB over USB (no external JTAG probe required).
+The Ibex Demo System is maintained by lowRISC but is not an official part of Ibex.
+
## Contributing
We highly appreciate community contributions. To ease our work of reviewing your contributions,
@@ -69,7 +85,7 @@ When contributing SystemVerilog source code, please try to be consistent and adh
coding style guide](https://github.com/lowRISC/style-guides/blob/master/VerilogCodingStyle.md).
When contributing C or C++ source code, please try to adhere to [the OpenTitan C++ coding style
-guide](https://docs.opentitan.org/doc/rm/c_cpp_coding_style/).
+guide](https://opentitan.org/book/doc/contributing/style_guides/c_cpp_coding_style.html).
All C and C++ code should be formatted with clang-format before committing.
Either run `clang-format -i filename.cc` or `git clang-format` on added files.
@@ -96,9 +112,3 @@ License, Version 2.0 (see LICENSE for full text).
Many people have contributed to Ibex through the years. Please have a look at
the [credits file](CREDITS.md) and the commit history for more information.
-
-## References
-1. [Schiavone, Pasquale Davide, et al. "Slow and steady wins the race? A comparison of
- ultra-low-power RISC-V cores for Internet-of-Things applications."
- _27th International Symposium on Power and Timing Modeling, Optimization and Simulation
- (PATMOS 2017)_](https://doi.org/10.1109/PATMOS.2017.8106976)
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 00000000..ab79a39c
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,8 @@
+# Reporting Security Issues
+
+The lowRISC team and Ibex community (including the OpenTitan partnership) take security issues seriously.
+
+We appreciate all efforts to find security vulnerabilities in Ibex and ask that responsible disclosure is practiced should you discover a potential vulnerability.
+
+As Ibex and in particular its secure configuration was developed as part of [OpenTitan](https://www.github.com/lowrisc/opentitan) contact [security@opentitan.org](mailto:security@opentitan.org) to report any security issues and do not open a public issue.
+[security@opentitan.org](mailto:security@opentitan.org) will advise on the coordinated vulnerability disclosure (CVD) procedure.
diff --git a/vendor/lowrisc_ip/util/dvsim/testplanner/__init__.py b/__init__.py
similarity index 100%
rename from vendor/lowrisc_ip/util/dvsim/testplanner/__init__.py
rename to __init__.py
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
deleted file mode 100644
index 592c1807..00000000
--- a/azure-pipelines.yml
+++ /dev/null
@@ -1,120 +0,0 @@
-# Copyright lowRISC contributors.
-# Licensed under the Apache License, Version 2.0, see LICENSE for details.
-# SPDX-License-Identifier: Apache-2.0
-
-# Azure Pipelines CI build configuration
-# Documentation at https://aka.ms/yaml
-
-variables:
-- template: ci/vars.yml
-
-trigger:
- batch: true
- branches:
- include:
- - '*'
- tags:
- include:
- - '*'
-pr:
- branches:
- include:
- - '*'
-
-# Note: All tests run as part of one job to avoid copying intermediate build
-# artifacts around (e.g. Verilator and toolchain builds). Once more builds/tests
-# are added, we need to re-evaluate this decision to parallelize jobs and
-# improve end-to-end CI times.
-
-jobs:
-- job: lint_dv
- displayName: Run quality checks (Lint and DV)
- pool:
- vmImage: "ubuntu-18.04"
- steps:
- - bash: |
- ci/install-build-deps.sh
- displayName: Install build dependencies
-
- - bash: |
- echo $PATH
- python3 --version
- echo -n "fusesoc "
- fusesoc --version
- verilator --version
- riscv32-unknown-elf-gcc --version
- verible-verilog-lint --version
- displayName: Display environment
-
- # Verible format is experimental so only run on default config for now,
- # will eventually become part of the per-config CI
- - bash: |
- fusesoc --cores-root . run --no-export --target=format --tool=veribleformat lowrisc:ibex:ibex_core_tracing
- if [ $? != 0 ]; then
- echo -n "##vso[task.logissue type=error]"
- echo "Verilog format with Verible failed. Run 'fusesoc --cores-root . run --no-export --target=format --tool=veribleformat lowrisc:ibex:ibex_core_tracing' to check and fix all errors."
- echo "This flow is currently experimental and failures can be ignored."
- fi
- # Show diff of what verilog_format would have changed, and then revert.
- git diff
- git reset --hard HEAD
- continueOnError: true
- displayName: Format all source code with Verible format (experimental)
-
- - bash: |
- fork_origin=$(git merge-base --fork-point origin/master)
- changed_files=$(git diff --name-only $fork_origin | grep -v '^vendor' | grep -E '\.(cpp|cc|c|h)$')
- test -z "$changed_files" || git diff -U0 $fork_origin $changed_files | clang-format-diff -p1 | tee clang-format-output
- if [ -s clang-format-output ]; then
- echo -n "##vso[task.logissue type=error]"
- echo "C/C++ lint failed. Use 'git clang-format' with appropriate options to reformat the changed code."
- exit 1
- fi
- # This check is not idempotent, but checks changes to a base branch.
- # Run it only on pull requests.
- condition: eq(variables['Build.Reason'], 'PullRequest')
- displayName: 'Use clang-format to check C/C++ coding style'
-
- - bash: |
- # Build and run CSR testbench, chosen Ibex configuration does not effect
- # this so doesn't need to be part of per-config CI
- fusesoc --cores-root=. run --target=sim --tool=verilator lowrisc:ibex:tb_cs_registers
- displayName: Build and run CSR testbench with Verilator
-
- - bash: |
- cd build
- git clone https://github.com/riscv/riscv-compliance.git
- cd riscv-compliance
- git checkout "$RISCV_COMPLIANCE_GIT_VERSION"
- displayName: Get RISC-V Compliance test suite
-
- # Run Ibex RTL CI per supported configuration
- - template : ci/ibex-rtl-ci-steps.yml
- parameters:
- ibex_configs:
- # Note: Try to keep the list of configurations in sync with the one used
- # in Private CI.
- - small
- - experimental-maxperf-pmp
- - experimental-maxperf-pmp-bmfull
- - experimental-maxperf-pmp-bmfull-icache
- - experimental-branch-predictor
-
- # Run lint on simple system
- - bash: |
- fusesoc --cores-root . run --target=lint --tool=verilator lowrisc:ibex:ibex_simple_system
- if [ $? != 0 ]; then
- echo -n "##vso[task.logissue type=error]"
- echo "Verilog lint with Verilator failed. Run 'fusesoc --cores-root . run --target=lint --tool=verilator lowrisc:ibex:ibex_simple_system' to check and fix all errors."
- exit 1
- fi
- displayName: Run Verilator lint on simple system
-
- - bash: |
- fusesoc --cores-root . run --target=lint --tool=veriblelint lowrisc:ibex:ibex_simple_system
- if [ $? != 0 ]; then
- echo -n "##vso[task.logissue type=error]"
- echo "Verilog lint with Verible failed. Run 'fusesoc --cores-root . run --target=lint --tool=veriblelint lowrisc:ibex:ibex_simple_system' to check and fix all errors."
- exit 1
- fi
- displayName: Run Verible lint on simple system
diff --git a/ci/azp-private.yml b/ci/azp-private.yml
deleted file mode 100644
index 04df3f4b..00000000
--- a/ci/azp-private.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright lowRISC contributors.
-# Licensed under the Apache License, Version 2.0, see LICENSE for details.
-# SPDX-License-Identifier: Apache-2.0
-#
-# Private CI trigger. Used to run tooling that can't currently be shared
-# publicly.
-
-trigger:
- batch: true
- branches:
- include:
- - '*'
- tags:
- include:
- - "*"
-pr:
- branches:
- include:
- - '*'
-
-# The runner used for private CI enforces the use of the template below. All
-# build steps need to be placed into the template.
-resources:
- repositories:
- - repository: lowrisc-private-ci
- type: github
- endpoint: lowRISC
- name: lowrisc/lowrisc-private-ci
-
-extends:
- template: jobs-ibex.yml@lowrisc-private-ci
diff --git a/ci/ibex-rtl-ci-steps.yml b/ci/ibex-rtl-ci-steps.yml
deleted file mode 100644
index 5fc32a7b..00000000
--- a/ci/ibex-rtl-ci-steps.yml
+++ /dev/null
@@ -1,67 +0,0 @@
-parameters:
- ibex_configs: []
-
-steps:
- - ${{ each config in parameters.ibex_configs }}:
- # ibex_config.py will exit with error code 1 on any error which will cause
- # the CI to fail if there's an issue with the configuration file or an
- # incorrect configuration name being used
- - bash: |
- set -e
- IBEX_CONFIG_OPTS=`./util/ibex_config.py ${{ config }} fusesoc_opts`
- echo $IBEX_CONFIG_OPTS
- echo "##vso[task.setvariable variable=ibex_config_opts]" $IBEX_CONFIG_OPTS
- displayName: Test and display fusesoc config for ${{ config }}
-
- - bash: |
- fusesoc --cores-root . run --target=lint --tool=verilator lowrisc:ibex:ibex_core_tracing $IBEX_CONFIG_OPTS
- if [ $? != 0 ]; then
- echo -n "##vso[task.logissue type=error]"
- echo "Verilog lint failed. Run 'fusesoc --cores-root . run --target=lint --tool=verilator lowrisc:ibex:ibex_core_tracing $IBEX_CONFIG_OPTS' to check and fix all errors."
- exit 1
- fi
- displayName: Lint Verilog source files with Verilator for ${{ config }}
-
- - bash: |
- fusesoc --cores-root . run --target=lint --tool=veriblelint lowrisc:ibex:ibex_core_tracing $IBEX_CONFIG_OPTS
- if [ $? != 0 ]; then
- echo -n "##vso[task.logissue type=error]"
- echo "Verilog lint failed. Run 'fusesoc --cores-root . run --target=lint --tool=veriblelint lowrisc:ibex:ibex_core_tracing $IBEX_CONFIG_OPTS' to check and fix all errors."
- exit 1
- fi
- displayName: Lint Verilog source files with Verible Verilog Lint for ${{ config }}
-
- - bash: |
- # Build simulation model of Ibex
- fusesoc --cores-root=. run --target=sim --setup --build lowrisc:ibex:ibex_riscv_compliance $IBEX_CONFIG_OPTS
- if [ $? != 0 ]; then
- echo -n "##vso[task.logissue type=error]"
- echo "Unable to build Verilator model of Ibex for compliance testing."
- exit 1
- fi
-
- # Run compliance test suite
- export TARGET_SIM=$PWD/build/lowrisc_ibex_ibex_riscv_compliance_0.1/sim-verilator/Vibex_riscv_compliance
- export RISCV_PREFIX=riscv32-unknown-elf-
- export RISCV_TARGET=ibex
- export RISCV_DEVICE=rv32imc
- fail=0
- for isa in rv32i rv32im rv32imc rv32Zicsr rv32Zifencei; do
- make -C build/riscv-compliance RISCV_ISA=$isa 2>&1 | tee run.log
- if [ ${PIPESTATUS[0]} != 0 ]; then
- echo -n "##vso[task.logissue type=error]"
- echo "The RISC-V compliance test suite failed for $isa"
-
- # There's no easy way to get the test results in machine-readable
- # form to properly exclude known-failing tests. Going with an
- # approximate solution for now.
- if [ $isa == rv32i ] && grep -q 'FAIL: 4/48' run.log; then
- echo -n "##vso[task.logissue type=error]"
- echo "Expected failure for rv32i, see lowrisc/ibex#100 more more information."
- else
- fail=1
- fi
- fi
- done
- exit $fail
- displayName: Run RISC-V Compliance test for Ibex RV32IMC for ${{ config }}
diff --git a/ci/install-build-deps.sh b/ci/install-build-deps.sh
index 5fef79f3..4dc913a8 100755
--- a/ci/install-build-deps.sh
+++ b/ci/install-build-deps.sh
@@ -11,27 +11,26 @@ set -e
[ -f /etc/os-release ] || (echo "/etc/os-release doesn't exist."; exit 1)
. /etc/os-release
-[ ! -z "$VERILATOR_VERSION" ] || (echo "VERILATOR_VERSION must be set."; exit 1)
-[ ! -z "$VERIBLE_VERSION" ] || (echo "VERIBLE_VERSION must be set."; exit 1)
-[ ! -z "$RISCV_TOOLCHAIN_TAR_VERSION" ] || (echo "RISCV_TOOLCHAIN_TAR_VERSION must be set."; exit 1)
-[ ! -z "$RISCV_TOOLCHAIN_TAR_VARIANT" ] || (echo "RISCV_TOOLCHAIN_TAR_VARIANT must be set."; exit 1)
+[ -n "$VERILATOR_VERSION" ] || (echo "VERILATOR_VERSION must be set."; exit 1)
+[ -n "$VERIBLE_VERSION" ] || (echo "VERIBLE_VERSION must be set."; exit 1)
+[ -n "$RISCV_TOOLCHAIN_TAR_VERSION" ] || (echo "RISCV_TOOLCHAIN_TAR_VERSION must be set."; exit 1)
+[ -n "$RISCV_TOOLCHAIN_TAR_VARIANT" ] || (echo "RISCV_TOOLCHAIN_TAR_VARIANT must be set."; exit 1)
SUDO_CMD=""
-if [ $(id -u) -ne 0 ]; then
+if [ "$(id -u)" -ne 0 ]; then
SUDO_CMD="sudo "
fi
+if [ -z "$GITHUB_ACTIONS" ]; then
+ GITHUB_PATH=/dev/null
+fi
+
case "$ID-$VERSION_ID" in
- ubuntu-16.04|ubuntu-18.04)
+ ubuntu-20.04|ubuntu-22.04)
# Curl must be available to get the repo key below.
$SUDO_CMD apt-get update
$SUDO_CMD apt-get install -y curl
- # Make Verilator repository available
- curl -Ls https://download.opensuse.org/repositories/home:phiwag:edatools/xUbuntu_$VERSION_ID/Release.key | $SUDO_CMD apt-key add -
- $SUDO_CMD sh -c "echo 'deb http://download.opensuse.org/repositories/home:/phiwag:/edatools/xUbuntu_$VERSION_ID/ /' > /etc/apt/sources.list.d/edatools.list"
- $SUDO_CMD apt-get update
-
# Packaged dependencies
# Install python3-yaml through apt to get a version with libyaml bindings,
# which is significantly faster than the pure Python version.
@@ -42,6 +41,7 @@ case "$ID-$VERSION_ID" in
python3-setuptools \
python3-wheel \
python3-yaml \
+ python3-dev \
srecord \
zlib1g-dev \
git \
@@ -52,27 +52,41 @@ case "$ID-$VERSION_ID" in
bison \
libelf-dev \
clang-format \
- "verilator-$VERILATOR_VERSION" \
- xz-utils
+ wget \
+ xz-utils \
+ libcairo2-dev
- # Python dependencies
- #
- # Updating pip and setuptools is required to have these tools properly
- # parse Python-version metadata, which some packages uses to specify that
- # an older version of a package must be used for a certain Python version.
- # If that information is not read, pip installs the latest version, which
- # then fails to run.
- $SUDO_CMD pip3 install -U pip setuptools
+ wget https://storage.googleapis.com/ibex-cosim-builds/ibex-cosim-"$IBEX_COSIM_VERSION".tar.gz
+ $SUDO_CMD mkdir -p /tools/riscv-isa-sim
+ $SUDO_CMD chmod 777 /tools/riscv-isa-sim
+ $SUDO_CMD tar -C /tools/riscv-isa-sim -xvzf ibex-cosim-"$IBEX_COSIM_VERSION".tar.gz --strip-components=1
+ echo "/tools/riscv-isa-sim/bin" >> $GITHUB_PATH
- $SUDO_CMD pip3 install -r python-requirements.txt
+ wget https://storage.googleapis.com/verilator-builds/verilator-"$VERILATOR_VERSION".tar.gz
+ $SUDO_CMD mkdir -p /tools/verilator
+ $SUDO_CMD chmod 777 /tools/verilator
+ $SUDO_CMD tar -C /tools/verilator -xvzf verilator-"$VERILATOR_VERSION".tar.gz
+ echo "/tools/verilator/$VERILATOR_VERSION/bin" >> $GITHUB_PATH
+ # Python dependencies
+ #
+ # Updating pip and setuptools is required to have these tools properly
+ # parse Python-version metadata, which some packages uses to specify that
+ # an older version of a package must be used for a certain Python version.
+ # If that information is not read, pip installs the latest version, which
+ # then fails to run.
+ $SUDO_CMD pip3 install -U pip "setuptools<66.0.0"
- # Install Verible
- mkdir -p build/verible
- cd build/verible
- curl -Ls -o verible.tar.gz "https://github.com/google/verible/releases/download/$VERIBLE_VERSION/verible-$VERIBLE_VERSION-Ubuntu-$VERSION_ID-$VERSION_CODENAME-x86_64.tar.gz"
- $SUDO_CMD mkdir -p /tools/verible && $SUDO_CMD chmod 777 /tools/verible
- tar -C /tools/verible -xf verible.tar.gz --strip-components=1
- echo "##vso[task.prependpath]/tools/verible/bin"
+ $SUDO_CMD pip3 install -r python-requirements.txt
+
+ # Install Verible
+ mkdir -p build/verible
+ cd build/verible
+ VERIBLE_URL="https://github.com/chipsalliance/verible/releases/download/$VERIBLE_VERSION/verible-$VERIBLE_VERSION-linux-static-x86_64.tar.gz"
+ $SUDO_CMD mkdir -p /tools/verible
+ curl -sSfL "$VERIBLE_URL" | $SUDO_CMD tar -C /tools/verible -xvzf - --strip-components=1
+ # Fixup bin permission which is broken in tarball.
+ $SUDO_CMD chmod 755 /tools/verible/bin
+ echo "/tools/verible/bin" >> $GITHUB_PATH
;;
*)
@@ -86,5 +100,5 @@ TOOLCHAIN_URL="https://github.com/lowRISC/lowrisc-toolchains/releases/download/$
mkdir -p build/toolchain
curl -Ls -o build/toolchain/rv32-toolchain.tar.xz "$TOOLCHAIN_URL"
$SUDO_CMD mkdir -p /tools/riscv && $SUDO_CMD chmod 777 /tools/riscv
-tar -C /tools/riscv -xf build/toolchain/rv32-toolchain.tar.xz --strip-components=1
-echo "##vso[task.prependpath]/tools/riscv/bin"
+$SUDO_CMD tar -C /tools/riscv -xf build/toolchain/rv32-toolchain.tar.xz --strip-components=1
+echo "/tools/riscv/bin" >> $GITHUB_PATH
diff --git a/ci/run-cosim-test.sh b/ci/run-cosim-test.sh
new file mode 100755
index 00000000..1165bf58
--- /dev/null
+++ b/ci/run-cosim-test.sh
@@ -0,0 +1,51 @@
+#!/bin/bash
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+#
+# Run an elf against simple system co-simulation and check the UART output for
+# reported pass/fail reporting as appropriate for use in GitHub Actions
+
+SKIP_PASS_CHECK=0
+
+if [ $# -eq 3 ]; then
+ if [ $1 == "--skip-pass-check" ]; then
+ SKIP_PASS_CHECK=1
+ fi
+
+ TEST_NAME=$2
+ TEST_ELF=$3
+elif [ $# -eq 2 ]; then
+ TEST_NAME=$1
+ TEST_ELF=$2
+else
+ echo "Usage: $0 [--skip-pass-check] test_name test_elf"
+ exit 1
+fi
+
+echo "Running $TEST_NAME with co-simulation"
+build/lowrisc_ibex_ibex_simple_system_cosim_0/sim-verilator/Vibex_simple_system --meminit=ram,$TEST_ELF
+if [ $? != 0 ]; then
+ echo "::error::Running % failed co-simulation testing"
+ exit 1
+fi
+
+grep 'FAILURE' ibex_simple_system.log
+if [ $? != 1 ]; then
+ echo "::error::Failure seen in $TEST_NAME log"
+ echo "Log contents:"
+ cat ibex_simple_system.log
+ exit 1
+fi
+
+if [ $SKIP_PASS_CHECK != 1 ]; then
+ grep 'PASS' ibex_simple_system.log
+ if [ $? != 0 ]; then
+ echo "::error::No pass seen in $TEST_NAME log"
+ echo "Log contents:"
+ cat ibex_simple_system.log
+ exit 1
+ fi
+fi
+
+echo "$TEST_NAME succeeded"
diff --git a/ci/setup-cosim.sh b/ci/setup-cosim.sh
new file mode 100644
index 00000000..d29ecae9
--- /dev/null
+++ b/ci/setup-cosim.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+export PKG_CONFIG_PATH=/tools/riscv-isa-sim/lib/pkgconfig:$PATH
diff --git a/ci/vars.env b/ci/vars.env
new file mode 100644
index 00000000..2e510087
--- /dev/null
+++ b/ci/vars.env
@@ -0,0 +1,15 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+# Pipeline variables, used by the public and private CI pipelines
+# Quote values to ensure they are parsed as string (version numbers might
+# end up as float otherwise).
+VERILATOR_VERSION=v4.210
+IBEX_COSIM_VERSION=39612f9
+RISCV_TOOLCHAIN_TAR_VERSION=20220210-1
+RISCV_TOOLCHAIN_TAR_VARIANT=lowrisc-toolchain-gcc-rv32imcb
+RISCV_COMPLIANCE_GIT_VERSION=844c6660ef3f0d9b96957991109dfd80cc4938e2
+VERIBLE_VERSION=v0.0-3622-g07b310a3
+# lowRISC-internal version numbers of Ibex-specific Spike builds.
+SPIKE_IBEX_VERSION=20220817-git-eccdcb15c3e51b4f7906c7b42fb824f24a4338a2
diff --git a/ci/vars.yml b/ci/vars.yml
deleted file mode 100644
index b72f98a1..00000000
--- a/ci/vars.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright lowRISC contributors.
-# Licensed under the Apache License, Version 2.0, see LICENSE for details.
-# SPDX-License-Identifier: Apache-2.0
-
-# Pipeline variables, used by the public and private CI pipelines
-# Quote values to ensure they are parsed as string (version numbers might
-# end up as float otherwise).
-variables:
- VERILATOR_VERSION: "4.040"
- RISCV_TOOLCHAIN_TAR_VERSION: "20200904-1"
- RISCV_TOOLCHAIN_TAR_VARIANT: "lowrisc-toolchain-gcc-rv32imcb"
- RISCV_COMPLIANCE_GIT_VERSION: "844c6660ef3f0d9b96957991109dfd80cc4938e2"
- VERIBLE_VERSION: "v0.0-705-g75249d0"
- # lowRISC-internal version numbers of Ibex-specific Spike builds.
- SPIKE_IBEX_VERSION: "20201023-git-255bf1cacc599b1413438c269100f3ecd0eb3352"
diff --git a/ci/vars_to_logging_cmd.py b/ci/vars_to_logging_cmd.py
deleted file mode 100755
index c719a0cb..00000000
--- a/ci/vars_to_logging_cmd.py
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env python3
-# Copyright lowRISC contributors.
-# Licensed under the Apache License, Version 2.0, see LICENSE for details.
-# SPDX-License-Identifier: Apache-2.0
-
-# Read an Azure Pipelines-compatible variables file, and convert it into
-# logging commands that Azure Pipelines understands, effectively setting the
-# variables at runtime.
-#
-# This script can be used as a workaround if variables cannot be included in the
-# Pipeline definition directly.
-#
-# See https://docs.microsoft.com/en-us/azure/devops/pipelines/scripts/logging-commands
-# for more information on logging commands.
-
-import sys
-import yaml
-
-def vars_to_logging_cmd(vars_file):
- data = {}
- print(vars_file)
- with open(vars_file, 'r', encoding="utf-8") as fp:
- data = yaml.load(fp, Loader=yaml.SafeLoader)
-
- if not (isinstance(data, dict) and 'variables' in data):
- print("YAML file wasn't a dictionary with a 'variables' key. Got: {}"
- .format(data))
-
- print("Setting variables from {}".format(vars_file))
- for key, value in data['variables'].items():
- # Note: These lines won't show up in the Azure Pipelines output unless
- # "System Diagnostics" are enabled (go to the Azure Pipelines web UI,
- # click on "Run pipeline" to manually run a pipeline, and check "Enable
- # system diagnostics".)
- print("##vso[task.setvariable variable={}]{}".format(key, value))
-
- return 0
-
-if __name__ == "__main__":
- if len(sys.argv) < 2:
- print("Usage: {} VARS_FILE".format(sys.argv[0]))
- sys.exit(1)
- sys.exit(vars_to_logging_cmd(sys.argv[1]))
diff --git a/doc/01_overview/compliance.rst b/doc/01_overview/compliance.rst
index ac3ee4d1..bdb039cd 100644
--- a/doc/01_overview/compliance.rst
+++ b/doc/01_overview/compliance.rst
@@ -5,10 +5,11 @@ Ibex is a standards-compliant 32 bit RISC-V processor.
It follows these specifications:
* `RISC-V Instruction Set Manual, Volume I: User-Level ISA, document version 20190608-Base-Ratified (June 8, 2019) `_
-* `RISC-V Instruction Set Manual, Volume II: Privileged Architecture, document version 20190608-Base-Ratified (June 8, 2019) `_.
- Ibex implements the Machine ISA version 1.11.
+* `RISC-V Instruction Set Manual, Volume II: Privileged Architecture, document version 20211203 (December 4, 2021) `_.
+ Ibex implements the Machine ISA version 1.12.
* `RISC-V External Debug Support, version 0.13.2 `_
-* `RISC-V Bit Manipulation Extension, version 0.92 (draft from November 8, 2019) `_
+* `RISC-V Bit-Manipulation Extension, version 1.0.0 `_ and `version 0.93 (draft from January 10, 2021) `_
+* `PMP Enhancements for memory access and execution prevention on Machine mode (Smepmp) version 1.0 `_
Many features in the RISC-V specification are optional, and Ibex can be parametrized to enable or disable some of them.
@@ -34,8 +35,8 @@ In addition, the following instruction set extensions are available.
- 2.0
- optional
- * - **B**: Draft Extension for Bit Manipulation Instructions
- - 0.92 [#B_draft]_
+ * - **B**: Standard Extension for Bit-Manipulation Instructions
+ - 1.0.0 + 0.93 [#B_draft]_
- optional
* - **Zicsr**: Control and Status Register Instructions
@@ -46,8 +47,11 @@ In addition, the following instruction set extensions are available.
- 2.0
- always enabled
-Most content of the RISC-V privileged specification is optional.
-Ibex currently supports the following features according to the RISC-V Privileged Specification, version 1.11.
+ * - **Smepmp** - PMP Enhancements for memory access and execution prevention on Machine mode
+ - 1.0
+ - always enabled in configurations with PMP see :ref:`PMP Enhancements`
+
+Ibex currently supports the following features according to the RISC-V Privileged Specification, version 1.12.
* M-Mode and U-Mode
* All CSRs listed in :ref:`cs-registers`
@@ -56,7 +60,9 @@ Ibex currently supports the following features according to the RISC-V Privilege
.. rubric:: Footnotes
-.. [#B_draft] Note that while Ibex fully implements draft version 0.92 of the RISC-V Bit Manipulation Extension, this extension may change before being ratified as a standard by the RISC-V Foundation.
+.. [#B_draft] Ibex fully implements the ratified version 1.0.0 of the RISC-V Bit-Manipulation Extension including the Zba, Zbb, Zbc and Zbs sub-extensions.
+ In addition, Ibex also supports the remaining Zbe, Zbf, Zbp, Zbr and Zbt sub-extensions as defined in draft version 0.93 of the RISC-V Bit-Manipulation Extension.
+ Note that the latter sub-extensions may change before being ratified as a standard by the RISC-V Foundation.
Ibex will be updated to match future versions of the specification.
Prior to ratification this may involve backwards incompatible changes.
Additionally, neither GCC or Clang have committed to maintaining support upstream for unratified versions of the specification.
diff --git a/doc/01_overview/index.rst b/doc/01_overview/index.rst
index 7eea4c65..a09a5a15 100644
--- a/doc/01_overview/index.rst
+++ b/doc/01_overview/index.rst
@@ -1,7 +1,7 @@
Introduction to Ibex
====================
-Ibex is a production-quality open source 32 bit RISC-V CPU core written in SystemVerilog.
+Ibex is a production-quality open source 32-bit RISC-V CPU core written in SystemVerilog.
The CPU core is heavily parametrizable and well suited for embedded control applications.
Ibex is being extensively verified and has seen multiple tape-outs.
@@ -14,3 +14,4 @@ Read on for more information Ibex in general: what standards it implements, what
compliance
targets
licensing
+ verification_overview
diff --git a/doc/01_overview/targets.rst b/doc/01_overview/targets.rst
index 15f97bd4..445934b3 100644
--- a/doc/01_overview/targets.rst
+++ b/doc/01_overview/targets.rst
@@ -7,8 +7,6 @@ ASIC Synthesis
ASIC synthesis is supported for Ibex.
The whole design is completely synchronous and uses positive-edge triggered flip-flops, except for the register file, which can be implemented either with latches or with flip-flops.
See :ref:`register-file` for more details.
-The core occupies an area of roughly 24 kGE when using the latch-based register file and implementing the RV32IMC ISA, or 16 kGE when implementing the RV32EC ISA.
-
FPGA Synthesis
--------------
diff --git a/doc/01_overview/verification_overview.rst b/doc/01_overview/verification_overview.rst
new file mode 100644
index 00000000..77921b7f
--- /dev/null
+++ b/doc/01_overview/verification_overview.rst
@@ -0,0 +1,22 @@
+Verification Overview
+=====================
+
+Ibex is verified using a :ref:`UVM based testbench` that employs a :ref:`co-simulation methodology` to cross-check Ibex execution against an ISS reference model (`Spike `_).
+The testbench runs binaries built from source produced by the `RISC-DV `_ random instruction generator.
+Additional stimulus is provided in the form of randomized memory timings, memory errors, interrupts and debug requests by the testbench.
+A comprehensive :ref:`testplan` and :ref:`coverage plan` are implemented.
+
+Verification Status
+-------------------
+
+Ibex has a large number of parameters resulting in a large number of possible configurations.
+The configuration space is too large to fully verify the design for all possible parameter sets.
+To manage this complexity regressions runs and verification closure target a number of :ref:`supported configurations`.
+
+Current verification closure effort is focussed on the ``opentitan`` configuration and is the only configuration with nightly regression runs.
+Verification maturity is tracked via :ref:`verification_stages` that are `defined by the OpenTitan project `_.
+Ibex has achieved **V2S** for the `opentitan` configuration, broadly this means verification is almost complete (over 90% code and functional coverage hit with over 90% regression pass rate with test plan and coverage plan fully implemented) but not yet closed.
+
+Nightly regression results, including a coverage summary and details of test failures, for the ``opentitan`` Ibex configuration are published at https://ibex.reports.lowrisc.org/opentitan/latest/report.html. Below is a summary of these results:
+
+.. image:: https://ibex.reports.lowrisc.org/opentitan/latest/summary.svg
diff --git a/doc/02_user/configuration.rst b/doc/02_user/configuration.rst
new file mode 100644
index 00000000..cbd59488
--- /dev/null
+++ b/doc/02_user/configuration.rst
@@ -0,0 +1,43 @@
+.. _ibex-config:
+
+Ibex Configurations
+===================
+
+The ``ibex_top`` module has a large number of top-level parameters which configure the core (see :ref:`core-integration`).
+This gives rise to a huge number of possible Ibex core configurations.
+To manage this complexity a number of named configurations is provided in the :file:`ibex_configs.yml` file.
+A subset of these are 'supported configurations' which are the focus of verification and development activities.
+
+Configuration Tool
+------------------
+
+A tool :file:`util/ibex_config.py` is provided to work with the named configurations.
+This tool provides command line options to set Ibex parameters for various EDA tools for a named configuration.
+Various Ibex flows (e.g. the DV flow) use this tool internally and can be provided with a configuration name from :file:`util/ibex_config.py` to work with.
+
+Here is an example of using the configuration tool to get the FuseSoC options required to build the ``opentitan`` configuration.
+
+.. code-block:: bash
+
+ # Request FuseSoC options required to build the 'opentitan' Ibex configuration.
+ ./util/ibex_config.py opentitan fusesoc_opts
+
+ # The output of the tool
+ --RV32E=0 --RV32M=ibex_pkg::RV32MSingleCycle --RV32B=ibex_pkg::RV32BOTEarlGrey --RegFile=ibex_pkg::RegFileFF --BranchTargetALU=1 --WritebackStage=1 --ICache=1 --ICacheECC=1 --ICacheScramble=1 --BranchPredictor=0 --DbgTriggerEn=1 --SecureIbex=1 --PMPEnable=1 --PMPGranularity=0 --PMPNumRegions=16 --MHPMCounterNum=10 --MHPMCounterWidth=32
+
+For further information about using the tool check the help provided on the command line.
+
+.. code-block:: bash
+
+ # Get help on using ibex_config.py
+ ./util/ibex_config.py -h
+
+Supported Configurations
+------------------------
+
+The current set of supported configurations are:
+
+ * ``small`` - RV32IMC with two stage pipeline and 3 cycle multiplier
+ * ``opentitan`` - The configuration used by the `OpenTitan `_ project
+ * ``maxperf`` - RV32IMC with three stage pipeline and single cycle multiplier, maximum performance (using stable features) configuration.
+ * ``maxperf-pmp-bmbalanced`` - ``maxperf`` configuration with PMP and the 'balanced' bit-manipulation configuration (:ref:`core-integration` for details).
diff --git a/doc/02_user/examples.rst b/doc/02_user/examples.rst
index ef9007f2..8a89bb03 100644
--- a/doc/02_user/examples.rst
+++ b/doc/02_user/examples.rst
@@ -3,16 +3,25 @@
Examples
========
-To make use of Ibex it has to be integrated as described in :ref:`core-integration`.
+There are two examples that demonstrate Ibex usage.
-FPGA
-----
+The first is 'Simple System' and is part of the Ibex repository.
+It demonstrates a minimal system connecting Ibex to some memory with a timer peripheral and is targeted at simulation.
-A minimal example for the `Arty A7 `_ FPGA Development board is provided.
-In this example Ibex is directly linked to a SRAM memory instance.
-Four LEDs from the board are connected to the data bus and are updated each time when a word is written.
-The memory is separated into a instruction and data section.
-The instructions memory is initialized at synthesis time by reading the output from the software build.
-The software writes to the data section the complementary lower for bits of a word every second resulting in blinking LEDs.
+The second is the `'Ibex Demo System' `_ which is a separate repository.
+It is targeted at FPGA implementation and contains some extra peripherals along with a RISC-V debug module integration.
+
+Simple System
+-------------
+
+Simple system is built via FuseSoC.
+Verilator is the primary simulator it is designed for, though other simulators are also supported (such as VCS).
+Its aim is to make running a binary against Ibex RTL, obtaining an instruction trace, wave trace and any other simulation outputs as simple as possible along with demonstrating basic Ibex integration.
+See the `Simple System README `_ for more information.
+
+There is an extended version of simple system which adds co-simulation checking.
+This cross-checks every instruction execution against a RISC-V ISS.
+It is the same co-simulation method used by our full DV environment but enables its use in a far simpler setup.
+The simple system co-simulation setup is compatible with Verilator (unlike our full DV environment).
+See :ref:`cosim` for more information.
-Find the description of how to build and program the Arty board in ``examples/fpga/artya7/README.md``.
diff --git a/doc/02_user/getting_started.rst b/doc/02_user/getting_started.rst
index c58407a5..e56b8300 100644
--- a/doc/02_user/getting_started.rst
+++ b/doc/02_user/getting_started.rst
@@ -3,11 +3,16 @@
Getting Started with Ibex
=========================
-This page discusses initial steps and requirements to start using Ibex in your design.
+The Ibex repository contains all the RTL needed to simulate and synthesize an Ibex core.
+`FuseSoC `_ core files list the RTL files required to build Ibex (see :file:`ibex_core.core`).
+The core itself is contained in the :file:`rtl/` directory, though it utilizes some primitives found in the :file:`vendor/lowrisc_ip/` directory.
+These primitives come from the `OpenTitan `_ project but are copied into the Ibex repository so the RTL has no external dependencies.
+You may wish to replace these primitives with your own and some are only required for specific configurations.
+See :ref:`integration-prims` for more information.
-Register File
--------------
+There are several paths to follow depending on what you wish to accomplish:
-Ibex comes with three different register file implementations that can be selected using the enumerated parameter ``RegFile`` defined in :file:`rtl/ibex_pkg.sv`.
-Depending on the target technology, either the flip-flop-based ("ibex_pkg::RegFileFF", default), the latch-based ("ibex_pkg::RegFileLatch") or an FPGA-targeted ("ibex_pkg::RegFileFPGA") implementation should be selected.
-For more information about the three register file implementations and their trade-offs, check out :ref:`register-file`.
+ * See :ref:`examples` for a basic simulation setup running the core in isolation and a simple FPGA system.
+ * See :ref:`verification` to begin working with the DV flow.
+ * See :ref:`core-integration` to integrate the Ibex core into your own design.
+ * See :ref:`integration-fusesoc-files` for information on how to get a complete RTL file listing to build Ibex for use outside of FuseSoC based flows.
diff --git a/doc/02_user/index.rst b/doc/02_user/index.rst
index e1158776..a373af0a 100644
--- a/doc/02_user/index.rst
+++ b/doc/02_user/index.rst
@@ -10,5 +10,6 @@ It is aimed at hardware developers integrating Ibex into a design, and software
system_requirements
getting_started
+ configuration
integration
examples
diff --git a/doc/02_user/integration.rst b/doc/02_user/integration.rst
index 018ed7ae..cc3c59c8 100644
--- a/doc/02_user/integration.rst
+++ b/doc/02_user/integration.rst
@@ -3,75 +3,166 @@
Core Integration
================
-The main module is named ``ibex_core`` and can be found in ``ibex_core.sv``.
-Below, the instantiation template is given and the parameters and interfaces are described.
+The main module is named ``ibex_top`` and can be found in ``ibex_top.sv``.
+Note that the core logic is split-out from the register file and RAMs under ``ibex_top``.
+This is to facilitate a dual-core lockstep implementation (see :ref:`security`).
+
+Register File
+-------------
+
+Ibex comes with three different register file implementations that can be selected using the enumerated parameter ``RegFile`` defined in :file:`rtl/ibex_pkg.sv`.
+Depending on the target technology, either the flip-flop-based ("ibex_pkg::RegFileFF", default), the latch-based ("ibex_pkg::RegFileLatch") or an FPGA-targeted ("ibex_pkg::RegFileFPGA") implementation should be selected.
+For more information about the three register file implementations and their trade-offs, check out :ref:`register-file`.
+
+Identification CSRs
+-------------------
+
+The RISC-V Privileged Architecture specifies several read-only CSRs that identify the vendor and micro-architecture of a CPU.
+These are ``mvendorid``, ``marchid`` and ``mimpid``.
+The fixed, read-only values for these CSRs are defined in :file:`rtl/ibex_pkg.sv`.
+Implementers should carefully consider appropriate values for these registers.
+Ibex, as an open source implementation, has an assigned architecture ID (``marchid``) of 22.
+(Allocations are specified in `marchid.md of the riscv-isa-manual repository `_.)
+If significant changes are made to the micro-architecture a different architecture ID should be used.
+The vendor ID and implementation ID (``mvendorid`` and ``mimpid``) both read as 0 by default, meaning non-implemented.
+Implementers may wish to use other values here.
+Please see the RISC-V Privileged Architecture specification for more details on what these IDs represent and how they should be chosen.
+
+.. _integration-prims:
+
+Primitives
+----------
+
+Ibex uses a number of primitive modules (that are held outside the :file:`rtl/` which contains the Ibex RTL).
+Full implementations of these primitives are provided in the Ibex repository but implementors may wish to provide their own implementations.
+Some of the primitives are only used for specific Ibex configurations so can be ignored/removed if you're not using one of those configurations.
+
+The mandatory primitives (used by all configurations) are:
+ * ``prim_buf`` - A buffer, used to ensure security critical logic isn't optimized out in synthesis (by applying suitable constraints to prim_buf).
+ In configurations where ``SecureIbex == 0`` it must exist but can be implemented as a straight passthrough.
+ * ``prim_clock_gating`` - A clock gate.
+
+The configuration dependent primitives are:
+ * ``prim_clock_mux2`` - A clock mux, used by the lockstep duplicate core.
+ Required where ``SecureIbex == 1``.
+ * ``prim_flop`` - A flip flop, used to ensure security critical logic isn't optimized out in synthesis (by applying suitable constraints to prim_flop).
+ Required where ``SecureIbex == 1``.
+ * ``prim_ram_1p`` - A single ported RAM.
+ Required where ``ICache == 1``.
+ * ``prim_ram_1p_scr`` - A single ported RAM which scrambles its contents with cryptographic primitives.
+ Required where ``ICache == 1`` and ``SecureIbex == 1``.
+ * ``prim_lfsr`` - Linear feedback shift register, used for pseudo random number generation for dummy instruction insertion.
+ Required where ``SecureIbex == 1``.
+ * ``prim_onehot_check`` - Checks a onehot signal is correct, for detecting fault injection attacks.
+ Required where ``SecureIbex == 1``.
+ * ``prim_secded_X`` - Various primitives to encode and decode SECDED (single error correct, double error detect) error detection and correction codes.
+ Required where ``SecureIbex == 1``.
+
+Primitives exclusively used by other primitives:
+ * ``prim_present`` / ``prim_prince`` / ``prim_subst_perm`` - Cryptographic primitives used by ``prim_ram_1p_scr``.
+ * ``prim_ram_1p_adv`` - Wrapper around ``prim_ram_1p`` that adds support for ECC, used by ``prim_ram_1p_scr``.
+
+.. _integration-fusesoc-files:
+
+RTL File List
+-------------
+
+Ibex flows use `FuseSoC `_ to gather needed RTL files and run builds.
+If you want to use Ibex without FuseSoC the following FuseSoC command will copy all the needed files into a build directory.
+
+.. code-block:: bash
+
+ fusesoc --cores-root . run --target=lint --setup --build-root ./build/ibex_out lowrisc:ibex:ibex_top
+
+FuseSoC uses Python and it can be installed using pip.
+
+.. code-block:: bash
+
+ pip3 install -U -r python-requirements.txt
+
+Ibex uses a `custom fork of FuseSoC `_, so you must install it via this method rather than installing FuseSoC separately.
+
+The RTL will be in :file:`./build/ibex_out/src` which is further divided into different sub-directories.
+A file list containing paths to all of the RTL files can be found in :file:`./build/ibex_out/ibex-verilator/lowrisc_ibex_ibex_top_0.1.vc`.
Instantiation Template
----------------------
.. code-block:: verilog
- ibex_core #(
- .PMPEnable ( 0 ),
- .PMPGranularity ( 0 ),
- .PMPNumRegions ( 4 ),
- .MHPMCounterNum ( 0 ),
- .MHPMCounterWidth ( 40 ),
- .RV32E ( 0 ),
- .RV32M ( ibex_pkg::RV32MFast ),
- .RV32B ( ibex_pkg::RV32BNone ),
- .RegFile ( ibex_pkg::RegFileFF ),
- .ICache ( 0 ),
- .ICacheECC ( 0 ),
- .BranchPrediction ( 0 ),
- .SecureIbex ( 0 ),
- .DbgTriggerEn ( 0 ),
- .DmHaltAddr ( 32'h1A110800 ),
- .DmExceptionAddr ( 32'h1A110808 )
- ) u_core (
+ ibex_top #(
+ .PMPEnable ( 0 ),
+ .PMPGranularity ( 0 ),
+ .PMPNumRegions ( 4 ),
+ .MHPMCounterNum ( 0 ),
+ .MHPMCounterWidth ( 40 ),
+ .RV32E ( 0 ),
+ .RV32M ( ibex_pkg::RV32MFast ),
+ .RV32B ( ibex_pkg::RV32BNone ),
+ .RegFile ( ibex_pkg::RegFileFF ),
+ .ICache ( 0 ),
+ .ICacheECC ( 0 ),
+ .ICacheScramble ( 0 ),
+ .BranchPrediction ( 0 ),
+ .SecureIbex ( 0 ),
+ .RndCnstLfsrSeed ( ibex_pkg::RndCnstLfsrSeedDefault ),
+ .RndCnstLfsrPerm ( ibex_pkg::RndCnstLfsrPermDefault ),
+ .DbgTriggerEn ( 0 ),
+ .DmBaseAddr ( 32'h1A110000 ),
+ .DmAddrMask ( 32'h00000FFF ),
+ .DmHaltAddr ( 32'h1A110800 ),
+ .DmExceptionAddr ( 32'h1A110808 )
+ ) u_top (
// Clock and reset
- .clk_i (),
- .rst_ni (),
- .test_en_i (),
+ .clk_i (),
+ .rst_ni (),
+ .test_en_i (),
+ .scan_rst_ni (),
+ .ram_cfg_i (),
// Configuration
- .hart_id_i (),
- .boot_addr_i (),
+ .hart_id_i (),
+ .boot_addr_i (),
// Instruction memory interface
- .instr_req_o (),
- .instr_gnt_i (),
- .instr_rvalid_i (),
- .instr_addr_o (),
- .instr_rdata_i (),
- .instr_err_i (),
+ .instr_req_o (),
+ .instr_gnt_i (),
+ .instr_rvalid_i (),
+ .instr_addr_o (),
+ .instr_rdata_i (),
+ .instr_rdata_intg_i (),
+ .instr_err_i (),
// Data memory interface
- .data_req_o (),
- .data_gnt_i (),
- .data_rvalid_i (),
- .data_we_o (),
- .data_be_o (),
- .data_addr_o (),
- .data_wdata_o (),
- .data_rdata_i (),
- .data_err_i (),
+ .data_req_o (),
+ .data_gnt_i (),
+ .data_rvalid_i (),
+ .data_we_o (),
+ .data_be_o (),
+ .data_addr_o (),
+ .data_wdata_o (),
+ .data_wdata_intg_o (),
+ .data_rdata_i (),
+ .data_rdata_intg_i (),
+ .data_err_i (),
// Interrupt inputs
- .irq_software_i (),
- .irq_timer_i (),
- .irq_external_i (),
- .irq_fast_i (),
- .irq_nm_i (),
+ .irq_software_i (),
+ .irq_timer_i (),
+ .irq_external_i (),
+ .irq_fast_i (),
+ .irq_nm_i (),
// Debug interface
- .debug_req_i (),
+ .debug_req_i (),
+ .crash_dump_o (),
// Special control signals
- .fetch_enable_i (),
- .alert_minor_o (),
- .alert_major_o (),
- .core_sleep_o ()
+ .fetch_enable_i (),
+ .alert_minor_o (),
+ .alert_major_internal_o (),
+ .alert_major_bus_o (),
+ .core_sleep_o ()
);
Parameters
@@ -100,34 +191,45 @@ Parameters
+------------------------------+---------------------+------------+-----------------------------------------------------------------------+
| ``RV32B`` | ibex_pkg::rv32b_e | RV32BNone | B(itmanipulation) extension select: |
| | | | "ibex_pkg::RV32BNone": No B-extension |
-| | | | "ibex_pkg::RV32BBalanced": Sub-extensions Zbb, Zbs, Zbf and Zbt |
-| | | | "ibex_pkg::RV32Full": All sub-extensions |
+| | | | "ibex_pkg::RV32BBalanced": Sub-extensions Zba, Zbb, Zbs, Zbf and Zbt |
+| | | | "ibex_pkg::RV32BOTEarlGrey": All sub-extensions except Zbe |
+| | | | "ibex_pkg::RV32BFull": All sub-extensions |
+------------------------------+---------------------+------------+-----------------------------------------------------------------------+
| ``RegFile`` | ibex_pkg::regfile_e | RegFileFF | Register file implementation select: |
| | | | "ibex_pkg::RegFileFF": Generic flip-flop-based register file |
| | | | "ibex_pkg::RegFileFPGA": Register file for FPGA targets |
| | | | "ibex_pkg::RegFileLatch": Latch-based register file for ASIC targets |
+------------------------------+---------------------+------------+-----------------------------------------------------------------------+
-| ``BranchTargetALU`` | bit | 0 | *EXPERIMENTAL* - Enables branch target ALU removing a stall |
-| | | | cycle from taken branches |
+| ``BranchTargetALU`` | bit | 0 | Enables branch target ALU removing a stall cycle from taken branches |
+------------------------------+---------------------+------------+-----------------------------------------------------------------------+
-| ``WritebackStage`` | bit | 0 | *EXPERIMENTAL* - Enables third pipeline stage (writeback) |
-| | | | improving performance of loads and stores |
+| ``WritebackStage`` | bit | 0 | Enables third pipeline stage (writeback) improving performance of |
+| | | | loads and stores |
+------------------------------+---------------------+------------+-----------------------------------------------------------------------+
-| ``ICache`` | bit | 0 | *EXPERIMENTAL* Enable instruction cache instead of prefetch |
-| | | | buffer |
+| ``ICache`` | bit | 0 | Enable instruction cache instead of prefetch buffer |
+------------------------------+---------------------+------------+-----------------------------------------------------------------------+
-| ``ICacheECC`` | bit | 0 | *EXPERIMENTAL* Enable SECDED ECC protection in ICache (if |
-| | | | ICache == 1) |
+| ``ICacheECC`` | bit | 0 | Enable SECDED ECC protection in ICache (if ICache == 1) |
++------------------------------+---------------------+------------+-----------------------------------------------------------------------+
+| ``ICacheScramble`` | bit | 0 | Enabling this parameter replaces tag and data RAMs of ICache with |
+| | | | scrambling RAM primitives. |
+------------------------------+---------------------+------------+-----------------------------------------------------------------------+
| ``BranchPrediction`` | bit | 0 | *EXPERIMENTAL* Enable Static branch prediction |
+------------------------------+---------------------+------------+-----------------------------------------------------------------------+
-| ``SecureIbex`` | bit | 0 | *EXPERIMENTAL* Enable various additional features targeting |
-| | | | secure code execution. Note: SecureIbex == 1'b1 and |
-| | | | RV32M == ibex_pkg::RV32MNone is an illegal combination. |
+| ``SecureIbex`` | bit | 0 | Enable various additional features targeting secure code execution. |
+| | | | Note: SecureIbex == 1'b1 and RV32M == ibex_pkg::RV32MNone is an |
+| | | | illegal combination. |
++------------------------------+---------------------+------------+-----------------------------------------------------------------------+
+| ``RndCnstLfsrSeed`` | lfsr_seed_t | see above | Set the starting seed of the LFSR used to generate dummy instructions |
+| | | | (only relevant when SecureIbex == 1'b1) |
++------------------------------+---------------------+------------+-----------------------------------------------------------------------+
+| ``RndCnstLfsrPerm`` | lfsr_perm_t | see above | Set the permutation applied to the output of the LFSR used to |
+| | | | generate dummy instructions (only relevant when SecureIbex == 1'b1) |
+------------------------------+---------------------+------------+-----------------------------------------------------------------------+
| ``DbgTriggerEn`` | bit | 0 | Enable debug trigger support (one trigger only) |
+------------------------------+---------------------+------------+-----------------------------------------------------------------------+
+| ``DmBaseAddr`` | int | 0x1A110000 | Base address of the Debug Module |
++------------------------------+---------------------+------------+-----------------------------------------------------------------------+
+| ``DmAddrMask`` | int | 0x1A110000 | Address mask of the Debug Module |
++------------------------------+---------------------+------------+-----------------------------------------------------------------------+
| ``DmHaltAddr`` | int | 0x1A110800 | Address to jump to when entering Debug Mode |
+------------------------------+---------------------+------------+-----------------------------------------------------------------------+
| ``DmExceptionAddr`` | int | 0x1A110808 | Address to jump to when an exception occurs while in Debug Mode |
@@ -148,52 +250,75 @@ This is well supported by most tools but some care is needed when overriding the
Interfaces
----------
-+-------------------------+-------------------------+-----+----------------------------------------+
-| Signal(s) | Width | Dir | Description |
-+=========================+=========================+=====+========================================+
-| ``clk_i`` | 1 | in | Clock signal |
-+-------------------------+-------------------------+-----+----------------------------------------+
-| ``rst_ni`` | 1 | in | Active-low asynchronous reset |
-+-------------------------+-------------------------+-----+----------------------------------------+
-| ``test_en_i`` | 1 | in | Test input, enables clock |
-+-------------------------+-------------------------+-----+----------------------------------------+
-| ``hart_id_i`` | 32 | in | Hart ID, usually static, can be read |
-| | | | from :ref:`csr-mhartid` CSR |
-+-------------------------+-------------------------+-----+----------------------------------------+
-| ``boot_addr_i`` | 32 | in | First program counter after reset |
-| | | | = ``boot_addr_i`` + 0x80, |
-| | | | see :ref:`exceptions-interrupts` |
-+-------------------------+-------------------------+-----+----------------------------------------+
-| ``instr_*`` | Instruction fetch interface, see :ref:`instruction-fetch` |
-+-------------------------+------------------------------------------------------------------------+
-| ``data_*`` | Load-store unit interface, see :ref:`load-store-unit` |
-+-------------------------+------------------------------------------------------------------------+
-| ``irq_*`` | Interrupt inputs, see :ref:`exceptions-interrupts` |
-+-------------------------+------------------------------------------------------------------------+
-| ``debug_*`` | Debug interface, see :ref:`debug-support` |
-+-------------------------+-------------------------+-----+----------------------------------------+
-| ``fetch_enable_i`` | 1 | in | When it comes out of reset, the core |
-| | | | will not start fetching and executing |
-| | | | instructions until it sees this pin |
-| | | | set to 1'b1. Once started, it will |
-| | | | continue until the next reset, |
-| | | | regardless of the value of this pin. |
-+-------------------------+-------------------------+-----+----------------------------------------+
-| ``core_sleep_o`` | 1 | out | Core in WFI with no outstanding data |
-| | | | or instruction accesses. Deasserts |
-| | | | if an external event (interrupt or |
-| | | | debug req) wakes the core up |
-+-------------------------+-------------------------+-----+----------------------------------------+
-| ``alert_minor_o`` | 1 | out | Core has detected a fault which it can |
-| | | | safely recover from. Can be used by a |
-| | | | system to log errors over time and |
-| | | | detect tampering / attack. This signal |
-| | | | is a pulse, one cycle per alert. |
-+-------------------------+-------------------------+-----+----------------------------------------+
-| ``alert_major_o`` | 1 | out | Core has detected a fault which cannot |
-| | | | be recovered from. Can be used by a |
-| | | | system to reset the core and possibly |
-| | | | take other remedial action. This |
-| | | | signal is a pulse, but might be set |
-| | | | for multiple cycles per alert. |
-+-------------------------+-------------------------+-----+----------------------------------------+
++----------------------------+-------------------------+-----+----------------------------------------+
+| Signal(s) | Width | Dir | Description |
++============================+=========================+=====+========================================+
+| ``clk_i`` | 1 | in | Clock signal |
++----------------------------+-------------------------+-----+----------------------------------------+
+| ``rst_ni`` | 1 | in | Active-low asynchronous reset |
++----------------------------+-------------------------+-----+----------------------------------------+
+| ``test_en_i`` | 1 | in | Test input, enables clock and allows |
+| | | | test control of reset. |
++----------------------------+-------------------------+-----+----------------------------------------+
+| ``scan_rst_ni`` | 1 | in | Test controlled reset. If DFT not |
+| | | | used, tie off to 1. |
++----------------------------+-------------------------+-----+----------------------------------------+
+| ``ram_cfg_i`` | 10 | in | RAM configuration inputs, routed to |
+| | | | the icache RAMs |
++----------------------------+-------------------------+-----+----------------------------------------+
+| ``hart_id_i`` | 32 | in | Hart ID, usually static, can be read |
+| | | | from :ref:`csr-mhartid` CSR |
++----------------------------+-------------------------+-----+----------------------------------------+
+| ``boot_addr_i`` | 32 | in | First program counter after reset |
+| | | | = ``boot_addr_i`` + 0x80, |
+| | | | see :ref:`exceptions-interrupts` |
++----------------------------+-------------------------+-----+----------------------------------------+
+| ``instr_*`` | Instruction fetch interface, see :ref:`instruction-fetch` |
++----------------------------+------------------------------------------------------------------------+
+| ``data_*`` | Load-store unit interface, see :ref:`load-store-unit` |
++----------------------------+------------------------------------------------------------------------+
+| ``irq_*`` | Interrupt inputs, see :ref:`exceptions-interrupts` |
++----------------------------+-------------------------+-----+----------------------------------------+
+| ``scramble_*`` | Scrambling key interface, see :ref:`icache` |
++----------------------------+------------------------------------------------------------------------+
+| ``debug_*`` | Debug interface, see :ref:`debug-support` |
++----------------------------+------------------------------------------------------------------------+
+| ``crash_dump_o`` | A set of signals that can be captured on reset to aid crash debugging. |
++----------------------------+------------------------------------------------------------------------+
+| ``double_fault_seen_o`` | A double fault was observed, see :ref:`double-fault-detect` |
++----------------------------+-------------------------+-----+----------------------------------------+
+| ``fetch_enable_i`` | 4 | in | Allow the core to fetch instructions. |
+| | | | If this bit is set low, the core will |
+| | | | pause fetching new instructions and |
+| | | | immediately halt once any in-flight |
+| | | | instructions in the ID/EX and WB |
+| | | | stages have finished. A multi-bit |
+| | | | encoding scheme is used. See |
+| | | | `IbexMuBiOn` / `IbexMuBiOff` in |
+| | | | :file:`rtl/ibex_pkg.sv` |
++----------------------------+-------------------------+-----+----------------------------------------+
+| ``core_sleep_o`` | 1 | out | Core in WFI with no outstanding data |
+| | | | or instruction accesses. Deasserts |
+| | | | if an external event (interrupt or |
+| | | | debug req) wakes the core up |
++----------------------------+-------------------------+-----+----------------------------------------+
+| ``alert_minor_o`` | 1 | out | Core has detected a fault which it can |
+| | | | safely recover from. Can be used by a |
+| | | | system to log errors over time and |
+| | | | detect tampering / attack. This signal |
+| | | | is a pulse, one cycle per alert. |
++----------------------------+-------------------------+-----+----------------------------------------+
+| ``alert_major_internal_o`` | 1 | out | Core has detected an internal fault |
+| | | | which cannot be recovered from. Can be |
+| | | | used by a system to reset the core and |
+| | | | possibly take other remedial action. |
+| | | | This signal is a pulse, but might be |
+| | | | set for multiple cycles per alert. |
++----------------------------+-------------------------+-----+----------------------------------------+
+| ``alert_major_bus_o`` | 1 | out | Core has detected a bus fault |
+| | | | which cannot be recovered from. Can be |
+| | | | used by a system to reset the core and |
+| | | | possibly take other remedial action. |
+| | | | This signal is a pulse, but might be |
+| | | | set for multiple cycles per alert. |
++----------------------------+-------------------------+-----+----------------------------------------+
diff --git a/doc/02_user/system_requirements.rst b/doc/02_user/system_requirements.rst
index 7fbd3f97..c6994672 100644
--- a/doc/02_user/system_requirements.rst
+++ b/doc/02_user/system_requirements.rst
@@ -8,9 +8,10 @@ The following tools are known to work with the RTL code of Ibex.
Please `file an issue `_ if you experience problems with any of the listed tools, or if you have successfully used a tool with Ibex which is not listed here.
- Synopsys Design Compiler
-- Xilinx Vivado
+- Cadence Genus
+- Xilinx Vivado, version |tool_requirements.vivado| and up.
- Verilator, version |tool_requirements.verilator| and up.
-- Synopsys VCS
+- Synopsys VCS, version at least |tool_requirements.vcs|.
- Cadence Incisive/Xcelium
- Mentor Questa
- Aldec Riviera Pro
@@ -18,6 +19,10 @@ Please `file an issue `_ if you experien
To run the UVM testbench a RTL simulator which supports SystemVerilog and UVM 1.2 is required.
The `documentation of riscv-dv `_ contains a list of supported simulators.
+To compile code that runs on Ibex, you'll need a RISC-V toolchain.
+This isn't part of the core as such, but is necessary for verification.
+See the :doc:`Verification <../03_reference/verification>` section of the Reference Guide for more details about which toolchains the project currently uses for testing.
+
Tools with known issues
-----------------------
diff --git a/doc/03_reference/cosim.rst b/doc/03_reference/cosim.rst
new file mode 100644
index 00000000..d4fd9b76
--- /dev/null
+++ b/doc/03_reference/cosim.rst
@@ -0,0 +1,177 @@
+.. _cosim:
+
+Co-simulation System
+====================
+
+Overview
+--------
+
+A co-simulation system is provided that can run in either the Ibex UVM DV environment or with Simple System.
+This system runs a RISC-V ISS (currently only Spike is supported) in lockstep with an Ibex core.
+All instructions executed by Ibex and memory transactions generated are checked against the behaviour of the ISS.
+This system supports memory errors, interrupt and debug requests which are observed in the RTL simulation and forwarded to the ISS so the ISS and RTL remain in sync.
+The system uses a generic interface to allow support of multiple ISSes.
+Only VCS is supported as a simulator, though no VCS specific functionality is required so adding support for another simulator should be straight-forward.
+
+To run the co-simulation system, a particular version of Spike is required (see the Setup and Usage section, below).
+
+The RISC-V Formal Interface (RVFI) is used to provide information about retired instructions and instructions that produce synchronous traps for checking.
+The RVFI has been extended to provide interrupt and debug information and the value of various CSRs that are harder to model (e.g. ``mcycle``).
+These extended signals have the prefix ``rvfi_ext``
+
+Setup and Usage
+---------------
+
+Clone the `lowRISC fork of Spike `_ and check out the ``ibex-cosim-v0.5`` tag.
+Other, later, versions called ``ibex-cosim-v*`` may also work but there's no guarantee of backwards compatibility.
+Follow the Spike build instructions to build and install Spike.
+The ``--enable-commitlog`` and ``--enable-misaligned`` options must be passed to ``configure``.
+We recommend using a custom install location (using ``--prefix=`` with ``configure``) to avoid cluttering system directories.
+Note that, if you do this, you will also need to add an entry to ``PKG_CONFIG_PATH`` so that ``pkg-config`` can tell us how to build against the installed Spike libraries.
+
+To build/run the UVM DV environment with the co-simulator, add the ``COSIM=1`` argument to the make command.
+To build Simple System with the co-simulator, build the ``lowrisc:ibex:ibex_simple_system_cosim`` core.
+
+Quick Build and Run Instructions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Build and install the co-simulator
+
+.. code-block:: bash
+
+ # Get the Ibex co-simulation spike branch
+ git clone -b ibex_cosim https://github.com/lowRISC/riscv-isa-sim.git riscv-isa-sim-cosim
+
+ # Setup build directory
+ cd riscv-isa-sim-cosim
+ mkdir build
+ cd build
+
+ # Configure and build spike
+ ../configure --enable-commitlog --enable-misaligned --prefix=/opt/spike-cosim
+ sudo make -j8 install
+
+Run the UVM DV regression with co-simulation enabled
+
+.. code-block:: bash
+
+ # Run regression with co-simulation enabled
+ cd /dv/uvm/core_ibex
+ make COSIM=1
+
+Build and run Simple System with the co-simulation enabled
+
+.. code-block:: bash
+
+ # Build simulator
+ fusesoc --cores-root=. run --target=sim --setup --build lowrisc:ibex:ibex_simple_system_cosim --RV32E=0 --RV32M=ibex_pkg::RV32MFast
+
+ # Build coremark test binary, with performance counter dump disabled. The
+ # co-simulator system doesn't produce matching performance counters in spike so
+ # any read of those CSRs results in a mismatch and a failure.
+ make -C ./examples/sw/benchmarks/coremark SUPPRESS_PCOUNT_DUMP=1
+
+ # Run coremark binary with co-simulation checking
+ build/lowrisc_ibex_ibex_simple_system_cosim_0/sim-verilator/Vibex_simple_system --meminit=ram,examples/sw/benchmarks/coremark/coremark.elf
+
+Co-simulation details
+----------------------
+
+The co-simulation system uses DPI calls to link the DV and ISS sides together.
+A C++ interface is defined in ``dv/cosim/cosim.h`` with a DPI wrapper provided by ``dv/cosim/cosim_dpi.cc`` and ``dv/cosim/cosim_dpi.h``.
+A ``chandle``, which points to some class instance that implements the interface, must be provided by the DV environment.
+All the co-simulation DPI calls take this ``chandle`` as a first argument.
+
+The details below discuss the C++ interface.
+The DPI version of the interface is almost identical, with all functions prefaced with ``riscv_cosim`` and taking a ``chandle`` of the co-simulation instance to use.
+
+The core function of the co-simulation interface is the ``step`` function:
+
+.. code-block:: c++
+
+ virtual bool step(uint32_t write_reg, uint32_t write_reg_data, uint32_t pc, bool sync_trap);
+
+``step`` takes arguments giving the PC of the most recently retired or synchronously trapping instruction in the DUT along with details of any register write that occurred.
+
+Where ``step`` is provided with a retired (successfully executed) instruction it steps the ISS by one instruction and checks it executed the same instruction, with the same register write result, as the DUT.
+
+When ``step`` is provided with an instruction that produces a synchronous trap, it checks the ISS also traps on the same instruction but does not step to the next executed instruction.
+That instruction will be the first instruction of the trap handler and will be checked/stepped by the next call to ``step`` when it retires from the DUT.
+
+Any data memory accesses that the ISS produces during the ``step`` are checked against observed DUT memory accesses.
+
+``step`` returns false if any checks have failed.
+If any errors occur during the step they can be accessed via ``get_errors`` which returns a vector of error messages.
+For the DPI interface errors are accessed using ``riscv_cosim_get_num_errors`` and ``riscv_cosim_get_error``.
+When errors have been checked they can be cleared with ``clear_errors``.
+
+Trap Handling
+^^^^^^^^^^^^^
+
+Traps are separated into two categories, synchronous and asynchronous.
+Synchronous traps are caused by a particular instruction's execution (e.g. an illegal instruction).
+Asynchronous traps are caused by external interrupts.
+Note that in Ibex error responses to both loads and store produce a synchronous trap so the co-simulation system has the same behaviour.
+
+A synchronous trap is associated with a particular instruction and prevents that instruction from completing its execution.
+That instruction doesn't retire, but is still made visible on the RVFI.
+The ``rvfi_trap`` signal is asserted for an instruction that causes a synchronous trap.
+As described above ``step`` should be called for any instruction that causes a synchronous trap to check the trap is also seen by the ISS.
+
+An asynchronous trap can be seen as occurring between instructions and as such doesn't have an associated instruction, nothing will be seen on RVFI with ``rvfi_trap`` set.
+The co-simulation system will immediately take any pending asynchronous trap when ``step`` is called, expecting the instruction checked with ``step`` to be the first instruction of the trap handler.
+
+While a debug request is not strictly an asynchronous trap (it doesn't use the same exception handling mechanism), they work identically to asynchronous traps for the co-simulation system.
+When a debug request is pending when ``step`` is called the co-simulation will expect the instruction checked by ``step`` to be the first instruction of the debug handler.
+
+Interrupts and Debug Requests
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The DV environment must observe any incoming interrupts and debug requests generated by the testbench and notify the co-simulation system of them using ``set_mip``, ``set_debug_req`` and ``set_nmi``.
+An interrupt or debug request will take immediate effect at the next ``step`` (if architecturally required to do so).
+The DV environment is responsible for determining when to call ``set_mip``, ``set_debug_req`` and ``set_nmi`` to ensure a RTL and co-simulation match.
+
+The state of the incoming interrupts and debug request is sampled when an instruction moves from IF to ID/EX.
+The sampled state is tracked with the rest of the RVFI pipeline and used to call ``set_mip``, ``set_debug_req`` and ``set_nmi`` when the instruction is output by the RVFI.
+
+A complication occurs when more than one interrupt or debug requests occur between individual instruction fetches.
+One interrupt or debug request may take priority over another when they all occur together but when they occur in time is important as well.
+If interrupt and debug request notification is associated exclusively with retired instructions the co-simulation system cannot correctly prioritise multiple interrupts and debug requests.
+To deal with this the RVFI can also signal an interrupt event not associated with an instruction by setting ``rvfi_ext_irq_valid`` without setting ``rvfi_valid``.
+When this is set the interrupt related RVFI signals are valid and provide the interrupt state.
+The RVFI is used in this way, as opposed to a separate notification interface, so the interrupt notifications are ordered relative to the retired instructions.
+
+See the comments in :file:`rtl/ibex_core.sv`, around the ``new_debug_req``, ``new_nmi``, ``new_irq`` and ``rvfi_irq_valid`` signals for further details.
+
+Memory Access Checking and Bus Errors
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The co-simulation system must be informed of all Dside accesses performed by the RTL using ``notify_dside_access``.
+See :file:`dv/cosim/cosim.h` for further details.
+As Ibex doesn't perform speculative Dside memory accesses, all notified accesses are expected to match with accesses performed by the ISS in the same order they are notified.
+
+Accesses notified via ``notify_dside_access`` can specify they saw an error response, the co-simulation system will produce the appropriate trap when the ISS attempts to access the address that saw the error.
+
+Accesses must be notified before they occur in the ISS for the access matching and trapping on errors to work.
+
+Iside accesses from Ibex can be speculative, so there is no simple link between accesses produced by the RTL and the accesses performed by the ISS for the Iside.
+This means no direct checking of Iside accesses is done, however errors on the Iside accesses that result in an instruction fault trap need to be notified to the co-simulation system.
+``set_iside_error`` does this, it is provided with the address that saw the bus error and it should be called immediately before the ``step`` that will process the trap.
+The co-simulation system will produce an instruction fault trap if it attempts to access the provided error address in the ``step`` call following the ``set_iside_error`` call.
+
+Two methods are available for dealing with bus errors on the Iside, they differ in where they probe.
+One probes on the external instr_X memory interface, the other probes internally within the IF stage.
+The probe used is selected by the ``probe_imem_for_err`` field of the ``core_ibex_cosim_cfg`` structure.
+When set external probing is used, otherwise internal probing is used.
+
+Both probe points look for addresses that have seen bus errors.
+If an instruction entering ID/EX fetches from an address that has seen a bus error (as recorded by one of the probing methods) its ``rvfi_order_id`` is recorded.
+When a faulting instruction is reported on the RVFI and its ``rvfi_order_id`` matches a recorded faulting one ``set_iside_error`` is called with the faulting address before the next ``step``.
+
+The external interface probe should be used when it is guaranteed that a bus error to address A on the external interface results in a fetch error the next time an instruction with address A is observed entering the ID/EX stage (providing no successful access to A has occurred in the mean time).
+Otherwise the internal probe should be used.
+When Ibex is used with the prefetch buffer this guarantee holds and the external probe can be used.
+When Ibex is used with the instruction cache this guarantee does not hold and the internal probe must be used.
+
+Care should be taken when using the internal probe as it will miss any bug that causes instruction faults to be ignored by the prefetch buffer or ICache (or whatever else has been used in place of these by a custom implementation).
+In the case of the Ibex ICache a separate testbench ensures instruction faults are dealt with appropriately within the ICache.
diff --git a/doc/03_reference/coverage_plan.rst b/doc/03_reference/coverage_plan.rst
new file mode 100644
index 00000000..551aadea
--- /dev/null
+++ b/doc/03_reference/coverage_plan.rst
@@ -0,0 +1,446 @@
+.. _coverage-plan:
+
+Coverage Plan
+=============
+
+.. todo::
+ Branch prediction hasn't yet been considered, this will add more coverage points and alter some others
+
+Introduction
+------------
+Ibex functional coverage is split into two major categories:
+
+* Architectural coverage - which is concerned with instructions being executed and exercising various features of the RISC-V architecture (e.g. PMP) and does not consider the details of how this execution occurs.
+* Microarchitectural coverage - which is concerned with the specifics of the RTL operation, ensuring interesting corner cases are seen along with various micro-architectural events (e.g. the different kinds of stall) and combinations of them.
+
+Architectural coverage is not Ibex specific. It can be determined directly from a trace of executed instructions and is handled by RISCV-DV, details can be found in the `RISCV-DV documentation `_.
+
+Microarchitectural coverage will probe the Ibex RTL directly and is described here.
+There is some inevitable overlap between architectural and microarchitectural coverage but we aim to minimise it.
+
+Coverage Implementation
+-----------------------
+All coverpoints and cross coverage defined below is associated with a name ``cp_name``.
+This is the name of the coverpoint or cross that implements the described coverage.
+Coverage is implemented in two files; :file:`dv/uvm/core_ibex/fcov/core_ibex_pmp_fcov_if.sv` for PMP related coverage and :file:`dv/uvm/core_ibex/fcov/core_ibex_fcov_if.sv` for everything else.
+
+Microarchitectural Events and Behaviour
+---------------------------------------
+Below are lists of specific things from the microarchitecture that will be included in functional coverage.
+Each of the points listed below must be covered.
+This will be further combined using cross coverage which is described in the section below.
+
+Instructions
+^^^^^^^^^^^^
+
+Categories
+""""""""""
+``cp_id_instr_category``
+
+Instructions can be grouped into a number of categories.
+Each category exercises different data and control paths in the core.
+For example the ``ADD`` and ``SUB`` instructions are in the same category as they are almost identical for the microarchitecture (both read two registers and write to one, both feed operands to the ALU and take their result from it, both have the same response to interrupts etc; the only difference is the ALU operation).
+
+Instructions can be compressed or uncompressed but that isn't factored into the instruction categories below (excepting for illegal instructions).
+The decompression occurs in the IF stage and is invisible to the ID/EX stage so isn't relevant for instruction execution.
+A separate set of category-agnostic compressed instruction behaviour is considered instead.
+
+An instruction category is sampled at the ID/EX stage (which is where all the varying behaviours actually occur).
+Some categories are just a single instruction, which is named without further description.
+
+
+* **ALU** - All of the reg/reg reg/imm instructions that use the ALU.
+ This is any RISC-V instruction with an opcode of ``7'b0010011`` or ``7'b0110011`` (``ibex_pkg::OPCODE_OP`` and ``ibex_pkg::OPCODE_OP_IMM``) other than the ``MUL*`` and ``DIV*`` family of instructions (from RV32M).
+* **Mul** - Any ``MUL*`` instruction (from RV32M).
+* **Div** - Any ``DIV*`` instruction (from RV32M).
+* **Branch** - Any ``B*`` family branch instruction.
+* **Jump** - ``JAL``/``JALR``
+* **Load** - Any ``L*`` family load instruction.
+* **Store** - Any ``S*`` family load instruction.
+* **CSRAccess** - Any instruction from Zicsr.
+* **EBreakDbg**/**EBreakExc** - An ``EBREAK`` instruction that either enters debug mode (Dbg) or causes an exception (Exc).
+ Which occurs depends upon the setting of ``dcsr.ebreakm`` / ``dcsr.ebreaku`` combined with the privilege level of executed instruction.
+* **ECall** - ``ECALL`` is an environment call used for escalation of privilege.
+* **MRet** - ``MRET`` return out of M-mode
+* **DRet** - ``DRET`` ruturn from debug mode.
+* **WFI** - wait for interrupt.
+* **Fence** - ``FENCE`` memory fence on the data side.
+* **FenceI** - ``FENCE.I`` instruction fence instruction.
+* **FetchError** - Any instruction that saw a fetch error.
+* **CompressedIllegal** - Any compressed instruction with an illegal encoding.
+* **UncompressedIllegal** - Any uncompressed instruction with an illegal encoding.
+* **CSRIllegal** - Any instruction attempting a CSR access that is not allowed.
+* **PrivIllegal** - Illegal due to privilege level or being in/out of debug mode.
+* **OtherIllegal** - Any other instruction that raises an Illegal instruction exception that isn't in the other categories.
+* **None** - No instruction in ID/EX stage.
+
+Stalls
+""""""
+``cp_stall_type_id``
+
+Not all instructions can see all kinds of stalls.
+A stall category is sampled at the ID/EX stage only (as stalls in IF and WB don't break down into categories).
+
+* **Instr** - A stall caused by a multi-cycle instruction.
+ This can be seen by instructions from categories:
+
+ * **MUL**
+ * **DIV**
+ * **Branch**
+ * **Jump**
+
+* **LdHz** - A load hazard, the instruction in ID/EX depends upon the result of a load that is awaiting a response in writeback.
+ This can be seen by instructions from categories:
+
+ * **ALU**
+ * **Mul**
+ * **Div**
+ * **Branch**
+ * **Jump**
+ * **Load**
+ * **Store**
+ * **CSRAccess**
+
+* **Mem** - Memory stall, the instruction in ID/EX is awaiting a prior memory request to complete before it can begin (to allow precise interrupts on a memory error response). This can be seen for all instruction categories
+
+Privilege Level
+"""""""""""""""
+Ibex can operate at either the M (machine) or U (user) privilege levels.
+Different aspects of the Ibex microarchitecture can be using different privilege levels at once.
+
+* ``cp_priv_mode_id`` - Privilege level of ID/EX stage instruction.
+* ``cp_priv_mode_lsu`` - Privilege level of LSU operation (ID/EX privilege level modified by ``mstatus.mprv`` and ``mstatus.mpp`` settings).
+
+Note that the privilege level of the instruction in WB isn't retained by the microarchitecture and is not relevant to coverage.
+The privilege level of the IF instruction is effectively unknown.
+The instruction is checked when moving from IF to ID/EX against the ID stage privilege level to check if execution is permitted by PMP.
+Any instruction that reaches WB can be considered bound to retire and any relevant checks and functionality altered by the privilege mode is dealt with at an earlier stage.
+
+Hazards
+"""""""
+Ibex hazards all occur in the interaction between the ID and EX stage.
+
+* RAW Reg - Read after write hazard, instruction in ID/EX reads a register that writeback is writing.
+ Split into two versions:
+
+ * RAW load - Instruction in ID/EX reading from destination of load in writeback.
+ Produces a stall (Category LdHz) and shouldn't forward data.
+ Covered by ``cp_stall_type_id``
+ * ``cp_wb_reg_no_load_hz`` - Instruction in writeback isn't a load.
+ Handled with data forwarding and no stall.
+
+* RAW Load/Store bytes - Load with bytes overlapping a store immediately before it.
+ Covered by ``cp_mem_raw_hz``
+
+State Specific Behaviour
+""""""""""""""""""""""""
+Some instructions will behave differently depending upon the state of the processor (e.g. the privilege level the instruction executes at, CSR settings or whether the processor is in debug mode).
+
+* Instruction illegal in U Mode.
+
+ * ``cp_mret_in_umode`` - ``MRET``
+ * ``cp_wfi_in_umode`` - ``WFI``
+ * Read and write to M-mode CSR - Covered by crosses ``csr_write_priv_cross`` and ``csr_read_only_priv_cross```
+
+* Debug mode instructions (cover execution in and out of debug mode).
+
+ * ``DRET``
+ * ``csr_read_only_debug_cross``, ``csr_write_debug_cross`` - Access to debug CSRs.
+
+ * ``dcsr``
+ * ``dpc``
+ * ``dscratch0``
+ * ``dscratch1``
+
+ * Access to trigger CSRs (also possible in M mode: cover execution in M mode, debug mode and U mode).
+ Covered by ``csr_read_only_debug_cross``, ``csr_write_debug_cross``, ``csr_read_only_priv_cross``, ``csr_write_priv_cross``.
+
+ * ``tselect``
+ * ``tdata1``
+ * ``tdata2``
+ * ``tdata3``
+
+* Loads/stores with ``mstatus.mprv`` set and unset.
+ Covered by ``mprv_effect_cross``
+* EBreak behaviour in U/M mode with different ``dcsr.ebreakm`` / ``dcsr.ebreaku`` settings.
+ Covered by ``priv_mode_instr_cross``
+* ``cp_single_step_instr`` - Single step over every instruction category
+
+Pipeline State
+^^^^^^^^^^^^^^
+Each pipeline stage has some associated state.
+
+* ``cp_if_stage_state`` - IF stage full and fetching, full and idle, empty and fetching, or empty and idle.
+ General IF stage full and stalled uninteresting as will only occur when ID stage is full and stalled.
+* ``cp_wb_stage_state`` - WB stage full and stalled, full and unstalled, or empty
+* ``cp_id_stage_state`` - ID stage full and stalled, full and unstalled, or empty.
+* Controller (within ID stage) state machine states
+
+ * ``cp_controller_fsm`` - Possible transitions between these states.
+
+ * ``RESET`` -> ``BOOT_SET``
+ * ``BOOT_SET`` -> ``FIRST_FETCH``
+ * ``FIRST_FETCH`` -> ``DECODE``
+ * ``FIRST_FETCH`` -> ``IRQ_TAKEN``
+ * ``FIRST_FETCH`` -> ``DBG_TAKEN_IF``
+ * ``DECODE`` -> ``FLUSH``
+ * ``DECODE`` -> ``DBG_TAKEN_IF``
+ * ``DECODE`` -> ``IRQ_TAKEN``
+ * ``IRQ_TAKEN`` -> ``DECODE``
+ * ``DBG_TAKEN_IF`` -> ``DECODE``
+ * ``DBG_TAKEN_ID`` -> ``DECODE``
+ * ``FLUSH`` -> ``DECODE``
+ * ``FLUSH`` -> ``DBG_TAKEN_ID``
+ * ``FLUSH`` -> ``WAIT_SLEEP``
+ * ``FLUSH`` -> ``DBG_TAKEN_IF``
+ * ``WAIT_SLEEP`` -> ``SLEEP``
+ * ``SLEEP`` -> ``FIRST_FETCH``
+
+Exceptions/Interrupts/Debug
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+Exceptions, interrupts and debug entry can all cause control flow changes combined with CSR writes and privilege level changes and work quite similarly within the controller but not identically.
+Furthermore they can all occur together and must be appropriately prioritised (consider an instruction with hardware trigger point matching it, that causes some exception and an interrupt is raised the cycle it enters the ID/EX stage).
+
+* Exception from instruction fetch error (covered by the **FetchError** instruction category).
+* ``pmp_iside_mode_cross`` - Exception from instruction PMP violation.
+* Exception from illegal instruction (covered by the illegal instruction categories).
+* ``cp_ls_error_exception`` - Exception from memory fetch error.
+* ``cp_ls_pmp_exception`` - Load store unit exception from PMP.
+* ``pmp_dside_mode_cross`` - Exception from memory access PMP violation.
+* Unaligned memory access
+
+ * ``misaligned_insn_bus_err_cross``, ``misaligned_data_bus_err_cross`` - Cover all error and no error scenarios for memory fetch error; first access saw error, second
+ access saw error, neither access saw error
+
+* Interrupt raised/taken.
+
+ * ``cp_interrupt_taken`` - Interrupt raised/taken for each available interrupt line.
+ For cross coverage, the precise interrupt that's raised/taken is not relevant and it only needs to be grouped by NMI vs non-NMI.
+ This is done by using ``cp_nmi_taken`` coverpoint in the crosses.
+ * ``interrupt_taken_instr_cross`` - Interrupt raised/taken the first cycle an instruction is in ID/EX or some other cycle the instruction is in ID/EX.
+
+* ``cp_debug_req`` - External debug request.
+* ``cp_single_step_taken`` - Instruction executed when debug single step enabled.
+* ``cp_single_step_exception`` - Single step over an instruction that takes an exception.
+* ``cp_insn_trigger_enter_debug`` - Instruction matches hardware trigger point.
+* ``cp_debug_mode`` - Ibex operating in debug mode.
+* ``cp_debug_wakeup`` - Ibex wakes up after being halted from debug request.
+* ``irq_wfi_cross``, ``debug_wfi_cross`` - Debug and Interrupt whilst sleeping with WFI
+
+ * Cover with global interrupts enabled and disabled
+ * Cover with specific interrupt enabled and disabled (Should exit sleep when
+ interrupt is enabled but global interrupts set to disabled, should continue
+ sleeping when both are disabled).
+ Continuing to sleep in the case explained above is covered by ``cp_irq_continue_sleep``, otherwise the behaviour is captured in ``irq_wfi_cross``
+
+* Debug and interrupt occurring whilst entering WFI
+
+ * Covering period between WFI entering ID/EX stage and going into sleep
+ Covered by bin ``enter_sleep`` of ``cp_controller_fsm_sleep`` that is used by ``irq_wfi_cross`` and ``debug_wfi_cross``.
+
+* ``cp_double_fault`` - Double fault
+
+PMP
+^^^
+* ``cp_region_mode`` - Each region configured with different matching modes.
+
+ * Off
+ * TOR
+ * NA4
+ * NAPOT
+
+* ``cp_napot_addr_modes`` - When NAPOT is enabled check that each address mode is seen at least once.
+
+* ``cp_region_priv_bits`` - Each region configured with all possible permissions including locked/unlocked.
+
+ * Different permissions with MML enabled and disabled, separate cover points for R/W/X/L values with and without MML.
+
+* Access fail & pass.
+
+ * ``misaligned_lsu_access_cross`` - All combinations of unaligned access split across a boundary, both halves pass, neither pass, just the first passes, just the second passes.
+
+ * Two possible boundary splits; across a 32-bit boundary within a region or a boundary between PMP regions.
+
+ * ``cp_pmp_iside_region_override``, ``cp_pmp_iside2_region_override``, ``cp_pmp_dside_region_override`` - Higher priority entry allows access that lower priority entry prevents.
+ * ``pmp_instr_edge_cross`` - Compressed instruction access (16-bit) passes PMP but 32-bit access at same address crosses PMP region boundary.
+
+* Each field of mssecfg enabled/disabled, as well as written to using a CSR write, with relevant functionality tested.
+
+ * RLB - rule locking bypass.
+
+ * ``cp_edit_locked_pmpcfg``, ``cp_edit_locked_pmpaddr`` - Modify locked region with RLB set.
+ * ``rlb_csr_cross`` - Try to enable RLB when RLB is disabled and locked regions present.
+
+ * MMWP - machine mode whitelist policy.
+
+ * ``pmp_dside/iside/iside2_nomatch_cross`` - M-mode access fail due to not matching any PMP regions.
+ * ``mmwp_csr_cross`` - Try to disable when enabled.
+
+ * MML - machine mode lockdown policy.
+
+ * ``mml_sticky_cross`` - Try to disable when enabled.
+
+* Access close to PMP region modification that allows/disallows that access.
+
+* ``pmp_wr_exec_region`` - Explores behaviour around adding executable regions when MML is enabled.
+ Cross of current region configuration with region configuration that is being written and RLB setting.
+ It only considers regions that aren't currently executable with writes attempted to make them executable.
+ Non MML configurations are not sampled.
+
+CSRs
+^^^^
+Basic read/write functionality must be tested on all implemented CSRs.
+
+* ``cp_csr_read_only`` - Read from CSR, there is also ``cp_csr_invalid_read_only`` for illegal CSRs.
+* ``cp_csr_write`` - Write to CSR, there is also ``cp_csr_invalid_write`` for illegal CSRs.
+
+ * Write to read only CSR.
+ Covered by ensuring ``cp_csr_write`` is seen for read-only CSRs
+
+* ``cp_warl_check_CSRNAME`` - Write illegal/unsupported value to WARL field for CSR named ``CSRNAME``.
+* ``csr_read_only_priv_cross``, ``csr_write_priv_cross``, ``csr_read_only_debug_cross``, ``csr_write_debug_cross`` - Crosses of reads and writes to CSRs from different privilege levels/debug mode.
+
+ * Access to CSR disallowed due to privilege levels/debug mode
+ Covered by ensuring within the crosses
+
+CSRs addresses do not need to be crossed with the variety of CSR instructions as these all use the same basic read & write interface into ``ibex_cs_registers``.
+Coverage of the above points will be sampled at the ``ibex_cs_registers`` interface (as opposed to sampling CSR instructions).
+
+Security Countermeasures
+^^^^^^^^^^^^^^^^^^^^^^^^
+For more detail about each security countermeasure in Ibex see :ref:`security`
+
+* ``cp_data_ind_timing`` - Enabling/Disabling "Data Independent Timing" feature.
+
+* ``cp_data_ind_timing_instr`` - Executing each instruction category while data independent timing feature is enabled.
+
+* ``cp_dummy_instr_en`` - Enabling/Disabling "Dummy Instruction Insertion" feature.
+
+* ``cp_dummy_instr_mask`` - Frequency of injection for the dummy instructions.
+
+* ``cp_dummy_instr_type`` - Type of the injected dummy instruction.
+
+* ``cp_dummy_instr`` - Executing each instruction category while dummy instruction insertion feature is enabled.
+
+* ``cp_dummy_instr_if_stage`` - The IF stage handles a dummy instruction.
+
+* ``cp_dummy_instr_id_stage`` - The ID/EX stage handles a dummy instruction.
+
+* ``cp_dummy_instr_wb_stage`` - The WB stage handles a dummy instruction.
+
+* ``cp_rf_a_ecc_err``, ``cp_rf_b_ecc_err`` - Register file integrity (ECC) fault is seen for port A/B.
+
+* ``cp_icache_ecc_err`` - ICache has seen an integrity (ECC) fault.
+
+* ``cp_mem_load_ecc_err`` - An ECC error has been seen on a load response
+
+* ``cp_mem_store_ecc_err`` - An ECC error has been seen on a store response
+
+* ``cp_lockstep_err`` - Lockstep glitch fault seen.
+
+* ``cp_rf_we_glitch_err`` - Register file write enable glitch fault seen.
+
+* ``cp_pc_mismatch_err`` - PC mismatch error seen.
+
+The :ref:`security features Ibex implements ` are given specific security countermeasure names in OpenTitan (see 'Security Countermeasures' in the `Comportability Definition and Specification `_ documentation section).
+The mapping between security countermeasures and coverpoints that demonstrate it being used is given below.
+
++--------------------------------+-------------------------------------------------------+
+| Security Countermeasure | Coverpoint(s) |
++================================+=======================================================+
+| BUS.INTEGRITY | ``cp_mem_load_ecc_err`` ``cp_mem_store_ecc_err`` |
++--------------------------------+-------------------------------------------------------+
+| SCRAMBLE.KEY.SIDELOAD | ``FENCE.I`` of ``cp_id_instr_category`` |
++--------------------------------+-------------------------------------------------------+
+| CORE.DATA_REG_SW.SCA | ``cp_data_ind_timing`` ``cp_data_ind_timining_instr`` |
++--------------------------------+-------------------------------------------------------+
+| PC.CTRL_FLOW.CONSISTENCY | ``cp_pc_mismatch_err`` |
++--------------------------------+-------------------------------------------------------+
+| CTRL_FLOW.UNPREDICTABLE | ``cp_dummy_instr`` and related coverpoints |
++--------------------------------+-------------------------------------------------------+
+| DATA_REG_SW.INTEGRITY | ``cp_rf_a_ecc_err`` ``cp_rf_b_ecc_err`` |
++--------------------------------+-------------------------------------------------------+
+| DATA_REG_SW.GLITCH_DETECT | ``cp_rf_we_glitch_err`` |
++--------------------------------+-------------------------------------------------------+
+| LOGIC.SHADOW | ``cp_lockstep_err`` |
++--------------------------------+-------------------------------------------------------+
+| FETCH.CTRL.LC_GATED | ``cp_fetch_enable`` |
++--------------------------------+-------------------------------------------------------+
+| EXCEPTION.CTRL_FLOW.LOCAL_ESC | ``cp_double_fault`` |
++--------------------------------+-------------------------------------------------------+
+| EXCEPTION.CTRL_FLOW.GLOBAL_ESC | ``cp_double_fault`` |
++--------------------------------+-------------------------------------------------------+
+| ICACHE.MEM.SCRAMBLE | ``FENCE.I`` of ``cp_id_instr_category`` |
++--------------------------------+-------------------------------------------------------+
+| ICACHE.MEM.INTEGRITY | ``cp_icache_ecc_err`` |
++--------------------------------+-------------------------------------------------------+
+
+Memory Interface Behaviour
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+Covering different scenarios around timing of memory requests and responses and
+related behaviour
+
+* ``cp_dmem_response_latency``/``cp_imem_response_latency`` - Latency of response from request for dmem and imem.
+ Separated into two bins ``single_cycle`` (immediate response after request) and ``multi_cycle`` (all other latencies).
+* ``dmem_req_gnt_valid``/``imem_req_gnt_rvalid`` - Request, grant and rvalid all seen in the same cycle for dmem and imem.
+ This means a response is seen the same cycle a new request is being granted.
+
+
+Miscellaneous
+^^^^^^^^^^^^^
+Various points of interest do not fit into the categories above.
+
+* ``instr_unstalled`` - Instruction unstalled - Cover the cycle an instruction is unstalled having just been stalled.
+* ``cp_icache_enable`` - Enabling/Disabling ICache.
+* ``cp_fetch_enable`` - Fetch enabled and disabled via top-level ``fetch_enable_i`` input.
+
+Cross Coverage
+--------------
+Much of the more complex behaviour lies at the combination of the individual microarchitectural behaviours above.
+Cross coverage is used to capture that.
+Crosses listed below are ones that don't already fit into the above categories.
+There are some broad crosses containing many bins aiming to capture all combinations of some generalised behaviours as well as some more specific ones to capture all combinations of behaviours focused on a particular area.
+
+Cross coverage will be intentionally broad.
+Where it is proving hard to hit particular bins they will be reviewed in more detail to determine if they're impossible to hit or if simply hard to hit and whether hitting them provides meaningful gains to verification quality.
+
+Excluded bins will either become illegal bins (where they are impossible to hit, so a failure will be seen if they are hit) or ignore bins (where they don't factor into coverage statistics).
+There must be a documented reason a particular bin is added to the illegal or ignore bins.
+
+* ``pipe_cross`` - Instruction Categories x Pipeline stage states across IF, ID/EX and WB
+
+ * Covers all possibilities of instruction combinations that could fill the pipeline. State only for IF/WB suffices to cover this as all the interesting per instruction behaviour occurs in ID/EX.
+ * All bins containing instruction categories other than **None** ignored when ID/EX stage is empty.
+
+* ``priv_mode_instr_cross`` - Instructions Categories x ID/EX Privilege level
+* ``stall_cross`` - Instruction Categories x Stall Categories
+
+ * Illegal bins will be used to exclude instruction and stall categories that cannot occur.
+
+* ``wb_reg_no_load_hz_instr_cross`` - Instruction Categories x Hazards
+
+ * ``stall_cross`` covers the RAW load hazard (as it produces a LdHz stall).
+ * RAW hazard between load/store requires no cross coverage as it's only seen for load and store instructions so the single coverpoint suffices.
+
+* ``debug_instruction_cross`` - Instruction Categories x Debug Mode
+* ``controller_instr_cross`` - Instruction Categories x Controller state transitions of interest
+* ``interrupt_taken_instr_cross``, ``debug_entry_if_instr_cross``, ``pipe_flush_instr_cross`` - Interrupt taken/Debug mode entry/Pipe flush x instruction unstalled x instruction category
+
+ * Three separate cross coverage groups: one for interrupt, debug and pipe flush.
+ * Covers all instruction categories being interrupted/entering debug mode/flushing the pipeline both where this occurs during a stall and when it occurs just when they've unstalled.
+
+* ``exception_stall_instr_cross`` - PMP exception x load/store error exception x instruction category x stall type x unstalled x irq pending x debug req
+
+ * Large cross to cover all possibilities of combinations between interrupt, debug and exceptions for all instruction categories across all stall behaviours.
+
+* ``pmp_iside_priv_bits_cross``, ``pmp_iside2_priv_bits_cross``, ``pmp_dside_priv_bits_cross``, PMP regions x permissions x access fail/pass x privilege level
+
+ * Three crosses, one for each PMP channel (instruction, instruction 2 and data).
+
+* ``dummy_instr_config_cross`` - Dummy Instruction Type x Dummy Instruction Insertion Frequency to explore all possible configurations.
+
+* ``rf_ecc_err_cross`` - ECC Error on Port A x ECC Error on Port B to explore all possible combinations of reported ECC errors.
+
+* ``debug_req_dummy_instr_{if,id,wb}_stage_cross`` - The IF, ID/EX, or WB stage handles a dummy instruction while a debug request arrives.
+
+* ``irq_pending_dummy_instr_{if,id,wb}_stage_cross`` - The IF, ID/EX, or WB stage handles a dummy instruction while an IRQ is pending.
diff --git a/doc/03_reference/cs_registers.rst b/doc/03_reference/cs_registers.rst
index 5294ac52..d334f0bd 100644
--- a/doc/03_reference/cs_registers.rst
+++ b/doc/03_reference/cs_registers.rst
@@ -46,6 +46,12 @@ Ibex implements all the Control and Status Registers (CSRs) listed in the follow
+---------+--------------------+--------+-----------------------------------------------+
| 0x3BF | ``pmpaddr15`` | WARL | PMP Address Register |
+---------+--------------------+--------+-----------------------------------------------+
+| 0x5A8 | ``scontext`` | WARL | Supervisor Context Register |
++---------+--------------------+--------+-----------------------------------------------+
+| 0x747 | ``mseccfg`` | WARL | Machine Security Configuration |
++---------+--------------------+--------+-----------------------------------------------+
+| 0x757 | ``mseccfgh`` | WARL | Upper 32 bits of ``mseccfg`` |
++---------+--------------------+--------+-----------------------------------------------+
| 0x7A0 | ``tselect`` | WARL | Trigger Select Register |
+---------+--------------------+--------+-----------------------------------------------+
| 0x7A1 | ``tdata1`` | WARL | Trigger Data Register 1 |
@@ -56,7 +62,7 @@ Ibex implements all the Control and Status Registers (CSRs) listed in the follow
+---------+--------------------+--------+-----------------------------------------------+
| 0x7A8 | ``mcontext`` | WARL | Machine Context Register |
+---------+--------------------+--------+-----------------------------------------------+
-| 0x7AA | ``scontext`` | WARL | Supervisor Context Register |
+| 0x7AA | ``mscontext`` | WARL | Machine Supervisor Context Register |
+---------+--------------------+--------+-----------------------------------------------+
| 0x7B0 | ``dcsr`` | WARL | Debug Control and Status Register |
+---------+--------------------+--------+-----------------------------------------------+
@@ -66,7 +72,7 @@ Ibex implements all the Control and Status Registers (CSRs) listed in the follow
+---------+--------------------+--------+-----------------------------------------------+
| 0x7B3 | ``dscratch1`` | RW | Debug Scratch Register 1 |
+---------+--------------------+--------+-----------------------------------------------+
-| 0x7C0 | ``cpuctrl`` | WARL | CPU Control Register (Custom CSR) |
+| 0x7C0 | ``cpuctrlsts`` | WARL | CPU Control and Status Register (Custom CSR) |
+---------+--------------------+--------+-----------------------------------------------+
| 0x7C1 | ``secureseed`` | WARL | Security feature random seed (Custom CSR) |
+---------+--------------------+--------+-----------------------------------------------+
@@ -90,6 +96,12 @@ Ibex implements all the Control and Status Registers (CSRs) listed in the follow
+---------+--------------------+--------+-----------------------------------------------+
| 0xB9F | ``mhpmcounter31h`` | WARL | Upper 32 bits of ``mhmpcounter31`` |
+---------+--------------------+--------+-----------------------------------------------+
+| 0xF11 | ``mvendorid`` | R | Machine Vendor ID |
++---------+--------------------+--------+-----------------------------------------------+
+| 0xF12 | ``marchid`` | R | Machine Architecture ID |
++---------+--------------------+--------+-----------------------------------------------+
+| 0xF13 | ``mimpid`` | R | Machine Implementation ID |
++---------+--------------------+--------+-----------------------------------------------+
| 0xF14 | ``mhartid`` | R | Hardware Thread ID |
+---------+--------------------+--------+-----------------------------------------------+
@@ -101,7 +113,7 @@ Machine Status (mstatus)
CSR Address: ``0x300``
-Reset Value: ``0x0000_1800``
+Reset Value: ``0x0000_0080``
+-------+-----+---------------------------------------------------------------------------------+
| Bit# | R/W | Description |
@@ -298,6 +310,29 @@ Reset Value: ``0x0000_0000``
| address[33:2] |
+----------------+
+Machine Security Configuration (mseccfg/mseccfgh)
+-------------------------------------------------
+
+CSR Address: ``mseccfg``: ``0x747`` ``mseccfg``: ``0x757``
+
+Reset Value: ``0x0000_0000_0000_0000``
+
++------+-----------------------------------------------------------------------------------------------------------------------------------+
+| Bit# | Definition |
++------+-----------------------------------------------------------------------------------------------------------------------------------+
+| 2 | **Rule Locking Bypass (RLB):** If set locked PMP entries can be modified |
++------+-----------------------------------------------------------------------------------------------------------------------------------+
+| 1 | **Machine Mode Whitelist Policy (MMWP):** If set default policy for PMP is deny for M-Mode accesses that don't match a PMP region |
++------+-----------------------------------------------------------------------------------------------------------------------------------+
+| 0 | **Machine Mode Lockdown (MML):** Alters behaviour of ``pmpcfgX`` bits |
++------+-----------------------------------------------------------------------------------------------------------------------------------+
+
+``mseccfg`` is specified in the Trusted Execution Environment (TEE) working group proposal `PMP Enhancements for memory access and execution prevention on Machine mode (Smepmp) version 0.9.3 `_, which gives the full details of it's functionality including the new PMP behaviour when ``mseccfg.MML`` is set.
+Note that the reset value means PMP behavior out of reset matches the RISC-V Privileged Architecture.
+A write to ``mseccfg`` is required to change it.
+Note ``mseccfgh`` reads as all 0s and ignores all writes.
+Any access to ``mseccfg`` or ``mseccfgh`` when using an Ibex configuration without PMP (``PMPEnable`` is 0) will trigger an illegal instruction exception.
+
.. _csr-tselect:
Trigger Select Register (tselect)
@@ -491,8 +526,8 @@ Reset Value: ``0x0000_0000``
Scratch register to be used by the debug module.
Accessible in Debug Mode only.
-CPU Control Register (cpuctrl)
-------------------------------
+CPU Control and Status Register (cpuctrlsts)
+--------------------------------------------
CSR Address: ``0x7C0``
@@ -505,6 +540,21 @@ Other bit fields read as zero.
+-------+------+------------------------------------------------------------------+
| Bit# | R/W | Description |
++=======+======+==================================================================+
+| 8 | R | **ic_scr_key_valid:** The icache scrambling key is valid. A |
+| | | ``fence.i`` instruction is guaranteed to fetch a new key. If |
+| | | the instruction cache has not been configured or the core has |
+| | | not been configured with security features (ICache parameter |
+| | | == 0 or SecureIbex parameter == 0), this field will always read |
+| | | as zero. (see :ref:`icache-scramble-key`) |
++-------+------+------------------------------------------------------------------+
+| 7 | RW | **double_fault_seen:** A synchronous exception was observed when |
+| | | the ``sync_exc_seen`` field was set. This field must be manually |
+| | | cleared, hardware only sets it (see :ref:`double-fault-detect`). |
++-------+------+------------------------------------------------------------------+
+| 6 | RW | **sync_exc_seen:** A synchronous exception has been observed. |
+| | | This flag is cleared when ``mret`` is executed. |
+| | | (see :ref:`double-fault-detect`). |
+-------+------+------------------------------------------------------------------+
| 5:3 | WARL | **dummy_instr_mask:** Mask to control frequency of dummy |
| | | instruction insertion. If the core has not been configured with |
@@ -549,6 +599,38 @@ The User Mode ``time(h)`` registers are not implemented in Ibex.
Any access to these registers will trap.
It is recommended that trap handler software provides a means of accessing platform-defined ``mtime(h)`` timers where available.
+Machine Vendor ID (mvendorid)
+-----------------------------
+
+CSR Address: ``0xF11``
+
+Reset Value: ``0x0000_0000``
+
+Use the ``CSR_MVENDORID_VALUE`` parameter in :file:`rtl/ibex_pkg.sv` to change the fixed value.
+Details of what the ID represents can be found in the RISC-V Privileged Specification.
+
+Machine Architecture ID (marchid)
+---------------------------------
+
+CSR Address: ``0xF12``
+
+Reset Value: ``0x0000_0016``
+
+Use the ``CSR_MARCHID_VALUE`` parameter in :file:`rtl/ibex_pkg.sv` to change the fixed value.
+The value used is allocated specifically to Ibex.
+If significant changes are made a different ID should be used.
+Details of what the ID represents can be found in the RISC-V Privileged Specification.
+
+Machine Implementation ID (mimpid)
+----------------------------------
+
+CSR Address: ``0xF13``
+
+Reset Value: ``0x0000_0000``
+
+Use the ``CSR_MIMPID_VALUE`` parameter in :file:`rtl/ibex_pkg.sv` to change the fixed value.
+Details of what the ID represents can be found in the RISC-V Privileged Specification.
+
.. _csr-mhartid:
Hardware Thread ID (mhartid)
diff --git a/doc/03_reference/debug.rst b/doc/03_reference/debug.rst
index aef413a7..6b67db42 100644
--- a/doc/03_reference/debug.rst
+++ b/doc/03_reference/debug.rst
@@ -3,7 +3,7 @@
Debug Support
=============
-Ibex offers support for execution-based debug according to the `RISC-V Debug Specification `_, version 0.13.
+Ibex offers support for execution-based debug according to the `RISC-V Debug Specification `_, version 0.13.
.. note::
@@ -32,6 +32,10 @@ Parameters
+---------------------+-----------------------------------------------------------------+
| Parameter | Description |
+=====================+=================================================================+
+| ``DmBaseAddr`` | Base address of the Debug Module |
++---------------------+-----------------------------------------------------------------+
+| ``DmAddrMask`` | Address mask of the Debug Module |
++---------------------+-----------------------------------------------------------------+
| ``DmHaltAddr`` | Address to jump to when entering Debug Mode |
+---------------------+-----------------------------------------------------------------+
| ``DmExceptionAddr`` | Address to jump to when an exception occurs while in Debug Mode |
diff --git a/doc/03_reference/exception_interrupts.rst b/doc/03_reference/exception_interrupts.rst
index 567c1499..ca8480bb 100644
--- a/doc/03_reference/exception_interrupts.rst
+++ b/doc/03_reference/exception_interrupts.rst
@@ -50,7 +50,8 @@ To enable interrupts, both the global interrupt enable (MIE) bit in the ``mstatu
For more information, see the :ref:`cs-registers` documentation.
If multiple interrupts are pending, they are handled in the priority order defined by the RISC-V Privileged Specification, version 1.11 (see Machine Interrupt Registers, Section 3.1.9).
-The highest priority is given to the interrupt with the highest ID, except for timer interrupts, which have the lowest priority.
+The fast interrupts have a platform defined priority.
+In Ibex they take priority over all other interrupts and between fast interrupts the highest priority is given to the interrupt with the lowest ID.
The NMI is enabled independent of the values in the ``mstatus`` and ``mie`` CSRs, and it is not visible through the ``mip`` CSR.
It has interrupt ID 31, i.e., it has the highest priority of all interrupts and the core jumps to the trap-handler base address (in ``mtvec``) plus 0x7C to handle the NMI.
@@ -62,6 +63,32 @@ It is assumed that the interrupt handler signals completion of the handling rout
In Debug Mode, all interrupts including the NMI are ignored independent of ``mstatus``.MIE and the content of the ``mie`` CSR.
+.. _internal-interrupts:
+
+Internal Interrupts
+-------------------
+
+Some events produce an 'internal interrupt'.
+An internal interrupt produces an NMI (using the same vector as the external NMI) with ``mcause`` and ``mtval`` being set to indicate the cause of the internal interrupt.
+The external NMI takes priority over all internal interrupts.
+Entering the handler for an internal interrupt automatically clears the internal interrupt.
+Internal interrupts are considered to be non-recoverable in general.
+Specific details of how an internal interrupt relates to the event that triggers it are listed below.
+Given these details it may be possible for software to recover from an internal interrupt under specific circumstances.
+
+The possible ``mcause`` values for an internal interrupt are listed below:
+
++-------------+-------------------------------------------------------------------------------------------------------------+
+| ``mcause`` | Description |
++-------------+-------------------------------------------------------------------------------------------------------------+
+| 0xFFFFFFE0 | Load integrity error internal interrupt. |
+| | Only generated when SecureIbex == 1. |
+| | ``mtval`` gives the faulting address. |
+| | The interrupt will be taken at most one instruction after the faulting load. |
+| | In particular a load or store immediately after a faulting load may execute before the interrupt is taken. |
++-------------+-------------------------------------------------------------------------------------------------------------+
+| 0x8000001F | External NMI |
++-------------+-------------------------------------------------------------------------------------------------------------+
Recoverable Non-Maskable Interrupt
----------------------------------
@@ -98,6 +125,9 @@ Ibex can trigger an exception due to the following exception causes:
The illegal instruction exception, instruction access fault, LSU error exceptions and ECALL instruction exceptions cannot be disabled and are always active.
+Note that Ibex cannot generated an 'instruction address misaligned' exception as all configurations implement the 'C' extension.
+Under the RISC-V architecture it is simply not possible to branch or otherwise start executing from a PC that isn't 16-bit aligned.
+So with 'C' implemented all possible PCs are appropriately aligned.
Nested Interrupt/Exception Handling
-----------------------------------
@@ -147,3 +177,19 @@ The purpose of the nonstandard ``mstack`` CSRs in Ibex is only to support recove
These CSRs are not accessible by software.
While handling an NMI, all interrupts are ignored independent of ``mstatus``.MIE.
Nested NMIs are not supported.
+
+.. _double-fault-detect:
+
+Double Fault Detection
+----------------------
+
+Ibex has a mechanism to detect when a double fault has occurred.
+A double fault is defined as a synchronous exception occurring whilst handling a previous synchronous exception.
+The ``cpuctrl`` custom CSR has fields to provide software visibility and access to this mechanism.
+
+When a synchronous exception occurs, Ibex sets ``cpuctrl``.sync_exception_seen.
+Ibex clears ``cpuctrl``.sync_exception_seen when ``mret`` is executed.
+If a synchronous exception occurs whilst ``cpuctrl``.sync_exception_seen is set, a double fault has been detected.
+
+When a double fault is detected, the ``double_fault_seen_o`` output is asserted for one cycle and ``cpuctrl``.double_fault_seen is set.
+Note that writing the ``cpuctrl``.double_fault_seen field has no effect on the ``double_fault_seen_o`` output.
diff --git a/doc/03_reference/icache.rst b/doc/03_reference/icache.rst
index c96273e3..48e23872 100644
--- a/doc/03_reference/icache.rst
+++ b/doc/03_reference/icache.rst
@@ -93,6 +93,32 @@ Indicative RAM sizes for common configurations are given in the table below:
| 4kB, 4 way, 64bit line | 4 x 128 x 22bit | 4 x 128 x 64bit |
+------------------------------+-----------------+------------------+
+ICache Scrambling
+^^^^^^^^^^^^^^^^^
+If ICacheScramble parameter is enabled, all RAM primitives are replaced with scrambling RAM primitive.
+For more information about how scrambling works internally (see :file:`vendor/lowrisc_ip/ip/prim/doc/prim_ram_1p_scr.md`).
+Interface for receiving scrambling key follows req / ack protocol.
+Ibex first requests a new ephemeral key by asserting the request (``scramble_req_o``) and when a fresh valid key is indicated by ``scramble_key_valid_i``, it deasserts the request.
+Note that in current implementation, it is assumed req/ack protocol is synchronized before arriving to Ibex top level.
+
+.. _icache-scramble-key:
+
+Scramble Key Renewal
+^^^^^^^^^^^^^^^^^^^^
+
+To get a new scrambling key execute a FENCE.I instruction.
+With a new scrambling key the existing cache contents are effectively corrupt and will be invalidated by the FENCE.I.
+Following a FENCE.I cache lookups will always miss until the invalidation is complete.
+This allows CPU fetch and execution to continue using direct memory accesses whilst the scramble key request and cache invalidation proceeds in the background.
+Should a second FENCE.I be executed before the first invalidation completes there are two possibilities
+
+1. The request for a new scramble key is still in progress.
+ As a new request cannot begin whilst one is in progress the FENCE.I is ignored.
+2. The request for a new scramble key has completed and the invalidation is in progress.
+ The invalidation stops and a new scramble key requested and the process starts over.
+
+To guarantee a new scramble key ensure the ``ic_scr_key_valid`` bit in the ``cpuctrlsts`` CSR is set before executing the FENCE.I instruction.
+
Sub Unit Description
--------------------
@@ -158,6 +184,8 @@ The remaining data from hits is buffered in the fill buffer data storage and sup
To deal with misalignment caused by compressed instructions, there is a 16bit skid buffer to store the upper halfword.
+.. _icache-ecc:
+
Cache ECC protection
^^^^^^^^^^^^^^^^^^^^
@@ -187,6 +215,7 @@ Any error (single or double bit) in any RAM will effectively cancel a cache hit
The request which observed an error will fetch it's data from the main instruction memory as normal for a cache miss.
The cache index and way (or ways) with errors are stored in IC1, and a cache write is forced the next cycle to invalidate that line.
Lookup requests will be blocked in IC0 while the invalidation write is performed.
+If an ECC error is seen a minor alert will be signaled.
Cache invalidation
^^^^^^^^^^^^^^^^^^
@@ -204,7 +233,7 @@ This isn't an attempt to describe the cache's performance characteristics.
The I$ has a single clock (``clk_i``) and asynchronous reset (``rst_ni``).
Data is requested from the instruction memory with the ports prefixed by ``instr_``. These work as described in :ref:`instruction-fetch`.
-Note that there's one extra port on the I$, which doesn't appear at the ``ibex_core`` top-level.
+Note that there's one extra port on the I$, which doesn't appear at the ``ibex_top`` top-level.
This is ``instr_pmp_err_i``.
If the PMP block disallows a fetch for a certain address, it will squash the outgoing memory request entirely and set ``instr_pmp_err_i``.
If that happens, the cache drops ``instr_req_o`` and stops making any further requests for that cache line.
diff --git a/doc/03_reference/images/blockdiagram.svg b/doc/03_reference/images/blockdiagram.svg
index 60ef6411..7827abe9 100644
--- a/doc/03_reference/images/blockdiagram.svg
+++ b/doc/03_reference/images/blockdiagram.svg
@@ -2,35 +2,23 @@
diff --git a/doc/03_reference/images/de_ex_stage.svg b/doc/03_reference/images/de_ex_stage.svg
index 5b0d1eb9..4c99ecf2 100644
--- a/doc/03_reference/images/de_ex_stage.svg
+++ b/doc/03_reference/images/de_ex_stage.svg
@@ -10,27 +10,15 @@
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="163mm"
- height="82.550011mm"
- viewBox="0 0 163 82.550011"
+ width="175.35347mm"
+ height="82.550018mm"
+ viewBox="0 0 175.35346 82.550019"
version="1.1"
id="svg8"
- inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="de_ex_stage.svg">
-
-
-
-
-
@@ -186,6 +165,1382 @@
x="29.104168"
y="195.13542" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ originx="-41.010413"
+ originy="-188.91251" />
@@ -234,895 +1589,1069 @@
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
- transform="translate(8.1359365,-201.48542)">
-
-
-
-
-
- CSR
-
- IM
- ID Stage
-
- EX Block
-
- IDEX
-
-
- Decoder
-
-
- Controller
-
-
- Reg File
-
-
- ALU
-
-
- OpA
- OpB
-
- MULTDIV
-
-
-
- RdA
- RdB
- Wr
-
- IM
-
- PC
- RF
-
- RF
- IM
-
-
-
-
-
-
-
-
-
-
-
-
- LSU
-
-
-
-
-
-
-
- Data Mem
-
-
-
-
-
-
- addr_o
- wdata_o
- rdata_i
- Ibex Core
-
-
-
-
-
-
-
-
-
-
- OpA
- OpB
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 32
-
- 32
- IM
-
-
- debug_req_i
- jump_target_ex
-
+ transform="translate(-41.010418,-25.537513)">
+
+
+
+
+ CSR
+
+ IM
+ ID Stage
+
+ EX Block
+
+ IDEX
+
+
+ Decoder
+
+
+ Controller
+
+
+ Reg File
+
+
+ ALU
+
+
+ OpA
+ OpB
+
+ MULTDIV
+
+
+
+ RdA
+ RdB
+ Wr
+
+ IM
+
+ PC
+ RF
+
+ RF
+ IM
+
+
+
+
+
+
+
+
+
+
+
+
+ LSU
+
+
+
+
+
+
+
+ Data Mem
+
+
+
+
+
+
+ addr_o
+ wdata_o
+ rdata_i
+ Ibex Core
+
+
+
+
+
+
+
+
+
+
+ OpA
+ OpB
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 32
+
+ 32
+ IM
+
+
+ debug_req_i
+ jump_target_ex
+
+ PMP
+
+
+
+
+
+
diff --git a/doc/03_reference/images/tb2.svg b/doc/03_reference/images/tb2.svg
new file mode 100644
index 00000000..1145b1c1
--- /dev/null
+++ b/doc/03_reference/images/tb2.svg
@@ -0,0 +1,994 @@
+
+
+
+
diff --git a/doc/03_reference/index.rst b/doc/03_reference/index.rst
index 6c96aaf1..1c1ebeef 100644
--- a/doc/03_reference/index.rst
+++ b/doc/03_reference/index.rst
@@ -22,5 +22,9 @@ It describes the design in detail, discusses the verification approach and the r
debug
tracer
verification
+ verification_stages
+ cosim
+ testplan
+ coverage_plan
rvfi
history
diff --git a/doc/03_reference/instruction_decode_execute.rst b/doc/03_reference/instruction_decode_execute.rst
index b79d5e43..77340803 100644
--- a/doc/03_reference/instruction_decode_execute.rst
+++ b/doc/03_reference/instruction_decode_execute.rst
@@ -56,7 +56,7 @@ Arithmetic Logic Unit (ALU)
---------------------------
Source File: :file:`rtl/ibex_alu.sv`
-The Arithmetic Logic Logic (ALU) is a purely combinational block that implements operations required for the Integer Computational Instructions and the comparison operations required for the Control Transfer Instructions in the RV32I RISC-V Specification.
+The Arithmetic Logic Unit (ALU) is a purely combinational block that implements operations required for the Integer Computational Instructions and the comparison operations required for the Control Transfer Instructions in the RV32I RISC-V Specification.
Other blocks use the ALU for the following tasks:
* Mult/Div uses it to perform addition as part of the multiplication and division algorithms
@@ -64,46 +64,45 @@ Other blocks use the ALU for the following tasks:
* It computes memory addresses for loads and stores with a Reg + Imm calculation
* The LSU uses it to increment addresses when performing two accesses to handle an unaligned access
-Bit Manipulation Extension
- Support for the `RISC-V Bit Manipulation Extension (draft version 0.92 from November 8, 2019) `_ is optional. [#B_draft]_
+Bit-Manipulation Extension
+ Support for the `RISC-V Bit-Manipulation Extension version 1.0.0 `_ and `draft version 0.93 from January 10, 2021 `_ is optional. [#B_draft]_
It can be enabled via the enumerated parameter ``RV32B`` defined in :file:`rtl/ibex_pkg.sv`.
- By default, this parameter is set to "ibex_pkg::RV32BNone" to disable the bit manipulation extension.
+ By default, this parameter is set to "ibex_pkg::RV32BNone" to disable the bit-manipulation extension.
- There are two versions of the bit manipulation extension available:
- The balanced implementation comprises a set of sub-extensions aiming for good benefits at a reasonable area overhead.
+ There are three versions of the bit-manipulation extension available:
+ The balanced version comprises a set of sub-extensions aiming for good benefits at a reasonable area overhead.
It can be selected by setting the ``RV32B`` parameter to "ibex_pkg::RV32BBalanced".
- The full implementation comprises all 32 bit instructions defined in the extension.
- This version can be selected by setting the ``RV32B`` parameter to "ibex_pkg::RV32BFull".
- The following table lists the implemented instructions in each version.
+ The OTEarlGrey version comprises all sub-extensions except for the Zbe.
+ This version can be selected by setting the ``RV32B`` parameter to "ibex_pkg::RV32BOTEarlGrey".
+ The full version comprises all sub-extensions and can be selected by setting the ``RV32B`` parameter to "ibex_pkg::RV32BFull".
+ The following table gives an overview of which sub-extensions are implemented in each version and of which instructions are implemented as multi-cycle instructions.
Multi-cycle instructions are completed in 2 cycles.
All remaining instructions complete in a single cycle.
- +---------------------------------+---------------+--------------------------+
- | Z-Extension | Version | Multi-Cycle Instructions |
- +=================================+===============+==========================+
- | Zbb (Base) | Balanced/Full | rol, ror[i] |
- +---------------------------------+---------------+--------------------------+
- | Zbs (Single-bit) | Balanced/Full | None |
- +---------------------------------+---------------+--------------------------+
- | Zbp (Permutation) | Full | None |
- +---------------------------------+---------------+--------------------------+
- | Zbe (Bit extract/deposit) | Full | All |
- +---------------------------------+---------------+--------------------------+
- | Zbf (Bit-field place) | Balanced/Full | All |
- +---------------------------------+---------------+--------------------------+
- | Zbc (Carry-less multiply) | Full | None |
- +---------------------------------+---------------+--------------------------+
- | Zbr (CRC) | Full | All |
- +---------------------------------+---------------+--------------------------+
- | Zbt (Ternary) | Balanced/Full | All |
- +---------------------------------+---------------+--------------------------+
- | Zb_tmp (Temporary) [#B_zb_tmp]_ | Balanced/Full | None |
- +---------------------------------+---------------+--------------------------+
+ +--------------------------------+---------+----------+------------+------+--------------------+
+ | Bit-Manipulation Sub-Extension | Spec. | Balanced | OTEarlGrey | Full | Multi-Cycle Instr. |
+ +================================+=========+==========+============+======+====================+
+ | Zba (Address generation) | v.1.0.0 | X | X | X | None |
+ +--------------------------------+---------+----------+------------+------+--------------------+
+ | Zbb (Base) | v.1.0.0 | X | X | X | rol, ror[i] |
+ +--------------------------------+---------+----------+------------+------+--------------------+
+ | Zbc (Carry-less multiply) | v.1.0.0 | | X | X | None |
+ +--------------------------------+---------+----------+------------+------+--------------------+
+ | Zbs (Single-bit) | v.1.0.0 | X | X | X | None |
+ +--------------------------------+---------+----------+------------+------+--------------------+
+ | Zbe (Bit compress/decompress) | v.0.93 | | | X | All |
+ +--------------------------------+---------+----------+------------+------+--------------------+
+ | Zbf (Bit-field place) | v.0.93 | X | X | X | All |
+ +--------------------------------+---------+----------+------------+------+--------------------+
+ | Zbp (Permutation) | v.0.93 | | X | X | None |
+ +--------------------------------+---------+----------+------------+------+--------------------+
+ | Zbr (CRC) | v.0.93 | | X | X | All |
+ +--------------------------------+---------+----------+------------+------+--------------------+
+ | Zbt (Ternary) | v.0.93 | X | X | X | All |
+ +--------------------------------+---------+----------+------------+------+--------------------+
- The implementation of the B-extension comes with an area overhead of 1.8 to 3.0 kGE for the balanced version and 6.0 to 8.7 kGE for the full version.
- That corresponds to an approximate percentage increase in area of 9 to 14 % and 25 to 30 % for the balanced and full versions respectively.
- The ranges correspond to synthesis results generated using relaxed and maximum frequency targets respectively.
- The designs have been synthesized using Synopsys Design Compiler targeting TSMC 65 nm technology.
+ The implementation of the Bit-Manipulation Extension comes with an area overhead of 2.7 kGE for the balanced version, 6.1 kGE for the OTEarlGrey version, and 7.5 kGE for the full version.
+ These numbers were obtained by synthesizing the design with Yosys and relaxed timing constraints.
.. _mult-div:
@@ -173,11 +172,9 @@ See :ref:`load-store-unit` for more details.
.. rubric:: Footnotes
-.. [#B_draft] Ibex fully implements draft version 0.92 of the RISC-V Bit Manipulation Extension.
- This extension may change before being ratified as a standard by the RISC-V Foundation.
+.. [#B_draft] Ibex fully implements the ratified version 1.0.0 of the RISC-V Bit-Manipulation Extension including the Zba, Zbb, Zbc and Zbs sub-extensions.
+ In addition, Ibex also supports the remaining Zbe, Zbf, Zbp, Zbr and Zbt sub-extensions as defined in draft version 0.93 of the RISC-V Bit-Manipulation Extension.
+ Note that the latter sub-extensions may change before being ratified as a standard by the RISC-V Foundation.
Ibex will be updated to match future versions of the specification.
Prior to ratification this may involve backwards incompatible changes.
Additionally, neither GCC or Clang have committed to maintaining support upstream for unratified versions of the specification.
-
-.. [#B_zb_tmp] The sign-extend instructions `sext.b/sext.h` are defined but not unambiguously categorized in draft version 0.92 of the extension.
- Temporarily, they have been assigned a separate Z-extension (Zb_tmp) both in Ibex and the RISCV-DV random instruction generator used to verify the bit manipulation instructions in Ibex.
diff --git a/doc/03_reference/instruction_fetch.rst b/doc/03_reference/instruction_fetch.rst
index c723c0d8..3faad536 100644
--- a/doc/03_reference/instruction_fetch.rst
+++ b/doc/03_reference/instruction_fetch.rst
@@ -45,26 +45,28 @@ The main difference is that the instruction interface does not allow for write t
.. tabularcolumns:: |p{4cm}|l|p{9cm}|
-+-------------------------+-----------+-----------------------------------------------+
-| Signal | Direction | Description |
-+=========================+===========+===============================================+
-| ``instr_req_o`` | output | Request valid, must stay high until |
-| | | ``instr_gnt_i`` is high for one cycle |
-+-------------------------+-----------+-----------------------------------------------+
-| ``instr_addr_o[31:0]`` | output | Address, word aligned |
-+-------------------------+-----------+-----------------------------------------------+
-| ``instr_gnt_i`` | input | The other side accepted the request. |
-| | | ``instr_req_o`` may be deasserted in the next |
-| | | cycle. |
-+-------------------------+-----------+-----------------------------------------------+
-| ``instr_rvalid_i`` | input | ``instr_rdata_i`` holds valid data when |
-| | | ``instr_rvalid_i`` is high. This signal will |
-| | | be high for exactly one cycle per request. |
-+-------------------------+-----------+-----------------------------------------------+
-| ``instr_rdata_i[31:0]`` | input | Data read from memory |
-+-------------------------+-----------+-----------------------------------------------+
-| ``instr_err_i`` | input | Memory access error |
-+-------------------------+-----------+-----------------------------------------------+
++-----------------------------+-----------+-----------------------------------------------+
+| Signal | Direction | Description |
++=============================+===========+===============================================+
+| ``instr_req_o`` | output | Request valid, must stay high until |
+| | | ``instr_gnt_i`` is high for one cycle |
++-----------------------------+-----------+-----------------------------------------------+
+| ``instr_addr_o[31:0]`` | output | Address, word aligned |
++-----------------------------+-----------+-----------------------------------------------+
+| ``instr_gnt_i`` | input | The other side accepted the request. |
+| | | ``instr_req_o`` may be deasserted in the next |
+| | | cycle. |
++-----------------------------+-----------+-----------------------------------------------+
+| ``instr_rvalid_i`` | input | ``instr_rdata_i`` holds valid data when |
+| | | ``instr_rvalid_i`` is high. This signal will |
+| | | be high for exactly one cycle per request. |
++-----------------------------+-----------+-----------------------------------------------+
+| ``instr_rdata_i[31:0]`` | input | Data read from memory |
++-----------------------------+-----------+-----------------------------------------------+
+| ``instr_rdata_intg_i[6:0]`` | input | Data integrity bits from memory |
++-----------------------------+-----------+-----------------------------------------------+
+| ``instr_err_i`` | input | Memory access error |
++-----------------------------+-----------+-----------------------------------------------+
Misaligned Accesses
diff --git a/doc/03_reference/load_store_unit.rst b/doc/03_reference/load_store_unit.rst
index 55b7737b..a26ee160 100644
--- a/doc/03_reference/load_store_unit.rst
+++ b/doc/03_reference/load_store_unit.rst
@@ -14,39 +14,60 @@ Data-Side Memory Interface
Signals that are used by the LSU:
-+-------------------------+-----------+-----------------------------------------------+
-| Signal | Direction | Description |
-+=========================+===========+===============================================+
-| ``data_req_o`` | output | Request valid, must stay high until |
-| | | ``data_gnt_i`` is high for one cycle |
-+-------------------------+-----------+-----------------------------------------------+
-| ``data_addr_o[31:0]`` | output | Address, word aligned |
-+-------------------------+-----------+-----------------------------------------------+
-| ``data_we_o`` | output | Write Enable, high for writes, low for |
-| | | reads. Sent together with ``data_req_o`` |
-+-------------------------+-----------+-----------------------------------------------+
-| ``data_be_o[3:0]`` | output | Byte Enable. Is set for the bytes to |
-| | | write/read, sent together with ``data_req_o`` |
-+-------------------------+-----------+-----------------------------------------------+
-| ``data_wdata_o[31:0]`` | output | Data to be written to memory, sent together |
-| | | with ``data_req_o`` |
-+-------------------------+-----------+-----------------------------------------------+
-| ``data_gnt_i`` | input | The other side accepted the request. |
-| | | Outputs may change in the next cycle. |
-+-------------------------+-----------+-----------------------------------------------+
-| ``data_rvalid_i`` | input | ``data_err_i`` and ``data_rdata_i`` hold |
-| | | valid data when ``data_rvalid_i`` is high. |
-| | | This signal will be high for exactly one |
-| | | cycle per request. |
-+-------------------------+-----------+-----------------------------------------------+
-| ``data_err_i`` | input | Error response from the bus or the memory: |
-| | | request cannot be handled. High in case of an |
-| | | error. |
-+-------------------------+-----------+-----------------------------------------------+
-| ``data_rdata_i[31:0]`` | input | Data read from memory |
-+-------------------------+-----------+-----------------------------------------------+
++----------------------------+-----------+-----------------------------------------------+
+| Signal | Direction | Description |
++============================+===========+===============================================+
+| ``data_req_o`` | output | Request valid, must stay high until |
+| | | ``data_gnt_i`` is high for one cycle |
++----------------------------+-----------+-----------------------------------------------+
+| ``data_addr_o[31:0]`` | output | Address, word aligned |
++----------------------------+-----------+-----------------------------------------------+
+| ``data_we_o`` | output | Write Enable, high for writes, low for |
+| | | reads. Sent together with ``data_req_o`` |
++----------------------------+-----------+-----------------------------------------------+
+| ``data_be_o[3:0]`` | output | Byte Enable. Is set for the bytes to |
+| | | write/read, sent together with ``data_req_o`` |
++----------------------------+-----------+-----------------------------------------------+
+| ``data_wdata_o[31:0]`` | output | Data to be written to memory, sent together |
+| | | with ``data_req_o`` |
++----------------------------+-----------+-----------------------------------------------+
+| ``data_wdata_intg_o[6:0]`` | output | Integrity bits to be written to memory, sent |
+| | | together with ``data_req_o`` (not used unless |
+| | | the SecureIbex parameter is set) |
++----------------------------+-----------+-----------------------------------------------+
+| ``data_gnt_i`` | input | The other side accepted the request. |
+| | | Outputs may change in the next cycle. |
++----------------------------+-----------+-----------------------------------------------+
+| ``data_rvalid_i`` | input | ``data_err_i`` and ``data_rdata_i`` hold |
+| | | valid data when ``data_rvalid_i`` is high. |
+| | | This signal will be high for exactly one |
+| | | cycle per request. |
++----------------------------+-----------+-----------------------------------------------+
+| ``data_err_i`` | input | Error response from the bus or the memory: |
+| | | request cannot be handled. High in case of an |
+| | | error. |
++----------------------------+-----------+-----------------------------------------------+
+| ``data_rdata_i[31:0]`` | input | Data read from memory |
++----------------------------+-----------+-----------------------------------------------+
+| ``data_rdata_intg_i[6:0]`` | input | Integrity bits read from memory (ignored |
+| | | unless the SecureIbex parameter is set) |
++----------------------------+-----------+-----------------------------------------------+
+Bus Integrity Checking
+----------------------
+
+The core can optionally generate and verify check bits sent alongside the data for memory accesses.
+Checkbits are generated and checked using an inverted 39/32 Hsaio code (see :file:`vendor/lowrisc_ip/ip/prim/rtl/prim_secded_inv_39_32_enc.sv`).
+An :ref:`internal interrupt` will be generated and a bus major alert signalled if there is a mismatch.
+Where load data has bad checkbits the write to the load's destination register will be suppressed.
+Ibex checks the integrity against the response data for both loads and stores.
+For stores the response data is otherwise ignored so the data can be any value provided the integrity is valid (``data_rdata_intg_i`` must match with ``data_rdata_i``).
+It is recommended for write responses some fixed value is placed on ``data_rdata_i`` and ``data_rdata_intg_i`` by the memory system Ibex is connected to in configurations where integrity is used.
+
+This feature is only used if the core is configured with the SecureIbex parameter set.
+For all other configurations, the integrity signals can be ignored.
+
Misaligned Accesses
-------------------
diff --git a/doc/03_reference/pipeline_details.rst b/doc/03_reference/pipeline_details.rst
index 26fd8d9b..e0d66343 100644
--- a/doc/03_reference/pipeline_details.rst
+++ b/doc/03_reference/pipeline_details.rst
@@ -26,7 +26,7 @@ See Multi- and Single-Cycle Instructions below for the details.
Third Pipeline Stage
--------------------
Ibex can be configured to have a third pipeline stage (Writeback) which has major effects on performance and instruction behaviour.
-This feature is *EXPERIMENTAL* and the details of its impact are not yet documented here.
+The details of its impact are not yet documented here.
All of the information presented below applies only to the two stage pipeline provided in the default configurations.
Multi- and Single-Cycle Instructions
diff --git a/doc/03_reference/pmp.rst b/doc/03_reference/pmp.rst
index fc8a246c..d4993020 100644
--- a/doc/03_reference/pmp.rst
+++ b/doc/03_reference/pmp.rst
@@ -3,7 +3,7 @@
Physical Memory Protection (PMP)
================================
-The Physical Memory Protection (PMP) unit implements region-based memory access checking in-accordance with the RISC-V Privileged Specification, version 1.11.
+The Physical Memory Protection (PMP) unit implements region-based memory access checking in-accordance with the RISC-V Privileged Specification, version 1.12 and implements the `PMP Enhancements for memory access and execution prevention on Machine mode (Smepmp) version 1.0 `_ extension.
The following configuration parameters are available to control PMP checking:
+----------------+---------------+----------------------------------------------------------+
@@ -30,3 +30,31 @@ PMP Granularity
The PMP granularity parameter is used to reduce the size of the address matching comparators by increasing the minimum region size.
When the granularity is greater than zero, NA4 mode is not available and will be treated as OFF mode.
+
+.. _pmp-enhancements:
+
+PMP Enhancements
+----------------
+
+These are described in more detail in `PMP Enhancements for memory access and execution prevention on Machine mode (Smepmp) version 1.0 `_.
+If Ibex is configured to include PMP (PMPEnable is not zero) the PMP enhancements are always included.
+Use of the enhanced behavior is optional, if no writes to ``mseccfg`` occur PMP behavior will remain exactly as if Smepmp was not implemented.
+The enhancements add:
+
+* A new CSR ``mseccfg`` providing functionality to allow locked regions to be modified and to implement default deny for M-mode accesses.
+* New PMP region configurations which are U-Mode or M-Mode accessible only with varying read/write/execute settings along with some shared U and M mode accessible configurations.
+ These new configurations supersede the original ones and are enabled via ``mseccfg``.
+
+Custom Reset Values
+-------------------
+
+By default all PMP CSRs (include ``mseccfg``) are reset to 0.
+Some applications may want other reset values.
+Default reset values are defined in :file:`ibex_pkg.sv`.
+An implementation can either modify this file or pass custom reset values as a module parameter.
+
+Debug Mode
+----------
+
+In debug mode, the PMP allows all accesses to addresses of the Debug Module, as defined by the `DmBaseAddr` and `DmAddrMask` module parameters.
+This is mandated by the RISC-V Debug Specification (v1.0.0).
diff --git a/doc/03_reference/security.rst b/doc/03_reference/security.rst
index 80bca312..52a62af5 100644
--- a/doc/03_reference/security.rst
+++ b/doc/03_reference/security.rst
@@ -9,8 +9,9 @@ All features are runtime configurable via bits in the **cpuctrl** custom CSR.
Outputs
-------
-Ibex has two alert outputs for signalling security issues.
-The major alert (**alert_major_o**) indicates a critical security issue from which the core cannot recover.
+Ibex has three alert outputs for signalling security issues.
+The internal major alert (**alert_major_internal_o**) indicates a critical security issue from which the core cannot recover which was detected internally in `ibex_top`.
+The bus major alert (**alert_major_internal_o**) indicates a critical security issue from which the core cannot recover which was detected on incoming bus data.
The minor alert (**alert_minor_o**) indicates potential security issues which can be monitored over time by a system.
Data Independent Timing
@@ -21,10 +22,20 @@ This makes it more difficult for an external observer to infer secret data by ob
In Ibex, most instructions already execute independent of their input operands.
When data-independent timing is enabled:
+
* Branches execute identically regardless of their taken/not-taken status
* Early completion of multiplication by zero/one is removed
* Early completion of divide by zero is removed
+Note that data memory operations to unaligned addresses might result in multiple bus accesses being made.
+This in turn could expose information about the address as a timing side-channel.
+It is therefore recommended to stick to aligned memory accesses when using this feature for critical code regions.
+
+When Ibex is configured to use an instruction cache, stalls on instruction fetch can see variable latency (depending on whether or not they hit in the cache).
+Software that has need of data independent timing may wish to disable the instruction cache to avoid this or to carefully analyse execution to determine if variable latency introduced by the cache causes unacceptable leakage.
+The instruction cache is controlled by the **icache_enable** bit in the **cpuctrl** register.
+Precise details of fetch timing will depend upon the memory system Ibex is connected to.
+
Dummy Instruction Insertion
---------------------------
@@ -49,18 +60,51 @@ The frequency of injected instructions can be tuned via the **dummy_instr_mask**
Other values of **dummy_instr_mask** are legal, but will have a less predictable impact.
The interval between instruction insertion is randomized in the core using an LFSR.
+The initial seed and output permutation for this LFSR can be set using parameters from the top-level of Ibex.
Sofware can periodically re-seed this LFSR with true random numbers (if available) via the **secureseed** CSR.
This will make the insertion interval of dummy instructions much harder for an attacker to predict.
Note that the dummy instruction feature inserts multiply and divide instructions.
The core must be configured with a multiplier (`RV32M != ibex_pkg::RV32MNone`) or errors will occur using this feature.
+Bus integrity checking
+----------------------
+
+Extra signals are available alongside the instruction and data side memory channels to support bus integrity checking.
+When the SecureIbex parameter is set, incoming data will be checked against the supplied checkbits.
+An :ref:`internal interrupt` will be generated and a bus major alert signalled if there is a mismatch.
+Where load data has bad checkbits the write to the load's destination register will be suppressed.
+Write data can be checked against the supplied checkbits at its destination to confirm integrity.
+
Register file ECC
-----------------
When Ibex is configured with the SecureIbex parameter, ECC checking is added to all reads of the register file.
This can be useful to detect fault injection attacks since the register file covers a reasonably large area.
-No attempt is made to correct detected errors, but an external alert is raised for the system to take action.
+No attempt is made to correct detected errors, but an internal major alert is signaled for the system to take action.
+
+Register file write enable glitch detection
+-------------------------------------------
+
+When Ibex is configured with the SecureIbex parameter, the write enable signal into the register file is checked to be one-hot.
+This can be useful to detect fault injection attacks.
+No attempt is made to correct detected errors, but an internal major alert is signaled for the system to take action.
+
+Register file read addresses glitch detection
+-------------------------------------------
+
+When Ibex is configured with the SecureIbex parameter, the read addresses provided to the register file are converted to one-hot encoded signals, and a one-hot encoded MUX is used to select the register to read from.
+By using one-hot encoding checkers, glitches in the one-hot encoded signals are detected.
+Bit-flips inside the plain read addresses before the one-hot conversion happens are detected by the dual core lockstep.
+This can be useful to detect fault injection attacks.
+No attempt is made to correct detected errors, but an internal major alert is signaled for the system to take action.
+
+ICache ECC
+----------
+
+The ICache can be configured with ECC protection.
+When an ECC error is detected a minor alert is signaled.
+See :ref:`icache-ecc` for more information.
Hardened PC
-----------
@@ -68,11 +112,22 @@ Hardened PC
This adds a check that the PC driven from the IF stage has not been modified.
A check is asserted that the current IF stage PC equals the previous PC plus the correct increment.
The check is disabled after branches and after reset.
-If a mismatch is detected, a major alert is signaled.
+If a mismatch is detected, an internal major alert is signaled.
Shadow CSRs
-----------
Certain critical CSRs (`mstatus`, `mtvec`, `cpuctrl`, `pmpcfg` and `pmpaddr`) have extra glitch detection enabled.
This creates a second copy of the register which stores a complemented version of the main CSR data.
-A constant check is made that the two copies are consistent, and a major alert is signalled if not.
+A constant check is made that the two copies are consistent, and an internal major alert is signalled if not.
+Note that this feature is not currently used when the SecureIbex parameter is set due to overlap with dual core lockstep.
+
+Dual core lockstep
+------------------
+
+This configuration option instantiates a second copy of the core logic, referred to as the shadow core.
+The shadow core executes using a delayed version of all inputs supplied to the main core.
+All outputs of the shadow core are compared against a delayed version of the outputs of the main core.
+Any mismatch between the two sets of outputs will trigger an internal major alert.
+
+Note that the register file and icache RAMs are not duplicated since these units are covered by ECC protection.
diff --git a/doc/03_reference/testplan.rst b/doc/03_reference/testplan.rst
new file mode 100644
index 00000000..88927610
--- /dev/null
+++ b/doc/03_reference/testplan.rst
@@ -0,0 +1,109 @@
+.. _testplan:
+
+.. todo::
+
+ Add detail about security hardening verification.
+
+.. note::
+
+ This testplan is a work in progress still being implemented so this document may not match the implemented verification in the repository.
+
+Test Plan
+=========
+
+Goals
+-----
+
+* Verify compliance with all the RISC-V specifications Ibex supports.
+* Verify Ibex's security hardening features.
+* Ensure correct functionality is maintained across all possible behaviours of external interfaces (interrupts, memory responses, debug requests etc).
+* Hit all functional coverage points, described in :ref:`coverage-plan`.
+
+Testbench Architecture
+----------------------
+
+.. figure:: images/tb2.svg
+ :alt: Testbench Architecture
+
+ Architecture of the UVM testbench for Ibex core
+
+Ibex utilises a co-simulation checking approach described in detail in :ref:`cosim`.
+With the co-simulation system all instructions Ibex executes and all external events such as an interrupts or memory errors are fed to a golden model.
+The results of every instruction execution and every memory access are crossed checked against the golden model with any mismatches resulting in a test failure.
+The aim is to check all possible externally observable behaviours of ``ibex_top`` against the golden model.
+The golden model used is the `Spike RISC-V ISS `_.
+
+The testbench uses UVM.
+It consists of 3 agents:
+
+Co-simulation Agent:
+ This has multiple monitors.
+ One monitors the RVFI interface which provides details of retired instructions.
+ The other monitors relate to fetched instructions and instruction memory errors; more details are provided in :ref:`coverage-plan`.
+ Additionally it connects to the monitor of the Memory Interface Agent for the instruction and data side via analysis ports.
+ The monitored transactions are used by a scoreboard to provide information to the co-simulation system allowing it to step the golden model and check its execution and memory activity against Ibex's behaviour.
+
+Memory Interface Agent
+ This provides a driver and a monitor for the :ref:`Ibex Memory Interface Protocol`.
+ The driver provides fully randomised and configurable timings for responses and randomisation of error responses.
+ Two agents are instantiated; one for the data memory interface the other for the instruction memory interface.
+ Read data for memory responses is provided from a backing memory; write requests update the contents of the backing memory.
+ This is separate from the memory used by the golden model in the co-simulation agent.
+ The contents of these two memories will be identical unless there is a mismatch resulting in a failure.
+ The backing memory is held in a memory model as a separate UVM component.
+ The two agents use the same backing memory so they have a coherent view of memory.
+
+IRQ Agent
+ This provides a driver and a monitor for the IRQ interface.
+ It provides randomised interrupt stimulus to Ibex when a test requests it.
+ Constraints can be used to control types of interrupts generated (e.g. NMI or not) and whether multiple interrupts should be raised together.
+
+Debug and reset signals are a single wire each so do not have a dedicated agent.
+Instead any sequence that wishes to use them will directly manipulate them via a virtual interface
+
+The testbench instantiates the agents described above along with the memory model used by both the data and instruction side memory agents.
+A test consists of executing a pre-built binary (which is loaded into the memory model at the start of the test via backdoor accesses) along with configuring agents to provide appropriate stimulus for the test.
+Some tests may use the agents to generate stimulus at particular times (e.g. interrupts).
+A test may perform additional checking on top of the co-simulation golden model comparison where appropriate (e.g. ensuring a raised interrupt has caused an exception).
+
+Stimulus Strategy
+-----------------
+
+Stimulus falls into two categories:
+
+* Instructions to execute: These are generated by the `RISC-V DV random instruction `_ generator and provided to the testbench via a raw binary file.
+* Activity on external interfaces.
+
+Instructions are generated ahead of time so the test has no control over them at run time.
+All external interfaces have their stimulus generated at run time so can be controlled by the test.
+It is the responsibility of the regression run environment to ensure generated instructions are matched with appropriate tests (e.g. ensuring an exception handler is present where interrupts are expected).
+
+Stimulus generation will use a coverage based approach.
+Stimulus is developed based upon the :ref:`coverage-plan`.
+Where coverage is not being hit stimulus will be added to hit it.
+
+Tests
+-----
+
+As with stimulus, test sequence development uses a coverage based approach.
+Tests will be added such that all coverage in the :ref:`coverage-plan` can be hit.
+Not all the details of specific tests will be documented here.
+The test list (`dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml `_), provides an exhaustive list of all tests along with a brief description of what the test does.
+
+A test will execute a binary whilst running zero or more sequences that provide stimulus to external interfaces of ``ibex_top``.
+As the memory interfaces are all driven by Ibex, with any testbench generated activity in response to a request from Ibex, they do not require explicit sequences run by the test.
+Instead the test can configure the randomisation of memory delays as it wishes.
+Memory errors can be configured to always occur in statically defined areas of the memory map or a sequence can be used to inject them via the memory interface agent.
+
+The following sequences are available for tests to use.
+Each sequence is derived from a base sequence which provides controls to repeat the sequence at fixed or random internals, forever or after a random number of repeats.
+Full details can be found in `dv/uvm/core_ibex/tests/core_ibex_seq_lib.sv `_.
+
+* ``irq_raise_seq`` - Raises one or more interrupts.
+ The testbench binary can write to a special memory location to acknowledge the interrupt and cause it to drop.
+ Alternatively the testbench can drop it after a given amount of time.
+* ``debug_seq`` - Raises the external debug request.
+ The testbench binary can write to a special memory location to acknowledge the request and cause it to drop.
+ Alternatively the testbench can drop it after a given amount of time.
+* ``mem_error_seq`` - Injects a memory error in either the instruction side or data side, so the next access results in an error response.
+* ``reset_seq`` - Resets the core.
diff --git a/doc/03_reference/tracer.rst b/doc/03_reference/tracer.rst
index 6a1fedab..38242063 100644
--- a/doc/03_reference/tracer.rst
+++ b/doc/03_reference/tracer.rst
@@ -4,7 +4,7 @@ Tracer
======
The module ``ibex_tracer`` can be used to create a log of the executed instructions.
-It is used by ``ibex_core_tracing`` which forwards the `RVFI signals `_ to the tracer (see also :ref:`rvfi`).
+It is used by ``ibex_top_tracing`` which forwards the `RVFI signals `_ to the tracer (see also :ref:`rvfi`).
Output file
-----------
diff --git a/doc/03_reference/verification.rst b/doc/03_reference/verification.rst
index 98c96d72..977cef0c 100644
--- a/doc/03_reference/verification.rst
+++ b/doc/03_reference/verification.rst
@@ -1,3 +1,5 @@
+.. _verification:
+
Verification
============
@@ -17,6 +19,14 @@ At a high level, this testbench uses the open source `RISCV-DV random instructio
simple memory model, stimulates the Ibex core to run this program in memory, and then compares the
core trace log against a golden model ISS trace log to check for correctness of execution.
+Verification maturity is tracked via :ref:`verification_stages` that are `defined by the OpenTitan project `_.
+
+Ibex has achieved **V2S** for the ``opentitan`` configuration, broadly this means verification almost complete (over 90% code and functional coverage hit with over 90% regression pass rate with test plan and coverage plan fully implemented) but not yet closed.
+
+Nightly regression results, including a coverage summary and details of test failures, for the ``opentitan`` Ibex configuration are published at https://ibex.reports.lowrisc.org/opentitan/latest/report.html. Below is a summary of these results:
+
+.. image:: https://ibex.reports.lowrisc.org/opentitan/latest/summary.svg
+
Testbench Architecture
^^^^^^^^^^^^^^^^^^^^^^
@@ -78,6 +88,7 @@ coverage. This includes testing all RV32IMCB instructions, privileged
spec compliance, exception and interrupt testing, Debug Mode operation etc.
The complete test list can be found in the file `dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml
`_.
+For details on coverage see the :ref:`coverage-plan`.
Please note that verification is still a work in progress.
@@ -90,18 +101,27 @@ Prerequisites & Environment Setup
In order to run the co-simulation flow, you'll need:
- A SystemVerilog simulator that supports UVM.
+
The flow is currently tested with VCS.
-- A RISC-V instruction set simulator, such as Spike_ or OVPsim_.
- Note that when building Spike the ``--enable-commitlog`` and ``--enable-misaligned`` options must be passed to the ``configure`` script.
+- The Spike RISC-V instruction set simulator
+
+ lowRISC maintains a `lowRISC-specific Spike fork `_, needed to model:
+ + Cosimulation (needed for verification)
+ + Some custom CSRs
+ + Custom NMI behavior
+
+ Ibex verification should work with the Spike version that named ``ibex_cosim``.
+
+ Spike must be built with the ``--enable-commitlog`` and ``--enable-misaligned`` options.
``--enable-commitlog`` is needed to produce log output to track the instructions that were executed.
``--enable-misaligned`` tells Spike to simulate a core that handles misaligned accesses in hardware (rather than jumping to a trap handler).
- If it is desired to simulate the core with the Icache enabled, a `lowRISC-specific branch of Spike `_ must be used.
- Ibex supports v0.92 of the Bitmanip specification.
- The ``master`` branch of Spike_ and OVPSim_ may support a different version.
- It is recommended the `lowRISC-specific branch of Spike `_ is used when using a configuration with Bitmanip to ensure the simulated version of the Bitmanip specification matches with the RTL implemented version.
+
+ Note that Ibex used to support the commercial OVPsim simulator.
+ This is not currently possible because OVPsim doesn't support the co-simulation approach that we use.
- A working RISC-V toolchain (to compile / assemble the generated programs before simulating them).
+
Either download a `pre-built toolchain `_ (quicker) or download and build the `RISC-V GNU compiler toolchain `_.
For the latter, the Bitmanip patches have to be manually installed to enable support for the Bitmanip draft extension.
For further information, checkout the `Bitmanip Extension on GitHub `_ and `how we create the pre-built toolchains `_.
@@ -115,16 +135,12 @@ to tell the RISCV-DV code where to find them:
export RISCV_GCC="$RISCV_TOOLCHAIN/bin/riscv32-unknown-elf-gcc"
export RISCV_OBJCOPY="$RISCV_TOOLCHAIN/bin/riscv32-unknown-elf-objcopy"
export SPIKE_PATH=/path/to/spike/bin
- export OVPSIM_PATH=/path/to/ovpsim/bin
+ export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/path/to/spike/lib/pkgconfig
-(Obviously, you only need to set ``SPIKE_PATH`` or ``OVPSIM_PATH`` if
-you have installed the corresponding instruction set simulator)
-
-.. _Spike: https://github.com/riscv/riscv-isa-sim
-.. _OVPsim: https://github.com/riscv/riscv-ovpsim
+.. _LRSpike: https://github.com/lowRISC/riscv-isa-sim
.. _riscv-toolchain-source: https://github.com/riscv/riscv-gnu-toolchain
.. _riscv-toolchain-releases: https://github.com/lowRISC/lowrisc-toolchains/releases
-.. _bitmanip-patches: https://github.com/lowRISC/lowrisc-toolchains#how-to-generate-the-bitmanip-patches
+.. _bitmanip-patches: https://github.com/lowRISC/lowrisc-toolchains#how-to-generate-the-bitmanip-patch
.. _bitmanip: https://github.com/riscv/riscv-bitmanip
End-to-end RTL/ISS co-simulation flow
@@ -149,11 +165,11 @@ proper interrupt handler, entered Debug Mode properly, updated any CSRs correctl
handshaking mechanism provided by the RISCV-DV instruction generator is heavily used, which
effectively allows the core to send status information to the testbench during program execution for
any analysis that is required to increase verification effectiveness.
-This mechanism is explained in detail at https://github.com/google/riscv-dv/blob/master/HANDSHAKE.md.
+This mechanism is explained in detail at https://github.com/google/riscv-dv/blob/master/docs/source/handshake.rst.
As a sidenote, the signature address that this testbench uses for the handshaking is ``0x8ffffffc``.
Additionally, as is mentioned in the RISCV-DV documentation of this handshake, a small set of API
tasks are provided in `dv/uvm/core_ibex/tests/core_ibex_base_test.sv
-`_ to enable easy
+`_ to enable easy
and efficient integration and usage of this mechanism in this test environment.
To see how this handshake is used during real simulations, look in
`dv/uvm/core_ibex/tests/core_ibex_test_lib.sv
@@ -199,15 +215,9 @@ The entirety of this flow is controlled by the Makefile found at
# Generate the assembly tests only
make gen
- # Pass addtional options to the generator
- make GEN_OPTS="xxxx" ...
-
# Compile and run RTL simulation
make TEST=xxx compile,rtl_sim
- # Use a different ISS (default is spike)
- make ... ISS=ovpsim
-
# Run a full regression with coverage
make COV=1
diff --git a/doc/03_reference/verification_stages.rst b/doc/03_reference/verification_stages.rst
new file mode 100644
index 00000000..74f4c3e3
--- /dev/null
+++ b/doc/03_reference/verification_stages.rst
@@ -0,0 +1,224 @@
+.. _verification_stages:
+
+Verification Stages
+===================
+
+Ibex is being verified as part of the `OpenTitan `_ project and follows the `verification stages used in OpenTitan `_.
+The current verification stage of the 'opentitan' configuration of Ibex is **V2S**.
+The full definition of V2S can be found at the `OpenTitan V2 `_ and `OpenTitan V2S `_ checklists.
+Other Ibex configurations do not have a formal verification stage at present.
+
+V1 Checklist
+------------
+
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Type | Item | Resolution | Notes |
++===============+====================================+============+=======================================================+
+| Documentation | DV_DOC_DRAFT_COMPLETE | Waived | Plan created, but does not conform to other templates |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Documentation | TESTPLAN_COMPLETED | Done | |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Testbench | TB_TOP_CREATED | Done | |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Testbench | PRELIMINARY_ASSERTION_CHECKS_ADDED | N/A | |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Testbench | SIM_TB_ENV_CREATED | Done | |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Testbench | SIM_RAL_MODEL_GEN_AUTOMATED | N/A | |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Testbench | CSR_CHECK_GEN_AUTOMATED | N/A | |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Testbench | TB_GEN_AUTOMATED | N/A | |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Tests | SIM_SMOKE_TEST_PASSING | Done | |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Tests | SIM_CSR_MEM_TEST_SUITE_PASSING | Done | |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Tests | FPV_MAIN_ASSERTIONS_PROVEN | N/A | |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Tool Setup | SIM_ALT_TOOL_SETUP | Waived | waived for now, doesn’t follow standard tool flow |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Regression | SIM_SMOKE_REGRESSION_SETUP | Done | |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Regression | SIM_NIGHTLY_REGRESSION_SETUP | Done | |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Regression | FPV_REGRESSION_SETUP | N/A | |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Coverage | SIM_COVERAGE_MODEL_ADDED | Done | |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Code Quality | TB_LINT_SETUP | Waived | |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Integration | PRE_VERIFIED_SUB_MODULES_V1 | N/A | |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Review | DESIGN_SPEC_REVIEWED | Done | |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Review | TESTPLAN_REVIEWED | Waived | Not done, will be reviewed in V2 |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Review | STD_TEST_CATEGORIES_PLANNED | Done | different format than comportable modules |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+| Review | V2_CHECKLIST_SCOPED | Done | |
++---------------+------------------------------------+------------+-------------------------------------------------------+
+
+V2 Checklist
+------------
+
++---------------+-------------------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Type | Item | Resolution | Notes |
++===============+=====================================+============+======================================================================================================================================================================+
+| Documentation | DESIGN_DELTAS_CAPTURED_V2 | Complete | |
++---------------+-------------------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Testbench | FUNCTIONAL_COVERAGE_IMPLEMENTED | Complete | |
++---------------+-------------------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Testbench | ALL_INTERFACES_EXERCISED | Complete | |
++---------------+-------------------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Testbench | ALL_ASSERTION_CHECKS_ADDED | Complete | |
++---------------+-------------------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Testbench | SIM_TB_ENV_COMPLETED | Complete | |
++---------------+-------------------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Tests | SIM_ALL_TESTS_PASSING | Complete | Note the ``riscv_assorted_traps_interrupts_debug`` test sees many failures (but does have some seeds that pass). |
+| | | | The test attempts to generally combine many different stimuli and under OpenTitan classification would be considered a V3 test. |
++---------------+-------------------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Tests | FPV_ALL_ASSERTIONS_WRITTEN | N/A | No formal applied for non-security features in Ibex. |
++---------------+-------------------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Tests | FPV_ALL_ASSUMPTIONS_REVIEWED | N/A | No formal applied for non-security features in Ibex. |
++---------------+-------------------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Tests | SIM_FW_SIMULATED | N/A | No ROM or firmware present. |
++---------------+-------------------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Regression | SIM_NIGHTLY_REGRESSION_V2 | Complete | Regression run in GitHub Actions only accessible to OpenTitan members. |
+| | | | Publicly viewable reports on the `OpenTitan regression dashboard `_ are planned for V3. |
++---------------+-------------------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Coverage | SIM_CODE_COVERAGE_V2 | Complete | Coverage results available in nightly regression run. |
++---------------+-------------------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Coverage | SIM_FUNCTIONAL_COVERAGE_V2 | Complete | Coverage results available in nightly regression run. |
+| | | | Note the average grade (the average of coverage % for each individual coverpoint and cross) is used for the 90% figure. |
+| | | | As the functional coverage contains some very large crosses a simple % of all bins hit biases too much toward these crosses. |
++---------------+-------------------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Coverage | FPV_CODE_COVERAGE_V2 | N/A | No formal applied for non-security features in Ibex. |
++---------------+-------------------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Coverage | FPV_COI_COVERAGE_V2 | N/A | No formal applied for non-security features in Ibex. |
++---------------+-------------------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Integration | PRE_VERIFIED_SUB_MODULES_V2 | Complete | ICache is verified in a seperate testbench. |
++---------------+-------------------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Issues | NO_HIGH_PRIORITY_ISSUES_PENDING | Complete | |
++---------------+-------------------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Issues | ALL_LOW_PRIORITY_ISSUES_ROOT_CAUSED | Complete | |
++---------------+-------------------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Review | DV_DOC_TESTPLAN_REVIEWED | Complete | |
++---------------+-------------------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Review | V3_CHECKLIST_SCOPED | Complete | |
++---------------+-------------------------------------+------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+**PMP Testing Note**: A large number of iterations of ``pmp_full_random_test`` are required to meet coverage goals and timed out tests must be included in the coverage collection.
+This is because of the large cross bins for PMP that aim to explore the full space of possible behaviour.
+The current strategy of random generation is very inefficient at exploring this space.
+It is also complex to write a randomly generated test that can deal with all possible scenarios without hitting a double faulting or time out scenarios (e.g. consider a random configuration that gives you no executable regions and ePMP modes like machine mode lockdown and machine mode whitelist policy).
+Co-simulation checking is enabled when this test is run (as it is for all block level verification tests) so would detect any incorrect behaviour.
+From investigation we are confident the time-outs seen are simply badly performing tests (e.g. very slowly working its way through an instruction block with no execute permissions by attempting to execute one instruction, faulting, trying the next and getting the same result over and over).
+For future work we will explore more efficient strategies for exploring this space as well as employing formal methods to achieve full verification closure.
+
+V2S Checklist
+-------------
+
++---------------+--------------------------+------------+--------------------------------------------------------------------------------------------------------------------------------------+
+| Type | Item | Resolution | Notes |
++===============+==========================+============+======================================================================================================================================+
+| Documentation | SEC_CM_TESTPLAN_COMPLETE | Complete | The security counter measure to test mapping can be found below |
++---------------+--------------------------+------------+--------------------------------------------------------------------------------------------------------------------------------------+
+| Tests | FPV_SEC_CM_VERIFIED | Complete | See the `OpenTitan FPV Results Dashboard `_. |
++---------------+--------------------------+------------+--------------------------------------------------------------------------------------------------------------------------------------+
+| Tests | SIM_SEC_CM_VERIFIED | Complete | |
++---------------+--------------------------+------------+--------------------------------------------------------------------------------------------------------------------------------------+
+| Coverage | SIM_COVERAGE_REVIEWED | Complete | |
++---------------+--------------------------+------------+--------------------------------------------------------------------------------------------------------------------------------------+
+| Review | SEC_CM_DV_REVIEWED | Complete | |
++---------------+--------------------------+------------+--------------------------------------------------------------------------------------------------------------------------------------+
+
+Ibex SEC_CM Test Mapping
+------------------------
+
+The :ref:`security features Ibex implements ` are given specific security countermeasure names in OpenTitan (see 'Security Countermeasures' in the `Comportability Definition and Specification `_ documentation section).
+Each countermeasure has a test that exercises it.
+The mapping between countermeasures and tests is given below
+
++--------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| Security Countermeasure | Test |
++================================+============================================================================================================================================================================================================================================================================================================+
+| BUS.INTEGRITY | ``riscv_mem_intg_error_test`` in Ibex DV. |
+| | The ``chip_sw_data_integrity`` OpenTitan top-level test will trigger integrity errors within the OpenTitan specific ``rv_core_ibex`` wrapper. |
+| | The TL-UL host adapter used in the OpenTitan specific ``rv_core_ibex`` is fully verified elsewhere in OpenTitan. |
++--------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| SCRAMBLE.KEY.SIDELOAD | ``riscv_rand_instr_test`` in Ibex DV. |
+| | This test executes ``FENCE.I`` which rotates the scramble key. |
+| | The ``rv_core_ibex_icache_invalidate_test`` OpenTitan top-level test covers assertions within the OpenTitan specific ``rv_core_ibex`` wrapper that check that a ``FENCE.I`` results in an icache scramble key request and that the returned key is correctly supplied to the scrambling memory primitives. |
++--------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| CORE.DATA_REG_SW.SCA | ``dit_test`` directed test run against simple system cosimulation. |
+| | The test runs functions that whose timing is data dependent with data independent timing disabled. |
+| | It passes where the runs with data independent timing enabled all execute in the same amount of time and the runs without it enabled take different amounts of time. |
++--------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| PC.CTRL_FLOW.CONSISTENCY | ``riscv_pc_intg_test`` in Ibex DV. |
++--------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| CTRL_FLOW.UNPREDICTABLE | ``dummy_instr_test`` directed test run against simple system cosimulation. |
+| | The test runs a function with dummy instructions disabled and enabled. |
+| | It passes where the runs without dummy instructions all have the same timing and runs with dummy instructions all have different timing. |
++--------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| DATA_REG_SW.INTEGRITY | ``riscv_rf_intg_test`` in Ibex DV. |
++--------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| DATA_REG_SW.GLITCH_DETECT | Covered by formal verification of security countermeasures within OpenTitan. |
++--------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| LOGIC.SHADOW | ``chip_sw_rv_core_ibex_lockstep_glitch`` top-level test in OpenTitan |
++--------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| FETCH.CTRL.LC_GATED | ``riscv_rand_instr_test`` in Ibex DV. |
+| | Fetch enable is randomly toggled in various tests and correct behaviour checked via an assertion. |
++--------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| EXCEPTION.CTRL_FLOW.LOCAL_ESC | ``riscv_pmp_full_random_test`` in Ibex DV. |
+| | This test produces double faults, which are checked by an assertion. |
+| | ``chip_sw_rv_core_ibex_double_fault`` top-level test in OpenTitan demonstrates escalation on a double fault |
++--------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| EXCEPTION.CTRL_FLOW.GLOBAL_ESC | ``riscv_pmp_full_random_test`` in Ibex DV. |
+| | This test produces double faults, which are checked by an assertion. |
+| | ``chip_sw_rv_core_ibex_double_fault`` top-level test in OpenTitan demonstrates escalation on a double fault |
++--------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| ICACHE.MEM.SCRAMBLE | No explicit testing, the scrambling memory primitive is seperately verified within OpenTitan. |
+| | Assertions in the OpenTitan specific ``rv_core_ibex`` wrapper ensure a newly requested scramble key is correctly applied to the scrambling memories. |
+| | The ``rv_core_ibex_icache_invalidate_test`` OpenTitan top-level test covers assertions within the OpenTitan specific ``rv_core_ibex`` wrapper that check that a ``FENCE.I`` results in an icache scramble key request and that the returned key is correctly supplied to the scrambling memory primitives. |
++--------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+| ICACHE.MEM.INTEGRITY | ``riscv_icache_intg_test`` in Ibex DV. |
++--------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+
+V3 Checklist
+------------
+
++---------------+--------------------------------+-------------+-------+
+| Type | Item | Resolution | Notes |
++===============+================================+=============+=======+
+| Documentation | DESIGN_DELTAS_CAPTURED_V3 | Not Started | |
++---------------+--------------------------------+-------------+-------+
+| Tests | X_PROP_ANALYSIS_COMPLETED | Not Started | |
++---------------+--------------------------------+-------------+-------+
+| Tests | FPV_ASSERTIONS_PROVEN_AT_V3 | Not Started | |
++---------------+--------------------------------+-------------+-------+
+| Regression | SIM_NIGHTLY_REGRESSION_AT_V3 | Not Started | |
++---------------+--------------------------------+-------------+-------+
+| Coverage | SIM_CODE_COVERAGE_AT_100 | Not Started | |
++---------------+--------------------------------+-------------+-------+
+| Coverage | SIM_FUNCTIONAL_COVERAGE_AT_100 | Not Started | |
++---------------+--------------------------------+-------------+-------+
+| Coverage | FPV_CODE_COVERAGE_AT_100 | Not Started | |
++---------------+--------------------------------+-------------+-------+
+| Coverage | FPV_COI_COVERAGE_AT_100 | Not Started | |
++---------------+--------------------------------+-------------+-------+
+| Code Quality | ALL_TODOS_RESOLVED | Not Started | |
++---------------+--------------------------------+-------------+-------+
+| Code Quality | NO_TOOL_WARNINGS_THROWN | Not Started | |
++---------------+--------------------------------+-------------+-------+
+| Code Quality | TB_LINT_COMPLETE | Not Started | |
++---------------+--------------------------------+-------------+-------+
+| Integration | PRE_VERIFIED_SUB_MODULES_V3 | Not Started | |
++---------------+--------------------------------+-------------+-------+
+| Issues | NO_ISSUES_PENDING | Not Started | |
++---------------+--------------------------------+-------------+-------+
+| Review | Reviewer(s) | Not Started | |
++---------------+--------------------------------+-------------+-------+
+| Review | Signoff date | Not Started | |
++---------------+--------------------------------+-------------+-------+
+
diff --git a/doc/04_developer/concierge.rst b/doc/04_developer/concierge.rst
index 74efc594..497c1ec8 100644
--- a/doc/04_developer/concierge.rst
+++ b/doc/04_developer/concierge.rst
@@ -25,10 +25,8 @@ The concierge duties rotate between several core developers on a weekly basis.
You can find today's concierge on duty in a `public calendar `_.
* Greg Chadwick (`@GregAC `_)
-* Tom Roberts (`@tomroberts-lowrisc `_)
* Rupert Swarbrick (`@rswarbrick `_)
* Pirmin Vogel (`@vogelpi `_)
-* Philipp Wagner (`@imphil `_)
You can be Ibex Concierge, too.
Please talk to any of the current concierges to discuss!
diff --git a/doc/_static/theme_overrides.css b/doc/_static/theme_overrides.css
index 63ee6cc7..828f0d34 100644
--- a/doc/_static/theme_overrides.css
+++ b/doc/_static/theme_overrides.css
@@ -11,3 +11,8 @@
overflow: visible !important;
}
}
+
+.wy-nav-content {
+ max-width: 1000px !important;
+}
+
diff --git a/doc/conf.py b/doc/conf.py
index 57e177d8..b4e8541a 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -12,12 +12,19 @@
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
-# import sys
-# sys.path.insert(0, os.path.abspath('.'))
+import sys
# Source top directory
topsrcdir = os.path.join(os.path.dirname(__file__), '..')
+old_sys_path = sys.path
+try:
+ sys.path.append(os.path.join(topsrcdir, 'util'))
+ import check_tool_requirements as ctr
+finally:
+ sys.path = old_sys_path
+
+
numfig=True
numfig_format = {'figure': 'Figure %s', 'table': 'Table %s', 'code-block': 'Listing %s'}
@@ -35,7 +42,9 @@ extensions = [
'sphinx.ext.todo',
]
+# Wavedrom
wavedrom_html_jsinline = False
+render_using_wavedrompy = True
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
@@ -105,11 +114,9 @@ html_logo = 'images/logo.svg'
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
-html_context = {
- 'css_files' : [
- '_static/theme_overrides.css', # Fix wide tables in RTD theme
- ],
- }
+html_css_files = [
+ 'theme_overrides.css', # Fix wide tables in RTD theme
+]
# -- Options for LaTeX output ---------------------------------------------
@@ -166,7 +173,8 @@ texinfo_documents = [
# Add minimum versions of required tools as variables for use inside the
# documentation.
-exec(open(os.path.join(topsrcdir, 'tool_requirements.py')).read())
+tool_reqs = ctr.read_tool_requirements()
rst_epilog = ""
-for tool_name, tool_version in __TOOL_REQUIREMENTS__.items():
- rst_epilog += ".. |tool_requirements.{}| replace:: {}\n".format(tool_name, tool_version)
+for tool, req in tool_reqs.items():
+ rst_epilog += (".. |tool_requirements.{}| replace:: {}\n"
+ .format(tool, req.min_version))
diff --git a/doc/requirements.txt b/doc/requirements.txt
index dc85676c..d376d330 100644
--- a/doc/requirements.txt
+++ b/doc/requirements.txt
@@ -1,5 +1,6 @@
setuptools_scm
-sphinx>=2.1.0
+sphinx>=7.0
sphinx_rtd_theme
sphinxcontrib-wavedrom
wavedrom>=1.9.0rc1
+jinja2 == 3.0.3
diff --git a/dv/cosim/cosim.core b/dv/cosim/cosim.core
new file mode 100644
index 00000000..4ff9e9a8
--- /dev/null
+++ b/dv/cosim/cosim.core
@@ -0,0 +1,19 @@
+CAPI=2:
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+name: "lowrisc:dv:cosim"
+description: "Co-simulator framework"
+filesets:
+ files_cpp:
+ files:
+ - cosim.h: { is_include_file: true }
+ - spike_cosim.cc
+ - spike_cosim.h: { is_include_file: true }
+ file_type: cppSource
+
+targets:
+ default:
+ filesets:
+ - files_cpp
diff --git a/dv/cosim/cosim.h b/dv/cosim/cosim.h
new file mode 100644
index 00000000..4a5c63c7
--- /dev/null
+++ b/dv/cosim/cosim.h
@@ -0,0 +1,166 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include
+#include
+
+#ifndef COSIM_H_
+#define COSIM_H_
+
+// Information about a dside transaction observed on the DUT memory interface
+struct DSideAccessInfo {
+ // set when the access is a store, in which case `data` is the store data from
+ // the DUT. Otherwise `data` is the load data provided to the DUT.
+ bool store;
+ // `addr` is the address and must be 32-bit aligned. `data` and `be` are
+ // aligned to the address. For example an 8-bit store of 0xff to 0x12 has
+ // `data` as 0x00ff0000, `addr` as 0x10 and `be` as 0b0100.
+ uint32_t data;
+ uint32_t addr;
+ uint32_t be;
+
+ // set if an error response to the transaction is seen.
+ bool error;
+
+ // `misaligned_first` and `misaligned_second` are set when the transaction is
+ // generated for a misaligned store or load instruction. `misaligned_first`
+ // is true when the transaction is for the lower half and `misaligned_second`
+ // is true when the transaction is for the upper half, if it exists.
+ //
+ // For example an unaligned 32-bit load to 0x3 produces a transaction with
+ // `addr` as 0x0 and `misaligned_first` set to true, then a transaction with
+ // `addr` as 0x4 and `misaligned_second` set to true. An unaligned 16-bit load
+ // to 0x01 only produces a transaction with `addr` as 0x0 and
+ // `misaligned_first` set to true, there is no second half.
+ bool misaligned_first;
+ bool misaligned_second;
+
+ bool misaligned_first_saw_error;
+
+ bool m_mode_access;
+};
+
+class Cosim {
+ public:
+ virtual ~Cosim() {}
+
+ // Add a memory to the co-simulator environment.
+ //
+ // Use `backdoor_write_mem`/`backdoor_read_mem` to access it from the
+ // simulation environment.
+ virtual void add_memory(uint32_t base_addr, size_t size) = 0;
+
+ // Write bytes to co-simulator memory.
+ //
+ // returns false if write fails (e.g. because no memory exists at the bytes
+ // being written).
+ virtual bool backdoor_write_mem(uint32_t addr, size_t len,
+ const uint8_t *data_in) = 0;
+
+ // Read bytes from co-simulator memory.
+ //
+ // returns false if read fails (e.g. because no memory exists at the bytes
+ // being read).
+ virtual bool backdoor_read_mem(uint32_t addr, size_t len,
+ uint8_t *data_out) = 0;
+
+ // Step the co-simulator, checking register write and PC of executed
+ // instruction match the supplied values. `write_reg` gives the index of the
+ // written register along with `write_reg_data` which provides the data. A
+ // `write_reg` of 0 indicates no register write occurred.
+ //
+ // `sync_trap` is set to true when the instruction caused a synchronous trap.
+ // In this case the instruction doesn't retire so no register write occurs (so
+ // `write_reg` must be 0).
+ //
+ // Returns false if there are any errors; use `get_errors` to obtain details
+ virtual bool step(uint32_t write_reg, uint32_t write_reg_data, uint32_t pc,
+ bool sync_trap, bool suppress_reg_write) = 0;
+
+ // When more than one of `set_mip`, `set_nmi` or `set_debug_req` is called
+ // before `step` which one takes effect is chosen by the co-simulator. Which
+ // should take priority is architecturally defined by the RISC-V
+ // specification.
+
+ // Set the value of MIP.
+ //
+ // Two versions of MIP must be supplied the `pre_mip` and the `post_mip`. The
+ // `pre_mip` is the value of MIP that is used to determine if an interrupt is
+ // pending. The `post_mip` is the value of MIP that the next instruction
+ // executed (which will be the first instruction of the interrupt vector when
+ // an interrupt ir triggered) observes. These will be different in the case
+ // where an interrupt is raised triggering an interrupt handler but then
+ // drops before the first instruction of the handler has executed.
+ //
+ // At the next call of `step`, the MIP values will take effect (i.e. if it's a
+ // new interrupt that is enabled it will step straight to that handler).
+ virtual void set_mip(uint32_t pre_mip, uint32_t post_mip) = 0;
+
+ // Set the state of the NMI (non-maskable interrupt) line.
+ //
+ // The NMI signal is a level triggered interrupt. When the NMI is taken the
+ // CPU ignores the NMI line until an `mret` instruction is executed. If the
+ // NMI is high following the `mret` (regardless of whether it has been low or
+ // not whilst the first NMI is being handled) a new NMI is taken.
+ //
+ // When an NMI is due to be taken that will occur at the next call of `step`.
+ virtual void set_nmi(bool nmi) = 0;
+
+ // Set the state of the internal NMI (non-maskable interrupt) line.
+ // Behaviour wise this is almost as same as external NMI case explained at
+ // set_nmi method. Difference is that this one is a response from Ibex rather
+ // than an input.
+ virtual void set_nmi_int(bool nmi_int) = 0;
+
+ // Set the debug request.
+ //
+ // When set to true the core will enter debug mode at the next step
+ virtual void set_debug_req(bool debug_req) = 0;
+
+ // Set the value of mcycle.
+ //
+ // The co-simulation model doesn't alter the value of mcycle itself (other
+ // than instructions that do a direct CSR write). mcycle should be set to the
+ // correct value before any `step` call that may execute an instruction that
+ // observes the value of mcycle.
+ //
+ // A full 64-bit value is provided setting both the mcycle and mcycleh CSRs.
+ virtual void set_mcycle(uint64_t mcycle) = 0;
+
+ // Set the value of a CSR. This is used when it is needed to have direct
+ // communication between DUT and Spike (e.g. Performance counters).
+ virtual void set_csr(const int csr_num, const uint32_t new_val) = 0;
+
+ // Set the ICache scramble key valid bit that is visible in CPUCTRLSTS.
+ virtual void set_ic_scr_key_valid(bool valid) = 0;
+
+ // Tell the co-simulation model about observed transactions on the dside
+ // memory interface of the DUT. Accesses are notified once the response to a
+ // transaction is seen.
+ //
+ // Observed transactions for the DUT are checked against accesses from the
+ // co-simulation model when a memory access occurs during a `step`. If there
+ // is a mismatch an error is reported which can be obtained via `get_errors`.
+ virtual void notify_dside_access(const DSideAccessInfo &access_info) = 0;
+
+ // Tell the co-simulation model about an error response to an iside fetch.
+ //
+ // `addr` must be 32-bit aligned.
+ //
+ // The next step following a call to `set_iside_error` must produce an
+ // instruction fault at the given address.
+ virtual void set_iside_error(uint32_t addr) = 0;
+
+ // Get a vector of strings describing errors that have occurred during `step`
+ virtual const std::vector &get_errors() = 0;
+
+ // Clear internal vector of error descriptions
+ virtual void clear_errors() = 0;
+
+ // Returns a count of instructions executed by co-simulator and DUT without
+ // failures.
+ virtual unsigned int get_insn_cnt() = 0;
+};
+
+#endif // COSIM_H_
diff --git a/dv/cosim/cosim_dpi.cc b/dv/cosim/cosim_dpi.cc
new file mode 100644
index 00000000..30a3da74
--- /dev/null
+++ b/dv/cosim/cosim_dpi.cc
@@ -0,0 +1,128 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include "cosim_dpi.h"
+
+#include
+
+#include
+
+#include "cosim.h"
+
+int riscv_cosim_step(Cosim *cosim, const svBitVecVal *write_reg,
+ const svBitVecVal *write_reg_data, const svBitVecVal *pc,
+ svBit sync_trap, svBit suppress_reg_write) {
+ assert(cosim);
+
+ return cosim->step(write_reg[0], write_reg_data[0], pc[0], sync_trap,
+ suppress_reg_write)
+ ? 1
+ : 0;
+}
+
+void riscv_cosim_set_mip(Cosim *cosim, const svBitVecVal *pre_mip,
+ const svBitVecVal *post_mip) {
+ assert(cosim);
+
+ cosim->set_mip(pre_mip[0], post_mip[0]);
+}
+
+void riscv_cosim_set_nmi(Cosim *cosim, svBit nmi) {
+ assert(cosim);
+
+ cosim->set_nmi(nmi);
+}
+
+void riscv_cosim_set_nmi_int(Cosim *cosim, svBit nmi_int) {
+ assert(cosim);
+
+ cosim->set_nmi_int(nmi_int);
+}
+void riscv_cosim_set_debug_req(Cosim *cosim, svBit debug_req) {
+ assert(cosim);
+
+ cosim->set_debug_req(debug_req);
+}
+
+void riscv_cosim_set_mcycle(Cosim *cosim, svBitVecVal *mcycle) {
+ assert(cosim);
+
+ uint64_t mcycle_full = mcycle[0] | (uint64_t)mcycle[1] << 32;
+ cosim->set_mcycle(mcycle_full);
+}
+
+void riscv_cosim_set_csr(Cosim *cosim, const int csr_id,
+ const svBitVecVal *csr_val) {
+ assert(cosim);
+
+ cosim->set_csr(csr_id, (uint32_t)csr_val[0]);
+}
+
+void riscv_cosim_set_ic_scr_key_valid(Cosim *cosim, svBit valid) {
+ assert(cosim);
+
+ cosim->set_ic_scr_key_valid(valid);
+}
+
+void riscv_cosim_notify_dside_access(Cosim *cosim, svBit store,
+ svBitVecVal *addr, svBitVecVal *data,
+ svBitVecVal *be, svBit error,
+ svBit misaligned_first,
+ svBit misaligned_second,
+ svBit misaligned_first_saw_error,
+ svBit m_mode_access) {
+ assert(cosim);
+
+ cosim->notify_dside_access(DSideAccessInfo{
+ .store = store != 0,
+ .data = data[0],
+ .addr = addr[0],
+ .be = be[0],
+ .error = error != 0,
+ .misaligned_first = misaligned_first != 0,
+ .misaligned_second = misaligned_second != 0,
+ .misaligned_first_saw_error = misaligned_first_saw_error != 0,
+ .m_mode_access = m_mode_access != 0});
+}
+
+void riscv_cosim_set_iside_error(Cosim *cosim, svBitVecVal *addr) {
+ assert(cosim);
+
+ cosim->set_iside_error(addr[0]);
+}
+
+int riscv_cosim_get_num_errors(Cosim *cosim) {
+ assert(cosim);
+
+ return cosim->get_errors().size();
+}
+
+const char *riscv_cosim_get_error(Cosim *cosim, int index) {
+ assert(cosim);
+
+ if (index >= cosim->get_errors().size()) {
+ return nullptr;
+ }
+
+ return cosim->get_errors()[index].c_str();
+}
+
+void riscv_cosim_clear_errors(Cosim *cosim) {
+ assert(cosim);
+
+ cosim->clear_errors();
+}
+
+void riscv_cosim_write_mem_byte(Cosim *cosim, const svBitVecVal *addr,
+ const svBitVecVal *d) {
+ assert(cosim);
+ uint8_t byte = d[0] & 0xff;
+ cosim->backdoor_write_mem(addr[0], 1, &byte);
+}
+
+unsigned int riscv_cosim_get_insn_cnt(Cosim *cosim) {
+ assert(cosim);
+
+ return cosim->get_insn_cnt();
+}
diff --git a/dv/cosim/cosim_dpi.core b/dv/cosim/cosim_dpi.core
new file mode 100644
index 00000000..8a5023a8
--- /dev/null
+++ b/dv/cosim/cosim_dpi.core
@@ -0,0 +1,20 @@
+CAPI=2:
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+name: "lowrisc:dv:cosim_dpi"
+description: "DPI wrapper for Co-simulator framework"
+filesets:
+ files_cpp:
+ depend:
+ - lowrisc:dv:cosim
+ files:
+ - cosim_dpi.cc: { file_type: cppSource }
+ - cosim_dpi.h: { file_type: cppSource, is_include_file: true }
+ - cosim_dpi.svh: {file_type: systemVerilogSource }
+
+targets:
+ default:
+ filesets:
+ - files_cpp
diff --git a/dv/cosim/cosim_dpi.h b/dv/cosim/cosim_dpi.h
new file mode 100644
index 00000000..bbadbc5e
--- /dev/null
+++ b/dv/cosim/cosim_dpi.h
@@ -0,0 +1,45 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef COSIM_DPI_H_
+#define COSIM_DPI_H_
+
+#include
+#include
+
+#include "cosim.h"
+
+// This adapts the C++ interface of the `Cosim` class to be used via DPI. See
+// the documentation in cosim.h for further details
+
+extern "C" {
+int riscv_cosim_step(Cosim *cosim, const svBitVecVal *write_reg,
+ const svBitVecVal *write_reg_data, const svBitVecVal *pc,
+ svBit sync_trap, svBit suppress_reg_write);
+void riscv_cosim_set_mip(Cosim *cosim, const svBitVecVal *pre_mip,
+ const svBitVecVal *post_mip);
+void riscv_cosim_set_nmi(Cosim *cosim, svBit nmi);
+void riscv_cosim_set_nmi_int(Cosim *cosim, svBit nmi_int);
+void riscv_cosim_set_debug_req(Cosim *cosim, svBit debug_req);
+void riscv_cosim_set_mcycle(Cosim *cosim, svBitVecVal *mcycle);
+void riscv_cosim_set_csr(Cosim *cosim, const int csr_id,
+ const svBitVecVal *csr_val);
+void riscv_cosim_set_ic_scr_key_valid(Cosim *cosim, svBit valid);
+void riscv_cosim_notify_dside_access(Cosim *cosim, svBit store,
+ svBitVecVal *addr, svBitVecVal *data,
+ svBitVecVal *be, svBit error,
+ svBit misaligned_first,
+ svBit misaligned_second,
+ svBit misaligned_first_saw_error,
+ svBit m_mode_access);
+void riscv_cosim_set_iside_error(Cosim *cosim, svBitVecVal *addr);
+int riscv_cosim_get_num_errors(Cosim *cosim);
+const char *riscv_cosim_get_error(Cosim *cosim, int index);
+void riscv_cosim_clear_errors(Cosim *cosim);
+void riscv_cosim_write_mem_byte(Cosim *cosim, const svBitVecVal *addr,
+ const svBitVecVal *d);
+unsigned int riscv_cosim_get_insn_cnt(Cosim *cosim);
+}
+
+#endif // COSIM_DPI_H_
diff --git a/dv/cosim/cosim_dpi.svh b/dv/cosim/cosim_dpi.svh
new file mode 100644
index 00000000..35ecd3b8
--- /dev/null
+++ b/dv/cosim/cosim_dpi.svh
@@ -0,0 +1,35 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// DPI interface to co-simulation model, see `cosim.h` for the interface description.
+
+// Implemented as a header file as VCS needs `import` declarations included in each verilog file
+// that uses them.
+
+`ifndef COSIM_DPI_SVH
+`define COSIM_DPI_SVH
+
+import "DPI-C" function int riscv_cosim_step(chandle cosim_handle, bit [4:0] write_reg,
+ bit [31:0] write_reg_data, bit [31:0] pc, bit sync_trap, bit suppress_reg_write);
+import "DPI-C" function void riscv_cosim_set_mip(chandle cosim_handle, bit [31:0] pre_mip,
+ bit [31:0] post_mip);
+import "DPI-C" function void riscv_cosim_set_nmi(chandle cosim_handle, bit nmi);
+import "DPI-C" function void riscv_cosim_set_nmi_int(chandle cosim_handle, bit nmi_int);
+import "DPI-C" function void riscv_cosim_set_debug_req(chandle cosim_handle, bit debug_req);
+import "DPI-C" function void riscv_cosim_set_mcycle(chandle cosim_handle, bit [63:0] mcycle);
+import "DPI-C" function void riscv_cosim_set_csr(chandle cosim_handle, int csr_id,
+ bit [31:0] csr_val);
+import "DPI-C" function void riscv_cosim_set_ic_scr_key_valid(chandle cosim_handle, bit valid);
+import "DPI-C" function void riscv_cosim_notify_dside_access(chandle cosim_handle, bit store,
+ bit [31:0] addr, bit [31:0] data, bit [3:0] be, bit error, bit misaligned_first,
+ bit misaligned_second, bit misaligned_first_saw_error, bit m_mode_access);
+import "DPI-C" function int riscv_cosim_set_iside_error(chandle cosim_handle, bit [31:0] addr);
+import "DPI-C" function int riscv_cosim_get_num_errors(chandle cosim_handle);
+import "DPI-C" function string riscv_cosim_get_error(chandle cosim_handle, int index);
+import "DPI-C" function void riscv_cosim_clear_errors(chandle cosim_handle);
+import "DPI-C" function void riscv_cosim_write_mem_byte(chandle cosim_handle, bit [31:0] addr,
+ bit [7:0] d);
+import "DPI-C" function int unsigned riscv_cosim_get_insn_cnt(chandle cosim_handle);
+
+`endif
diff --git a/dv/cosim/spike_cosim.cc b/dv/cosim/spike_cosim.cc
new file mode 100644
index 00000000..336d5209
--- /dev/null
+++ b/dv/cosim/spike_cosim.cc
@@ -0,0 +1,1144 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include "spike_cosim.h"
+
+#include
+#include
+#include
+
+#include "riscv/config.h"
+#include "riscv/decode.h"
+#include "riscv/devices.h"
+#include "riscv/log_file.h"
+#include "riscv/mmu.h"
+#include "riscv/processor.h"
+#include "riscv/simif.h"
+
+// For a short time, we're going to support building against version
+// ibex-cosim-v0.2 (20a886c) and also ibex-cosim-v0.3 (9af9730). Unfortunately,
+// they've got different APIs and spike doesn't expose a version string.
+//
+// However, a bit of digging around finds some defines that have been added
+// between the two versions.
+//
+// TODO: Once there's been a bit of a window to avoid a complete flag day,
+// remove this ugly hack!
+#ifndef HGATP_MODE_SV57X4
+#define OLD_SPIKE
+#endif
+
+#ifndef OLD_SPIKE
+#include "riscv/isa_parser.h"
+#endif
+
+SpikeCosim::SpikeCosim(const std::string &isa_string, uint32_t start_pc,
+ uint32_t start_mtvec, const std::string &trace_log_path,
+ bool secure_ibex, bool icache_en,
+ uint32_t pmp_num_regions, uint32_t pmp_granularity,
+ uint32_t mhpm_counter_num)
+ : nmi_mode(false), pending_iside_error(false), insn_cnt(0) {
+ FILE *log_file = nullptr;
+ if (trace_log_path.length() != 0) {
+ log = std::make_unique(trace_log_path.c_str());
+ log_file = log->get();
+ }
+
+#ifdef OLD_SPIKE
+ processor =
+ std::make_unique(isa_string.c_str(), "MU", DEFAULT_VARCH,
+ this, 0, false, log_file, std::cerr);
+#else
+
+#ifdef COSIM_SIGSEGV_WORKAROUND
+ isa_parser = new isa_parser_t(isa_string.c_str(), "MU");
+ processor = std::make_unique(isa_parser, DEFAULT_VARCH, this, 0,
+ false, log_file, std::cerr);
+#else
+ isa_parser = std::make_unique(isa_string.c_str(), "MU");
+ processor = std::make_unique(
+ isa_parser.get(), DEFAULT_VARCH, this, 0, false, log_file, std::cerr);
+#endif
+
+#endif
+
+ processor->set_pmp_num(pmp_num_regions);
+ processor->set_mhpm_counter_num(mhpm_counter_num);
+ processor->set_pmp_granularity(1 << (pmp_granularity + 2));
+ processor->set_ibex_flags(secure_ibex, icache_en);
+
+ initial_proc_setup(start_pc, start_mtvec, mhpm_counter_num);
+
+ if (log) {
+ processor->set_debug(true);
+ processor->enable_log_commits();
+ }
+}
+
+// always return nullptr so all memory accesses go via mmio_load/mmio_store
+char *SpikeCosim::addr_to_mem(reg_t addr) { return nullptr; }
+
+bool SpikeCosim::mmio_load(reg_t addr, size_t len, uint8_t *bytes) {
+ bool bus_error = !bus.load(addr, len, bytes);
+
+ bool dut_error = false;
+
+ // Incoming access may be an iside or dside access. Use PC to help determine
+ // which. PC is 64 bits in spike, we only care about the bottom 32-bit so mask
+ // off the top bits.
+ uint64_t pc = processor->get_state()->pc & 0xffffffff;
+ uint32_t aligned_addr = addr & 0xfffffffc;
+
+ if (pending_iside_error && (aligned_addr == pending_iside_err_addr)) {
+ // Check if the incoming access is subject to an iside error, in which case
+ // assume it's an iside access and produce an error.
+ pending_iside_error = false;
+ dut_error = true;
+ } else {
+ // Spike may attempt to access up to 8-bytes from the PC when fetching, so
+ // only check as a dside access when it falls outside that range
+ bool in_iside_range = (addr >= pc && addr < pc + 8);
+
+ if (!in_iside_range) {
+ dut_error = (check_mem_access(false, addr, len, bytes) != kCheckMemOk);
+ }
+ }
+
+ return !(bus_error || dut_error);
+}
+
+bool SpikeCosim::mmio_store(reg_t addr, size_t len, const uint8_t *bytes) {
+ bool bus_error = !bus.store(addr, len, bytes);
+ // If the RTL produced a bus error for the access, or the checking failed
+ // produce a memory fault in spike.
+ bool dut_error = (check_mem_access(true, addr, len, bytes) != kCheckMemOk);
+
+ return !(bus_error || dut_error);
+}
+
+void SpikeCosim::proc_reset(unsigned id) {}
+
+const char *SpikeCosim::get_symbol(uint64_t addr) { return nullptr; }
+
+void SpikeCosim::add_memory(uint32_t base_addr, size_t size) {
+ auto new_mem = std::make_unique(size);
+ bus.add_device(base_addr, new_mem.get());
+ mems.emplace_back(std::move(new_mem));
+}
+
+bool SpikeCosim::backdoor_write_mem(uint32_t addr, size_t len,
+ const uint8_t *data_in) {
+ return bus.store(addr, len, data_in);
+}
+
+bool SpikeCosim::backdoor_read_mem(uint32_t addr, size_t len,
+ uint8_t *data_out) {
+ return bus.load(addr, len, data_out);
+}
+
+// When we call processor->step(), spike advances to the next pc IFF a trap does
+// not occur. If a trap does occur, state.last_inst_pc is set to PC_INVALID, and
+// we need to call step() again to actually execute the first instruction of the
+// trap handler.
+// This sentinel value PC_INVALID of state.last_inst_pc allows the cosimulation
+// testbench to detect when spike is in this transient state, where we have
+// attempted to step but have taken a trap instead and not actually executed
+// another instruction.
+//
+// The flow of spike goes something like this...
+// - Start of processor_t::step()
+// Set state.last_inst_pc to PC_INVALID. This is only set back to a
+// non-sentinel valid pc if the processor is able to completely execute the
+// next instruction. It is set back to a valid pc at the end of
+// execute_insn().
+// - When calling execute_insn(), we try/except the fetch.func(), which
+// eventually calls one of the templated instructions in insn_template.cc.
+// These functions return the npc. From fetch.func(), we expect to catch
+// the exceptions (wait_for_interrupt_t, mem_trap_t&), which don't finish
+// executing the insn, but do result in printing to the log and re-throwing
+// the exception to be caught up one level by the step() function.
+// - In step(), while trying to execute an instruction (down either the
+// fast/slow paths), we can catch an exception (trap_t&, triggers::matched_t&,
+// wait_for_interrupt_t), which means the pc never gets advanced. The pc only
+// gets advanced right at the end of the main paths if nothing goes awry (In
+// the macro advance_pc()).
+// The state.last_inst_pc also remains with the sentinel value PC_INVALID.
+// - If we catch a trap_t&, then the take_trap() fn updates the state of the
+// processor, and when we call step() again we start executing in the new
+// context of the trap (trap andler, new MSTATUS, debug rom, etc. etc.)
+bool SpikeCosim::step(uint32_t write_reg, uint32_t write_reg_data, uint32_t pc,
+ bool sync_trap, bool suppress_reg_write) {
+ assert(write_reg < 32);
+
+ // The DUT has just produced an RVFI item
+ // (parameters of this func is the data in the RVFI item).
+
+ // First check to see if this is an ebreak that should enter debug mode. These
+ // need specific handling. When spike steps over them it'll immediately step
+ // the next instruction (i.e. the first instruction of the debug handler) too.
+ // In effect it treats it as a transition to debug mode that doesn't retire
+ // any instruction so needs to execute the next instruction to step a single
+ // time. To deal with this if it's a debug ebreak we skip the rest of this
+ // function checking a few invariants on the debug ebreak first.
+ if (pc_is_debug_ebreak(pc)) {
+ return check_debug_ebreak(write_reg, pc, sync_trap);
+ }
+
+ uint32_t initial_spike_pc;
+ uint32_t suppressed_write_reg;
+ uint32_t suppressed_write_reg_data;
+ bool pending_sync_exception = false;
+
+ if (suppress_reg_write) {
+ // If Ibex suppressed a register write (which occurs when a load gets data
+ // with bad integrity) record the state of the destination register before
+ // we do the stop, so we can restore it after the step (as spike won't
+ // suppressed the register write).
+ //
+ // First check retired instruciton to ensure load suppression is correct
+ if (!check_suppress_reg_write(write_reg, pc, suppressed_write_reg)) {
+ return false;
+ }
+
+ // The check gives us the destination register the instruction would have
+ // written to (write_reg will be 0 to indicate to write). Record the
+ // contents of that register.
+ suppressed_write_reg_data =
+ processor->get_state()->XPR[suppressed_write_reg];
+ }
+
+ // Before stepping Spike, record the current spike pc.
+ // (If the current step causes a synchronous trap, it will be
+ // recorded against the current pc)
+ initial_spike_pc = (processor->get_state()->pc & 0xffffffff);
+ processor->step(1);
+
+ // ISS
+ // - If encountered an async trap,
+ // - PC_INVALID == true
+ // - step again to execute 1st instr of handler
+ // - If encountered a sync trap,
+ // - PC_INVALID == true
+ // - current state is that of the trapping instruction
+ // - step again to execute 1st instr of handler
+ // - If encountering a sync trap, immediately upon trying to jump to a async
+ // trap handler, (the reverse is not possible, as async traps are
+ // disabled upon entering a handler)
+ // - PC_INVALID == true
+ // - current state is that of the trapping instruction
+ // DUT
+ // - If the dut encounters an async trap (which can be thought of as occuring
+ // between instructions), an rvfi_item will be generated for the the first
+ // retired instruction of the trap handler.
+ // - If the dut encounters a sync trap, an rvfi_item will be generated for the
+ // trapping instruction, with sync_trap == True. (The trapping instruction
+ // is presented on the RVFI but was not retired.)
+
+ if (processor->get_state()->last_inst_pc == PC_INVALID) {
+ if (!(processor->get_state()->mcause->read() & 0x80000000) ||
+ processor->get_state()
+ ->debug_mode) { // (Async-Traps are disabled in debug mode)
+ // Spike encountered a synchronous trap
+ pending_sync_exception = true;
+
+ } else {
+ // Spike encountered an asynchronous trap.
+
+ // Step to the first instruction of the ISR.
+ initial_spike_pc = (processor->get_state()->pc & 0xffffffff);
+ processor->step(1);
+
+ if (processor->get_state()->last_inst_pc == PC_INVALID) {
+ // If we see PC_INVALID here, the first instr of the ISR must cause an
+ // exception, as interrupts are now disabled.
+ pending_sync_exception = true;
+ }
+ }
+
+ // If spike has advanced to be at a synchronous trap, now check that it
+ // matches the reported dut behaviour.
+ if (pending_sync_exception) {
+ if (!sync_trap) {
+ std::stringstream err_str;
+ err_str << "Synchronous trap was expected at ISS PC: " << std::hex
+ << processor->get_state()->pc
+ << " but the DUT didn't report one at PC " << pc;
+ errors.emplace_back(err_str.str());
+ return false;
+ }
+
+ if (!check_sync_trap(write_reg, pc, initial_spike_pc)) {
+ return false;
+ }
+
+ handle_cpuctrl_exception_entry();
+
+ // This is all the checking possible when consider a
+ // synchronously-trapping instruction that never retired.
+ return true;
+ }
+ }
+
+ // We reached a retired instruction, so check spike and the dut behaved
+ // consistently.
+
+ if (!sync_trap && pc_is_mret(pc)) {
+ change_cpuctrlsts_sync_exc_seen(false);
+
+ if (nmi_mode) {
+ // Do handling for recoverable NMI
+ leave_nmi_mode();
+ }
+ }
+
+ if (pending_iside_error) {
+ std::stringstream err_str;
+ err_str << "DUT generated an iside error for address: " << std::hex
+ << pending_iside_err_addr << " but the ISS didn't produce one";
+ errors.emplace_back(err_str.str());
+ return false;
+ }
+ pending_iside_error = false;
+
+ if (suppress_reg_write) {
+ // If we suppressed a register write restore the old register state now
+ processor->get_state()->XPR.write(suppressed_write_reg,
+ suppressed_write_reg_data);
+ }
+
+ if (!check_retired_instr(write_reg, write_reg_data, pc, suppress_reg_write)) {
+ return false;
+ }
+
+ // Only increment insn_cnt and return true if there are no errors
+ insn_cnt++;
+ return true;
+}
+
+bool SpikeCosim::check_retired_instr(uint32_t write_reg,
+ uint32_t write_reg_data, uint32_t dut_pc,
+ bool suppress_reg_write) {
+ // Check the retired instruction and all of its side-effects match those from
+ // the DUT
+
+ // Check PC of executed instruction matches the expected PC
+ // TODO: Confirm details of why spike sign extends PC, something to do with
+ // 32-bit address as 64-bit address must be sign extended?
+ if ((processor->get_state()->last_inst_pc & 0xffffffff) != dut_pc) {
+ std::stringstream err_str;
+ err_str << "PC mismatch, DUT retired : " << std::hex << dut_pc
+ << " , but the ISS retired: " << std::hex
+ << processor->get_state()->last_inst_pc;
+ errors.emplace_back(err_str.str());
+ return false;
+ }
+
+ // Check register writes from executed instruction match what is expected
+ auto ®_changes = processor->get_state()->log_reg_write;
+
+ bool gpr_write_seen = false;
+
+ for (auto reg_change : reg_changes) {
+ // reg_change.first provides register type in bottom 4 bits, then register
+ // index above that
+
+ // Ignore writes to x0
+ if (reg_change.first == 0)
+ continue;
+
+ if ((reg_change.first & 0xf) == 0) {
+ // register is GPR
+ // should never see more than one GPR write per step
+ assert(!gpr_write_seen);
+
+ if (!suppress_reg_write &&
+ !check_gpr_write(reg_change, write_reg, write_reg_data)) {
+ return false;
+ }
+
+ gpr_write_seen = true;
+ } else if ((reg_change.first & 0xf) == 4) {
+ // register is CSR
+ on_csr_write(reg_change);
+ } else {
+ // should never see other types
+ assert(false);
+ }
+ }
+
+ if (write_reg != 0 && !gpr_write_seen) {
+ std::stringstream err_str;
+ err_str << "DUT wrote register x" << write_reg
+ << " but a write was not expected" << std::endl;
+ errors.emplace_back(err_str.str());
+ return false;
+ }
+
+ // Errors may have been generated outside of step()
+ // (e.g. in check_mem_access()).
+ if (errors.size() != 0) {
+ return false;
+ }
+
+ return true;
+}
+
+bool SpikeCosim::check_sync_trap(uint32_t write_reg, uint32_t dut_pc,
+ uint32_t initial_spike_pc) {
+ // Check if an synchronously-trapping instruction matches
+ // between Spike and the DUT.
+
+ // Check that both spike and DUT trapped on the same pc
+ if (initial_spike_pc != dut_pc) {
+ std::stringstream err_str;
+ err_str << "PC mismatch at synchronous trap, DUT at pc: " << std::hex
+ << dut_pc << "while ISS pc is at : " << std::hex
+ << initial_spike_pc;
+ errors.emplace_back(err_str.str());
+ return false;
+ }
+
+ // A sync trap should not have any side-effects, as the instruction appears on
+ // the DUT RVFI but is not actually retired.
+ if (write_reg != 0) {
+ std::stringstream err_str;
+ err_str << "Synchronous trap occurred at PC: " << std::hex << dut_pc
+ << "but DUT wrote to register: x" << std::dec << write_reg;
+ errors.emplace_back(err_str.str());
+ return false;
+ }
+
+ if ((processor->get_state()->mcause->read() == 0x5) ||
+ (processor->get_state()->mcause->read() == 0x7)) {
+ // We have a load or store access fault, apply fixup for misaligned accesses
+ misaligned_pmp_fixup();
+ }
+
+ // If we see an internal NMI, that means we receive an extra memory intf item.
+ // Deleting that is necessary since next Load/Store would fail otherwise.
+ if (processor->get_state()->mcause->read() == 0xFFFFFFE0) {
+ pending_dside_accesses.erase(pending_dside_accesses.begin());
+ }
+
+ // Errors may have been generated outside of step() (e.g. in
+ // check_mem_access()), return false if there are any.
+ if (errors.size() != 0) {
+ return false;
+ }
+
+ return true;
+}
+
+bool SpikeCosim::check_gpr_write(const commit_log_reg_t::value_type ®_change,
+ uint32_t write_reg, uint32_t write_reg_data) {
+ uint32_t cosim_write_reg = (reg_change.first >> 4) & 0x1f;
+
+ if (write_reg == 0) {
+ std::stringstream err_str;
+ err_str << "DUT didn't write to register x" << cosim_write_reg
+ << ", but a write was expected";
+ errors.emplace_back(err_str.str());
+
+ return false;
+ }
+
+ if (write_reg != cosim_write_reg) {
+ std::stringstream err_str;
+ err_str << "Register write index mismatch, DUT: x" << write_reg
+ << " expected: x" << cosim_write_reg;
+ errors.emplace_back(err_str.str());
+
+ return false;
+ }
+
+ // TODO: Investigate why this fails (may be because spike can produce PCs
+ // with high 32 bits set).
+ // assert((reg_change.second.v[0] & 0xffffffff00000000) == 0);
+ uint32_t cosim_write_reg_data = reg_change.second.v[0];
+
+ if (write_reg_data != cosim_write_reg_data) {
+ std::stringstream err_str;
+ err_str << "Register write data mismatch to x" << cosim_write_reg
+ << " DUT: " << std::hex << write_reg_data
+ << " expected: " << cosim_write_reg_data;
+ errors.emplace_back(err_str.str());
+
+ return false;
+ }
+
+ return true;
+}
+
+bool SpikeCosim::check_suppress_reg_write(uint32_t write_reg, uint32_t pc,
+ uint32_t &suppressed_write_reg) {
+ if (write_reg != 0) {
+ std::stringstream err_str;
+ err_str << "Instruction at " << std::hex << pc
+ << " indicated a suppressed register write but wrote to x"
+ << std::dec << write_reg;
+ errors.emplace_back(err_str.str());
+
+ return false;
+ }
+
+ if (!pc_is_load(pc, suppressed_write_reg)) {
+ std::stringstream err_str;
+ err_str << "Instruction at " << std::hex << pc
+ << " indicated a suppressed register write is it not a load"
+ " only loads can suppress register writes";
+ errors.emplace_back(err_str.str());
+
+ return false;
+ }
+
+ return true;
+}
+
+void SpikeCosim::on_csr_write(const commit_log_reg_t::value_type ®_change) {
+ int cosim_write_csr = (reg_change.first >> 4) & 0xfff;
+
+ // TODO: Investigate why this fails (may be because spike can produce PCs
+ // with high 32 bits set).
+ // assert((reg_change.second.v[0] & 0xffffffff00000000) == 0);
+ uint32_t cosim_write_csr_data = reg_change.second.v[0];
+
+ // Spike and Ibex have different WARL behaviours so after any CSR write
+ // check the fields and adjust to match Ibex behaviour.
+ fixup_csr(cosim_write_csr, cosim_write_csr_data);
+}
+
+void SpikeCosim::leave_nmi_mode() {
+ nmi_mode = false;
+
+ // Restore CSR status from mstack
+ uint32_t mstatus = processor->get_csr(CSR_MSTATUS);
+ mstatus = set_field(mstatus, MSTATUS_MPP, mstack.mpp);
+ mstatus = set_field(mstatus, MSTATUS_MPIE, mstack.mpie);
+#ifdef OLD_SPIKE
+ processor->set_csr(CSR_MSTATUS, mstatus);
+
+ processor->set_csr(CSR_MEPC, mstack.epc);
+ processor->set_csr(CSR_MCAUSE, mstack.cause);
+#else
+ processor->put_csr(CSR_MSTATUS, mstatus);
+
+ processor->put_csr(CSR_MEPC, mstack.epc);
+ processor->put_csr(CSR_MCAUSE, mstack.cause);
+#endif
+}
+
+void SpikeCosim::handle_cpuctrl_exception_entry() {
+ if (!processor->get_state()->debug_mode) {
+ bool old_sync_exc_seen = change_cpuctrlsts_sync_exc_seen(true);
+ if (old_sync_exc_seen) {
+ set_cpuctrlsts_double_fault_seen();
+ }
+ }
+}
+
+bool SpikeCosim::change_cpuctrlsts_sync_exc_seen(bool flag) {
+ bool old_flag = false;
+ uint32_t cpuctrlsts = processor->get_csr(CSR_CPUCTRLSTS);
+
+ // If sync_exc_seen (bit 6) is already set update old_flag to match
+ if (cpuctrlsts & 0x40) {
+ old_flag = true;
+ }
+
+ cpuctrlsts = (cpuctrlsts & 0x1bf) | (flag ? 0x40 : 0);
+ processor->put_csr(CSR_CPUCTRLSTS, cpuctrlsts);
+
+ return old_flag;
+}
+
+void SpikeCosim::set_cpuctrlsts_double_fault_seen() {
+ uint32_t cpuctrlsts = processor->get_csr(CSR_CPUCTRLSTS);
+ // Set double_fault_seen (bit 7)
+ cpuctrlsts = (cpuctrlsts & 0x17f) | 0x80;
+ processor->put_csr(CSR_CPUCTRLSTS, cpuctrlsts);
+}
+
+void SpikeCosim::initial_proc_setup(uint32_t start_pc, uint32_t start_mtvec,
+ uint32_t mhpm_counter_num) {
+ processor->get_state()->pc = start_pc;
+ processor->get_state()->mtvec->write(start_mtvec);
+
+ processor->get_state()->csrmap[CSR_MARCHID] =
+ std::make_shared(processor.get(), CSR_MARCHID, IBEX_MARCHID);
+
+ processor->set_mmu_capability(IMPL_MMU_SBARE);
+
+ for (int i = 0; i < processor->TM.count(); ++i) {
+ processor->TM.tdata2_write(processor.get(), i, 0);
+ processor->TM.tdata1_write(processor.get(), i, 0x28001048);
+ }
+
+ for (int i = 0; i < mhpm_counter_num; i++) {
+ processor->get_state()->csrmap[CSR_MHPMEVENT3 + i] =
+ std::make_shared(processor.get(), CSR_MHPMEVENT3 + i,
+ 1 << i);
+ }
+}
+
+void SpikeCosim::set_mip(uint32_t pre_mip, uint32_t post_mip) {
+ uint32_t new_mip = pre_mip;
+ uint32_t old_mip = processor->get_state()->mip->read();
+
+ processor->get_state()->mip->write_with_mask(0xffffffff, post_mip);
+ processor->get_state()->mip->write_pre_val(pre_mip);
+
+ if (processor->get_state()->debug_mode ||
+ (processor->halt_request == processor_t::HR_REGULAR) ||
+ (!get_field(processor->get_csr(CSR_MSTATUS), MSTATUS_MIE) &&
+ processor->get_state()->prv == PRV_M)) {
+ // Return now if new MIP won't trigger an interrupt handler either because
+ // we're in or heading to debug mode or interrupts are disabled.
+ return;
+ }
+
+ uint32_t old_enabled_irq = old_mip & processor->get_state()->mie->read();
+ uint32_t new_enabled_irq = new_mip & processor->get_state()->mie->read();
+
+ // Check to see if new MIP will trigger an interrupt (which occurs when new
+ // MIP produces an enabled interrupt for the first time).
+ if ((old_enabled_irq == 0) && (new_enabled_irq != 0)) {
+ // Early interrupt handle if the interrupt is triggered.
+ early_interrupt_handle();
+ }
+}
+
+void SpikeCosim::early_interrupt_handle() {
+ // Execute a spike step on the assumption an interrupt will occur so no new
+ // instruction is executed just the state altered to reflect the interrupt.
+ uint32_t initial_spike_pc = (processor->get_state()->pc & 0xffffffff);
+ processor->step(1);
+
+ if (processor->get_state()->last_inst_pc != PC_INVALID) {
+ std::stringstream err_str;
+ err_str << "Attempted step for interrupt, expecting no instruction would "
+ << "be executed but saw one. PC before: " << std::hex
+ << initial_spike_pc
+ << " PC after: " << (processor->get_state()->pc & 0xffffffff);
+ errors.emplace_back(err_str.str());
+ }
+}
+
+// Ibex splits misaligned accesses into two separate requests. They
+// independently undergo PMP access checks. It is possible for one to fail (so
+// no request produced for that half of the access) whilst the other successed
+// (producing a request for that half of the access).
+//
+// Spike splits misaligned accesses up into bytes and will apply PMP access
+// checks byte by byte in a linear order. As soon as a byte sees a PMP
+// permission failure the rest of the misaligned access is aborted.
+//
+// This results in mismatches as in some misaligned access cases Ibex will
+// produce a request and spike will not.
+//
+// This fixup detects this condition and removes the Ibex access from
+// pending_dside_accesses to avoid a mismatch. This removed access is checked
+// against PMP using the spike MMU to check spike agrees it passes PMP checks.
+//
+// There may be a better way to handle this (e.g. altering spike behaviour to
+// match Ibex) so for now a warning is generated in fixup cases so they can be
+// easily identified.
+void SpikeCosim::misaligned_pmp_fixup() {
+ if (pending_dside_accesses.size() != 0) {
+ auto &top_pending_access = pending_dside_accesses.front();
+ auto &top_pending_access_info = top_pending_access.dut_access_info;
+
+ // If top access is the second half of a misaligned access where the first
+ // half saw an error we have the PMP fixup case
+ if (top_pending_access_info.misaligned_second &&
+ top_pending_access_info.misaligned_first_saw_error) {
+ mmu_t *mmu = processor->get_mmu();
+
+ // Check if the second half of the access (which Ibex produces a request
+ // for and spike does not) passes PMP
+ if (!mmu->pmp_ok(top_pending_access_info.addr, 4,
+ top_pending_access_info.store ? STORE : LOAD,
+ top_pending_access_info.m_mode_access ? PRV_M : PRV_U)) {
+ // Raise an error if the second half shouldn't have passed PMP
+ std::stringstream err_str;
+ err_str << "Saw second half of a misaligned access which not have "
+ << "generated a memory request as it does not pass a PMP check,"
+ << " address: " << std::hex << top_pending_access_info.addr;
+ errors.emplace_back(err_str.str());
+ } else {
+ // Output warning on stdout so we're aware which tests this is happening
+ // in
+ std::cout << "WARNING: Cosim dropping second half of misaligned access "
+ << "as first half saw an error and second half passed PMP "
+ << "check, address: " << std::hex
+ << top_pending_access_info.addr << std::endl;
+ std::cout << std::dec;
+
+ pending_dside_accesses.erase(pending_dside_accesses.begin());
+ }
+ }
+ }
+}
+
+void SpikeCosim::set_nmi(bool nmi) {
+ if (nmi && !nmi_mode && !processor->get_state()->debug_mode &&
+ processor->halt_request != processor_t::HR_REGULAR) {
+ processor->get_state()->nmi = true;
+ nmi_mode = true;
+
+ // When NMI is set it is guaranteed NMI trap will be taken at the next step
+ // so save CSR state for recoverable NMI to mstack now.
+ mstack.mpp = get_field(processor->get_csr(CSR_MSTATUS), MSTATUS_MPP);
+ mstack.mpie = get_field(processor->get_csr(CSR_MSTATUS), MSTATUS_MPIE);
+ mstack.epc = processor->get_csr(CSR_MEPC);
+ mstack.cause = processor->get_csr(CSR_MCAUSE);
+
+ early_interrupt_handle();
+ }
+}
+
+void SpikeCosim::set_nmi_int(bool nmi_int) {
+ if (nmi_int && !nmi_mode && !processor->get_state()->debug_mode &&
+ processor->halt_request != processor_t::HR_REGULAR) {
+ processor->get_state()->nmi_int = true;
+ nmi_mode = true;
+
+ // When NMI is set it is guaranteed NMI trap will be taken at the next step
+ // so save CSR state for recoverable NMI to mstack now.
+ mstack.mpp = get_field(processor->get_csr(CSR_MSTATUS), MSTATUS_MPP);
+ mstack.mpie = get_field(processor->get_csr(CSR_MSTATUS), MSTATUS_MPIE);
+ mstack.epc = processor->get_csr(CSR_MEPC);
+ mstack.cause = processor->get_csr(CSR_MCAUSE);
+
+ early_interrupt_handle();
+ }
+}
+
+void SpikeCosim::set_debug_req(bool debug_req) {
+ processor->halt_request =
+ debug_req ? processor_t::HR_REGULAR : processor_t::HR_NONE;
+}
+
+void SpikeCosim::set_mcycle(uint64_t mcycle) {
+ uint32_t upper_mcycle = mcycle >> 32;
+ uint32_t lower_mcycle = mcycle & 0xffffffff;
+
+ // Spike decrements the MCYCLE CSR when you write to it to hack around an
+ // issue it has with incorrectly setting minstret/mcycle when there's an
+ // explicit write to them. There's no backdoor write available via the public
+ // interface to skip this. To complicate matters we can only write 32 bits at
+ // a time and get a decrement each time.
+
+ // Write the lower half first, incremented twice due to the double decrement
+ processor->get_state()->csrmap[CSR_MCYCLE]->write(lower_mcycle + 2);
+
+ if ((processor->get_state()->csrmap[CSR_MCYCLE]->read() & 0xffffffff) == 0) {
+ // If the lower half is 0 at this point then the upper half will get
+ // decremented, so increment it first.
+ upper_mcycle++;
+ }
+
+ // Set the upper half
+ processor->get_state()->csrmap[CSR_MCYCLEH]->write(upper_mcycle);
+
+ // TODO: Do a neater job of this, a more recent spike release should allow us
+ // to write all 64 bits at once at least.
+}
+
+void SpikeCosim::set_csr(const int csr_num, const uint32_t new_val) {
+ // Note that this is tested with ibex-cosim-v0.3 version of Spike. 'set_csr'
+ // method might have a hardwired zero for mhpmcounterX registers.
+#ifdef OLD_SPIKE
+ processor->set_csr(csr_num, new_val);
+#else
+ processor->put_csr(csr_num, new_val);
+#endif
+}
+
+void SpikeCosim::set_ic_scr_key_valid(bool valid) {
+ processor->set_ic_scr_key_valid(valid);
+}
+
+void SpikeCosim::notify_dside_access(const DSideAccessInfo &access_info) {
+ // Address must be 32-bit aligned
+ assert((access_info.addr & 0x3) == 0);
+
+ pending_dside_accesses.emplace_back(
+ PendingMemAccess{.dut_access_info = access_info, .be_spike = 0});
+}
+
+void SpikeCosim::set_iside_error(uint32_t addr) {
+ // Address must be 32-bit aligned
+ assert((addr & 0x3) == 0);
+
+ pending_iside_error = true;
+ pending_iside_err_addr = addr;
+}
+
+const std::vector &SpikeCosim::get_errors() { return errors; }
+
+void SpikeCosim::clear_errors() { errors.clear(); }
+
+void SpikeCosim::fixup_csr(int csr_num, uint32_t csr_val) {
+ switch (csr_num) {
+ case CSR_MSTATUS: {
+ reg_t mask =
+ MSTATUS_MIE | MSTATUS_MPIE | MSTATUS_MPRV | MSTATUS_MPP | MSTATUS_TW;
+
+ reg_t new_val = csr_val & mask;
+#ifdef OLD_SPIKE
+ processor->set_csr(csr_num, new_val);
+#else
+ processor->put_csr(csr_num, new_val);
+#endif
+ break;
+ }
+ case CSR_MCAUSE: {
+ uint32_t any_interrupt = csr_val & 0x80000000;
+ uint32_t int_interrupt = csr_val & 0x40000000;
+
+ reg_t new_val = (csr_val & 0x0000001f) | any_interrupt;
+
+ if (any_interrupt && int_interrupt) {
+ new_val |= 0x7fffffe0;
+ }
+#ifdef OLD_SPIKE
+ processor->set_csr(csr_num, new_val);
+#else
+ processor->put_csr(csr_num, new_val);
+#endif
+ break;
+ }
+ case CSR_MTVEC: {
+ uint32_t mtvec_and_mask = 0xffffff00;
+ uint32_t mtvec_or_mask = 0x1;
+
+ // For Ibex, mtvec.MODE is set to vectored and
+ // mtvec.BASE must be 256-byte aligned
+ reg_t new_val = (csr_val & mtvec_and_mask) | mtvec_or_mask;
+#ifdef OLD_SPIKE
+ processor->set_csr(csr_num, new_val);
+#else
+ processor->put_csr(csr_num, new_val);
+#endif
+ break;
+ }
+ case CSR_MISA: {
+ // For Ibex, misa is hardwired
+ reg_t new_val = 0x40901104;
+#ifdef OLD_SPIKE
+ processor->set_csr(csr_num, new_val);
+#else
+ processor->put_csr(csr_num, new_val);
+#endif
+ break;
+ }
+ }
+}
+
+SpikeCosim::check_mem_result_e SpikeCosim::check_mem_access(
+ bool store, uint32_t addr, size_t len, const uint8_t *bytes) {
+ assert(len >= 1 && len <= 4);
+ // Expect that no spike memory accesses cross a 32-bit boundary
+ assert(((addr + (len - 1)) & 0xfffffffc) == (addr & 0xfffffffc));
+
+ std::string iss_action = store ? "store" : "load";
+
+ // Check if there are any pending DUT accesses to check against
+ if (pending_dside_accesses.size() == 0) {
+ std::stringstream err_str;
+ err_str << "A " << iss_action << " at address " << std::hex << addr
+ << " was expected but there are no pending accesses";
+ errors.emplace_back(err_str.str());
+
+ return kCheckMemCheckFailed;
+ }
+
+ auto &top_pending_access = pending_dside_accesses.front();
+ auto &top_pending_access_info = top_pending_access.dut_access_info;
+
+ std::string dut_action = top_pending_access_info.store ? "store" : "load";
+
+ // Check for an address match
+ uint32_t aligned_addr = addr & 0xfffffffc;
+ if (aligned_addr != top_pending_access_info.addr) {
+ std::stringstream err_str;
+ err_str << "DUT generated " << dut_action << " at address " << std::hex
+ << top_pending_access_info.addr << " but " << iss_action
+ << " at address " << aligned_addr << " was expected";
+ errors.emplace_back(err_str.str());
+
+ return kCheckMemCheckFailed;
+ }
+
+ // Check access type match
+ if (store != top_pending_access_info.store) {
+ std::stringstream err_str;
+ err_str << "DUT generated " << dut_action << " at addr " << std::hex
+ << top_pending_access_info.addr << " but a " << iss_action
+ << " was expected";
+ errors.emplace_back(err_str.str());
+
+ return kCheckMemCheckFailed;
+ }
+
+ // Calculate bytes within aligned 32-bit word that spike has accessed
+ uint32_t expected_be = ((1 << len) - 1) << (addr & 0x3);
+
+ bool pending_access_done = false;
+ bool misaligned = top_pending_access_info.misaligned_first ||
+ top_pending_access_info.misaligned_second;
+
+ if (misaligned) {
+ // For misaligned accesses spike will generated multiple single byte
+ // accesses where the DUT will generate an access covering all bytes within
+ // an aligned 32-bit word.
+
+ // Check bytes accessed this time haven't already been been seen for the DUT
+ // access we are trying to match against
+ if ((expected_be & top_pending_access.be_spike) != 0) {
+ std::stringstream err_str;
+ err_str << "DUT generated " << dut_action << " at address " << std::hex
+ << top_pending_access_info.addr << " with BE "
+ << top_pending_access_info.be << " and expected BE "
+ << expected_be << " has been seen twice, so far seen "
+ << top_pending_access.be_spike;
+
+ errors.emplace_back(err_str.str());
+
+ return kCheckMemCheckFailed;
+ }
+
+ // Check expected access isn't trying to access bytes that the DUT access
+ // didn't access.
+ if ((expected_be & ~top_pending_access_info.be) != 0) {
+ std::stringstream err_str;
+ err_str << "DUT generated " << dut_action << " at address " << std::hex
+ << top_pending_access_info.addr << " with BE "
+ << top_pending_access_info.be << " but expected BE "
+ << expected_be << " has other bytes enabled";
+ errors.emplace_back(err_str.str());
+ return kCheckMemCheckFailed;
+ }
+
+ // Record which bytes have been seen from spike
+ top_pending_access.be_spike |= expected_be;
+
+ // If all bytes have been seen from spike we're done with this DUT access
+ if (top_pending_access.be_spike == top_pending_access_info.be) {
+ pending_access_done = true;
+ }
+ } else {
+ // For aligned accesses bytes from spike access must precisely match bytes
+ // from DUT access in one go
+ if (expected_be != top_pending_access_info.be) {
+ std::stringstream err_str;
+ err_str << "DUT generated " << dut_action << " at address " << std::hex
+ << top_pending_access_info.addr << " with BE "
+ << top_pending_access_info.be << " but BE " << expected_be
+ << " was expected";
+ errors.emplace_back(err_str.str());
+
+ return kCheckMemCheckFailed;
+ }
+
+ pending_access_done = true;
+ }
+
+ // Check data from expected access matches pending DUT access.
+ // Data is ignored on error responses to loads so don't check it. Always check
+ // store data.
+ if (store || !top_pending_access_info.error) {
+ // Combine bytes into a single word
+ uint32_t expected_data = 0;
+ for (int i = 0; i < len; ++i) {
+ expected_data |= bytes[i] << (i * 8);
+ }
+
+ // Shift bytes into their position within an aligned 32-bit word
+ expected_data <<= (addr & 0x3) * 8;
+
+ // Mask off bytes expected access doesn't touch and check bytes match for
+ // those that it does
+ uint32_t expected_be_bits = (((uint64_t)1 << (len * 8)) - 1)
+ << ((addr & 0x3) * 8);
+ uint32_t masked_dut_data = top_pending_access_info.data & expected_be_bits;
+
+ if (expected_data != masked_dut_data) {
+ std::stringstream err_str;
+ err_str << "DUT generated " << iss_action << " at address " << std::hex
+ << top_pending_access_info.addr << " with data "
+ << masked_dut_data << " but data " << expected_data
+ << " was expected with byte mask " << expected_be;
+
+ errors.emplace_back(err_str.str());
+
+ return kCheckMemCheckFailed;
+ }
+ }
+
+ bool pending_access_error = top_pending_access_info.error;
+
+ if (pending_access_error && misaligned) {
+ // When misaligned accesses see an error, if they have crossed a 32-bit
+ // boundary DUT will generate two accesses. If the top pending access from
+ // the DUT was the first half of a misaligned access which accesses the top
+ // byte, it must have crossed the 32-bit boundary and generated a second
+ // access
+ if (top_pending_access_info.misaligned_first &&
+ ((top_pending_access_info.be & 0x8) != 0)) {
+ // Check the second access DUT exists
+ if ((pending_dside_accesses.size() < 2) ||
+ !pending_dside_accesses[1].dut_access_info.misaligned_second) {
+ std::stringstream err_str;
+ err_str << "DUT generated first half of misaligned " << iss_action
+ << " at address " << std::hex << top_pending_access_info.addr
+ << " but second half was expected and not seen";
+
+ errors.emplace_back(err_str.str());
+
+ return kCheckMemCheckFailed;
+ }
+
+ // Check the second access had the expected address
+ if (pending_dside_accesses[1].dut_access_info.addr !=
+ (top_pending_access_info.addr + 4)) {
+ std::stringstream err_str;
+ err_str << "DUT generated first half of misaligned " << iss_action
+ << " at address " << std::hex << top_pending_access_info.addr
+ << " but second half had incorrect address "
+ << pending_dside_accesses[1].dut_access_info.addr;
+
+ errors.emplace_back(err_str.str());
+
+ return kCheckMemCheckFailed;
+ }
+
+ // TODO: How to check BE? May need length of transaction?
+
+ // Remove the top pending access now so both the first and second DUT
+ // accesses for this misaligned access are removed.
+ pending_dside_accesses.erase(pending_dside_accesses.begin());
+ }
+
+ // For any misaligned access that sees an error immediately indicate to
+ // spike the error has occured, so ensure the top pending access gets
+ // removed.
+ pending_access_done = true;
+ }
+
+ if (pending_access_done) {
+ pending_dside_accesses.erase(pending_dside_accesses.begin());
+ }
+
+ return pending_access_error ? kCheckMemBusError : kCheckMemOk;
+}
+
+bool SpikeCosim::pc_is_mret(uint32_t pc) {
+ uint32_t insn;
+
+ if (!backdoor_read_mem(pc, 4, reinterpret_cast(&insn))) {
+ return false;
+ }
+
+ return insn == 0x30200073;
+}
+
+bool SpikeCosim::pc_is_debug_ebreak(uint32_t pc) {
+ uint32_t dcsr = processor->get_csr(CSR_DCSR);
+
+ // ebreak debug entry is controlled by the ebreakm (bit 15) and ebreaku (bit
+ // 12) fields of DCSR. If the appropriate bit of the current privlege level
+ // isn't set ebreak won't enter debug so return false.
+ if ((processor->get_state()->prv == PRV_M) && ((dcsr & 0x1000) == 0) ||
+ (processor->get_state()->prv == PRV_U) && ((dcsr & 0x8000) == 0)) {
+ return false;
+ }
+
+ // First check for 16-bit c.ebreak
+ uint16_t insn_16;
+ if (!backdoor_read_mem(pc, 2, reinterpret_cast(&insn_16))) {
+ return false;
+ }
+
+ if (insn_16 == 0x9002) {
+ return true;
+ }
+
+ // Not a c.ebreak, check for 32 bit ebreak
+ uint32_t insn_32;
+ if (!backdoor_read_mem(pc, 4, reinterpret_cast(&insn_32))) {
+ return false;
+ }
+
+ return insn_32 == 0x00100073;
+}
+
+bool SpikeCosim::check_debug_ebreak(uint32_t write_reg, uint32_t pc,
+ bool sync_trap) {
+ // A ebreak from the DUT should not write a register and will be reported as a
+ // 'sync_trap' (though doesn't act like a trap in various respects).
+
+ if (write_reg != 0) {
+ std::stringstream err_str;
+ err_str << "DUT executed ebreak at " << std::hex << pc
+ << " but also wrote register x" << std::dec << write_reg
+ << " which was unexpected";
+ errors.emplace_back(err_str.str());
+
+ return false;
+ }
+
+ if (sync_trap) {
+ std::stringstream err_str;
+ err_str << "DUT executed ebreak into debug at " << std::hex << pc
+ << " but indicated a synchronous trap, which was unexpected";
+ errors.emplace_back(err_str.str());
+
+ return false;
+ }
+
+ return true;
+}
+
+bool SpikeCosim::pc_is_load(uint32_t pc, uint32_t &rd_out) {
+ uint16_t insn_16;
+
+ if (!backdoor_read_mem(pc, 2, reinterpret_cast(&insn_16))) {
+ return false;
+ }
+
+ // C.LW
+ if ((insn_16 & 0xE003) == 0x4000) {
+ rd_out = ((insn_16 >> 2) & 0x7) + 8;
+ return true;
+ }
+
+ // C.LWSP
+ if ((insn_16 & 0xE003) == 0x4002) {
+ rd_out = (insn_16 >> 7) & 0x1F;
+ return rd_out != 0;
+ }
+
+ uint16_t insn_32;
+
+ if (!backdoor_read_mem(pc, 4, reinterpret_cast(&insn_32))) {
+ return false;
+ }
+
+ // LB/LH/LW/LBU/LHU
+ if ((insn_32 & 0x7F) == 0x3) {
+ uint32_t func = (insn_32 >> 12) & 0x7;
+ if ((func == 0x3) || (func == 0x6) || (func == 0x7)) {
+ // Not valid load encodings
+ return false;
+ }
+
+ rd_out = (insn_32 >> 7) & 0x1F;
+ return true;
+ }
+
+ return false;
+}
+
+unsigned int SpikeCosim::get_insn_cnt() { return insn_cnt; }
diff --git a/dv/cosim/spike_cosim.h b/dv/cosim/spike_cosim.h
new file mode 100644
index 00000000..a4baad5d
--- /dev/null
+++ b/dv/cosim/spike_cosim.h
@@ -0,0 +1,147 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#ifndef SPIKE_COSIM_H_
+#define SPIKE_COSIM_H_
+
+#include
+
+#include
+#include
+#include
+#include
+
+#include "cosim.h"
+#include "riscv/devices.h"
+#include "riscv/log_file.h"
+#include "riscv/processor.h"
+#include "riscv/simif.h"
+
+#define IBEX_MARCHID 22
+
+class SpikeCosim : public simif_t, public Cosim {
+ private:
+ // A sigsegv has been observed when deleting isa_parser_t instances under
+ // Xcelium on CentOS 7. The root cause is unknown so for a workaround simply
+ // use a raw pointer for isa_parser that never gets deleted. This produces a
+ // minor memory leak but it is of little consequence as when SpikeCosim is
+ // being deleted it is the end of simulation and the process will be
+ // terminated shortly anyway.
+#ifdef COSIM_SIGSEGV_WORKAROUND
+ isa_parser_t *isa_parser;
+#else
+ std::unique_ptr isa_parser;
+#endif
+ std::unique_ptr processor;
+ std::unique_ptr log;
+ bus_t bus;
+ std::vector> mems;
+ std::vector errors;
+ bool nmi_mode;
+
+ typedef struct {
+ uint8_t mpp;
+ bool mpie;
+ uint32_t epc;
+ uint32_t cause;
+ } mstack_t;
+
+ mstack_t mstack;
+
+ void fixup_csr(int csr_num, uint32_t csr_val);
+
+ struct PendingMemAccess {
+ DSideAccessInfo dut_access_info;
+ uint32_t be_spike;
+ };
+
+ std::vector pending_dside_accesses;
+
+ bool pending_iside_error;
+ uint32_t pending_iside_err_addr;
+
+ typedef enum {
+ kCheckMemOk, // Checks passed and access succeded in RTL
+ kCheckMemCheckFailed, // Checks failed
+ kCheckMemBusError // Checks passed, but access generated bus error in RTL
+ } check_mem_result_e;
+
+ check_mem_result_e check_mem_access(bool store, uint32_t addr, size_t len,
+ const uint8_t *bytes);
+
+ bool pc_is_mret(uint32_t pc);
+ bool pc_is_load(uint32_t pc, uint32_t &rd_out);
+
+ bool pc_is_debug_ebreak(uint32_t pc);
+ bool check_debug_ebreak(uint32_t write_reg, uint32_t pc, bool sync_trap);
+
+ bool check_gpr_write(const commit_log_reg_t::value_type ®_change,
+ uint32_t write_reg, uint32_t write_reg_data);
+
+ bool check_suppress_reg_write(uint32_t write_reg, uint32_t pc,
+ uint32_t &suppressed_write_reg);
+
+ void on_csr_write(const commit_log_reg_t::value_type ®_change);
+
+ void leave_nmi_mode();
+
+ bool change_cpuctrlsts_sync_exc_seen(bool flag);
+ void set_cpuctrlsts_double_fault_seen();
+ void handle_cpuctrl_exception_entry();
+
+ void initial_proc_setup(uint32_t start_pc, uint32_t start_mtvec,
+ uint32_t mhpm_counter_num);
+
+ void early_interrupt_handle();
+
+ void misaligned_pmp_fixup();
+
+ unsigned int insn_cnt;
+
+ public:
+ SpikeCosim(const std::string &isa_string, uint32_t start_pc,
+ uint32_t start_mtvec, const std::string &trace_log_path,
+ bool secure_ibex, bool icache_en, uint32_t pmp_num_regions,
+ uint32_t pmp_granularity, uint32_t mhpm_counter_num);
+
+ // simif_t implementation
+ virtual char *addr_to_mem(reg_t addr) override;
+ virtual bool mmio_load(reg_t addr, size_t len, uint8_t *bytes) override;
+ virtual bool mmio_store(reg_t addr, size_t len,
+ const uint8_t *bytes) override;
+ virtual void proc_reset(unsigned id) override;
+ virtual const char *get_symbol(uint64_t addr) override;
+
+ // Cosim implementation
+ void add_memory(uint32_t base_addr, size_t size) override;
+ bool backdoor_write_mem(uint32_t addr, size_t len,
+ const uint8_t *data_in) override;
+ bool backdoor_read_mem(uint32_t addr, size_t len, uint8_t *data_out) override;
+ bool step(uint32_t write_reg, uint32_t write_reg_data, uint32_t pc,
+ bool sync_trap, bool suppress_reg_write) override;
+
+ bool check_retired_instr(uint32_t write_reg, uint32_t write_reg_data,
+ uint32_t dut_pc, bool suppress_reg_write);
+ bool check_sync_trap(uint32_t write_reg, uint32_t pc,
+ uint32_t initial_spike_pc);
+ void set_mip(uint32_t pre_mip, uint32_t post_mip) override;
+ void set_nmi(bool nmi) override;
+ void set_nmi_int(bool nmi_int) override;
+ void set_debug_req(bool debug_req) override;
+ void set_mcycle(uint64_t mcycle) override;
+ void set_csr(const int csr_num, const uint32_t new_val) override;
+ void set_ic_scr_key_valid(bool valid) override;
+ void notify_dside_access(const DSideAccessInfo &access_info) override;
+ // The spike co-simulator assumes iside and dside accesses within a step are
+ // disjoint. If both access the same address within a step memory faults may
+ // be incorrectly cause on one rather than the other or the access checking
+ // will break.
+ // TODO: Work on spike changes to remove this restriction
+ void set_iside_error(uint32_t addr) override;
+ const std::vector &get_errors() override;
+ void clear_errors() override;
+ unsigned int get_insn_cnt() override;
+};
+
+#endif // SPIKE_COSIM_H_
diff --git a/dv/cs_registers/lint/verilator_waiver.vlt b/dv/cs_registers/lint/verilator_waiver.vlt
index 14f01fab..911700c5 100644
--- a/dv/cs_registers/lint/verilator_waiver.vlt
+++ b/dv/cs_registers/lint/verilator_waiver.vlt
@@ -9,7 +9,7 @@
// 'rtl' directory), see verilator_waiver_rtl.vlt in the same
// directory.
//
-// See https://www.veripool.org/projects/verilator/wiki/Manual-verilator#CONFIGURATION-FILES
+// See https://verilator.org/guide/latest/exe_verilator.html#configuration-files
// for documentation.
//
// Important: This file must included *before* any other Verilog file is read.
diff --git a/dv/cs_registers/model/base_register.cc b/dv/cs_registers/model/base_register.cc
index 4e4a11ef..a0716f5d 100644
--- a/dv/cs_registers/model/base_register.cc
+++ b/dv/cs_registers/model/base_register.cc
@@ -4,6 +4,7 @@
#include "base_register.h"
+#include
#include
BaseRegister::BaseRegister(
@@ -32,8 +33,8 @@ uint32_t BaseRegister::RegisterClear(uint32_t newval) {
return read_value;
}
-bool BaseRegister::MatchAddr(uint32_t addr) {
- return (addr == register_address_);
+bool BaseRegister::MatchAddr(uint32_t addr, uint32_t addr_mask) {
+ return ((addr & addr_mask) == (register_address_ & addr_mask));
}
bool BaseRegister::ProcessTransaction(bool *match, RegisterTransaction *trans) {
@@ -82,7 +83,62 @@ uint32_t BaseRegister::RegisterRead() { return register_value_; }
uint32_t BaseRegister::GetLockMask() { return 0; }
+BaseRegister *BaseRegister::GetRegisterFromMap(uint32_t addr) {
+ for (auto ® : *map_pointer_) {
+ if (reg->MatchAddr(addr)) {
+ return reg.get();
+ }
+ }
+
+ return nullptr;
+}
+
+MSeccfgRegister::MSeccfgRegister(
+ uint32_t addr, std::vector> *map_pointer)
+ : BaseRegister(addr, map_pointer) {}
+
+bool MSeccfgRegister::AnyPmpCfgsLocked() {
+ for (auto ® : *map_pointer_) {
+ // Iterate through PMPCfgX CSRs, returning true is any has a lock bit set
+ if (reg->MatchAddr(kCSRPMPCfg0, 0xfffffffc)) {
+ if ((reg->RegisterRead() & 0x80808080) != 0) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+uint32_t MSeccfgRegister::GetLockMask() {
+ uint32_t lock_mask = 0xFFFFFFF8;
+
+ // When RLB == 0 and any PMPCfgX has a lock bit set RLB must remain 0
+ if (AnyPmpCfgsLocked() && ((register_value_ & kMSeccfgRlb) == 0)) {
+ lock_mask |= kMSeccfgRlb;
+ }
+
+ // Once set MMWP cannot be unset
+ if (register_value_ & kMSeccfgMmwp) {
+ lock_mask |= kMSeccfgMmwp;
+ }
+
+ // Once set MML cannot be unset
+ if (register_value_ & kMSeccfgMml) {
+ lock_mask |= kMSeccfgMml;
+ }
+
+ return lock_mask;
+}
+
uint32_t PmpCfgRegister::GetLockMask() {
+ BaseRegister *mseccfg = GetRegisterFromMap(kCSRMSeccfg);
+ assert(mseccfg);
+
+ if (mseccfg->RegisterRead() & kMSeccfgRlb) {
+ return 0;
+ }
+
uint32_t lock_mask = 0;
if (register_value_ & 0x80)
lock_mask |= 0xFF;
@@ -98,44 +154,53 @@ uint32_t PmpCfgRegister::GetLockMask() {
uint32_t PmpCfgRegister::RegisterWrite(uint32_t newval) {
uint32_t lock_mask = GetLockMask();
uint32_t read_value = register_value_;
+
register_value_ &= lock_mask;
register_value_ |= (newval & ~lock_mask);
- register_value_ &= raz_mask_;
- for (int i = 0; i < 4; i++) {
- // Reserved check, W = 1, R = 0
- if (((register_value_ >> (8 * i)) & 0x3) == 0x2) {
- register_value_ &= ~(0x3 << (8 * i));
- }
- }
+ register_value_ = HandleReservedVals(register_value_);
+
return read_value;
}
uint32_t PmpCfgRegister::RegisterSet(uint32_t newval) {
uint32_t lock_mask = GetLockMask();
uint32_t read_value = register_value_;
+
register_value_ |= (newval & ~lock_mask);
- register_value_ &= raz_mask_;
- for (int i = 0; i < 4; i++) {
- // Reserved check, W = 1, R = 0
- if (((register_value_ >> (8 * i)) & 0x3) == 0x2) {
- register_value_ &= ~(0x3 << (8 * i));
- }
- }
+ register_value_ = HandleReservedVals(register_value_);
+
return read_value;
}
uint32_t PmpCfgRegister::RegisterClear(uint32_t newval) {
uint32_t lock_mask = GetLockMask();
uint32_t read_value = register_value_;
+
register_value_ &= (~newval | lock_mask);
- register_value_ &= raz_mask_;
+ register_value_ = HandleReservedVals(register_value_);
+
+ return read_value;
+}
+
+uint32_t PmpCfgRegister::HandleReservedVals(uint32_t cfg_val) {
+ BaseRegister *mseccfg = GetRegisterFromMap(kCSRMSeccfg);
+ assert(mseccfg);
+
+ cfg_val &= raz_mask_;
+
+ if (mseccfg->RegisterRead() & kMSeccfgMml) {
+ // No reserved L/R/W/X values when MML Set
+ return cfg_val;
+ }
+
for (int i = 0; i < 4; i++) {
// Reserved check, W = 1, R = 0
- if (((register_value_ >> (8 * i)) & 0x3) == 0x2) {
- register_value_ &= ~(0x3 << (8 * i));
+ if (((cfg_val >> (8 * i)) & 0x3) == 0x2) {
+ cfg_val &= ~(0x3 << (8 * i));
}
}
- return read_value;
+
+ return cfg_val;
}
uint32_t PmpAddrRegister::GetLockMask() {
diff --git a/dv/cs_registers/model/base_register.h b/dv/cs_registers/model/base_register.h
index e7ff9dd8..ac30beac 100644
--- a/dv/cs_registers/model/base_register.h
+++ b/dv/cs_registers/model/base_register.h
@@ -26,13 +26,30 @@ class BaseRegister {
virtual uint32_t RegisterClear(uint32_t newval);
virtual uint32_t RegisterRead();
virtual bool ProcessTransaction(bool *match, RegisterTransaction *trans);
- virtual bool MatchAddr(uint32_t addr);
+ virtual bool MatchAddr(uint32_t addr, uint32_t addr_mask = 0xFFFFFFFF);
virtual uint32_t GetLockMask();
protected:
uint32_t register_value_;
uint32_t register_address_;
std::vector> *map_pointer_;
+ BaseRegister *GetRegisterFromMap(uint32_t addr);
+};
+
+/**
+ * Machine Security Configuration class
+ *
+ * Has special behaviour for when bits are locked so requires a custom
+ * `GetLockMask` implementation
+ */
+class MSeccfgRegister : public BaseRegister {
+ public:
+ MSeccfgRegister(uint32_t addr,
+ std::vector> *map_pointer);
+ uint32_t GetLockMask();
+
+ private:
+ bool AnyPmpCfgsLocked();
};
/**
@@ -48,6 +65,7 @@ class PmpCfgRegister : public BaseRegister {
uint32_t RegisterClear(uint32_t newval);
private:
+ uint32_t HandleReservedVals(uint32_t cfg_val);
const uint32_t raz_mask_ = 0x9F9F9F9F;
};
diff --git a/dv/cs_registers/model/register_model.cc b/dv/cs_registers/model/register_model.cc
index 60aaf007..78cbb4c1 100644
--- a/dv/cs_registers/model/register_model.cc
+++ b/dv/cs_registers/model/register_model.cc
@@ -7,6 +7,10 @@
#include
RegisterModel::RegisterModel(SimCtrl *sc, CSRParams *params) : simctrl_(sc) {
+ register_map_.push_back(
+ std::make_unique(kCSRMSeccfg, ®ister_map_));
+ register_map_.push_back(
+ std::make_unique(kCSRMSeccfgh, ®ister_map_));
// Instantiate all the registers
for (unsigned int i = 0; i < 4; i++) {
uint32_t reg_addr = 0x3A0 + i;
@@ -29,11 +33,11 @@ RegisterModel::RegisterModel(SimCtrl *sc, CSRParams *params) : simctrl_(sc) {
}
}
// mcountinhibit
- // - MSBs are always 1: unused counters cannot be enabled
+ // - MSBs are always 0: unused counters cannot be inhibited
// - Bit 1 is always 0: time cannot be disabled
uint32_t mcountinhibit_mask =
(~((0x1 << params->MHPMCounterNum) - 1) << 3) | 0x2;
- uint32_t mcountinhibit_resval = ~((0x1 << params->MHPMCounterNum) - 1) << 3;
+ uint32_t mcountinhibit_resval = 0;
register_map_.push_back(std::make_unique(
0x320, ®ister_map_, mcountinhibit_mask, mcountinhibit_resval));
// Performance counter setup
@@ -41,7 +45,7 @@ RegisterModel::RegisterModel(SimCtrl *sc, CSRParams *params) : simctrl_(sc) {
uint32_t reg_addr = 0x320 + i;
if (i < (params->MHPMCounterNum + 3)) {
register_map_.push_back(std::make_unique(
- reg_addr, ®ister_map_, 0xFFFFFFFF, 0x1 << i));
+ reg_addr, ®ister_map_, 0xFFFFFFFF, 0x1 << (i - 3)));
} else {
register_map_.push_back(
std::make_unique(reg_addr, ®ister_map_));
diff --git a/dv/cs_registers/reg_driver/csr_listing.def b/dv/cs_registers/reg_driver/csr_listing.def
index 5a9a9609..5cab0fab 100644
--- a/dv/cs_registers/reg_driver/csr_listing.def
+++ b/dv/cs_registers/reg_driver/csr_listing.def
@@ -58,6 +58,8 @@ CSR(MHPMEvent28, 0x33C)
CSR(MHPMEvent29, 0x33D)
CSR(MHPMEvent30, 0x33E)
CSR(MHPMEvent31, 0x33F)
+CSR(MSeccfg, 0x747)
+CSR(MSeccfgh, 0x757)
CSR(MCycle, 0xB00)
CSR(MInstret, 0xB02)
CSR(MHPMCounter3, 0xB03)
diff --git a/dv/cs_registers/reg_driver/register_transaction.h b/dv/cs_registers/reg_driver/register_transaction.h
index 4f6e9555..41991b1e 100644
--- a/dv/cs_registers/reg_driver/register_transaction.h
+++ b/dv/cs_registers/reg_driver/register_transaction.h
@@ -15,6 +15,11 @@ enum CSRegisterAddr : int {
#include "csr_listing.def"
};
+// Individual bits for MSECCFG CSR
+const int kMSeccfgMml = 0x1;
+const int kMSeccfgMmwp = 0x2;
+const int kMSeccfgRlb = 0x4;
+
// Create an indexable array of all CSR addresses
static const uint16_t CSRAddresses[] = {
#define CSR(reg, addr) addr,
diff --git a/dv/cs_registers/tb/tb_cs_registers.sv b/dv/cs_registers/tb/tb_cs_registers.sv
index 57be8a7d..23e706e0 100644
--- a/dv/cs_registers/tb/tb_cs_registers.sv
+++ b/dv/cs_registers/tb/tb_cs_registers.sv
@@ -33,6 +33,11 @@ module tb_cs_registers #(
logic illegal_csr_insn_o;
+ logic csr_access_d;
+ ibex_pkg::csr_num_e csr_addr_d;
+ logic [31:0] csr_wdata_d;
+ ibex_pkg::csr_op_e csr_op_d;
+ logic csr_op_en_d;
//-----------------
// Reset generation
//-----------------
@@ -121,12 +126,26 @@ module tb_cs_registers #(
csr_addr_i,
csr_wdata_i,
csr_rdata_o);
+
reg_dpi::driver_tick("reg_driver",
- csr_access_i,
- csr_op_i,
- csr_op_en_i,
- csr_addr_i,
- csr_wdata_i);
+ csr_access_d,
+ csr_op_d,
+ csr_op_en_d,
+ csr_addr_d,
+ csr_wdata_d);
+
+ // Use NBA to drive inputs to ensure correct scheduling.
+ // This always_ff block will be executed on the positive edge of the clock with undefined order
+ // vs all other always_ff triggered on the positive edge of the clock. If `driver_tick` drives
+ // the inputs directly some of the always_ff blocks will see the old version of the inputs and
+ // others will see the new version depending on scheduling order. This schedules all the inputs
+ // to be NBA updates to avoid the race condition (in effect acting like any other always_ff
+ // block with the _d values being computed via DPI rather than combinational logic).
+ csr_access_i <= csr_access_d;
+ csr_addr_i <= csr_addr_d;
+ csr_wdata_i <= csr_wdata_d;
+ csr_op_i <= csr_op_d;
+ csr_op_en_i <= csr_op_en_d;
end
endmodule
diff --git a/dv/riscv_compliance/ibex_riscv_compliance.cc b/dv/riscv_compliance/ibex_riscv_compliance.cc
index 1f72389f..8a32b22a 100644
--- a/dv/riscv_compliance/ibex_riscv_compliance.cc
+++ b/dv/riscv_compliance/ibex_riscv_compliance.cc
@@ -13,9 +13,11 @@ int main(int argc, char **argv) {
simctrl.SetTop(&top, &top.IO_CLK, &top.IO_RST_N,
VerilatorSimCtrlFlags::ResetPolarityNegative);
- memutil.RegisterMemoryArea(
- "ram",
- "TOP.ibex_riscv_compliance.u_ram.u_ram.gen_generic.u_impl_generic");
+ MemArea ram(
+ "TOP.ibex_riscv_compliance.u_ram.u_ram.gen_generic.u_impl_generic",
+ 64 * 1024 / 4, 4);
+
+ memutil.RegisterMemoryArea("ram", 0x0, &ram);
simctrl.RegisterExtension(&memutil);
return simctrl.Exec(argc, argv).first;
diff --git a/dv/riscv_compliance/ibex_riscv_compliance.core b/dv/riscv_compliance/ibex_riscv_compliance.core
index 0e5f56e7..9e45809f 100644
--- a/dv/riscv_compliance/ibex_riscv_compliance.core
+++ b/dv/riscv_compliance/ibex_riscv_compliance.core
@@ -5,24 +5,23 @@ CAPI=2:
name: "lowrisc:ibex:ibex_riscv_compliance:0.1"
description: "Ibex simulation for RISC-V compliance testing (using Verilator)"
filesets:
- files_sim_verilator:
+ files_sim:
depend:
- - lowrisc:dv_verilator:memutil_verilator
- - lowrisc:dv_verilator:simutil_verilator
- - lowrisc:ibex:ibex_core_tracing
+ - lowrisc:ibex:ibex_top_tracing
- lowrisc:ibex:sim_shared
-
files:
- rtl/ibex_riscv_compliance.sv
- - ibex_riscv_compliance.cc: { file_type: cppSource }
- rtl/riscv_testutil.sv
file_type: systemVerilogSource
- files_verilator_waiver:
+ files_verilator:
+ depend:
+ - lowrisc:dv_verilator:memutil_verilator
+ - lowrisc:dv_verilator:simutil_verilator
files:
+ - ibex_riscv_compliance.cc: { file_type: cppSource }
- lint/verilator_waiver.vlt: {file_type: vlt}
-
parameters:
RV32E:
datatype: int
@@ -78,6 +77,24 @@ parameters:
default: 0
description: "Enables static branch prediction (EXPERIMENTAL)"
+ DbgTriggerEn:
+ datatype: int
+ default: 0
+ paramtype: vlogparam
+ description: "Enable support for debug triggers. "
+
+ SecureIbex:
+ datatype: int
+ default: 0
+ paramtype: vlogparam
+ description: "Enables security hardening features (EXPERIMENTAL) [0/1]"
+
+ ICacheScramble:
+ datatype: int
+ default: 0
+ paramtype: vlogparam
+ description: "Enables ICache scrambling feature (EXPERIMENTAL) [0/1]"
+
PMPEnable:
datatype: int
default: 0
@@ -96,12 +113,24 @@ parameters:
paramtype: vlogparam
description: "Number of PMP regions"
+ MHPMCounterNum:
+ datatype: int
+ paramtype: vlogparam
+ default: 0
+ description: Number of performance monitor event counters [0/29]
+
+ MHPMCounterWidth:
+ datatype: int
+ paramtype: vlogparam
+ default: 40
+ description: Bit width of performance monitor event counters [32/64]
+
targets:
sim:
default_tool: verilator
filesets:
- - tool_verilator ? (files_verilator_waiver)
- - files_sim_verilator
+ - files_sim
+ - tool_verilator ? (files_verilator)
parameters:
- RV32E
- RV32M
@@ -112,9 +141,14 @@ targets:
- BranchTargetALU
- WritebackStage
- BranchPredictor
+ - DbgTriggerEn
+ - SecureIbex
+ - ICacheScramble
- PMPEnable
- PMPGranularity
- PMPNumRegions
+ - MHPMCounterNum
+ - MHPMCounterWidth
toplevel: ibex_riscv_compliance
tools:
verilator:
@@ -127,6 +161,6 @@ targets:
- '--trace-structs'
- '--trace-params'
- '--trace-max-array 1024'
- - '-CFLAGS "-std=c++11 -Wall -DVM_TRACE_FMT_FST -DTOPLEVEL_NAME=ibex_riscv_compliance -g"'
+ - '-CFLAGS "-std=c++14 -Wall -DVM_TRACE_FMT_FST -DTOPLEVEL_NAME=ibex_riscv_compliance -g"'
- '-LDFLAGS "-pthread -lutil -lelf"'
- "-Wall"
diff --git a/dv/riscv_compliance/lint/verilator_waiver.vlt b/dv/riscv_compliance/lint/verilator_waiver.vlt
index fc9e0973..287b8406 100644
--- a/dv/riscv_compliance/lint/verilator_waiver.vlt
+++ b/dv/riscv_compliance/lint/verilator_waiver.vlt
@@ -9,7 +9,7 @@
// 'rtl' directory), see verilator_waiver_rtl.vlt in the same
// directory.
//
-// See https://www.veripool.org/projects/verilator/wiki/Manual-verilator#CONFIGURATION-FILES
+// See https://verilator.org/guide/latest/exe_verilator.html#configuration-files
// for documentation.
//
// Important: This file must included *before* any other Verilog file is read.
diff --git a/dv/riscv_compliance/rtl/ibex_riscv_compliance.sv b/dv/riscv_compliance/rtl/ibex_riscv_compliance.sv
index 44d1044a..10d0bb05 100644
--- a/dv/riscv_compliance/rtl/ibex_riscv_compliance.sv
+++ b/dv/riscv_compliance/rtl/ibex_riscv_compliance.sv
@@ -15,18 +15,23 @@ module ibex_riscv_compliance (
input IO_RST_N
);
- parameter bit PMPEnable = 1'b0;
- parameter int unsigned PMPGranularity = 0;
- parameter int unsigned PMPNumRegions = 4;
- parameter bit RV32E = 1'b0;
- parameter ibex_pkg::rv32m_e RV32M = ibex_pkg::RV32MFast;
- parameter ibex_pkg::rv32b_e RV32B = ibex_pkg::RV32BNone;
- parameter ibex_pkg::regfile_e RegFile = ibex_pkg::RegFileFF;
- parameter bit BranchTargetALU = 1'b0;
- parameter bit WritebackStage = 1'b0;
- parameter bit ICache = 1'b0;
- parameter bit ICacheECC = 1'b0;
- parameter bit BranchPredictor = 1'b0;
+ parameter bit PMPEnable = 1'b0;
+ parameter int unsigned PMPGranularity = 0;
+ parameter int unsigned PMPNumRegions = 4;
+ parameter int unsigned MHPMCounterNum = 0;
+ parameter int unsigned MHPMCounterWidth = 40;
+ parameter bit RV32E = 1'b0;
+ parameter ibex_pkg::rv32m_e RV32M = ibex_pkg::RV32MFast;
+ parameter ibex_pkg::rv32b_e RV32B = ibex_pkg::RV32BNone;
+ parameter ibex_pkg::regfile_e RegFile = ibex_pkg::RegFileFF;
+ parameter bit BranchTargetALU = 1'b0;
+ parameter bit WritebackStage = 1'b0;
+ parameter bit ICache = 1'b0;
+ parameter bit ICacheECC = 1'b0;
+ parameter bit BranchPredictor = 1'b0;
+ parameter bit SecureIbex = 1'b0;
+ parameter bit ICacheScramble = 1'b0;
+ parameter bit DbgTriggerEn = 1'b0;
logic clk_sys, rst_sys_n;
@@ -61,6 +66,9 @@ module ibex_riscv_compliance (
logic [31:0] host_rdata [NrHosts];
logic host_err [NrHosts];
+ logic [6:0] ibex_data_rdata_intg;
+ logic [6:0] ibex_instr_rdata_intg;
+
// devices (slaves)
logic device_req [NrDevices];
logic [31:0] device_addr [NrDevices];
@@ -79,7 +87,6 @@ module ibex_riscv_compliance (
assign cfg_device_addr_base[TestUtilDevice] = 32'h20000;
assign cfg_device_addr_mask[TestUtilDevice] = ~32'h3FF; // 1 kB
-
bus #(
.NrDevices (NrDevices),
.NrHosts (NrHosts ),
@@ -112,60 +119,98 @@ module ibex_riscv_compliance (
.cfg_device_addr_mask
);
- ibex_core_tracing #(
- .PMPEnable (PMPEnable ),
- .PMPGranularity (PMPGranularity ),
- .PMPNumRegions (PMPNumRegions ),
- .RV32E (RV32E ),
- .RV32M (RV32M ),
- .RV32B (RV32B ),
- .RegFile (RegFile ),
- .BranchTargetALU (BranchTargetALU ),
- .WritebackStage (WritebackStage ),
- .ICache (ICache ),
- .ICacheECC (ICacheECC ),
- .BranchPredictor (BranchPredictor ),
- .DmHaltAddr (32'h00000000 ),
- .DmExceptionAddr (32'h00000000 )
- ) u_core (
- .clk_i (clk_sys ),
- .rst_ni (rst_sys_n ),
+ if (SecureIbex) begin : g_mem_rdata_ecc
+ logic [31:0] unused_data_rdata;
+ logic [31:0] unused_instr_rdata;
- .test_en_i ('b0 ),
+ prim_secded_inv_39_32_enc u_data_rdata_intg_gen (
+ .data_i (host_rdata[CoreD]),
+ .data_o ({ibex_data_rdata_intg, unused_data_rdata})
+ );
- .hart_id_i (32'b0 ),
+ prim_secded_inv_39_32_enc u_instr_rdata_intg_gen (
+ .data_i (host_rdata[CoreI]),
+ .data_o ({ibex_instr_rdata_intg, unused_instr_rdata})
+ );
+ end else begin : g_no_mem_rdata_ecc
+ assign ibex_data_rdata_intg = '0;
+ assign ibex_instr_rdata_intg = '0;
+ end
+
+ ibex_top_tracing #(
+ .PMPEnable (PMPEnable ),
+ .PMPGranularity (PMPGranularity ),
+ .PMPNumRegions (PMPNumRegions ),
+ .MHPMCounterNum (MHPMCounterNum ),
+ .MHPMCounterWidth (MHPMCounterWidth ),
+ .RV32E (RV32E ),
+ .RV32M (RV32M ),
+ .RV32B (RV32B ),
+ .RegFile (RegFile ),
+ .BranchTargetALU (BranchTargetALU ),
+ .WritebackStage (WritebackStage ),
+ .ICache (ICache ),
+ .ICacheECC (ICacheECC ),
+ .BranchPredictor (BranchPredictor ),
+ .DbgTriggerEn (DbgTriggerEn ),
+ .SecureIbex (SecureIbex ),
+ .ICacheScramble (ICacheScramble ),
+ .DmBaseAddr (32'h00000000 ),
+ .DmAddrMask (32'h00000003 ),
+ .DmHaltAddr (32'h00000000 ),
+ .DmExceptionAddr (32'h00000000 )
+ ) u_top (
+ .clk_i (clk_sys ),
+ .rst_ni (rst_sys_n ),
+
+ .test_en_i ('b0 ),
+ .scan_rst_ni (1'b1 ),
+ .ram_cfg_i ('b0 ),
+
+ .hart_id_i (32'b0 ),
// First instruction executed is at 0x0 + 0x80
- .boot_addr_i (32'h00000000 ),
+ .boot_addr_i (32'h00000000 ),
- .instr_req_o (host_req[CoreI] ),
- .instr_gnt_i (host_gnt[CoreI] ),
- .instr_rvalid_i (host_rvalid[CoreI]),
- .instr_addr_o (host_addr[CoreI] ),
- .instr_rdata_i (host_rdata[CoreI] ),
- .instr_err_i (host_err[CoreI] ),
+ .instr_req_o (host_req[CoreI] ),
+ .instr_gnt_i (host_gnt[CoreI] ),
+ .instr_rvalid_i (host_rvalid[CoreI] ),
+ .instr_addr_o (host_addr[CoreI] ),
+ .instr_rdata_i (host_rdata[CoreI] ),
+ .instr_rdata_intg_i (ibex_instr_rdata_intg),
+ .instr_err_i (host_err[CoreI] ),
- .data_req_o (host_req[CoreD] ),
- .data_gnt_i (host_gnt[CoreD] ),
- .data_rvalid_i (host_rvalid[CoreD]),
- .data_we_o (host_we[CoreD] ),
- .data_be_o (host_be[CoreD] ),
- .data_addr_o (host_addr[CoreD] ),
- .data_wdata_o (host_wdata[CoreD] ),
- .data_rdata_i (host_rdata[CoreD] ),
- .data_err_i (host_err[CoreD] ),
+ .data_req_o (host_req[CoreD] ),
+ .data_gnt_i (host_gnt[CoreD] ),
+ .data_rvalid_i (host_rvalid[CoreD] ),
+ .data_we_o (host_we[CoreD] ),
+ .data_be_o (host_be[CoreD] ),
+ .data_addr_o (host_addr[CoreD] ),
+ .data_wdata_o (host_wdata[CoreD] ),
+ .data_wdata_intg_o ( ),
+ .data_rdata_i (host_rdata[CoreD] ),
+ .data_rdata_intg_i (ibex_data_rdata_intg ),
+ .data_err_i (host_err[CoreD] ),
- .irq_software_i (1'b0 ),
- .irq_timer_i (1'b0 ),
- .irq_external_i (1'b0 ),
- .irq_fast_i (15'b0 ),
- .irq_nm_i (1'b0 ),
+ .irq_software_i (1'b0 ),
+ .irq_timer_i (1'b0 ),
+ .irq_external_i (1'b0 ),
+ .irq_fast_i (15'b0 ),
+ .irq_nm_i (1'b0 ),
- .debug_req_i ('b0 ),
+ .scramble_key_valid_i ('0 ),
+ .scramble_key_i ('0 ),
+ .scramble_nonce_i ('0 ),
+ .scramble_req_o ( ),
- .fetch_enable_i ('b1 ),
- .alert_minor_o ( ),
- .alert_major_o ( ),
- .core_sleep_o ( )
+ .debug_req_i ('b0 ),
+ .crash_dump_o ( ),
+ .double_fault_seen_o ( ),
+
+ .fetch_enable_i (ibex_pkg::IbexMuBiOn ),
+ .alert_minor_o ( ),
+ .alert_major_internal_o ( ),
+ .alert_major_bus_o ( ),
+ .core_sleep_o ( )
);
// SRAM block for instruction and data storage
diff --git a/dv/uvm/common_project_cfg.hjson b/dv/uvm/common_project_cfg.hjson
index 9aa450af..ef0499fe 100644
--- a/dv/uvm/common_project_cfg.hjson
+++ b/dv/uvm/common_project_cfg.hjson
@@ -5,14 +5,20 @@
project: ibex
// These keys are expected by dvsim.py, so we have to set them to something.
- doc_server: bogus.doc.server
- results_server: bogus.results.server
+ book: bogus.book.domain
+ doc_server: bogus.doc.server
+ results_server: bogus.results.server
+ results_html_name: report.html
// Default directory structure for the output
scratch_base_path: "{scratch_root}/{dut}.{flow}.{tool}"
scratch_path: "{scratch_base_path}/{branch}"
tool_srcs_dir: "{scratch_path}/{tool}"
+ // Common DVSIM data structures
+ build_pass_patterns: []
+ build_fail_patterns: []
+
// The current design level
design_level: "ip"
}
diff --git a/dv/uvm/core_ibex/.gitignore b/dv/uvm/core_ibex/.gitignore
new file mode 100644
index 00000000..07ed58fc
--- /dev/null
+++ b/dv/uvm/core_ibex/.gitignore
@@ -0,0 +1,25 @@
+# This is generated by VCS when running DV simulations with WAVE=1.
+ucli.key
+
+# This is generated by UVM when running simulations and doesn't seem
+# to be something you can disable.
+tr_db.log
+
+# This is the default output directory in dv/uvm/core_ibex and
+# contains auto-generated files from building and running tests.
+out
+
+# This is generated by the Makefile based on the ibex configuration
+riscv_dv_extension/riscv_core_setting.sv
+
+# This is generated by Xcelium when running DV simulations, even with WAVE=0
+waves.shm
+
+# Log files generated by Cadence tools when running DV simulations
+xrun.history
+xrun.log
+xmsc.log
+
+# Generated by coverage
+imc.key
+mdv.log
diff --git a/dv/uvm/core_ibex/Makefile b/dv/uvm/core_ibex/Makefile
index 802fde7c..69909cac 100644
--- a/dv/uvm/core_ibex/Makefile
+++ b/dv/uvm/core_ibex/Makefile
@@ -2,11 +2,20 @@
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
-GEN_DIR := $(realpath ../../../vendor/google_riscv-dv)
-TOOLCHAIN := ${RISCV_TOOLCHAIN}
+# Top-Level Makefile
+###############################################################################
+
+.SUFFIXES:
+export
# Explicitly ask for the bash shell
-SHELL := bash
+SHELL := bash
+
+# Build the 'all' target by default, override with e.g. GOAL=rtl_tb_compile
+GOAL ?= all
+
+###############################################################################
+# CONFIGURATION KNOBS
# Seed for instruction generator and RTL simulation
#
@@ -17,423 +26,79 @@ SHELL := bash
# start passing again without fixing the bug).
SEED := $(shell echo $$RANDOM)
-# This is the top-level output directory. Everything we generate goes in
-# here. Most generated stuff actually goes in $(OUT)/seed-$(SEED), which allows
-# us to run multiple times without deleting existing results.
-OUT := out
-OUT-SEED := $(OUT)/seed-$(SEED)
-
-# Run time options for the instruction generator
-GEN_OPTS :=
-# Compile time options for ibex RTL simulation
-COMPILE_OPTS +=
-# Run time options for ibex RTL simulation
-SIM_OPTS :=
# Enable waveform dumping
-WAVES := 1
+WAVES := 0
# Enable coverage dump
COV := 0
-# RTL simulator
-SIMULATOR := vcs
+# RTL simulator (xlm, vcs, questa, dsim, )
+SIMULATOR := xlm
# ISS (spike, ovpsim)
ISS := spike
-# ISS runtime options
-ISS_OPTS :=
-# ISA
-ISA := rv32imcb
# Test name (default: full regression)
TEST := all
-TESTLIST := riscv_dv_extension/testlist.yaml
+RISCV-DV-TESTLIST := riscv_dv_extension/testlist.yaml
+DIRECTED-TESTLIST := directed_tests/directed_testlist.yaml
# Verbose logging
-VERBOSE :=
-# Number of iterations for each test, assign a non-zero value to override the
+VERBOSE := 0
+# Number of iterations for each test, assign a non-empty value to override the
# iteration count in the test list
-ITERATIONS := 0
-# LSF CMD
-LSF_CMD :=
-# Generator timeout limit in seconds
-TIMEOUT := 1800
-# Privileged CSR YAML description file
-CSR_FILE := riscv_dv_extension/csr_description.yaml
-# Pass/fail signature address at the end of test
+ITERATIONS :=
+# Pass/fail signature address at the end of test (see riscv_dv handshake documentation)
SIGNATURE_ADDR := 8ffffffc
### Ibex top level parameters ###
-### Required by RISCV-DV, some ISS, and RTL ###
-# PMP Regions
-PMP_REGIONS := 16
-# PMP Granularity
-PMP_GRANULARITY := 0
+IBEX_CONFIG := opentitan
-IBEX_CONFIG := experimental-maxperf-pmp-bmfull-icache
+# Path to DUT used for coverage reports
+DUT_COV_RTL_PATH := "ibex_top"
-# TODO(udinator) - might need options for SAIL/Whisper/Spike
-ifeq (${ISS},ovpsim)
- ISS_OPTS += --override riscvOVPsim/cpu/PMP_registers=${PMP_REGIONS}
- ISS_OPTS += --override riscvOVPsim/cpu/PMP_grain=${PMP_GRANULARITY}
+export EXTRA_COSIM_CFLAGS ?=
+
+ifeq ($(COSIM_SIGSEGV_WORKAROUND), 1)
+ EXTRA_COSIM_CFLAGS += -DCOSIM_SIGSEGV_WORKAROUND
endif
-# A version of $(OUT) with a trailing '/'. The point is that this will
-# never match the name of a phony targets like "sim" (which causes
-# strange rebuilds otherwise). The call to $(dir ) avoids adding
-# another trailing slash if $(OUT) had one already.
-OUT-DIR := $(dir $(OUT)/)
+###############################################################################
-# This expands to '@' if VERBOSE is 0 or not set, and to the empty
-# string otherwise. Prefix commands with it in order that they only
-# get printed when VERBOSE.
-verb = $(if $(filter-out 0,$(VERBOSE)),,@)
+# Setup the necessary paths for all python scripts to find all other relevant modules.
+export PYTHONPATH := $(shell python3 -c 'from scripts.setup_imports import get_pythonpath; get_pythonpath()')
-SHELL=/bin/bash
+# We run the 'create_metadata' step in this top-level makefile, so the sub-make
+# invocations can query the generated metadata objects. Since the targets/dependencies
+# are extracted from this metadata, it must be query-able in the makefile 'immediate' stage.
+.PHONY: run
+run:
+ @env PYTHONPATH=$(PYTHONPATH) python3 ./scripts/metadata.py \
+ --op "create_metadata" \
+ --dir-metadata $(METADATA-DIR) \
+ --dir-out $(OUT-DIR) \
+ --args-list "\
+ SEED=$(SEED) WAVES=$(WAVES) COV=$(COV) SIMULATOR=$(SIMULATOR) \
+ ISS=$(ISS) TEST=$(TEST) VERBOSE=$(VERBOSE) ITERATIONS=$(ITERATIONS) \
+ SIGNATURE_ADDR=$(SIGNATURE_ADDR) IBEX_CONFIG=$(IBEX_CONFIG) \
+ DUT_COV_RTL_PATH=$(DUT_COV_RTL_PATH)"
+ @$(MAKE) --file wrapper.mk --environment-overrides --no-print-directory $(GOAL)
-export PRJ_DIR:= $(realpath ../../..)
+###############################################################################
-all: sim
+# This is the top-level output directory. Everything we generate goes in
+# here.
+OUT := out
-instr: iss_sim
+# Derived directories from $(OUT), used for stuff that's built once or
+# stuff that gets run for each seed, respectively. Using OUT-DIR on
+# the way avoids ugly double slashes if $(OUT) happens to end in a /.
+export OUT-DIR := $(dir $(OUT)/)
+export METADATA-DIR := $(OUT-DIR)metadata
-sim: post_compare cov
+# riscv-dv extension directory
+export EXT_DIR := riscv_dv_extension
+
+###############################################################################
.PHONY: clean
clean:
rm -rf $(OUT-DIR)
-
-# Common options for all targets
-COMMON_OPTS := $(if $(call equal,$(VERBOSE),1),--verbose,)
-
-# Options for all targets that depend on the tests we're running.
-TEST_OPTS := $(COMMON_OPTS) \
- --start_seed=${SEED} \
- --test="${TEST}" \
- --testlist=${TESTLIST} \
- --iterations=${ITERATIONS}
-
-# Options used for privileged CSR test generation
-CSR_OPTS=--csr_yaml=${CSR_FILE} \
- --isa="${ISA}" \
- --end_signature_addr=${SIGNATURE_ADDR}
-
-RISCV_DV_OPTS=--custom_target=riscv_dv_extension \
- --isa="${ISA}" \
- --mabi=ilp32 \
-
-# To avoid cluttering the output directory with stamp files, we place them in
-# $(metadata).
-metadata := $(OUT-SEED)/.metadata
-
-# This is a list of directories that are automatically generated by some
-# targets. To ensure the directory has been built, add a order-only dependency
-# (with the pipe symbol before it) on the directory name and add the directory
-# to this list.
-gen-dirs := $(OUT-DIR) $(OUT-SEED) $(metadata) $(OUT-DIR)rtl_sim
-
-$(gen-dirs): %:
- mkdir -p $@
-
-# sim-cfg-mk is a makefile fragment that sets-up anything simulator specific, it
-# is generated by sim_makefrag_gen.py
-sim-cfg-mk = $(OUT-DIR).sim-cfg.mk
-
-# The include of $(sim-cfg-mk) below tells Make that it should ensure the file
-# exists. This rule tells Make how to build it. We also want to ensure it's
-# built on every run. Declaring the rule to be .PHONY doesn't work because it
-# causes Make to no longer think the rule actually generates the file. If you
-# do that, the file gets re-built, but Make doesn't read the new contents. So
-# instead we depend on FORCE (a phony target). This ensures a rebuild, but also
-# causes an infinite recursion: when we re-read this file to include the new
-# contents of $(sim-cfg-mk), we run the rule again. To avoid that, we check for
-# MAKE_RESTARTS, which is defined on re-runs. Phew!
-ifndef MAKE_RESTARTS
-$(sim-cfg-mk): FORCE | $(OUT-DIR)
- @./sim_makefrag_gen.py $(SIMULATOR) $(IBEX_CONFIG) $(PRJ_DIR) $@
-endif
-
-include $(sim-cfg-mk)
-
-.PHONY: test-cfg
-test-cfg:
- @echo "COMPILE_OPTS" $(COMPILE_OPTS)
- @echo "SIM_OPTS" $(SIM_OPTS)
+ rm -f $(EXT_DIR)/riscv_core_setting.sv
###############################################################################
-# Utility functions.
-#
-# If VS is a list of variable names, P is a path and X is a string, then $(call
-# dump-vars,P,X,VS) will expand to a list of 'file' commands that write each
-# variable to P in Makefile syntax, but with "last-X-" prepended. At the start
-# of the file, we also define last-X-vars-loaded to 1. You can use this to
-# check whether there was a dump file at all.
-#
-# Note that this doesn't work by expanding to a command. Instead, *evaluating*
-# dump-vars causes the variables to be dumped.
-dump-var = $(file >>$(1),last-$(2)-$(3) := $($(3)))
-dump-vars = $(file >$(1),last-$(2)-vars-loaded := .) \
- $(foreach name,$(3),$(call dump-var,$(1),$(2),$(name)))
-
-# equal checks whether two strings are equal, evaluating to '.' if they are and
-# '' otherwise.
-both-empty = $(if $(1),,$(if $(2),,.))
-find-find = $(if $(and $(findstring $(1),$(2)),$(findstring $(2),$(1))),.,)
-equal = $(or $(call both-empty,$(1),$(2)),$(call find-find,$(1),$(2)))
-
-# var-differs is used to check whether a variable has changed since it was
-# dumped. If it has changed, the function evaluates to '.' (with some
-# whitespace) and prints a message to the console; if not, it evaluates to ''.
-#
-# Call it as $(call var-differs,X,TGT,V).
-var-differs = \
- $(if $(call equal,$(strip $($(3))),$(strip $(last-$(1)-$(3)))),,\
- .$(info Repeating $(2) because variable $(3) has changed value.))
-
-# vars-differ is used to check whether several variables have the same value as
-# they had when they were dumped. If we haven't loaded the dumpfile, it
-# silently evaluates to '!'. Otherwise, if all the variables match, it
-# evaluates to '.'. If not, it evaluates to '.' and prints some messages to the
-# console explaining why a rebuild is happening.
-#
-# Call it as $(call vars-differ,X,TGT,VS).
-vars-differ-lst = $(foreach v,$(3),$(call var-differs,$(1),$(2),$(v)))
-vars-differ-sp = \
- $(if $(last-$(1)-vars-loaded),\
- $(if $(strip $(call vars-differ-lst,$(1),$(2),$(3))),.,),\
- !)
-vars-differ = $(strip $(call vars-differ-sp,$(1),$(2),$(3)))
-
-# A phony target which can be used to force recompilation.
-.PHONY: FORCE
-FORCE:
-
-# vars-prereq is empty if every variable in VS matches the last run (loaded
-# with tag X), otherwise it is set to FORCE (which will force a recompile and
-# might print a message to the console explaining why we're rebuilding TGT).
-#
-# Call it as $(call vars-prereq,X,TGT,VS)
-vars-prereq = $(if $(call vars-differ,$(1),$(2),$(3)),FORCE,)
-
-###############################################################################
-# Generate random instructions
-#
-# This depends on the vendored in code in $(GEN_DIR). It also depends on the
-# values of some variables (we want to regenerate things if, for example, the
-# simulator changes). Since we're writing out to $(OUT-SEED), we don't have to
-# depend on the value of SEED. However, we do have to make sure that the
-# variables whose names are listed in $(gen-var-deps) haven't changed.
-#
-# To do this variable tracking, we dump each of the variables to a Makefile
-# fragment and try to load it up the next time around.
-gen-var-deps := GEN_OPTS SIMULATOR RISCV_DV_OPTS CSR_OPTS \
- SIGNATURE_ADDR PMP_REGIONS PMP_GRANULARITY TEST_OPTS
-
-# Load up the generation stage's saved variable values. If this fails, that's
-# no problem: we'll assume that the previous run either doesn't exist or
-# something went wrong.
--include $(metadata)/gen-vars.mk
-
-# gen-vars-prereq is empty if every variable in gen-var-deps matches the last run,
-# otherwise it is set to FORCE (which will force a recompile). Note that we
-# define it with '=', not ':=', so we don't evaluate it if we're not trying to
-# run the gen target.
-gen-vars-prereq = \
- $(call vars-prereq,gen,building instruction generator,$(gen-var-deps))
-
-# A variable containing a file list for the riscv-dv vendored-in module.
-# Depending on these files gives a safe over-approximation that will ensure we
-# rebuild things if that module changes.
-#
-# Note that this is defined with ":=". As a result, we'll always run the find
-# command exactly once. Wasteful if we're trying to make clean, but much better
-# than running it for every target otherwise.
-risc-dv-files := $(shell find $(GEN_DIR) -type f)
-
-# This actually runs the instruction generator. Note that the rule depends on
-# the (phony) FORCE target if any variables have changed. If the rule actually
-# runs, it starts by deleting any existing contents of $(OUT-SEED)/instr_gen.
-$(metadata)/instr_gen.gen.stamp: \
- $(gen-vars-prereq) $(risc-dv-files) $(TESTLIST) | $(metadata)
- $(verb)rm -rf $(OUT-SEED)/instr_gen
- $(verb)python3 ${GEN_DIR}/run.py \
- --output=$(OUT-SEED)/instr_gen ${GEN_OPTS} \
- --steps=gen \
- --gen_timeout=${TIMEOUT} \
- --lsf_cmd="${LSF_CMD}" \
- --simulator="${SIMULATOR}" \
- ${RISCV_DV_OPTS} \
- ${TEST_OPTS} \
- ${CSR_OPTS} \
- --sim_opts="+uvm_set_inst_override=riscv_asm_program_gen,ibex_asm_program_gen,"uvm_test_top.asm_gen" \
- +signature_addr=${SIGNATURE_ADDR} +pmp_num_regions=${PMP_REGIONS} \
- +pmp_granularity=${PMP_GRANULARITY} +tvec_alignment=8"
- $(call dump-vars,$(metadata)/gen-vars.mk,gen,$(gen-var-deps))
- @touch $@
-
-.PHONY: gen
-gen: $(metadata)/instr_gen.gen.stamp
-
-###############################################################################
-# Compile the generated assembly programs
-#
-# We don't explicitly track dependencies on the RISCV toolchain, so this
-# doesn't depend on anything more than the instr_gen stage did.
-$(metadata)/instr_gen.compile.stamp: \
- $(metadata)/instr_gen.gen.stamp $(TESTLIST)
- $(verb)python3 ${GEN_DIR}/run.py \
- --o=$(OUT-SEED)/instr_gen ${GEN_OPTS} \
- --steps=gcc_compile \
- ${TEST_OPTS} \
- --gcc_opts=-mno-strict-align \
- ${RISCV_DV_OPTS} && \
- touch $@
-
-.PHONY: gcc_compile
-gcc_compile: $(metadata)/instr_gen.compile.stamp
-
-###############################################################################
-# Run the instruction set simulator
-#
-# This (obviously) depends on having compiled the generated programs, so we
-# don't have to worry about variables that affect the 'gen' stage. However, the
-# ISS and ISS_OPTS variables do affect the output, so we need to dump them. See
-# the 'gen' stage for more verbose explanations of how this works.
-iss-var-deps := ISS ISS_OPTS
--include $(metadata)/iss-vars.mk
-iss-vars-prereq = $(call vars-prereq,iss,running ISS,$(iss-var-deps))
-
-$(metadata)/instr_gen.iss.stamp: \
- $(iss-vars-prereq) $(TESTLIST) $(metadata)/instr_gen.compile.stamp
- $(verb)python3 ${GEN_DIR}/run.py \
- --o=$(OUT-SEED)/instr_gen ${GEN_OPTS} \
- --steps=iss_sim \
- ${TEST_OPTS} \
- --iss="${ISS}" \
- --iss_opts="${ISS_OPTS}" \
- ${RISCV_DV_OPTS}
- $(call dump-vars,$(metadata)/iss-vars.mk,iss,$(iss-var-deps))
- @touch $@
-
-.PHONY: iss_sim
-iss_sim: $(metadata)/instr_gen.iss.stamp
-
-
-###############################################################################
-# Compile ibex core TB
-#
-# Note that (unlike everything else) this doesn't depend on the seed: the DUT
-# doesn't depend on which test we're running!
-#
-# It does, however, depend on various variables. These are listed in
-# compile-var-deps. See the 'gen' stage for more verbose explanations of how
-# the variable dumping works.
-#
-# The compiled ibex testbench (obviously!) also depends on the design and the
-# DV code. The clever way of doing this would be to look at a dependency
-# listing generated by the simulator as a side-effect of doing the compile (a
-# bit like using the -M flags with a C compiler). Unfortunately, that doesn't
-# look like it's particularly easy, so we'll just depend on every .v, .sv or
-# .svh file in the dv or rtl directories. Note that this variable is set with
-# '=', rather than ':='. This means that we don't bother running the find
-# commands unless we need the compiled testbench.
-all-verilog = \
- $(shell find ../../../rtl -name '*.v' -o -name '*.sv' -o -name '*.svh') \
- $(shell find ../.. -name '*.v' -o -name '*.sv' -o -name '*.svh')
-
-compile-var-deps := COMMON_OPTS SIMULATOR COV WAVES COMPILE_OPTS
--include $(OUT-DIR)rtl_sim/.compile-vars.mk
-compile-vars-prereq = $(call vars-prereq,comp,compiling TB,$(compile-var-deps))
-
-$(call dump-vars-match,$(compile-var-deps),comp)
-
-cov-arg := $(if $(call equal,$(COV),1),--en_cov,)
-wave-arg := $(if $(call equal,$(WAVES),1),--en_wave,)
-lsf-arg := $(if $(LSF_CMD),--lsf_cmd="$(LSF_CMD)",)
-
-$(OUT-DIR)rtl_sim/.compile.stamp: \
- $(compile-vars-prereq) $(all-verilog) $(risc-dv-files) \
- sim.py yaml/rtl_simulation.yaml \
- | $(OUT-DIR)rtl_sim
- $(verb)./sim.py \
- --o=$(OUT-DIR) \
- --steps=compile \
- ${COMMON_OPTS} \
- --simulator="${SIMULATOR}" --simulator_yaml=yaml/rtl_simulation.yaml \
- $(cov-arg) $(wave-arg) $(lsf-arg) \
- --cmp_opts="${COMPILE_OPTS}"
- $(call dump-vars,$(OUT-DIR)rtl_sim/.compile-vars.mk,comp,$(compile-var-deps))
- @touch $@
-
-.PHONY: compile
-compile: $(OUT-DIR)rtl_sim/.compile.stamp
-
-###############################################################################
-# Run ibex RTL simulation with generated programs
-#
-# Because we compile a TB once rather than for each seed, we have to copy in
-# that directory before we start. We make this step (rather than actually
-# running the test) dependent on having the right variables. That way, we'll
-# correctly delete the sim directory and re-copy it if necessary.
-#
-# Note that the variables we depend on are gen-vars-prereq. We also depend on
-# COV and WAVES, but these dependencies will come for free from the dependency
-# on the compiled TB.
-$(metadata)/rtl_sim.compile.stamp: \
- $(gen-vars-prereq) $(risc-dv-files) $(OUT-DIR)rtl_sim/.compile.stamp
- rm -rf $(OUT-SEED)/rtl_sim
- cp -r $(OUT-DIR)rtl_sim $(OUT-SEED)
- @touch $@
-
-# This rule actually runs the simulation. It depends on the copied-in testbench
-# and also on us having already compiled the test programs.
-$(metadata)/rtl_sim.run.stamp: \
- $(metadata)/rtl_sim.compile.stamp \
- $(metadata)/instr_gen.compile.stamp $(TESTLIST) \
- sim.py yaml/rtl_simulation.yaml
- $(verb)./sim.py \
- --o=$(OUT-SEED) \
- --steps=sim \
- ${TEST_OPTS} \
- --simulator="${SIMULATOR}" --simulator_yaml=yaml/rtl_simulation.yaml \
- $(cov-arg) $(wave-arg) $(lsf-arg) \
- --sim_opts="+signature_addr=${SIGNATURE_ADDR} ${SIM_OPTS}"
- @touch $@
-
-.PHONY: rtl_sim
-rtl_sim: $(metadata)/rtl_sim.run.stamp
-
-###############################################################################
-# Compare ISS and RTL sim results
-$(OUT-SEED)/regr.log: \
- $(metadata)/instr_gen.iss.stamp \
- $(metadata)/rtl_sim.run.stamp $(TESTLIST)
- $(verb)rm -f $@
- $(verb)./sim.py \
- --o=$(OUT-SEED) \
- --steps=compare \
- ${TEST_OPTS} \
- --simulator="${SIMULATOR}" \
- --iss="${ISS}"
-
-.PHONY: post_compare
-post_compare: $(OUT-SEED)/regr.log
-
-###############################################################################
-# Generate RISCV-DV functional coverage
-# TODO(udi) - add B extension
-fcov:
- $(verb)python3 ${GEN_DIR}/cov.py \
- --core ibex \
- --dir ${OUT-SEED}/rtl_sim \
- -o ${OUT-SEED}/fcov \
- --isa rv32imcb \
- --custom_target riscv_dv_extension
-
-# Merge all output coverage directories into the /rtl_sim directory
-cov:
- $(verb)rm -rf $(OUT-DIR)rtl_sim/test.vdb
- $(verb)./sim.py \
- --steps=cov \
- ${TEST_OPTS} \
- --simulator="${SIMULATOR}" \
- $(lsf-arg) \
- --o="$(OUT-DIR)"
- @if [ -d "test.vdb" ]; then \
- mv -f test.vdb $(OUT-DIR)rtl_sim/; \
- fi
diff --git a/dv/uvm/core_ibex/README.md b/dv/uvm/core_ibex/README.md
new file mode 100644
index 00000000..d1fdc092
--- /dev/null
+++ b/dv/uvm/core_ibex/README.md
@@ -0,0 +1,35 @@
+# DV for the ibex core
+
+For detailed documention on how Ibex's verification works, please have a look at [the dedicated documentation page](https://ibex-core.readthedocs.io/en/latest/03_reference/verification.html).
+This README provides a quick start guide to get things running.
+
+## Prerequisites
+You need to have Xcelium available on your machine.
+You can check whether you have it available by running: `xrun --verison`
+
+You also need Spike to be able to compare to in the cosimulation.
+We use a lowRISC specific Spike which you can find [on its own GitHub page](https://github.com/lowRISC/riscv-isa-sim/tree/ibex_cosim).
+Some quick build instructions from within the `riscv-isa-sim` repo:
+```bash
+mkdir build
+cd build
+../configure --enable-commitlog --enable-misaligned --prefix=$SPIKE_INSTALL_DIR
+make
+make install
+export SPIKE_PATH=$SPIKE_INSTALL_DIR/bin
+export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$SPIKE_INSTALL_DIR/lib/pkgconfig
+```
+
+You will need the [RISC-V toolchain](https://github.com/riscv-collab/riscv-gnu-toolchain).
+You'll need to add this to your path and then also set the following environment variables:
+```bash
+export RISCV_GCC=riscv32-unknown-elf-gcc
+export RISCV_OBJCOPY=riscv32-unknown-elf-objcopy
+```
+
+## Running tests
+
+To run tests you can make variations of the following command, where you replace `$TEST_NAME` with the test (or a series of comma-separated tests) that you would like to run as specified in `dv/uvm/core_ibex/riscv_dv_extension/testlist.yaml`:
+```bash
+make --keep-going IBEX_CONFIG=opentitan SIMULATOR=xlm ISS=spike ITERATIONS=1 SEED=1 TEST=$TEST_NAME WAVES=0 COV=0
+```
\ No newline at end of file
diff --git a/lint/verible_waiver.vbw b/dv/uvm/core_ibex/__init__.py
similarity index 100%
rename from lint/verible_waiver.vbw
rename to dv/uvm/core_ibex/__init__.py
diff --git a/dv/uvm/icache/dv/ibex_icache_ecc_agent/seq_lib/ibex_icache_ecc_seq_list.sv b/dv/uvm/core_ibex/common/date.c
similarity index 68%
rename from dv/uvm/icache/dv/ibex_icache_ecc_agent/seq_lib/ibex_icache_ecc_seq_list.sv
rename to dv/uvm/core_ibex/common/date.c
index ccc8b96f..c402503b 100644
--- a/dv/uvm/icache/dv/ibex_icache_ecc_agent/seq_lib/ibex_icache_ecc_seq_list.sv
+++ b/dv/uvm/core_ibex/common/date.c
@@ -2,4 +2,5 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
-`include "ibex_icache_ecc_base_seq.sv"
+#include
+long int get_unix_timestamp() { return time(NULL); }
diff --git a/dv/uvm/core_ibex/common/date_dpi.svh b/dv/uvm/core_ibex/common/date_dpi.svh
new file mode 100644
index 00000000..62e42670
--- /dev/null
+++ b/dv/uvm/core_ibex/common/date_dpi.svh
@@ -0,0 +1,10 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+`ifndef DATE_DPI_SVH
+`define DATE_DPI_SVH
+
+import "DPI-C" function longint get_unix_timestamp();
+
+`endif
diff --git a/dv/uvm/core_ibex/common/ibex_cosim_agent/core_ibex_ifetch_if.sv b/dv/uvm/core_ibex/common/ibex_cosim_agent/core_ibex_ifetch_if.sv
new file mode 100644
index 00000000..bea78ef6
--- /dev/null
+++ b/dv/uvm/core_ibex/common/ibex_cosim_agent/core_ibex_ifetch_if.sv
@@ -0,0 +1,28 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+interface core_ibex_ifetch_if(input logic clk);
+ logic reset;
+
+ logic fetch_ready;
+ logic fetch_valid;
+ logic [31:0] fetch_rdata;
+ logic [31:0] fetch_addr;
+ logic fetch_err;
+ logic fetch_err_plus2;
+
+ clocking monitor_cb @(posedge clk);
+ input reset;
+ input fetch_ready;
+ input fetch_valid;
+ input fetch_rdata;
+ input fetch_addr;
+ input fetch_err;
+ input fetch_err_plus2;
+ endclocking
+
+ task automatic wait_clks(input int num);
+ repeat (num) @(posedge clk);
+ endtask
+endinterface
diff --git a/dv/uvm/core_ibex/common/ibex_cosim_agent/core_ibex_ifetch_pmp_if.sv b/dv/uvm/core_ibex/common/ibex_cosim_agent/core_ibex_ifetch_pmp_if.sv
new file mode 100644
index 00000000..9555102f
--- /dev/null
+++ b/dv/uvm/core_ibex/common/ibex_cosim_agent/core_ibex_ifetch_pmp_if.sv
@@ -0,0 +1,22 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+interface core_ibex_ifetch_pmp_if(input logic clk);
+ logic reset;
+
+ logic fetch_valid;
+ logic [31:0] fetch_addr;
+ logic fetch_pmp_err;
+
+ clocking monitor_cb @(posedge clk);
+ input reset;
+ input fetch_valid;
+ input fetch_addr;
+ input fetch_pmp_err;
+ endclocking
+
+ task automatic wait_clks(input int num);
+ repeat (num) @(posedge clk);
+ endtask
+endinterface : core_ibex_ifetch_pmp_if
diff --git a/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_cosim_agent.sv b/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_cosim_agent.sv
new file mode 100644
index 00000000..7a1d5088
--- /dev/null
+++ b/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_cosim_agent.sv
@@ -0,0 +1,80 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+`include "cosim_dpi.svh"
+
+class ibex_cosim_agent extends uvm_agent;
+ ibex_rvfi_monitor rvfi_monitor;
+ ibex_ifetch_monitor ifetch_monitor;
+ ibex_ifetch_pmp_monitor ifetch_pmp_monitor;
+ ibex_cosim_scoreboard scoreboard;
+
+ uvm_analysis_export#(ibex_mem_intf_seq_item) dmem_port;
+ uvm_analysis_export#(ibex_mem_intf_seq_item) imem_port;
+
+ `uvm_component_utils(ibex_cosim_agent)
+
+ function new(string name="", uvm_component parent=null);
+ super.new(name, parent);
+
+ dmem_port = new("dmem_port", this);
+ imem_port = new("imem_port", this);
+ endfunction
+
+ virtual function void build_phase(uvm_phase phase);
+ super.build_phase(phase);
+
+ rvfi_monitor = ibex_rvfi_monitor::type_id::create("rvfi_monitor", this);
+ scoreboard = ibex_cosim_scoreboard::type_id::create("scoreboard", this);
+ ifetch_monitor = ibex_ifetch_monitor::type_id::create("ifetch_monitor", this);
+ ifetch_pmp_monitor = ibex_ifetch_pmp_monitor::type_id::create("ifetch_pmp_monitor", this);
+ endfunction: build_phase
+
+ virtual function void connect_phase(uvm_phase phase);
+ super.connect_phase(phase);
+
+ rvfi_monitor.item_collected_port.connect(scoreboard.rvfi_port.analysis_export);
+ ifetch_monitor.item_collected_port.connect(scoreboard.ifetch_port.analysis_export);
+ ifetch_pmp_monitor.item_collected_port.connect(scoreboard.ifetch_pmp_port.analysis_export);
+ dmem_port.connect(scoreboard.dmem_port.analysis_export);
+ imem_port.connect(scoreboard.imem_port.analysis_export);
+ endfunction: connect_phase
+
+ function void write_mem_byte(bit [31:0] addr, bit [7:0] d);
+ riscv_cosim_write_mem_byte(scoreboard.cosim_handle, addr, d);
+ endfunction
+
+ function void write_mem_word(bit [31:0] addr, bit [DATA_WIDTH-1:0] d);
+ for (int i = 0; i < DATA_WIDTH / 8; i++) begin
+ write_mem_byte(addr + i, d[7:0]);
+ d = d >> 8;
+ end
+ endfunction
+
+ // Backdoor-load the test binary file into the cosim memory model
+ function void load_binary_to_mem(bit[31:0] base_addr, string bin);
+ bit [7:0] r8;
+ bit [31:0] addr = base_addr;
+ int bin_fd;
+ bin_fd = $fopen(bin,"rb");
+ if (!bin_fd)
+ `uvm_fatal(get_full_name(), $sformatf("Cannot open file %0s", bin))
+ while ($fread(r8,bin_fd)) begin
+ `uvm_info(`gfn, $sformatf("Init mem [0x%h] = 0x%0h", addr, r8), UVM_FULL)
+ write_mem_byte(addr, r8);
+ addr++;
+ end
+ endfunction
+
+ function void reset();
+ scoreboard.rvfi_port.flush();
+ scoreboard.dmem_port.flush();
+ scoreboard.imem_port.flush();
+ scoreboard.ifetch_port.flush();
+ scoreboard.ifetch_pmp_port.flush();
+
+ scoreboard.reset_e.trigger();
+ endfunction : reset
+
+endclass : ibex_cosim_agent
diff --git a/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_cosim_agent_pkg.sv b/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_cosim_agent_pkg.sv
new file mode 100644
index 00000000..12efaa6d
--- /dev/null
+++ b/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_cosim_agent_pkg.sv
@@ -0,0 +1,20 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+package ibex_cosim_agent_pkg;
+ import uvm_pkg::*;
+ import ibex_mem_intf_pkg::*;
+
+ `include "uvm_macros.svh"
+
+ `include "ibex_cosim_cfg.sv"
+ `include "ibex_rvfi_seq_item.sv"
+ `include "ibex_rvfi_monitor.sv"
+ `include "ibex_ifetch_seq_item.sv"
+ `include "ibex_ifetch_monitor.sv"
+ `include "ibex_ifetch_pmp_seq_item.sv"
+ `include "ibex_ifetch_pmp_monitor.sv"
+ `include "ibex_cosim_scoreboard.sv"
+ `include "ibex_cosim_agent.sv"
+endpackage
diff --git a/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_cosim_cfg.sv b/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_cosim_cfg.sv
new file mode 100644
index 00000000..f6ddbed3
--- /dev/null
+++ b/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_cosim_cfg.sv
@@ -0,0 +1,32 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class core_ibex_cosim_cfg extends uvm_object;
+ string isa_string;
+ bit [31:0] start_pc;
+ bit [31:0] start_mtvec;
+ bit probe_imem_for_errs;
+ string log_file;
+ bit [31:0] pmp_num_regions;
+ bit [31:0] pmp_granularity;
+ bit [31:0] mhpm_counter_num;
+ bit relax_cosim_check;
+ bit secure_ibex;
+ bit icache;
+
+ `uvm_object_utils_begin(core_ibex_cosim_cfg)
+ `uvm_field_string(isa_string, UVM_DEFAULT)
+ `uvm_field_int(start_pc, UVM_DEFAULT)
+ `uvm_field_int(start_mtvec, UVM_DEFAULT)
+ `uvm_field_int(probe_imem_for_errs, UVM_DEFAULT)
+ `uvm_field_string(log_file, UVM_DEFAULT)
+ `uvm_field_int(pmp_num_regions, UVM_DEFAULT)
+ `uvm_field_int(pmp_granularity, UVM_DEFAULT)
+ `uvm_field_int(mhpm_counter_num, UVM_DEFAULT)
+ `uvm_field_int(secure_ibex, UVM_DEFAULT)
+ `uvm_field_int(icache, UVM_DEFAULT)
+ `uvm_object_utils_end
+
+ `uvm_object_new
+endclass
diff --git a/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_cosim_scoreboard.sv b/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_cosim_scoreboard.sv
new file mode 100644
index 00000000..5fd0685e
--- /dev/null
+++ b/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_cosim_scoreboard.sv
@@ -0,0 +1,358 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+`include "spike_cosim_dpi.svh"
+`include "cosim_dpi.svh"
+
+class ibex_cosim_scoreboard extends uvm_scoreboard;
+ chandle cosim_handle;
+
+ core_ibex_cosim_cfg cfg;
+
+ uvm_tlm_analysis_fifo #(ibex_rvfi_seq_item) rvfi_port;
+ uvm_tlm_analysis_fifo #(ibex_mem_intf_seq_item) dmem_port;
+ uvm_tlm_analysis_fifo #(ibex_mem_intf_seq_item) imem_port;
+ uvm_tlm_analysis_fifo #(ibex_ifetch_seq_item) ifetch_port;
+ uvm_tlm_analysis_fifo #(ibex_ifetch_pmp_seq_item) ifetch_pmp_port;
+
+ virtual core_ibex_instr_monitor_if instr_vif;
+ virtual core_ibex_dut_probe_if dut_vif;
+
+ uvm_event reset_e;
+ uvm_event check_inserted_iside_error_e;
+
+ bit failed_iside_accesses [bit[31:0]];
+ bit iside_pmp_failure [bit[31:0]];
+
+ typedef struct {
+ bit [63:0] order;
+ bit [31:0] addr;
+ } iside_err_t;
+
+ iside_err_t iside_error_queue [$];
+
+ `uvm_component_utils(ibex_cosim_scoreboard)
+
+ function new(string name="", uvm_component parent=null);
+ super.new(name, parent);
+
+ rvfi_port = new("rvfi_port", this);
+ dmem_port = new("dmem_port", this);
+ imem_port = new("imem_port", this);
+ ifetch_port = new("ifetch_port", this);
+ ifetch_pmp_port = new("ifetch_pmp_port", this);
+ cosim_handle = null;
+ reset_e = new();
+ check_inserted_iside_error_e = new();
+ endfunction
+
+ function void build_phase(uvm_phase phase);
+ super.build_phase(phase);
+
+ if (!uvm_config_db#(core_ibex_cosim_cfg)::get(this, "", "cosim_cfg", cfg)) begin
+ `uvm_fatal(`gfn, "Cannot get cosim configuration")
+ end
+
+ if (!uvm_config_db#(virtual core_ibex_instr_monitor_if)::get(null, "", "instr_monitor_if",
+ instr_vif)) begin
+ `uvm_fatal(`gfn, "Cannot get instr_monitor_if")
+ end
+
+ if (!uvm_config_db#(virtual core_ibex_dut_probe_if)::get(null, "", "dut_if",
+ dut_vif)) begin
+ `uvm_fatal(`gfn, "Cannot get dut_probe_if")
+ end
+
+ init_cosim();
+ endfunction : build_phase
+
+ protected function void init_cosim();
+ cleanup_cosim();
+
+ // TODO: Ensure log file on reset gets append rather than overwrite?
+ cosim_handle = spike_cosim_init(cfg.isa_string, cfg.start_pc, cfg.start_mtvec, cfg.log_file,
+ cfg.pmp_num_regions, cfg.pmp_granularity, cfg.mhpm_counter_num, cfg.secure_ibex, cfg.icache);
+
+ if (cosim_handle == null) begin
+ `uvm_fatal(`gfn, "Could not initialise cosim")
+ end
+ endfunction
+
+ protected function void cleanup_cosim();
+ if (cosim_handle) begin
+ spike_cosim_release(cosim_handle);
+ end
+ cosim_handle = null;
+ endfunction
+
+ virtual task run_phase(uvm_phase phase);
+ forever begin
+ @(negedge instr_vif.reset)
+ fork : isolation_fork
+ run_cosim_rvfi();
+ run_cosim_dmem();
+ run_cosim_imem_errors();
+ run_cosim_prune_imem_errors();
+ if (cfg.probe_imem_for_errs) begin
+ run_cosim_imem();
+ end else begin
+ fork
+ run_cosim_ifetch();
+ run_cosim_ifetch_pmp();
+ join_any
+ end
+ join_none
+ reset_e.wait_trigger();
+ disable fork;
+ handle_reset();
+ end // forever
+ endtask : run_phase
+
+ task run_cosim_rvfi();
+ ibex_rvfi_seq_item rvfi_instr;
+
+ forever begin
+ rvfi_port.get(rvfi_instr);
+
+ if (rvfi_instr.irq_only) begin
+ // RVFI item is only notifying about new interrupts, not a retired instruction, so provide
+ // cosim with interrupt information and loop back to await the next item.
+ riscv_cosim_set_nmi(cosim_handle, rvfi_instr.nmi);
+ riscv_cosim_set_nmi_int(cosim_handle, rvfi_instr.nmi_int);
+ riscv_cosim_set_mip(cosim_handle, rvfi_instr.pre_mip, rvfi_instr.pre_mip);
+
+ continue;
+ end
+
+ if (iside_error_queue.size() > 0) begin
+ // Remove entries from iside_error_queue where the instruction never reaches the RVFI
+ // interface because it was flushed.
+ while (iside_error_queue.size() > 0 && iside_error_queue[0].order < rvfi_instr.order) begin
+ iside_error_queue.pop_front();
+ end
+
+ // Check if the top of the iside_error_queue relates to the current RVFI instruction. If so
+ // notify the cosim environment of an instruction error.
+ if (iside_error_queue.size() !=0 && iside_error_queue[0].order == rvfi_instr.order) begin
+ riscv_cosim_set_iside_error(cosim_handle, iside_error_queue[0].addr);
+ iside_error_queue.pop_front();
+ end
+ end
+
+ // Note these must be called in this order to ensure debug vs nmi vs normal interrupt are
+ // handled with the correct priority when they occur together.
+ riscv_cosim_set_debug_req(cosim_handle, rvfi_instr.debug_req);
+ riscv_cosim_set_nmi(cosim_handle, rvfi_instr.nmi);
+ riscv_cosim_set_nmi_int(cosim_handle, rvfi_instr.nmi_int);
+ riscv_cosim_set_mip(cosim_handle, rvfi_instr.pre_mip, rvfi_instr.post_mip);
+ riscv_cosim_set_mcycle(cosim_handle, rvfi_instr.mcycle);
+
+ // Set performance counters through a pseudo-backdoor write
+ for (int i=0; i < 10; i++) begin
+ riscv_cosim_set_csr(cosim_handle,
+ ibex_pkg::CSR_MHPMCOUNTER3 + i, rvfi_instr.mhpmcounters[i]);
+ riscv_cosim_set_csr(cosim_handle,
+ ibex_pkg::CSR_MHPMCOUNTER3H + i, rvfi_instr.mhpmcountersh[i]);
+ end
+
+ riscv_cosim_set_ic_scr_key_valid(cosim_handle, rvfi_instr.ic_scr_key_valid);
+
+ if (!riscv_cosim_step(cosim_handle, rvfi_instr.rd_addr, rvfi_instr.rd_wdata, rvfi_instr.pc,
+ rvfi_instr.trap, rvfi_instr.rf_wr_suppress)) begin
+ // cosim instruction step doesn't match rvfi captured instruction, report a fatal error
+ // with the details
+ if (cfg.relax_cosim_check) begin
+ `uvm_info(`gfn, get_cosim_error_str(), UVM_LOW)
+ end else begin
+ `uvm_fatal(`gfn, get_cosim_error_str())
+ end
+ end
+ end
+ endtask: run_cosim_rvfi
+
+ task run_cosim_dmem();
+ ibex_mem_intf_seq_item mem_op;
+
+ forever begin
+ dmem_port.get(mem_op);
+ // Notify the cosim of all dside accesses emitted by the RTL
+ riscv_cosim_notify_dside_access(cosim_handle, mem_op.read_write == WRITE, mem_op.addr,
+ mem_op.data, mem_op.be, mem_op.error, mem_op.misaligned_first, mem_op.misaligned_second,
+ mem_op.misaligned_first_saw_error, mem_op.m_mode_access);
+ end
+ endtask: run_cosim_dmem
+
+ task run_cosim_imem();
+ ibex_mem_intf_seq_item mem_op;
+
+ forever begin
+ // Take stream of transaction from imem monitor. Where an imem access has an error record it
+ // in failed_iside_accesses. If an access has succeeded remove it from failed_imem_accesses if
+ // it's there.
+ // Note all transactions are 32-bit aligned.
+ imem_port.get(mem_op);
+ if (mem_op.error) begin
+ failed_iside_accesses[mem_op.addr] = 1'b1;
+ end else begin
+ if (failed_iside_accesses.exists(mem_op.addr)) begin
+ failed_iside_accesses.delete(mem_op.addr);
+ end
+ end
+ end
+ endtask: run_cosim_imem
+
+ task run_cosim_ifetch();
+ ibex_ifetch_seq_item ifetch;
+ bit [31:0] aligned_fetch_addr;
+ bit [31:0] aligned_fetch_addr_next;
+
+ forever begin
+ ifetch_port.get(ifetch);
+ aligned_fetch_addr = {ifetch.fetch_addr[31:2], 2'b0};
+ aligned_fetch_addr_next = aligned_fetch_addr + 32'd4;
+
+ if (ifetch.fetch_err) begin
+ // Instruction error observed in fetch stage
+ bit [31:0] failing_addr;
+
+ // Determine which address failed.
+ if (ifetch.fetch_err_plus2) begin
+ // Instruction crosses a 32-bit boundary and second half failed
+ failing_addr = aligned_fetch_addr_next;
+ end else begin
+ failing_addr = aligned_fetch_addr;
+ end
+
+ failed_iside_accesses[failing_addr] = 1'b1;
+ end else begin
+ if (ifetch.fetch_addr[1:0] != 0 && ifetch.fetch_rdata[1:0] == 2'b11) begin
+ // Instruction crosses 32-bit boundary, so remove any failed accesses on the other side of
+ // the 32-bit boundary.
+ if (failed_iside_accesses.exists(aligned_fetch_addr_next)) begin
+ failed_iside_accesses.delete(aligned_fetch_addr_next);
+ end
+ end
+
+ if (failed_iside_accesses.exists(aligned_fetch_addr)) begin
+ failed_iside_accesses.delete(aligned_fetch_addr);
+ end
+ end
+ end
+ endtask: run_cosim_ifetch
+
+ task run_cosim_ifetch_pmp();
+ ibex_ifetch_pmp_seq_item ifetch_pmp;
+
+ // Keep track of which addresses have seen PMP failures.
+ forever begin
+ ifetch_pmp_port.get(ifetch_pmp);
+
+ if (ifetch_pmp.fetch_pmp_err) begin
+ iside_pmp_failure[ifetch_pmp.fetch_addr] = 1'b1;
+ end else begin
+ if (iside_pmp_failure.exists(ifetch_pmp.fetch_addr)) begin
+ iside_pmp_failure.delete(ifetch_pmp.fetch_addr);
+ end
+ end
+ end
+ endtask
+
+ task run_cosim_imem_errors();
+ bit [63:0] latest_order = 64'hffffffff_ffffffff;
+ bit [31:0] aligned_addr;
+ bit [31:0] aligned_next_addr;
+ forever begin
+ // Wait for new instruction to appear in ID stage
+ wait (instr_vif.instr_cb.valid_id &&
+ instr_vif.instr_cb.instr_new_id &&
+ latest_order != instr_vif.instr_cb.rvfi_order_id);
+
+ latest_order = instr_vif.instr_cb.rvfi_order_id;
+
+ if (dut_vif.dut_cb.wb_exception)
+ // If an exception in writeback occurs the instruction in ID will be flushed and hence not
+ // produce an iside error so skip the rest of the loop. A writeback exception may occur
+ // after this cycle before the instruction in ID moves out of the ID stage. The
+ // `run_cosim_prune_imem_errors` task deals with this case.
+ continue;
+
+ // Determine if the instruction comes from an address that has seen an error that wasn't a PMP
+ // error (the icache records both PMP errors and fetch errors with the same error bits). If a
+ // fetch error was seen add the instruction order ID and address to iside_error_queue.
+ aligned_addr = instr_vif.instr_cb.pc_id & 32'hfffffffc;
+ aligned_next_addr = aligned_addr + 32'd4;
+
+ if (failed_iside_accesses.exists(aligned_addr) && !iside_pmp_failure.exists(aligned_addr))
+ begin
+ iside_error_queue.push_back('{order : instr_vif.instr_cb.rvfi_order_id,
+ addr : aligned_addr});
+ check_inserted_iside_error_e.trigger();
+ end else if (!instr_vif.instr_cb.is_compressed_id &&
+ (instr_vif.instr_cb.pc_id & 32'h3) != 0 &&
+ failed_iside_accesses.exists(aligned_next_addr) &&
+ !iside_pmp_failure.exists(aligned_next_addr))
+ begin
+ // Where an instruction crosses a 32-bit boundary, check if an error was seen on the other
+ // side of the boundary
+ iside_error_queue.push_back('{order : instr_vif.instr_cb.rvfi_order_id,
+ addr : aligned_next_addr});
+ check_inserted_iside_error_e.trigger();
+ end
+
+ end
+ endtask: run_cosim_imem_errors;
+
+ task run_cosim_prune_imem_errors();
+ // Errors are added to the iside error queue the first cycle the instruction that sees the error
+ // is in the ID stage. Cycles following this the writeback stage may cause an exception flushing
+ // the ID stage so the iside error never occurs. When this happens we need to pop the new iside
+ // error off the queue.
+ forever begin
+ // Wait until the `run_cosim_imem_errors` task notifies us it's added a error to the queue
+ check_inserted_iside_error_e.wait_ptrigger();
+ // Wait for the next clock
+ @(instr_vif.instr_cb);
+ // Wait for a new instruction or a writeback exception. When a new instruction has entered the
+ // ID stage and we haven't seen a writeback exception we know the instruction associated with the
+ // error just added to the queue isn't getting flushed.
+ wait (instr_vif.instr_cb.instr_new_id || dut_vif.dut_cb.wb_exception);
+
+ if (!instr_vif.instr_cb.instr_new_id && dut_vif.dut_cb.wb_exception) begin
+ // If we hit a writeback exception without seeing a new instruction then the newly added
+ // error relates to an instruction just flushed from the ID stage so pop it from the
+ // queue.
+ iside_error_queue.pop_back();
+ end
+ end
+ endtask: run_cosim_prune_imem_errors
+
+ function string get_cosim_error_str();
+ string error = "Cosim mismatch ";
+ for (int i = 0; i < riscv_cosim_get_num_errors(cosim_handle); ++i) begin
+ error = {error, riscv_cosim_get_error(cosim_handle, i), "\n"};
+ end
+ riscv_cosim_clear_errors(cosim_handle);
+
+ return error;
+ endfunction : get_cosim_error_str
+
+ function void final_phase(uvm_phase phase);
+ super.final_phase(phase);
+
+ `uvm_info(`gfn, $sformatf("Co-simulation matched %d instructions",
+ riscv_cosim_get_insn_cnt(cosim_handle)), UVM_LOW)
+
+ cleanup_cosim();
+ endfunction : final_phase
+
+ // If the UVM_EXIT action is triggered (such as by reaching max_quit_count), this callback is run.
+ // This ensures proper cleanup, such as commiting the logfile to disk.
+ function void pre_abort();
+ cleanup_cosim();
+ endfunction
+
+ task handle_reset();
+ init_cosim();
+ endtask
+endclass : ibex_cosim_scoreboard
diff --git a/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_ifetch_monitor.sv b/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_ifetch_monitor.sv
new file mode 100644
index 00000000..d76a3ae1
--- /dev/null
+++ b/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_ifetch_monitor.sv
@@ -0,0 +1,45 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class ibex_ifetch_monitor extends uvm_monitor;
+ protected virtual core_ibex_ifetch_if vif;
+
+ uvm_analysis_port#(ibex_ifetch_seq_item) item_collected_port;
+
+ `uvm_component_utils(ibex_ifetch_monitor)
+ `uvm_component_new
+
+ function void build_phase(uvm_phase phase);
+ super.build_phase(phase);
+
+ item_collected_port = new("item_collected_port", this);
+
+ if(!uvm_config_db#(virtual core_ibex_ifetch_if)::get(this, "", "ifetch_if", vif)) begin
+ `uvm_fatal("NOVIF", {"virtual interface must be set for: ", get_full_name(), ".vif"});
+ end
+ endfunction
+
+ virtual task run_phase(uvm_phase phase);
+ ibex_ifetch_seq_item trans_collected;
+
+ wait (vif.monitor_cb.reset === 1'b0);
+
+ forever begin
+ while(!(vif.monitor_cb.fetch_valid && vif.monitor_cb.fetch_ready)) vif.wait_clks(1);
+
+ trans_collected = ibex_ifetch_seq_item::type_id::create("trans_collected");
+ trans_collected.fetch_rdata = vif.monitor_cb.fetch_rdata;
+ trans_collected.fetch_addr = vif.monitor_cb.fetch_addr;
+ trans_collected.fetch_err = vif.monitor_cb.fetch_err;
+ trans_collected.fetch_err_plus2 = vif.monitor_cb.fetch_err_plus2;
+
+ `uvm_info(`gfn, $sformatf("Seen ifetch:\n%s", trans_collected.sprint()),
+ UVM_HIGH)
+
+ item_collected_port.write(trans_collected);
+
+ vif.wait_clks(1);
+ end
+ endtask: run_phase
+endclass : ibex_ifetch_monitor
diff --git a/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_ifetch_pmp_monitor.sv b/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_ifetch_pmp_monitor.sv
new file mode 100644
index 00000000..a5b232e3
--- /dev/null
+++ b/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_ifetch_pmp_monitor.sv
@@ -0,0 +1,43 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class ibex_ifetch_pmp_monitor extends uvm_monitor;
+ protected virtual core_ibex_ifetch_pmp_if vif;
+
+ uvm_analysis_port#(ibex_ifetch_pmp_seq_item) item_collected_port;
+
+ `uvm_component_utils(ibex_ifetch_pmp_monitor)
+ `uvm_component_new
+
+ function void build_phase(uvm_phase phase);
+ super.build_phase(phase);
+
+ item_collected_port = new("item_collected_port", this);
+
+ if(!uvm_config_db#(virtual core_ibex_ifetch_pmp_if)::get(this, "", "ifetch_pmp_if", vif)) begin
+ `uvm_fatal("NOVIF", {"virtual interface must be set for: ", get_full_name(), ".vif"});
+ end
+ endfunction
+
+ virtual task run_phase(uvm_phase phase);
+ ibex_ifetch_pmp_seq_item trans_collected;
+
+ wait (vif.monitor_cb.reset === 1'b0);
+
+ forever begin
+ while(!vif.monitor_cb.fetch_valid) vif.wait_clks(1);
+
+ trans_collected = ibex_ifetch_pmp_seq_item::type_id::create("trans_collected");
+ trans_collected.fetch_addr = vif.monitor_cb.fetch_addr;
+ trans_collected.fetch_pmp_err = vif.monitor_cb.fetch_pmp_err;
+
+ `uvm_info(`gfn, $sformatf("Seen ifetch:\n%s", trans_collected.sprint()),
+ UVM_HIGH)
+
+ item_collected_port.write(trans_collected);
+
+ vif.wait_clks(1);
+ end
+ endtask: run_phase
+endclass : ibex_ifetch_pmp_monitor
diff --git a/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_ifetch_pmp_seq_item.sv b/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_ifetch_pmp_seq_item.sv
new file mode 100644
index 00000000..d981d737
--- /dev/null
+++ b/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_ifetch_pmp_seq_item.sv
@@ -0,0 +1,15 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class ibex_ifetch_pmp_seq_item extends uvm_sequence_item;
+ bit [31:0] fetch_addr;
+ bit fetch_pmp_err;
+
+ `uvm_object_utils_begin(ibex_ifetch_pmp_seq_item)
+ `uvm_field_int (fetch_addr, UVM_DEFAULT)
+ `uvm_field_int (fetch_pmp_err, UVM_DEFAULT)
+ `uvm_object_utils_end
+
+ `uvm_object_new
+endclass : ibex_ifetch_pmp_seq_item
diff --git a/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_ifetch_seq_item.sv b/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_ifetch_seq_item.sv
new file mode 100644
index 00000000..9b6e7d03
--- /dev/null
+++ b/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_ifetch_seq_item.sv
@@ -0,0 +1,19 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class ibex_ifetch_seq_item extends uvm_sequence_item;
+ bit [31:0] fetch_rdata;
+ bit [31:0] fetch_addr;
+ bit fetch_err;
+ bit fetch_err_plus2;
+
+ `uvm_object_utils_begin(ibex_ifetch_seq_item)
+ `uvm_field_int (fetch_rdata, UVM_DEFAULT)
+ `uvm_field_int (fetch_addr, UVM_DEFAULT)
+ `uvm_field_int (fetch_err, UVM_DEFAULT)
+ `uvm_field_int (fetch_err_plus2, UVM_DEFAULT)
+ `uvm_object_utils_end
+
+ `uvm_object_new
+endclass : ibex_ifetch_seq_item
diff --git a/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_rvfi_monitor.sv b/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_rvfi_monitor.sv
new file mode 100644
index 00000000..0bf50116
--- /dev/null
+++ b/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_rvfi_monitor.sv
@@ -0,0 +1,62 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class ibex_rvfi_monitor extends uvm_monitor;
+ protected virtual core_ibex_rvfi_if vif;
+
+ uvm_analysis_port#(ibex_rvfi_seq_item) item_collected_port;
+
+ `uvm_component_utils(ibex_rvfi_monitor)
+ `uvm_component_new
+
+ function void build_phase(uvm_phase phase);
+ super.build_phase(phase);
+
+ item_collected_port = new("item_collected_port", this);
+
+ if(!uvm_config_db#(virtual core_ibex_rvfi_if)::get(this, "", "rvfi_if", vif)) begin
+ `uvm_fatal("NOVIF", {"virtual interface must be set for: ", get_full_name(), ".vif"});
+ end
+ endfunction: build_phase
+
+ virtual task run_phase(uvm_phase phase);
+ ibex_rvfi_seq_item trans_collected;
+
+ wait (vif.monitor_cb.reset === 1'b0);
+
+ forever begin
+ // Wait for a retired instruction
+ while(!(vif.monitor_cb.valid || vif.monitor_cb.ext_irq_valid)) vif.wait_clks(1);
+
+ // Read instruction details from RVFI interface
+ trans_collected = ibex_rvfi_seq_item::type_id::create("trans_collected");
+ trans_collected.irq_only = !vif.monitor_cb.valid && vif.monitor_cb.ext_irq_valid;
+ trans_collected.trap = vif.monitor_cb.trap;
+ trans_collected.pc = vif.monitor_cb.pc_rdata;
+ trans_collected.rd_addr = vif.monitor_cb.rd_addr;
+ trans_collected.rd_wdata = vif.monitor_cb.rd_wdata;
+ trans_collected.order = vif.monitor_cb.order;
+ trans_collected.pre_mip = vif.monitor_cb.ext_pre_mip;
+ trans_collected.post_mip = vif.monitor_cb.ext_post_mip;
+ trans_collected.nmi = vif.monitor_cb.ext_nmi;
+ trans_collected.nmi_int = vif.monitor_cb.ext_nmi_int;
+ trans_collected.debug_req = vif.monitor_cb.ext_debug_req;
+ trans_collected.rf_wr_suppress = vif.monitor_cb.ext_rf_wr_suppress;
+ trans_collected.mcycle = vif.monitor_cb.ext_mcycle;
+ trans_collected.ic_scr_key_valid = vif.monitor_cb.ext_ic_scr_key_valid;
+
+ for (int i=0; i < 10; i++) begin
+ trans_collected.mhpmcounters[i] = vif.monitor_cb.ext_mhpmcounters[i];
+ trans_collected.mhpmcountersh[i] = vif.monitor_cb.ext_mhpmcountersh[i];
+ end
+
+ `uvm_info(get_full_name(), $sformatf("Seen instruction:\n%s", trans_collected.sprint()),
+ UVM_HIGH)
+
+ item_collected_port.write(trans_collected);
+
+ vif.wait_clks(1);
+ end
+ endtask : run_phase
+endclass : ibex_rvfi_monitor
diff --git a/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_rvfi_seq_item.sv b/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_rvfi_seq_item.sv
new file mode 100644
index 00000000..dceba31c
--- /dev/null
+++ b/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_rvfi_seq_item.sv
@@ -0,0 +1,44 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class ibex_rvfi_seq_item extends uvm_sequence_item;
+ bit irq_only;
+ bit trap;
+ bit [31:0] pc;
+ bit [4:0] rd_addr;
+ bit [31:0] rd_wdata;
+ bit [63:0] order;
+ bit [31:0] pre_mip;
+ bit [31:0] post_mip;
+ bit nmi;
+ bit nmi_int;
+ bit debug_req;
+ bit rf_wr_suppress;
+ bit [63:0] mcycle;
+
+ bit [31:0] mhpmcounters [10];
+ bit [31:0] mhpmcountersh [10];
+ bit ic_scr_key_valid;
+
+ `uvm_object_utils_begin(ibex_rvfi_seq_item)
+ `uvm_field_int (trap, UVM_DEFAULT)
+ `uvm_field_int (pc, UVM_DEFAULT)
+ `uvm_field_int (rd_addr, UVM_DEFAULT)
+ `uvm_field_int (rd_wdata, UVM_DEFAULT)
+ `uvm_field_int (order, UVM_DEFAULT)
+ `uvm_field_int (pre_mip, UVM_DEFAULT)
+ `uvm_field_int (post_mip, UVM_DEFAULT)
+ `uvm_field_int (nmi, UVM_DEFAULT)
+ `uvm_field_int (nmi_int, UVM_DEFAULT)
+ `uvm_field_int (debug_req, UVM_DEFAULT)
+ `uvm_field_int (rf_wr_suppress, UVM_DEFAULT)
+ `uvm_field_int (mcycle, UVM_DEFAULT)
+ `uvm_field_sarray_int (mhpmcounters, UVM_DEFAULT)
+ `uvm_field_sarray_int (mhpmcountersh, UVM_DEFAULT)
+ `uvm_field_int (ic_scr_key_valid, UVM_DEFAULT)
+ `uvm_object_utils_end
+
+ `uvm_object_new
+
+endclass : ibex_rvfi_seq_item
diff --git a/dv/uvm/core_ibex/common/ibex_cosim_agent/spike_cosim_dpi.cc b/dv/uvm/core_ibex/common/ibex_cosim_agent/spike_cosim_dpi.cc
new file mode 100644
index 00000000..b60d35a8
--- /dev/null
+++ b/dv/uvm/core_ibex/common/ibex_cosim_agent/spike_cosim_dpi.cc
@@ -0,0 +1,40 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+#include
+
+#include
+
+#include "cosim.h"
+#include "spike_cosim.h"
+
+extern "C" {
+void *spike_cosim_init(const char *isa_string, svBitVecVal *start_pc,
+ svBitVecVal *start_mtvec, const char *log_file_path_cstr,
+ svBitVecVal *pmp_num_regions,
+ svBitVecVal *pmp_granularity,
+ svBitVecVal *mhpm_counter_num, svBit secure_ibex,
+ svBit icache) {
+ assert(isa_string);
+
+ std::string log_file_path;
+
+ if (log_file_path_cstr) {
+ log_file_path = log_file_path_cstr;
+ }
+
+ SpikeCosim *cosim = new SpikeCosim(
+ isa_string, start_pc[0], start_mtvec[0], log_file_path, secure_ibex,
+ icache, pmp_num_regions[0], pmp_granularity[0], mhpm_counter_num[0]);
+ cosim->add_memory(0x80000000, 0x80000000);
+ cosim->add_memory(0x00000000, 0x80000000);
+ return static_cast(cosim);
+}
+
+void spike_cosim_release(void *cosim_handle) {
+ auto cosim = static_cast(cosim_handle);
+
+ delete cosim;
+}
+}
diff --git a/dv/uvm/core_ibex/common/ibex_cosim_agent/spike_cosim_dpi.svh b/dv/uvm/core_ibex/common/ibex_cosim_agent/spike_cosim_dpi.svh
new file mode 100644
index 00000000..462ff6bf
--- /dev/null
+++ b/dv/uvm/core_ibex/common/ibex_cosim_agent/spike_cosim_dpi.svh
@@ -0,0 +1,21 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+`ifndef SPIKE_COSIM_DPI_SVH
+`define SPIKE_COSIM_DPI_SVH
+
+import "DPI-C" function
+ chandle spike_cosim_init(string isa_string,
+ bit [31:0] start_pc,
+ bit [31:0] start_mtvec,
+ string log_file_path,
+ bit [31:0] pmp_num_regions,
+ bit [31:0] pmp_granularity,
+ bit [31:0] mhpm_counter_num,
+ bit secure_ibex,
+ bit icache);
+
+import "DPI-C" function void spike_cosim_release(chandle cosim_handle);
+
+`endif
diff --git a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf.sv b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf.sv
index 220a263a..e170e4dd 100644
--- a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf.sv
+++ b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf.sv
@@ -4,7 +4,8 @@
interface ibex_mem_intf#(
parameter int ADDR_WIDTH = 32,
- parameter int DATA_WIDTH = 32
+ parameter int DATA_WIDTH = 32,
+ parameter int INTG_WIDTH = 7
) (
input clk
);
@@ -17,8 +18,15 @@ interface ibex_mem_intf#(
wire [DATA_WIDTH/8-1:0] be;
wire rvalid;
wire [DATA_WIDTH-1:0] wdata;
+ wire [INTG_WIDTH-1:0] wintg;
wire [DATA_WIDTH-1:0] rdata;
+ wire [INTG_WIDTH-1:0] rintg;
wire error;
+ wire misaligned_first;
+ wire misaligned_second;
+ wire misaligned_first_saw_error;
+ wire m_mode_access;
+ wire spurious_response;
clocking request_driver_cb @(posedge clk);
input reset;
@@ -29,8 +37,11 @@ interface ibex_mem_intf#(
output be;
input rvalid;
output wdata;
+ output wintg;
input rdata;
+ input rintg;
input error;
+ input spurious_response;
endclocking
clocking response_driver_cb @(posedge clk);
@@ -42,8 +53,11 @@ interface ibex_mem_intf#(
input be;
output rvalid;
input wdata;
+ input wintg;
output rdata;
+ output rintg;
output error;
+ output spurious_response;
endclocking
clocking monitor_cb @(posedge clk);
@@ -55,8 +69,15 @@ interface ibex_mem_intf#(
input be;
input rvalid;
input wdata;
+ input wintg;
input rdata;
+ input rintg;
input error;
+ input misaligned_first;
+ input misaligned_second;
+ input misaligned_first_saw_error;
+ input m_mode_access;
+ input spurious_response;
endclocking
task automatic wait_clks(input int num);
diff --git a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_agent_pkg.sv b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_agent_pkg.sv
index a42683be..cde11e1a 100644
--- a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_agent_pkg.sv
+++ b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_agent_pkg.sv
@@ -5,19 +5,16 @@
package ibex_mem_intf_agent_pkg;
import uvm_pkg::*;
+ import ibex_mem_intf_pkg::*;
import mem_model_pkg::*;
-
- parameter int DATA_WIDTH = 32;
- parameter int ADDR_WIDTH = 32;
-
- typedef enum { READ, WRITE } rw_e;
+ import ibex_cosim_agent_pkg::*;
`include "uvm_macros.svh"
- `include "ibex_mem_intf_seq_item.sv"
typedef uvm_sequencer#(ibex_mem_intf_seq_item) ibex_mem_intf_request_sequencer;
`include "ibex_mem_intf_monitor.sv"
+ `include "ibex_mem_intf_response_agent_cfg.sv"
`include "ibex_mem_intf_response_driver.sv"
`include "ibex_mem_intf_response_sequencer.sv"
`include "ibex_mem_intf_response_seq_lib.sv"
@@ -25,4 +22,8 @@ package ibex_mem_intf_agent_pkg;
`include "ibex_mem_intf_request_driver.sv"
`include "ibex_mem_intf_request_agent.sv"
+ // Re-export parameters from ibex_mem_intf_pkg so that other packages can access them through this
+ // package.
+ export ibex_mem_intf_pkg::*;
+
endpackage
diff --git a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_monitor.sv b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_monitor.sv
index 5717469d..c37fb499 100644
--- a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_monitor.sv
+++ b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_monitor.sv
@@ -10,18 +10,28 @@ class ibex_mem_intf_monitor extends uvm_monitor;
protected virtual ibex_mem_intf vif;
- mailbox #(ibex_mem_intf_seq_item) collect_data_queue;
+ // The monitor tick event fires every clock cycle once any writes to
+ // outstanding_access_port and addr_ph_ports have occurred.
+ event monitor_tick;
+
+ mailbox #(ibex_mem_intf_seq_item) collect_response_queue;
uvm_analysis_port#(ibex_mem_intf_seq_item) item_collected_port;
uvm_analysis_port#(ibex_mem_intf_seq_item) addr_ph_port;
+ // The number of outstanding accesses is written to this port every clock cycle
+ uvm_analysis_port#(int) outstanding_accesses_port;
`uvm_component_utils(ibex_mem_intf_monitor)
`uvm_component_new
+ int outstanding_accesses = 0;
+
function void build_phase(uvm_phase phase);
super.build_phase(phase);
item_collected_port = new("item_collected_port", this);
addr_ph_port = new("addr_ph_port_monitor", this);
- collect_data_queue = new();
+ collect_response_queue = new();
+ outstanding_accesses_port = new("outstanding_accesses_port", this);
+
if(!uvm_config_db#(virtual ibex_mem_intf)::get(this, "", "vif", vif)) begin
`uvm_fatal("NOVIF",{"virtual interface must be set for: ",get_full_name(),".vif"});
end
@@ -30,13 +40,15 @@ class ibex_mem_intf_monitor extends uvm_monitor;
virtual task run_phase(uvm_phase phase);
wait (vif.monitor_cb.reset === 1'b0);
forever begin
- fork : check_mem_intf
- collect_address_phase();
- collect_data_phase();
- wait (vif.monitor_cb.reset === 1'b1);
- join_any
- // Will only reach this point when mid-test reset is asserted
- disable fork;
+ fork begin : isolation_fork
+ fork : check_mem_intf
+ collect_address_phase();
+ collect_response_phase();
+ wait (vif.monitor_cb.reset === 1'b1);
+ join_any
+ // Will only reach this point when mid-test reset is asserted
+ disable fork;
+ end join
handle_reset();
end
endtask : run_phase
@@ -44,45 +56,74 @@ class ibex_mem_intf_monitor extends uvm_monitor;
virtual protected task handle_reset();
ibex_mem_intf_seq_item mailbox_result;
// Clear the mailbox of any content
- while (collect_data_queue.try_get(mailbox_result));
+ while (collect_response_queue.try_get(mailbox_result));
wait (vif.monitor_cb.reset === 1'b0);
endtask
virtual protected task collect_address_phase();
ibex_mem_intf_seq_item trans_collected;
+
+
forever begin
+ @(vif.monitor_cb);
+
trans_collected = ibex_mem_intf_seq_item::type_id::create("trans_collected");
- while(!(vif.monitor_cb.request && vif.monitor_cb.grant)) vif.wait_clks(1);
- trans_collected.addr = vif.monitor_cb.addr;
- trans_collected.be = vif.monitor_cb.be;
+
+ while (!(vif.monitor_cb.request && vif.monitor_cb.grant)) begin
+ if (vif.monitor_cb.rvalid && !vif.monitor_cb.spurious_response) begin
+ outstanding_accesses--;
+ end
+ outstanding_accesses_port.write(outstanding_accesses);
+
+ -> monitor_tick;
+ @(vif.monitor_cb);
+ end
+
+ trans_collected.addr = vif.monitor_cb.addr;
+ trans_collected.be = vif.monitor_cb.be;
+ trans_collected.misaligned_first = vif.monitor_cb.misaligned_first;
+ trans_collected.misaligned_second = vif.monitor_cb.misaligned_second;
+ trans_collected.misaligned_first_saw_error = vif.monitor_cb.misaligned_first_saw_error;
+ trans_collected.m_mode_access = vif.monitor_cb.m_mode_access;
`uvm_info(get_full_name(), $sformatf("Detect request with address: %0x",
trans_collected.addr), UVM_HIGH)
- if(vif.monitor_cb.we) begin
+ if (vif.monitor_cb.we) begin
trans_collected.read_write = WRITE;
trans_collected.data = vif.monitor_cb.wdata;
+ trans_collected.intg = vif.monitor_cb.wintg;
end else begin
trans_collected.read_write = READ;
end
addr_ph_port.write(trans_collected);
`uvm_info(get_full_name(),"Send through addr_ph_port", UVM_HIGH)
- if(trans_collected.read_write == WRITE)
- item_collected_port.write(trans_collected);
- else
- collect_data_queue.put(trans_collected);
- vif.wait_clks(1);
+ collect_response_queue.put(trans_collected);
+
+ outstanding_accesses++;
+ if (vif.monitor_cb.rvalid && !vif.monitor_cb.spurious_response) begin
+ outstanding_accesses--;
+ end
+ outstanding_accesses_port.write(outstanding_accesses);
+
+ -> monitor_tick;
end
endtask : collect_address_phase
- virtual protected task collect_data_phase();
+ virtual protected task collect_response_phase();
ibex_mem_intf_seq_item trans_collected;
forever begin
- collect_data_queue.get(trans_collected);
+ collect_response_queue.get(trans_collected);
do
- vif.wait_clks(1);
- while(vif.monitor_cb.rvalid === 0);
- trans_collected.data = vif.monitor_cb.rdata;
+ @(vif.monitor_cb);
+ while(vif.monitor_cb.rvalid === 0 || vif.monitor_cb.spurious_response === 1);
+
+ if (trans_collected.read_write == READ) begin
+ trans_collected.data = vif.monitor_cb.rdata;
+ trans_collected.intg = vif.monitor_cb.rintg;
+ end
+
+ trans_collected.error = vif.monitor_cb.error;
item_collected_port.write(trans_collected);
end
- endtask : collect_data_phase
+ endtask : collect_response_phase
endclass : ibex_mem_intf_monitor
diff --git a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_pkg.sv b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_pkg.sv
new file mode 100644
index 00000000..3391c4a6
--- /dev/null
+++ b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_pkg.sv
@@ -0,0 +1,18 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+package ibex_mem_intf_pkg;
+
+ import uvm_pkg::*;
+
+ parameter int DATA_WIDTH = 32;
+ parameter int ADDR_WIDTH = 32;
+ parameter int INTG_WIDTH = 7;
+
+ typedef enum { READ, WRITE } rw_e;
+
+ `include "uvm_macros.svh"
+ `include "ibex_mem_intf_seq_item.sv"
+
+endpackage
diff --git a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_request_driver.sv b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_request_driver.sv
index 86e37ce6..6ad0a267 100644
--- a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_request_driver.sv
+++ b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_request_driver.sv
@@ -49,6 +49,7 @@ class ibex_mem_intf_request_driver extends uvm_driver #(ibex_mem_intf_seq_item);
vif.request_driver_cb.request <= 'h0;
vif.request_driver_cb.addr <= 'hz;
vif.request_driver_cb.wdata <= 'hz;
+ vif.request_driver_cb.wintg <= 'hz;
vif.request_driver_cb.be <= 'bz;
vif.request_driver_cb.we <= 'bz;
end
@@ -63,11 +64,13 @@ class ibex_mem_intf_request_driver extends uvm_driver #(ibex_mem_intf_seq_item);
vif.request_driver_cb.be <= trans.be;
vif.request_driver_cb.we <= trans.read_write;
vif.request_driver_cb.wdata <= trans.data;
+ vif.request_driver_cb.wintg <= trans.intg;
wait (vif.request_driver_cb.grant === 1'b1);
vif.wait_clks(1);
vif.request_driver_cb.request <= 'h0;
vif.request_driver_cb.addr <= 'hz;
vif.request_driver_cb.wdata <= 'hz;
+ vif.request_driver_cb.wintg <= 'hz;
vif.request_driver_cb.be <= 'bz;
vif.request_driver_cb.we <= 'bz;
rdata_queue.put(trans);
@@ -78,9 +81,10 @@ class ibex_mem_intf_request_driver extends uvm_driver #(ibex_mem_intf_seq_item);
forever begin
rdata_queue.get(tr);
vif.wait_clks(1);
- while(vif.rvalid !== 1'b1) vif.wait_clks(1);
+ while((vif.rvalid !== 1'b1 || vif.spurious_response === 1'b1)) vif.wait_clks(1);
if(tr.read_write == READ)
tr.data = vif.request_driver_cb.rdata;
+ tr.intg = vif.request_driver_cb.rintg;
seq_item_port.put_response(tr);
end
endtask : collect_response
diff --git a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_agent.sv b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_agent.sv
index 789c7ff9..c6326389 100644
--- a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_agent.sv
+++ b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_agent.sv
@@ -10,18 +10,33 @@ class ibex_mem_intf_response_agent extends uvm_agent;
ibex_mem_intf_response_driver driver;
ibex_mem_intf_response_sequencer sequencer;
- ibex_mem_intf_monitor monitor;
+ ibex_mem_intf_monitor monitor;
+ ibex_mem_intf_response_agent_cfg cfg;
`uvm_component_utils(ibex_mem_intf_response_agent)
`uvm_component_new
virtual function void build_phase(uvm_phase phase);
+ bit secure_ibex;
+
super.build_phase(phase);
monitor = ibex_mem_intf_monitor::type_id::create("monitor", this);
+ if (cfg == null)
+ if(!uvm_config_db #(ibex_mem_intf_response_agent_cfg)::get(this, "", "cfg", cfg))
+ `uvm_fatal(`gfn, "Could not locate mem_intf cfg object in uvm_config_db!")
+
if(get_is_active() == UVM_ACTIVE) begin
driver = ibex_mem_intf_response_driver::type_id::create("driver", this);
sequencer = ibex_mem_intf_response_sequencer::type_id::create("sequencer", this);
end
+ if(!uvm_config_db#(virtual ibex_mem_intf)::get(this, "", "vif", cfg.vif))
+ `uvm_fatal("NOVIF",{"virtual interface must be set for: ",get_full_name(),".vif"});
+
+ if (!uvm_config_db#(bit)::get(null, "", "SecureIbex", secure_ibex)) begin
+ secure_ibex = 1'b0;
+ end
+
+ cfg.fixed_data_write_response = secure_ibex;
endfunction : build_phase
function void connect_phase(uvm_phase phase);
@@ -29,7 +44,12 @@ class ibex_mem_intf_response_agent extends uvm_agent;
if(get_is_active() == UVM_ACTIVE) begin
driver.seq_item_port.connect(sequencer.seq_item_export);
monitor.addr_ph_port.connect(sequencer.addr_ph_port.analysis_export);
+ monitor.outstanding_accesses_port.connect(sequencer.outstanding_accesses_imp);
end
+ driver.cfg = cfg;
+ sequencer.cfg = cfg;
+
+ sequencer.monitor_tick = monitor.monitor_tick;
endfunction : connect_phase
function void reset();
diff --git a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_agent_cfg.sv b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_agent_cfg.sv
new file mode 100644
index 00000000..04c2575a
--- /dev/null
+++ b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_agent_cfg.sv
@@ -0,0 +1,67 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+//------------------------------------------------------------------------------
+// CLASS: ibex_mem_intf_response_agent_cfg
+//------------------------------------------------------------------------------
+
+class ibex_mem_intf_response_agent_cfg extends uvm_object;
+
+ // interface handle used by driver & monitor
+ virtual ibex_mem_intf vif;
+
+ // When set write responses have a fixed 32'hffffffff for rdata and matching correct rintg. When
+ // unset both rdata and rintg fields are x for write responses
+ bit fixed_data_write_response = 1'b0;
+
+ // delay between request and grant
+ int unsigned gnt_delay_min = 0;
+ int unsigned gnt_delay_max = 10;
+ // Pick the weight assigned to choosing medium and long gaps between request and grant
+ int unsigned gnt_pick_medium_speed_weight = 1;
+ int unsigned gnt_pick_slow_speed_weight = 1;
+
+ // delay between grant and rvalid
+ int unsigned valid_delay_min = 0;
+ int unsigned valid_delay_max = 20;
+ // Pick the weight assigned to choosing medium and long gaps between grant and rvalid
+ int unsigned valid_pick_medium_speed_weight = 1;
+ int unsigned valid_pick_slow_speed_weight = 1;
+
+ // Enables/disable all protocol delays.
+ rand bit zero_delays;
+
+ // Knob to enable percentage of zero delay in auto-response sequence.
+ // Default set to 50% for zero delay to be picked
+ int unsigned zero_delay_pct = 50;
+
+ // CONTROL_KNOB : enable/disable to generation of bad integrity upon uninit accesses
+ bit enable_bad_intg_on_uninit_access = 0;
+
+ int unsigned spurious_response_delay_min = 0;
+ int unsigned spurious_response_delay_max = 100;
+
+ constraint zero_delays_c {
+ zero_delays dist {1 :/ zero_delay_pct,
+ 0 :/ 100 - zero_delay_pct};
+ }
+
+ `uvm_object_utils_begin(ibex_mem_intf_response_agent_cfg)
+ `uvm_field_int(fixed_data_write_response, UVM_DEFAULT)
+ `uvm_field_int(gnt_delay_min, UVM_DEFAULT)
+ `uvm_field_int(gnt_delay_max, UVM_DEFAULT)
+ `uvm_field_int(valid_delay_min, UVM_DEFAULT)
+ `uvm_field_int(valid_delay_max, UVM_DEFAULT)
+ `uvm_field_int(zero_delays, UVM_DEFAULT)
+ `uvm_field_int(zero_delay_pct, UVM_DEFAULT)
+ `uvm_field_int(spurious_response_delay_min, UVM_DEFAULT)
+ `uvm_field_int(spurious_response_delay_max, UVM_DEFAULT)
+
+ `uvm_object_utils_end
+
+ function new(string name = "");
+ super.new(name);
+ endfunction
+
+endclass
diff --git a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_driver.sv b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_driver.sv
index 56b80f88..e136c2f9 100644
--- a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_driver.sv
+++ b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_driver.sv
@@ -8,10 +8,7 @@
class ibex_mem_intf_response_driver extends uvm_driver #(ibex_mem_intf_seq_item);
- protected virtual ibex_mem_intf vif;
-
- int unsigned min_grant_delay = 0;
- int unsigned max_grant_delay = 10;
+ ibex_mem_intf_response_agent_cfg cfg;
`uvm_component_utils(ibex_mem_intf_response_driver)
`uvm_component_new
@@ -21,21 +18,21 @@ class ibex_mem_intf_response_driver extends uvm_driver #(ibex_mem_intf_seq_item)
function void build_phase(uvm_phase phase);
super.build_phase(phase);
rdata_queue = new();
- if(!uvm_config_db#(virtual ibex_mem_intf)::get(this, "", "vif", vif))
- `uvm_fatal("NOVIF",{"virtual interface must be set for: ",get_full_name(),".vif"});
endfunction: build_phase
virtual task run_phase(uvm_phase phase);
reset_signals();
- wait (vif.response_driver_cb.reset === 1'b0);
+ wait (cfg.vif.response_driver_cb.reset === 1'b0);
forever begin
- fork : drive_stimulus
- send_grant();
- get_and_drive();
- wait (vif.response_driver_cb.reset === 1'b1);
- join_any
- // Will only be reached after mid-test reset
- disable fork;
+ fork begin : isolation_fork
+ fork : drive_stimulus
+ send_grant();
+ get_and_drive();
+ wait (cfg.vif.response_driver_cb.reset === 1'b1);
+ join_any
+ // Will only be reached after mid-test reset
+ disable fork;
+ end join
handle_reset();
end
endtask : run_phase
@@ -52,26 +49,28 @@ class ibex_mem_intf_response_driver extends uvm_driver #(ibex_mem_intf_seq_item)
end
end while (req != null);
reset_signals();
- wait (vif.response_driver_cb.reset === 1'b0);
+ wait (cfg.vif.response_driver_cb.reset === 1'b0);
endtask
virtual protected task reset_signals();
- vif.response_driver_cb.rvalid <= 1'b0;
- vif.response_driver_cb.grant <= 1'b0;
- vif.response_driver_cb.rdata <= 'b0;
- vif.response_driver_cb.error <= 1'b0;
+ cfg.vif.response_driver_cb.rvalid <= 1'b0;
+ cfg.vif.response_driver_cb.grant <= 1'b0;
+ cfg.vif.response_driver_cb.rdata <= 'b0;
+ cfg.vif.response_driver_cb.rintg <= 'b0;
+ cfg.vif.response_driver_cb.error <= 1'b0;
endtask : reset_signals
virtual protected task get_and_drive();
- wait (vif.response_driver_cb.reset === 1'b0);
+ wait (cfg.vif.response_driver_cb.reset === 1'b0);
+
fork
begin
forever begin
ibex_mem_intf_seq_item req, req_c;
- vif.wait_clks(1);
+ @(cfg.vif.response_driver_cb);
seq_item_port.get_next_item(req);
$cast(req_c, req.clone());
- if(~vif.response_driver_cb.reset) begin
+ if(~cfg.vif.response_driver_cb.reset) begin
rdata_queue.put(req_c);
end
seq_item_port.item_done();
@@ -86,23 +85,27 @@ class ibex_mem_intf_response_driver extends uvm_driver #(ibex_mem_intf_seq_item)
virtual protected task send_grant();
int gnt_delay;
forever begin
- while(vif.response_driver_cb.request !== 1'b1) begin
- vif.wait_neg_clks(1);
+ while(cfg.vif.response_driver_cb.request !== 1'b1) begin
+ cfg.vif.wait_neg_clks(1);
end
- if (!std::randomize(gnt_delay) with {
- gnt_delay dist {
- min_grant_delay :/ 1,
- [min_grant_delay+1 : max_grant_delay-1] :/ 1,
- max_grant_delay :/ 1
- };
- }) begin
- `uvm_fatal(`gfn, $sformatf("Cannot randomize grant"))
+ if(cfg.zero_delays) begin
+ gnt_delay = 0;
+ end else begin
+ if (!std::randomize(gnt_delay) with {
+ gnt_delay dist {
+ cfg.gnt_delay_min :/ 10,
+ [cfg.gnt_delay_min+1 : cfg.gnt_delay_max-1] :/ cfg.valid_pick_medium_speed_weight,
+ cfg.gnt_delay_max :/ cfg.valid_pick_slow_speed_weight
+ };
+ }) begin
+ `uvm_fatal(`gfn, $sformatf("Cannot randomize grant"))
+ end
end
- vif.wait_neg_clks(gnt_delay);
- if(~vif.response_driver_cb.reset) begin
- vif.response_driver_cb.grant <= 1'b1;
- vif.wait_neg_clks(1);
- vif.response_driver_cb.grant <= 1'b0;
+ cfg.vif.wait_neg_clks(gnt_delay);
+ if(~cfg.vif.response_driver_cb.reset) begin
+ cfg.vif.response_driver_cb.grant <= 1'b1;
+ cfg.vif.wait_neg_clks(1);
+ cfg.vif.response_driver_cb.grant <= 1'b0;
end
end
endtask : send_grant
@@ -110,17 +113,50 @@ class ibex_mem_intf_response_driver extends uvm_driver #(ibex_mem_intf_seq_item)
virtual protected task send_read_data();
ibex_mem_intf_seq_item tr;
forever begin
- vif.wait_clks(1);
- vif.response_driver_cb.rvalid <= 1'b0;
- vif.response_driver_cb.rdata <= 'x;
- vif.response_driver_cb.error <= 1'b0;
+ @(cfg.vif.response_driver_cb);
+ cfg.vif.response_driver_cb.rvalid <= 1'b0;
+ cfg.vif.response_driver_cb.spurious_response <= 1'b0;
+ cfg.vif.response_driver_cb.rdata <= 'x;
+ cfg.vif.response_driver_cb.rintg <= 'x;
+ cfg.vif.response_driver_cb.error <= 'x;
+
rdata_queue.get(tr);
- if(vif.response_driver_cb.reset) continue;
- vif.wait_clks(tr.rvalid_delay);
- if(~vif.response_driver_cb.reset) begin
- vif.response_driver_cb.rvalid <= 1'b1;
- vif.response_driver_cb.error <= tr.error;
- vif.response_driver_cb.rdata <= tr.data;
+
+ `uvm_info(`gfn, $sformatf("Got response for addr %x", tr.addr), UVM_HIGH)
+
+ if(cfg.vif.response_driver_cb.reset) continue;
+
+ repeat (tr.rvalid_delay) @(cfg.vif.response_driver_cb);
+
+ if(~cfg.vif.response_driver_cb.reset) begin
+ if (tr.spurious_response) begin
+ `uvm_info(`gfn, $sformatf("Driving spurious response"), UVM_HIGH)
+ end else begin
+ `uvm_info(`gfn, $sformatf("Driving response for addr %x", tr.addr), UVM_HIGH)
+ end
+
+ cfg.vif.response_driver_cb.rvalid <= 1'b1;
+ cfg.vif.response_driver_cb.error <= tr.error;
+ // A spurious response is not associated with any request. This is flagged in the vif
+ // signals so other components in the testbench can ignore them if needed.
+ cfg.vif.response_driver_cb.spurious_response <= tr.spurious_response;
+
+ if (tr.read_write == READ) begin
+ cfg.vif.response_driver_cb.rdata <= tr.data;
+ cfg.vif.response_driver_cb.rintg <= tr.intg;
+ end else begin
+ // rdata and intg fields aren't relevant to write responses
+ if (cfg.fixed_data_write_response) begin
+ // when fixed_data_write_response is set, sequence item is responsible for producing
+ // fixed values so just copy them across here.
+ cfg.vif.response_driver_cb.rdata <= tr.data;
+ cfg.vif.response_driver_cb.rintg <= tr.intg;
+ end else begin
+ // when fixed_data_write_response is not set, drive the irrelevant fields to x.
+ cfg.vif.response_driver_cb.rdata <= 'x;
+ cfg.vif.response_driver_cb.rintg <= 'x;
+ end
+ end
end
end
endtask : send_read_data
diff --git a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_seq_lib.sv b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_seq_lib.sv
index bded3347..614216f6 100644
--- a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_seq_lib.sv
+++ b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_seq_lib.sv
@@ -8,79 +8,160 @@
class ibex_mem_intf_response_seq extends uvm_sequence #(ibex_mem_intf_seq_item);
- int max_rvalid_delay = 20;
- int min_rvalid_delay = 0;
- ibex_mem_intf_seq_item item;
- mem_model m_mem;
- bit enable_error = 1'b0;
+ ibex_mem_intf_seq_item item;
+ mem_model m_mem;
+ ibex_cosim_agent cosim_agent;
+ bit enable_intg_error = 1'b0;
+ bit enable_error = 1'b0;
// Used to ensure that whenever inject_error() is called, the very next transaction will inject an
// error, and that enable_error will not be flipped back to 0 immediately
- bit error_synch = 1'b1;
- bit is_dmem_seq = 1'b0;
+ bit error_synch = 1'b1;
+ bit is_dmem_seq = 1'b0;
+ bit suppress_error_on_exc = 1'b0;
+ bit enable_spurious_response = 1'b0;
+
`uvm_object_utils(ibex_mem_intf_response_seq)
`uvm_declare_p_sequencer(ibex_mem_intf_response_sequencer)
`uvm_object_new
+ rand int unsigned spurious_response_delay_cycles;
+
+ constraint spurious_response_delay_cycles_c {
+ spurious_response_delay_cycles inside {[p_sequencer.cfg.spurious_response_delay_min :
+ p_sequencer.cfg.spurious_response_delay_max]};
+ }
+
virtual task body();
- if(m_mem == null)
- `uvm_fatal(get_full_name(), "Cannot get memory model")
+ virtual core_ibex_dut_probe_if ibex_dut_vif;
+
+ if (!uvm_config_db#(virtual core_ibex_dut_probe_if)::get(null, "", "dut_if",
+ ibex_dut_vif)) begin
+ `uvm_fatal(`gfn, "failed to get ibex dut_if from uvm_config_db")
+ end
+
+ if (m_mem == null) `uvm_fatal(get_full_name(), "Cannot get memory model")
`uvm_info(`gfn, $sformatf("is_dmem_seq: 0x%0x", is_dmem_seq), UVM_LOW)
+
+ `DV_CHECK_MEMBER_RANDOMIZE_FATAL(spurious_response_delay_cycles)
+
forever
begin
bit [ADDR_WIDTH-1:0] aligned_addr;
bit [DATA_WIDTH-1:0] rand_data;
bit [DATA_WIDTH-1:0] read_data;
- p_sequencer.addr_ph_port.get(item);
+ bit [INTG_WIDTH-1:0] read_intg;
+ bit data_was_uninitialized = 1'b0;
+
+ if (enable_spurious_response) begin
+ // When spurious responses are enabled we wake every monitor tick to decide whether to
+ // insert a spurious response.
+ while (1) begin
+ @p_sequencer.monitor_tick;
+
+ if (p_sequencer.addr_ph_port.try_get(item)) begin
+ // If we have a new request proceed as normal.
+ break;
+ end
+
+ if ((spurious_response_delay_cycles == 0)
+ && (p_sequencer.outstanding_accesses == 0)) begin
+
+ // If we've hit the time generate a new spurious responses and there's no outstanding
+ // responses (we must only generate a spurious response when the interface is idle)
+ // send one to the driver.
+ req = ibex_mem_intf_seq_item::type_id::create("req");
+
+ `DV_CHECK_RANDOMIZE_WITH_FATAL(req, rvalid_delay == 0;)
+
+ req.spurious_response = 1'b1;
+ {req.intg, req.data} = prim_secded_pkg::prim_secded_inv_39_32_enc(req.data);
+
+ `uvm_info(`gfn, $sformatf("Generated spurious response:\n%0s", req.sprint()), UVM_HIGH)
+ start_item(req);
+ finish_item(req);
+
+ `DV_CHECK_MEMBER_RANDOMIZE_FATAL(spurious_response_delay_cycles)
+ end else if (spurious_response_delay_cycles > 0) begin
+ spurious_response_delay_cycles = spurious_response_delay_cycles - 1;
+ end
+ end
+ end else begin
+ // Without spurious responses just wait for the monitor to report a new request
+ p_sequencer.addr_ph_port.get(item);
+ end
+
+ aligned_addr = {item.addr[DATA_WIDTH-1:2], 2'b0};
+
req = ibex_mem_intf_seq_item::type_id::create("req");
error_synch = 1'b0;
+ if (suppress_error_on_exc &&
+ (ibex_dut_vif.dut_cb.sync_exc_seen || ibex_dut_vif.dut_cb.irq_exc_seen)) begin
+ enable_error = 1'b0;
+ enable_intg_error = 1'b0;
+ end
+
if (!req.randomize() with {
addr == item.addr;
read_write == item.read_write;
data == item.data;
+ intg == item.intg;
be == item.be;
- rvalid_delay dist {
- min_rvalid_delay :/ 5,
- [min_rvalid_delay + 1 : max_rvalid_delay / 2 - 1] :/ 3,
- [max_rvalid_delay / 2 : max_rvalid_delay - 1] :/ 1,
- max_rvalid_delay :/ 1
- };
+ if (p_sequencer.cfg.zero_delays) {
+ rvalid_delay == 0;
+ } else {
+ rvalid_delay dist {
+ p_sequencer.cfg.valid_delay_min :/ 5,
+ [p_sequencer.cfg.valid_delay_min + 1 : p_sequencer.cfg.valid_delay_max / 2 - 1] :/ 3,
+ [p_sequencer.cfg.valid_delay_max / 2 : p_sequencer.cfg.valid_delay_max - 1]
+ :/ p_sequencer.cfg.valid_pick_medium_speed_weight,
+ p_sequencer.cfg.valid_delay_max
+ :/ p_sequencer.cfg.valid_pick_slow_speed_weight
+ };
+ }
error == enable_error;
}) begin
`uvm_fatal(`gfn, "Cannot randomize response request")
end
- enable_error = 1'b0;
+
error_synch = 1'b1;
+ enable_error = 1'b0; // Disable after single inserted error.
aligned_addr = {req.addr[DATA_WIDTH-1:2], 2'b0};
+ // Do not inject any error to the handshake test_control_addr
+ // TODO: Parametrize this. Until then, this needs to be changed manually.
+ if (aligned_addr inside {32'h8ffffff8, 32'h8ffffffc}) begin
+ req.error = 1'b0;
+ enable_intg_error = 1'b0;
+ end
if (req.error) begin
`DV_CHECK_STD_RANDOMIZE_FATAL(rand_data)
req.data = rand_data;
- end else begin
- if(req.read_write == READ) begin : READ_block
- if (is_dmem_seq) begin
- for (int i = DATA_WIDTH / 8 - 1; i >= 0; i--) begin
- read_data = read_data << 8;
- if (req.be[i])
- read_data[7:0] = m_mem.read_byte(aligned_addr + i);
- end
- req.data = read_data;
- end else begin
- req.data = m_mem.read(aligned_addr);
- end
+ end else if(item.read_write == READ) begin
+ // Get data from memory_model, handle uninit memory accesses.
+ req.data = read(aligned_addr, data_was_uninitialized);
+ end else if(item.read_write == WRITE) begin
+ // Update memory_model
+ write(aligned_addr, item.data);
+ if (p_sequencer.cfg.fixed_data_write_response) begin
+ // When fixed_data_write_response is set drive data in store response to fixed
+ // 32'hffffffff value. Integrity is calculated below.
+ req.data = 32'hffffffff;
end
end
+ // Add integrity bits
+ {req.intg, req.data} = prim_secded_pkg::prim_secded_inv_39_32_enc(req.data);
+
+ // If data_was_uninitialized is true then we want to force bad integrity bits: invert the
+ // correct ones, which we know will break things for the codes we use.
+ if ((p_sequencer.cfg.enable_bad_intg_on_uninit_access && data_was_uninitialized) || enable_intg_error) begin
+ req.intg = ~req.intg;
+ enable_intg_error = 1'b0;
+ end
+
`uvm_info(get_full_name(), $sformatf("Response transfer:\n%0s", req.sprint()), UVM_HIGH)
start_item(req);
finish_item(req);
- if(item.read_write == WRITE) begin : WRITE_block
- bit [DATA_WIDTH-1:0] data;
- data = req.data;
- for (int i = 0; i < DATA_WIDTH / 8; i++) begin
- if (req.be[i])
- m_mem.write_byte(aligned_addr + i, data[7:0]);
- data = data >> 8;
- end
- end
+
end
endtask : body
@@ -88,8 +169,71 @@ class ibex_mem_intf_response_seq extends uvm_sequence #(ibex_mem_intf_seq_item);
this.enable_error = 1'b1;
endfunction
+ virtual function void inject_intg_error();
+ this.enable_intg_error = 1'b1;
+ endfunction
+
virtual function bit get_error_synch();
return this.error_synch;
endfunction
+ // Read a word of DATA_WIDTH bits from addr.
+ // Handle reads fromm uninit memory as follows:
+ // - DMEM : return a random value
+ // - IMEM : return {2{C.unimp}}
+ protected function logic [DATA_WIDTH-1:0] read(bit [ADDR_WIDTH-1:0] addr,
+ output bit did_access_uninit_mem);
+ logic [DATA_WIDTH-1:0] data = '0;
+ bit [7:0] byte_data = '0;
+ bit byte_is_uninit = 1'b0;
+ for (int i = (DATA_WIDTH / 8) - 1; i >= 0 ; i--) begin
+ data = data << 8;
+ byte_data = read_byte(addr + i, byte_is_uninit);
+ if (byte_is_uninit) begin
+ did_access_uninit_mem = 1'b1;
+ // If any byte of the access comes back as uninit, bork the whole access.
+ if (is_dmem_seq) begin
+ // DMEM
+ `DV_CHECK_STD_RANDOMIZE_FATAL(byte_data)
+ // Update mem_model(s) with the randomized data.
+ `uvm_info(`gfn,
+ $sformatf("Addr is uninit! DMEM seq, returning random data 0x%0h", data),
+ UVM_MEDIUM)
+ m_mem.write_byte(addr + i, byte_data); // Update UVM mem_model
+ cosim_agent.write_mem_byte(addr + i, byte_data); // Update cosim mem_model
+ end else begin
+ // IMEM
+ `uvm_info(`gfn,
+ $sformatf("Addr is uninit! IMEM seq, returning 0x0000 (c.unimp)"),
+ UVM_MEDIUM)
+ return {2{16'h0000}}; // 2x C.unimp instructions
+ end
+ end
+ data[7:0] = byte_data;
+ end
+ return data;
+ endfunction
+
+ // Write a word of DATA_WIDTH bits at addr.
+ protected function void write(bit [ADDR_WIDTH-1:0] addr, bit [DATA_WIDTH-1:0] data);
+ for (int i = 0; i < DATA_WIDTH / 8; i++) begin
+ if (req.be[i])
+ m_mem.write_byte(addr + i, data[7:0]);
+ data = data >> 8;
+ end
+ endfunction
+
+ // Re-implement the read_byte function from mem_model.sv, but without the fatal assertion.
+ function bit [7:0] read_byte(bit [ADDR_WIDTH-1:0] addr, output bit is_byte_uninit);
+ bit [7:0] data = '0;
+ if (!m_mem.addr_exists(addr)) begin
+ `uvm_info(`gfn, $sformatf("Read from uninitialized addr 0x%0h", addr), UVM_MEDIUM)
+ is_byte_uninit = 1'b1;
+ end else begin
+ data = m_mem.system_memory[addr];
+ `uvm_info(`gfn, $sformatf("Read Mem : Addr[0x%0h], Data[0x%0h]", addr, data), UVM_HIGH)
+ end
+ return data;
+ endfunction
+
endclass : ibex_mem_intf_response_seq
diff --git a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_sequencer.sv b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_sequencer.sv
index dfa8c042..71b17aa3 100644
--- a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_sequencer.sv
+++ b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_response_sequencer.sv
@@ -10,12 +10,18 @@ class ibex_mem_intf_response_sequencer extends uvm_sequencer #(ibex_mem_intf_seq
// TLM port to peek the address phase from the response monitor
uvm_tlm_analysis_fifo #(ibex_mem_intf_seq_item) addr_ph_port;
+ uvm_analysis_imp #(int, ibex_mem_intf_response_sequencer) outstanding_accesses_imp;
+ ibex_mem_intf_response_agent_cfg cfg;
+
+ event monitor_tick = null;
+ int outstanding_accesses = 0;
`uvm_component_utils(ibex_mem_intf_response_sequencer)
function new (string name, uvm_component parent);
super.new(name, parent);
addr_ph_port = new("addr_ph_port_sequencer", this);
+ outstanding_accesses_imp = new("outstanding_access_imp", this);
endfunction : new
// On reset, empty the tlm fifo
@@ -23,4 +29,8 @@ class ibex_mem_intf_response_sequencer extends uvm_sequencer #(ibex_mem_intf_seq
addr_ph_port.flush();
endfunction
+ function void write(int x);
+ outstanding_accesses = x;
+ endfunction
+
endclass : ibex_mem_intf_response_sequencer
diff --git a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_seq_item.sv b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_seq_item.sv
index fc218c06..55633abb 100644
--- a/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_seq_item.sv
+++ b/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_seq_item.sv
@@ -11,20 +11,32 @@ class ibex_mem_intf_seq_item extends uvm_sequence_item;
rand bit [ADDR_WIDTH-1:0] addr;
rand rw_e read_write;
rand bit [DATA_WIDTH-1:0] data;
+ rand bit [INTG_WIDTH-1:0] intg;
rand bit [DATA_WIDTH/8-1:0] be;
rand bit [3:0] gnt_delay;
rand bit [3:0] req_delay;
rand bit [5:0] rvalid_delay;
rand bit error;
+ bit spurious_response;
+ bit misaligned_first;
+ bit misaligned_second;
+ bit misaligned_first_saw_error;
+ bit m_mode_access;
`uvm_object_utils_begin(ibex_mem_intf_seq_item)
- `uvm_field_int (addr, UVM_DEFAULT)
- `uvm_field_enum (rw_e, read_write, UVM_DEFAULT)
- `uvm_field_int (be, UVM_DEFAULT)
- `uvm_field_int (data, UVM_DEFAULT)
- `uvm_field_int (gnt_delay, UVM_DEFAULT)
- `uvm_field_int (rvalid_delay, UVM_DEFAULT)
- `uvm_field_int (error, UVM_DEFAULT)
+ `uvm_field_int (addr, UVM_DEFAULT)
+ `uvm_field_enum (rw_e, read_write, UVM_DEFAULT)
+ `uvm_field_int (be, UVM_DEFAULT)
+ `uvm_field_int (data, UVM_DEFAULT)
+ `uvm_field_int (intg, UVM_DEFAULT)
+ `uvm_field_int (gnt_delay, UVM_DEFAULT)
+ `uvm_field_int (rvalid_delay, UVM_DEFAULT)
+ `uvm_field_int (error, UVM_DEFAULT)
+ `uvm_field_int (misaligned_first, UVM_DEFAULT)
+ `uvm_field_int (misaligned_second, UVM_DEFAULT)
+ `uvm_field_int (misaligned_first_saw_error, UVM_DEFAULT)
+ `uvm_field_int (m_mode_access, UVM_DEFAULT)
+ `uvm_field_int (spurious_response, UVM_DEFAULT)
`uvm_object_utils_end
`uvm_object_new
diff --git a/dv/uvm/core_ibex/common/irq_agent/irq_monitor.sv b/dv/uvm/core_ibex/common/irq_agent/irq_monitor.sv
index b94c5d16..b56cbbc1 100644
--- a/dv/uvm/core_ibex/common/irq_agent/irq_monitor.sv
+++ b/dv/uvm/core_ibex/common/irq_agent/irq_monitor.sv
@@ -24,12 +24,14 @@ class irq_monitor extends uvm_monitor;
virtual task run_phase(uvm_phase phase);
forever begin
wait (vif.monitor_cb.reset === 1'b0);
- fork : monitor_irq
- collect_irq();
- wait (vif.monitor_cb.reset === 1'b1);
- join_any
- // Will only reach here on mid-test reset
- disable fork;
+ fork begin : isolation_fork
+ fork : monitor_irq
+ collect_irq();
+ wait (vif.monitor_cb.reset === 1'b1);
+ join_any
+ // Will only reach here on mid-test reset
+ disable fork;
+ end join
end
endtask : run_phase
diff --git a/dv/uvm/core_ibex/common/irq_agent/irq_request_driver.sv b/dv/uvm/core_ibex/common/irq_agent/irq_request_driver.sv
index b92a5a53..8c729212 100644
--- a/dv/uvm/core_ibex/common/irq_agent/irq_request_driver.sv
+++ b/dv/uvm/core_ibex/common/irq_agent/irq_request_driver.sv
@@ -6,7 +6,7 @@ class irq_request_driver extends uvm_driver #(irq_seq_item);
// The virtual interface used to drive and view HDL signals.
protected virtual irq_if vif;
-`uvm_component_utils(irq_request_driver)
+ `uvm_component_utils(irq_request_driver)
`uvm_component_new
function void build_phase(uvm_phase phase);
@@ -18,14 +18,19 @@ class irq_request_driver extends uvm_driver #(irq_seq_item);
virtual task run_phase(uvm_phase phase);
reset_signals();
+ wait (vif.driver_cb.reset === 1'b0);
forever begin
- fork : drive_irq
- get_and_drive();
- wait (vif.driver_cb.reset === 1'b1);
- join_any
- // Will only reach here on mid-test reset
- disable fork;
- handle_reset();
+ fork begin : isolation_fork
+ fork : drive_irq
+ // Setup a single get_REQ -> drive -> send_RSP long-running task.
+ // This seq_item contains all signals on the interface at once.
+ get_and_drive();
+ wait (vif.driver_cb.reset === 1'b1);
+ join_any
+ // Will only reach here on mid-test reset
+ disable fork;
+ handle_reset();
+ end join
end
endtask : run_phase
@@ -41,8 +46,9 @@ class irq_request_driver extends uvm_driver #(irq_seq_item);
reset_signals();
endtask
+ // Every cycle, check for a new REQ and drive it.
+ // Simultaneously, return the same REQ as a RSP back to the sequence.
virtual protected task get_and_drive();
- wait (vif.driver_cb.reset === 1'b0);
forever begin
seq_item_port.try_next_item(req);
if (req != null) begin
@@ -57,7 +63,7 @@ class irq_request_driver extends uvm_driver #(irq_seq_item);
endtask : get_and_drive
virtual protected task reset_signals();
- @(negedge vif.driver_cb.reset);
+ @(posedge vif.driver_cb.reset);
drive_reset_value();
endtask : reset_signals
diff --git a/dv/uvm/core_ibex/common/prim/prim_and2.sv b/dv/uvm/core_ibex/common/prim/prim_and2.sv
new file mode 100644
index 00000000..157d4dba
--- /dev/null
+++ b/dv/uvm/core_ibex/common/prim/prim_and2.sv
@@ -0,0 +1,27 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// Abstract primitives wrapper.
+//
+// This file is a stop-gap until the DV file list is generated by FuseSoC.
+// Its contents are taken from the file which would be generated by FuseSoC.
+// https://github.com/lowRISC/ibex/issues/893
+
+module prim_and2 #(
+ parameter int Width = 1
+) (
+ input [Width-1:0] in0_i,
+ input [Width-1:0] in1_i,
+ output logic [Width-1:0] out_o
+);
+
+if (1) begin : gen_generic
+ prim_generic_and2 #(
+ .Width(Width)
+ ) u_impl_generic (
+ .*
+ );
+end
+
+endmodule
diff --git a/dv/uvm/core_ibex/common/prim/prim_buf.sv b/dv/uvm/core_ibex/common/prim/prim_buf.sv
new file mode 100644
index 00000000..39cde3d8
--- /dev/null
+++ b/dv/uvm/core_ibex/common/prim/prim_buf.sv
@@ -0,0 +1,24 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// Abstract primitives wrapper.
+//
+// This file is a stop-gap until the DV file list is generated by FuseSoC.
+// Its contents are taken from the file which would be generated by FuseSoC.
+// https://github.com/lowRISC/ibex/issues/893
+
+module prim_buf #(
+ parameter int Width = 1
+) (
+ input [Width-1:0] in_i,
+ output logic [Width-1:0] out_o
+);
+
+ if (1) begin : gen_generic
+ prim_generic_buf#(.Width(Width)) u_impl_generic (
+ .*
+ );
+ end
+
+endmodule
diff --git a/dv/uvm/core_ibex/common/prim/prim_clock_mux2.sv b/dv/uvm/core_ibex/common/prim/prim_clock_mux2.sv
new file mode 100644
index 00000000..92d36791
--- /dev/null
+++ b/dv/uvm/core_ibex/common/prim/prim_clock_mux2.sv
@@ -0,0 +1,28 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// Abstract primitives wrapper.
+//
+// This file is a stop-gap until the DV file list is generated by FuseSoC.
+// Its contents are taken from the file which would be generated by FuseSoC.
+// https://github.com/lowRISC/ibex/issues/893
+
+module prim_clock_mux2 #(
+ parameter bit NoFpgaBufG = 1'b0
+) (
+ input clk0_i,
+ input clk1_i,
+ input sel_i,
+ output logic clk_o
+);
+
+if (1) begin : gen_generic
+ prim_generic_clock_mux2 #(
+ .NoFpgaBufG(NoFpgaBufG)
+ ) u_impl_generic (
+ .*
+ );
+end
+
+endmodule
diff --git a/dv/uvm/core_ibex/common/prim/prim_flop.sv b/dv/uvm/core_ibex/common/prim/prim_flop.sv
new file mode 100644
index 00000000..52e982a2
--- /dev/null
+++ b/dv/uvm/core_ibex/common/prim/prim_flop.sv
@@ -0,0 +1,30 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// Abstract primitives wrapper.
+//
+// This file is a stop-gap until the DV file list is generated by FuseSoC.
+// Its contents are taken from the file which would be generated by FuseSoC.
+// https://github.com/lowRISC/ibex/issues/893
+
+module prim_flop #(
+ parameter int Width = 1,
+ parameter logic [Width-1:0] ResetValue = 0
+) (
+ input clk_i,
+ input rst_ni,
+ input [Width-1:0] d_i,
+ output logic [Width-1:0] q_o
+);
+
+if (1) begin : gen_generic
+ prim_generic_flop #(
+ .ResetValue(ResetValue),
+ .Width(Width)
+ ) u_impl_generic (
+ .*
+ );
+end
+
+endmodule
diff --git a/dv/uvm/core_ibex/common/prim/prim_ram_1p.sv b/dv/uvm/core_ibex/common/prim/prim_ram_1p.sv
index d81acd55..c44af506 100644
--- a/dv/uvm/core_ibex/common/prim/prim_ram_1p.sv
+++ b/dv/uvm/core_ibex/common/prim/prim_ram_1p.sv
@@ -8,7 +8,7 @@
// Its contents are taken from the file which would be generated by FuseSoC.
// https://github.com/lowRISC/ibex/issues/893
-module prim_ram_1p
+module prim_ram_1p import prim_ram_1p_pkg::*;
#(
@@ -21,6 +21,7 @@ module prim_ram_1p
) (
input logic clk_i,
+ input ram_1p_cfg_t cfg_i,
input logic req_i,
input logic write_i,
diff --git a/dv/uvm/core_ibex/directed_tests/README.md b/dv/uvm/core_ibex/directed_tests/README.md
new file mode 100644
index 00000000..cb82814d
--- /dev/null
+++ b/dv/uvm/core_ibex/directed_tests/README.md
@@ -0,0 +1,18 @@
+# Directed Tests
+
+This directory contains the custom directed tests as well as scripts and headers for running directed tests vendored from various open source repositories.
+
+Currently following open source test suites are vendored:
+- [riscv-tests](https://github.com/riscv-software-src/riscv-tests)
+- [riscv-arch-tests](https://github.com/riscv-non-isa/riscv-arch-test)
+- epmp-tests ([fork](https://github.com/lowRISC/riscv-isa-sim/tree/mseccfg_tests) from an opensource [repo](https://github.com/joxie/riscv-isa-sim))
+
+## Generating test list
+
+To generate a testlist containing all of the directed tests (custom + tests from vendored repos).
+
+```
+python3 gen_testlist.py --add_tests riscv-tests,riscv-arch-tests,epmp-tests
+```
+
+Please note that the custom directed tests needs to be added in the `gen_testlist.py` script and it needs to be run in order to update `directed_testlist.yaml`.
diff --git a/dv/uvm/core_ibex/directed_tests/access_pmp_overlap/access_pmp_overlap.S b/dv/uvm/core_ibex/directed_tests/access_pmp_overlap/access_pmp_overlap.S
new file mode 100644
index 00000000..6d4713d0
--- /dev/null
+++ b/dv/uvm/core_ibex/directed_tests/access_pmp_overlap/access_pmp_overlap.S
@@ -0,0 +1,53 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+###############################################################################
+# Description:
+# Test to access misalign address between a PMP
+# and a non-PMP region. PMP region allows access
+# so the purpose is to check the implementation
+# behavior of multiple accesses.
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64M
+RVTEST_CODE_BEGIN
+
+ # setting machine handler
+ la t0, mtvec_handler
+ csrw mtvec, t0
+
+ # setting the PMP region
+ la t0, pmp_region_start
+ srli t1, t0, PMP_SHIFT
+ csrw pmpaddr0, t1
+ la t1, pmp_region_end
+ srli t1, t1, PMP_SHIFT
+ csrw pmpaddr1, t1
+ li t1, (PMP_L | PMP_TOR | PMP_R | PMP_W | PMP_X) << 8
+ csrw pmpcfg0, t1
+
+ # access across the boundary between PMP and non-PMP
+ lw t1, -2(t0)
+
+ j pass
+
+ TEST_PASSFAIL
+
+.balign 256
+mtvec_handler:
+ j fail
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+.balign 0x1000
+pmp_region_start: .zero 0x1000
+pmp_region_end:
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/dv/uvm/core_ibex/directed_tests/custom_macros.h b/dv/uvm/core_ibex/directed_tests/custom_macros.h
new file mode 100644
index 00000000..b26f719d
--- /dev/null
+++ b/dv/uvm/core_ibex/directed_tests/custom_macros.h
@@ -0,0 +1,154 @@
+#Copyright lowRISC contributors.
+#Licensed under the Apache License, Version 2.0, see LICENSE for details.
+#SPDX - License - Identifier : Apache - 2.0
+
+############################################################################## #
+
+#Reset PMP CSRs
+#define RESET_PMP \
+ csrw pmpcfg0, x0; \
+ csrw pmpcfg1, x0; \
+ csrw pmpcfg2, x0; \
+ csrw pmpcfg3, x0; \
+ csrw pmpaddr0, x0; \
+ csrw pmpaddr1, x0; \
+ csrw pmpaddr2, x0; \
+ csrw pmpaddr3, x0; \
+ csrw pmpaddr4, x0; \
+ csrw pmpaddr5, x0; \
+ csrw pmpaddr6, x0; \
+ csrw pmpaddr7, x0; \
+ csrw pmpaddr8, x0; \
+ csrw pmpaddr9, x0; \
+ csrw pmpaddr10, x0; \
+ csrw pmpaddr11, x0; \
+ csrw pmpaddr12, x0; \
+ csrw pmpaddr13, x0; \
+ csrw pmpaddr14, x0; \
+ csrw pmpaddr15, x0; \
+ csrw CSR_MSECCFG, x0;
+
+#Calculate NAPOT addr by applying mask
+#define SET_NAPOT_ADDR(addr, gran) \
+ li t0, gran >> 3; \
+ not t2, t0; \
+ la t1, addr; \
+ srli t1, t1, 2; \
+ and t1, t1, t2; \
+ addi t0, t0, -1; \
+ or t1, t1, t0;
+
+#Set pmp configuration CSR depending upon region
+#define SET_PMP_CFG(pmp_cfg, pmp_region) \
+ li t0, (8 * pmp_region) & 0x1f; \
+ li t1, pmp_region; \
+ li t2, 3; \
+ bgt t1, t2, 1f; \
+ li t1, pmp_cfg; \
+ sll t1, t1, t0; \
+ csrw pmpcfg0, t1; \
+ j 4f; \
+ 1 : li t2, 7; \
+ bgt t1, t2, 2f; \
+ li t1, pmp_cfg; \
+ sll t1, t1, t0; \
+ csrw pmpcfg1, t1; \
+ j 4f; \
+ 2 : li t2, 11; \
+ bgt t1, t2, 3f; \
+ li t1, pmp_cfg; \
+ sll t1, t1, t0; \
+ csrw pmpcfg2, t1; \
+ j 4f; \
+ 3 : li t2, 15; \
+ bgt t1, t2, 4f; \
+ li t1, pmp_cfg; \
+ sll t1, t1, t0; \
+ csrw pmpcfg3, t1; \
+ 4:
+
+#define SET_PMP_NAPOT(addr, gran, pmp_cfg, pmp_region) \
+ SET_NAPOT_ADDR(addr, gran); \
+ csrw pmpaddr##pmp_region, t1; \
+ SET_PMP_CFG(pmp_cfg, pmp_region);
+
+#define SET_PMP_TOR(addr_high, addr_low, pmp_cfg, pmp_region_high, \
+ pmp_region_low) \
+ la t0, addr_low; \
+ srli t0, t0, 2; \
+ csrw pmpaddr##pmp_region_low, t0; \
+ la t0, addr_high; \
+ srli t0, t0, 2; \
+ csrw pmpaddr##pmp_region_high, t0; \
+ SET_PMP_CFG(pmp_cfg, pmp_region_high);
+
+#define SET_PMP_TOR_ADDR_FROM_REG(addr_high, addr_low, pmp_cfg, \
+ pmp_region_high, pmp_region_low) \
+ srli t0, addr_low, 2; \
+ csrw pmpaddr##pmp_region_low, t0; \
+ srli t0, addr_high, 2; \
+ csrw pmpaddr##pmp_region_high, t0; \
+ SET_PMP_CFG(pmp_cfg, pmp_region_high);
+
+#define SKIP_PC \
+ csrr t0, mepc; \
+ lb t1, 0(t0); \
+ li t2, 0x3; \
+ and t1, t1, t2; \
+ bne t1, t2, 1f; \
+ addi t0, t0, 2; \
+ 1 : addi t0, t0, 2; \
+ csrw mepc, t0;
+
+#define RW_ACCESSES_IN_M_MODE(pmp_addr, gran) \
+ la s0, pmp_addr; \
+ lw s1, 0(s0); \
+ sw s1, 0(s0); \
+ li s1, gran / 2; \
+ add s2, s0, s1; \
+ lw s1, 0(s2); \
+ sw s1, 0(s2); \
+ li s1, gran - 4; \
+ add s2, s0, s1; \
+ lw s1, 0(s2); \
+ sw s1, 0(s2);
+
+// This assumes a PMP access failure on the read and write where the handler
+// jumps back to the failing access in M mode. If the access succeeds it remains
+// in U mode and the second SWITCH_TO_U_MODE will trap (due to attempting a
+// write to mstatus).
+#define RW_ACCESSES_IN_U_MODE(pmp_addr, gran) \
+ la s0, pmp_addr; \
+ SWITCH_TO_U_MODE_LABEL(1f); \
+ 1 : lw s1, 0(s0); \
+ SWITCH_TO_U_MODE_LABEL(1f); \
+ 1 : sw s1, 0(s0);
+
+#Accesses at start, mid and end of PMP range
+
+#ifdef U_MODE
+#define RW_ACCESSES(pmp_addr, gran) RW_ACCESSES_IN_U_MODE(pmp_addr, gran)
+#else
+#define RW_ACCESSES(pmp_addr, gran) RW_ACCESSES_IN_M_MODE(pmp_addr, gran)
+#endif
+
+#define SET_MSECCFG(val) \
+ li t1, val; \
+ csrs CSR_MSECCFG, t1;
+
+#define SWITCH_TO_U_MODE_LABEL(label) \
+ li t0, MSTATUS_MPP; \
+ csrc mstatus, t0; \
+ la t0, label; \
+ csrw mepc, t0; \
+ la a0, 1f; \
+ mret; \
+ 1:
+
+#define SWITCH_TO_U_MODE_REG(reg) \
+ li t0, MSTATUS_MPP; \
+ csrc mstatus, t0; \
+ csrw mepc, reg; \
+ la a0, 1f; \
+ mret; \
+ 1:
diff --git a/dv/uvm/core_ibex/directed_tests/directed_testlist.yaml b/dv/uvm/core_ibex/directed_tests/directed_testlist.yaml
new file mode 100644
index 00000000..2517f54a
--- /dev/null
+++ b/dv/uvm/core_ibex/directed_tests/directed_testlist.yaml
@@ -0,0 +1,6784 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+##########################################################
+
+# This file is generated by gen_testlist.py script and largely copies
+# the formatting of the testlist.yaml used by riscv-dv, but only specifies
+# directed tests.
+#
+# - All paths are relative to THIS FILE.
+# - Each 'test' can specify a config by name to re-use common configuration
+# - If a test redefines a key already in the config, the test option takes priority.
+
+##########################################################
+
+- config: riscv-tests
+ ld_script: link.ld
+ includes: .
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ rtl_test: core_ibex_base_test
+ rtl_params:
+ PMPEnable: 1
+ timeout_s: 300
+
+- config: riscv-arch-tests
+ ld_script: link.ld
+ includes: .
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-arch-tests/riscv-test-suite/env/
+ -I../../../vendor/riscv-isa-sim/arch_test_target/spike/
+ rtl_test: core_ibex_base_test
+ rtl_params:
+ PMPEnable: 1
+ timeout_s: 300
+
+- config: epmp-tests
+ ld_script: ../../../../vendor/riscv-isa-sim/tests/mseccfg/mseccfg_test.ld
+ includes: .
+ gcc_opts: -march=rv32imc -O2 -I . -I ./. -I ../softfloat -I ../riscv -fno-builtin-printf
+ -fdata-sections -fno-section-anchors -DPRINTF_SUPPORTED=1
+ ../../../vendor/riscv-isa-sim/tests/mseccfg/crt.S
+ ../../../vendor/riscv-isa-sim/tests/mseccfg/syscalls.c
+ -mcmodel=medany -static -nostdlib -nostartfiles -lm -lgcc
+ -Wl,-M -Wl,-Map=link.log
+ rtl_test: core_ibex_base_test
+ rtl_params:
+ PMPEnable: 1
+ timeout_s: 300
+
+# Custom directed tests
+
+- test: empty
+ desc: >
+ Empty directed test
+ iterations: 1
+ test_srcs: empty/empty.S
+ config: riscv-tests
+
+- test: pmp_mseccfg_test_rlb1_l0_0_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DPMP_REGION=4 -DRLB -DSET_PMP_L=0 -DSET_PMP_L_PREV=0
+
+- test: pmp_mseccfg_test_rlb1_l0_1_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DPMP_REGION=4 -DRLB -DSET_PMP_L=1 -DSET_PMP_L_PREV=0
+
+- test: pmp_mseccfg_test_rlb1_l1_0_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DPMP_REGION=4 -DRLB -DSET_PMP_L=0 -DSET_PMP_L_PREV=1
+
+- test: pmp_mseccfg_test_rlb1_l1_1_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DPMP_REGION=4 -DRLB -DSET_PMP_L=1 -DSET_PMP_L_PREV=1
+
+- test: pmp_mseccfg_test_rlb0_l0_0_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DPMP_REGION=4 -DSET_PMP_L=0 -DSET_PMP_L_PREV=0
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_r1_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_R1
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_w1_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_W1
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_x1_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_X1
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_r1_w1_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_R1_W1
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_r1_x1_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_R1_X1
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_w1_x1_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_W1_X1
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_r1_w1_x1_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_R1_W1_X1
+
+- test: pmp_mseccfg_test_rlb1_l0_0_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DPMP_REGION=4 -DRLB -DSET_PMP_L=0 -DSET_PMP_L_PREV=0 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb1_l0_1_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DPMP_REGION=4 -DRLB -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb1_l1_0_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DPMP_REGION=4 -DRLB -DSET_PMP_L=0 -DSET_PMP_L_PREV=1 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb1_l1_1_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DPMP_REGION=4 -DRLB -DSET_PMP_L=1 -DSET_PMP_L_PREV=1 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb0_l0_0_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DPMP_REGION=4 -DSET_PMP_L=0 -DSET_PMP_L_PREV=0 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_r1_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_R1 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_w1_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_W1 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_x1_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_X1 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_r1_w1_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_R1_W1 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_r1_x1_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_R1_X1 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_w1_x1_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_W1_X1 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_r1_w1_x1_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_R1_W1_X1 -DU_MODE
+
+- test: access_pmp_overlap
+ desc: >
+ PMP access basic test
+ iterations: 1
+ test_srcs: access_pmp_overlap/access_pmp_overlap.S
+ config: riscv-tests
+
+- test: u_mode_exec_test
+ desc: >
+ PMP U mode exec test
+ iterations: 1
+ test_srcs: u_mode_exec_test/u_mode_exec_test.S
+ config: riscv-tests
+
+# Test-suite: riscv-tests
+
+- test: breakpoint
+ desc: >
+ riscv test - breakpoint
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32mi/breakpoint.S
+ config: riscv-tests
+
+- test: csr
+ desc: >
+ riscv test - csr
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32mi/csr.S
+ config: riscv-tests
+
+- test: illegal
+ desc: >
+ riscv test - illegal
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32mi/illegal.S
+ config: riscv-tests
+
+- test: lh-misaligned
+ desc: >
+ riscv test - lh-misaligned
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32mi/lh-misaligned.S
+ config: riscv-tests
+
+- test: lw-misaligned
+ desc: >
+ riscv test - lw-misaligned
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32mi/lw-misaligned.S
+ config: riscv-tests
+
+- test: ma_addr
+ desc: >
+ riscv test - ma_addr
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32mi/ma_addr.S
+ config: riscv-tests
+
+- test: ma_fetch
+ desc: >
+ riscv test - ma_fetch
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32mi/ma_fetch.S
+ config: riscv-tests
+
+- test: mcsr
+ desc: >
+ riscv test - mcsr
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32mi/mcsr.S
+ config: riscv-tests
+
+- test: sbreak
+ desc: >
+ riscv test - sbreak
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32mi/sbreak.S
+ config: riscv-tests
+
+- test: scall
+ desc: >
+ riscv test - scall
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32mi/scall.S
+ config: riscv-tests
+
+- test: shamt
+ desc: >
+ riscv test - shamt
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32mi/shamt.S
+ config: riscv-tests
+
+- test: sh-misaligned
+ desc: >
+ riscv test - sh-misaligned
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32mi/sh-misaligned.S
+ config: riscv-tests
+
+- test: sw-misaligned
+ desc: >
+ riscv test - sw-misaligned
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32mi/sw-misaligned.S
+ config: riscv-tests
+
+- test: zicntr
+ desc: >
+ riscv test - zicntr
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32mi/zicntr.S
+ config: riscv-tests
+
+- test: rvc
+ desc: >
+ riscv test - rvc
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32uc/rvc.S
+ config: riscv-tests
+
+- test: div
+ desc: >
+ riscv test - div
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32um/div.S
+ config: riscv-tests
+
+- test: divu
+ desc: >
+ riscv test - divu
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32um/divu.S
+ config: riscv-tests
+
+- test: mulh
+ desc: >
+ riscv test - mulh
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32um/mulh.S
+ config: riscv-tests
+
+- test: mulhsu
+ desc: >
+ riscv test - mulhsu
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32um/mulhsu.S
+ config: riscv-tests
+
+- test: mulhu
+ desc: >
+ riscv test - mulhu
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32um/mulhu.S
+ config: riscv-tests
+
+- test: mul
+ desc: >
+ riscv test - mul
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32um/mul.S
+ config: riscv-tests
+
+- test: rem
+ desc: >
+ riscv test - rem
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32um/rem.S
+ config: riscv-tests
+
+- test: remu
+ desc: >
+ riscv test - remu
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32um/remu.S
+ config: riscv-tests
+
+- test: addi
+ desc: >
+ riscv test - addi
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/addi.S
+ config: riscv-tests
+
+- test: add
+ desc: >
+ riscv test - add
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/add.S
+ config: riscv-tests
+
+- test: andi
+ desc: >
+ riscv test - andi
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/andi.S
+ config: riscv-tests
+
+- test: and
+ desc: >
+ riscv test - and
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/and.S
+ config: riscv-tests
+
+- test: auipc
+ desc: >
+ riscv test - auipc
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/auipc.S
+ config: riscv-tests
+
+- test: beq
+ desc: >
+ riscv test - beq
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/beq.S
+ config: riscv-tests
+
+- test: bge
+ desc: >
+ riscv test - bge
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/bge.S
+ config: riscv-tests
+
+- test: bgeu
+ desc: >
+ riscv test - bgeu
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/bgeu.S
+ config: riscv-tests
+
+- test: blt
+ desc: >
+ riscv test - blt
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/blt.S
+ config: riscv-tests
+
+- test: bltu
+ desc: >
+ riscv test - bltu
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/bltu.S
+ config: riscv-tests
+
+- test: bne
+ desc: >
+ riscv test - bne
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/bne.S
+ config: riscv-tests
+
+- test: fence_i
+ desc: >
+ riscv test - fence_i
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/fence_i.S
+ config: riscv-tests
+
+- test: jalr
+ desc: >
+ riscv test - jalr
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/jalr.S
+ config: riscv-tests
+
+- test: jal
+ desc: >
+ riscv test - jal
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/jal.S
+ config: riscv-tests
+
+- test: lb
+ desc: >
+ riscv test - lb
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/lb.S
+ config: riscv-tests
+
+- test: lbu
+ desc: >
+ riscv test - lbu
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/lbu.S
+ config: riscv-tests
+
+- test: lh
+ desc: >
+ riscv test - lh
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/lh.S
+ config: riscv-tests
+
+- test: lhu
+ desc: >
+ riscv test - lhu
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/lhu.S
+ config: riscv-tests
+
+- test: lui
+ desc: >
+ riscv test - lui
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/lui.S
+ config: riscv-tests
+
+- test: lw
+ desc: >
+ riscv test - lw
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/lw.S
+ config: riscv-tests
+
+- test: ori
+ desc: >
+ riscv test - ori
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/ori.S
+ config: riscv-tests
+
+- test: or
+ desc: >
+ riscv test - or
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/or.S
+ config: riscv-tests
+
+- test: sb
+ desc: >
+ riscv test - sb
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/sb.S
+ config: riscv-tests
+
+- test: sh
+ desc: >
+ riscv test - sh
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/sh.S
+ config: riscv-tests
+
+- test: simple
+ desc: >
+ riscv test - simple
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/simple.S
+ config: riscv-tests
+
+- test: slli
+ desc: >
+ riscv test - slli
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/slli.S
+ config: riscv-tests
+
+- test: sll
+ desc: >
+ riscv test - sll
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/sll.S
+ config: riscv-tests
+
+- test: slti
+ desc: >
+ riscv test - slti
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/slti.S
+ config: riscv-tests
+
+- test: sltiu
+ desc: >
+ riscv test - sltiu
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/sltiu.S
+ config: riscv-tests
+
+- test: slt
+ desc: >
+ riscv test - slt
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/slt.S
+ config: riscv-tests
+
+- test: sltu
+ desc: >
+ riscv test - sltu
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/sltu.S
+ config: riscv-tests
+
+- test: srai
+ desc: >
+ riscv test - srai
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/srai.S
+ config: riscv-tests
+
+- test: sra
+ desc: >
+ riscv test - sra
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/sra.S
+ config: riscv-tests
+
+- test: srli
+ desc: >
+ riscv test - srli
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/srli.S
+ config: riscv-tests
+
+- test: srl
+ desc: >
+ riscv test - srl
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/srl.S
+ config: riscv-tests
+
+- test: sub
+ desc: >
+ riscv test - sub
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/sub.S
+ config: riscv-tests
+
+- test: sw
+ desc: >
+ riscv test - sw
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/sw.S
+ config: riscv-tests
+
+- test: xori
+ desc: >
+ riscv test - xori
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/xori.S
+ config: riscv-tests
+
+- test: xor
+ desc: >
+ riscv test - xor
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-tests/isa/rv32ui/xor.S
+ config: riscv-tests
+
+# Test-suite: riscv-arch-tests
+
+- test: div-01
+ desc: >
+ riscv test - div-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/M/src/div-01.S
+ config: riscv-arch-tests
+
+- test: divu-01
+ desc: >
+ riscv test - divu-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/M/src/divu-01.S
+ config: riscv-arch-tests
+
+- test: mul-01
+ desc: >
+ riscv test - mul-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/M/src/mul-01.S
+ config: riscv-arch-tests
+
+- test: mulh-01
+ desc: >
+ riscv test - mulh-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/M/src/mulh-01.S
+ config: riscv-arch-tests
+
+- test: mulhsu-01
+ desc: >
+ riscv test - mulhsu-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/M/src/mulhsu-01.S
+ config: riscv-arch-tests
+
+- test: mulhu-01
+ desc: >
+ riscv test - mulhu-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/M/src/mulhu-01.S
+ config: riscv-arch-tests
+
+- test: rem-01
+ desc: >
+ riscv test - rem-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/M/src/rem-01.S
+ config: riscv-arch-tests
+
+- test: remu-01
+ desc: >
+ riscv test - remu-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/M/src/remu-01.S
+ config: riscv-arch-tests
+
+- test: cadd-01
+ desc: >
+ riscv test - cadd-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/cadd-01.S
+ config: riscv-arch-tests
+
+- test: caddi-01
+ desc: >
+ riscv test - caddi-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/caddi-01.S
+ config: riscv-arch-tests
+
+- test: caddi16sp-01
+ desc: >
+ riscv test - caddi16sp-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/caddi16sp-01.S
+ config: riscv-arch-tests
+
+- test: caddi4spn-01
+ desc: >
+ riscv test - caddi4spn-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/caddi4spn-01.S
+ config: riscv-arch-tests
+
+- test: cand-01
+ desc: >
+ riscv test - cand-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/cand-01.S
+ config: riscv-arch-tests
+
+- test: candi-01
+ desc: >
+ riscv test - candi-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/candi-01.S
+ config: riscv-arch-tests
+
+- test: cbeqz-01
+ desc: >
+ riscv test - cbeqz-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/cbeqz-01.S
+ config: riscv-arch-tests
+
+- test: cbnez-01
+ desc: >
+ riscv test - cbnez-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/cbnez-01.S
+ config: riscv-arch-tests
+
+- test: cebreak-01
+ desc: >
+ riscv test - cebreak-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/cebreak-01.S
+ config: riscv-arch-tests
+
+- test: cj-01
+ desc: >
+ riscv test - cj-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/cj-01.S
+ config: riscv-arch-tests
+
+- test: cjal-01
+ desc: >
+ riscv test - cjal-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/cjal-01.S
+ config: riscv-arch-tests
+
+- test: cjalr-01
+ desc: >
+ riscv test - cjalr-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/cjalr-01.S
+ config: riscv-arch-tests
+
+- test: cjr-01
+ desc: >
+ riscv test - cjr-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/cjr-01.S
+ config: riscv-arch-tests
+
+- test: cli-01
+ desc: >
+ riscv test - cli-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/cli-01.S
+ config: riscv-arch-tests
+
+- test: clui-01
+ desc: >
+ riscv test - clui-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/clui-01.S
+ config: riscv-arch-tests
+
+- test: clw-01
+ desc: >
+ riscv test - clw-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/clw-01.S
+ config: riscv-arch-tests
+
+- test: clwsp-01
+ desc: >
+ riscv test - clwsp-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/clwsp-01.S
+ config: riscv-arch-tests
+
+- test: cmv-01
+ desc: >
+ riscv test - cmv-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/cmv-01.S
+ config: riscv-arch-tests
+
+- test: cnop-01
+ desc: >
+ riscv test - cnop-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/cnop-01.S
+ config: riscv-arch-tests
+
+- test: cor-01
+ desc: >
+ riscv test - cor-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/cor-01.S
+ config: riscv-arch-tests
+
+- test: cslli-01
+ desc: >
+ riscv test - cslli-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/cslli-01.S
+ config: riscv-arch-tests
+
+- test: csrai-01
+ desc: >
+ riscv test - csrai-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/csrai-01.S
+ config: riscv-arch-tests
+
+- test: csrli-01
+ desc: >
+ riscv test - csrli-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/csrli-01.S
+ config: riscv-arch-tests
+
+- test: csub-01
+ desc: >
+ riscv test - csub-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/csub-01.S
+ config: riscv-arch-tests
+
+- test: csw-01
+ desc: >
+ riscv test - csw-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/csw-01.S
+ config: riscv-arch-tests
+
+- test: cswsp-01
+ desc: >
+ riscv test - cswsp-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/cswsp-01.S
+ config: riscv-arch-tests
+
+- test: cxor-01
+ desc: >
+ riscv test - cxor-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/C/src/cxor-01.S
+ config: riscv-arch-tests
+
+- test: Fencei
+ desc: >
+ riscv test - Fencei
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/Zifencei/src/Fencei.S
+ config: riscv-arch-tests
+
+- test: add-01
+ desc: >
+ riscv test - add-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/add-01.S
+ config: riscv-arch-tests
+
+- test: addi-01
+ desc: >
+ riscv test - addi-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/addi-01.S
+ config: riscv-arch-tests
+
+- test: and-01
+ desc: >
+ riscv test - and-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/and-01.S
+ config: riscv-arch-tests
+
+- test: andi-01
+ desc: >
+ riscv test - andi-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/andi-01.S
+ config: riscv-arch-tests
+
+- test: auipc-01
+ desc: >
+ riscv test - auipc-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/auipc-01.S
+ config: riscv-arch-tests
+
+- test: beq-01
+ desc: >
+ riscv test - beq-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/beq-01.S
+ config: riscv-arch-tests
+
+- test: bge-01
+ desc: >
+ riscv test - bge-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/bge-01.S
+ config: riscv-arch-tests
+
+- test: bgeu-01
+ desc: >
+ riscv test - bgeu-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/bgeu-01.S
+ config: riscv-arch-tests
+
+- test: blt-01
+ desc: >
+ riscv test - blt-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/blt-01.S
+ config: riscv-arch-tests
+
+- test: bltu-01
+ desc: >
+ riscv test - bltu-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/bltu-01.S
+ config: riscv-arch-tests
+
+- test: bne-01
+ desc: >
+ riscv test - bne-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/bne-01.S
+ config: riscv-arch-tests
+
+- test: fence-01
+ desc: >
+ riscv test - fence-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/fence-01.S
+ config: riscv-arch-tests
+
+- test: jal-01
+ desc: >
+ riscv test - jal-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/jal-01.S
+ config: riscv-arch-tests
+
+- test: jalr-01
+ desc: >
+ riscv test - jalr-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/jalr-01.S
+ config: riscv-arch-tests
+
+- test: lb-align-01
+ desc: >
+ riscv test - lb-align-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/lb-align-01.S
+ config: riscv-arch-tests
+
+- test: lbu-align-01
+ desc: >
+ riscv test - lbu-align-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/lbu-align-01.S
+ config: riscv-arch-tests
+
+- test: lh-align-01
+ desc: >
+ riscv test - lh-align-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/lh-align-01.S
+ config: riscv-arch-tests
+
+- test: lhu-align-01
+ desc: >
+ riscv test - lhu-align-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/lhu-align-01.S
+ config: riscv-arch-tests
+
+- test: lui-01
+ desc: >
+ riscv test - lui-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/lui-01.S
+ config: riscv-arch-tests
+
+- test: lw-align-01
+ desc: >
+ riscv test - lw-align-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/lw-align-01.S
+ config: riscv-arch-tests
+
+- test: misalign1-jalr-01
+ desc: >
+ riscv test - misalign1-jalr-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/misalign1-jalr-01.S
+ config: riscv-arch-tests
+
+- test: or-01
+ desc: >
+ riscv test - or-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/or-01.S
+ config: riscv-arch-tests
+
+- test: ori-01
+ desc: >
+ riscv test - ori-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/ori-01.S
+ config: riscv-arch-tests
+
+- test: sb-align-01
+ desc: >
+ riscv test - sb-align-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/sb-align-01.S
+ config: riscv-arch-tests
+
+- test: sh-align-01
+ desc: >
+ riscv test - sh-align-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/sh-align-01.S
+ config: riscv-arch-tests
+
+- test: sll-01
+ desc: >
+ riscv test - sll-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/sll-01.S
+ config: riscv-arch-tests
+
+- test: slli-01
+ desc: >
+ riscv test - slli-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/slli-01.S
+ config: riscv-arch-tests
+
+- test: slt-01
+ desc: >
+ riscv test - slt-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/slt-01.S
+ config: riscv-arch-tests
+
+- test: slti-01
+ desc: >
+ riscv test - slti-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/slti-01.S
+ config: riscv-arch-tests
+
+- test: sltiu-01
+ desc: >
+ riscv test - sltiu-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/sltiu-01.S
+ config: riscv-arch-tests
+
+- test: sltu-01
+ desc: >
+ riscv test - sltu-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/sltu-01.S
+ config: riscv-arch-tests
+
+- test: sra-01
+ desc: >
+ riscv test - sra-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/sra-01.S
+ config: riscv-arch-tests
+
+- test: srai-01
+ desc: >
+ riscv test - srai-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/srai-01.S
+ config: riscv-arch-tests
+
+- test: srl-01
+ desc: >
+ riscv test - srl-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/srl-01.S
+ config: riscv-arch-tests
+
+- test: srli-01
+ desc: >
+ riscv test - srli-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/srli-01.S
+ config: riscv-arch-tests
+
+- test: sub-01
+ desc: >
+ riscv test - sub-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/sub-01.S
+ config: riscv-arch-tests
+
+- test: sw-align-01
+ desc: >
+ riscv test - sw-align-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/sw-align-01.S
+ config: riscv-arch-tests
+
+- test: xor-01
+ desc: >
+ riscv test - xor-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/xor-01.S
+ config: riscv-arch-tests
+
+- test: xori-01
+ desc: >
+ riscv test - xori-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/I/src/xori-01.S
+ config: riscv-arch-tests
+
+- test: andn-01
+ desc: >
+ riscv test - andn-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/andn-01.S
+ config: riscv-arch-tests
+
+- test: bclr-01
+ desc: >
+ riscv test - bclr-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/bclr-01.S
+ config: riscv-arch-tests
+
+- test: bclri-01
+ desc: >
+ riscv test - bclri-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/bclri-01.S
+ config: riscv-arch-tests
+
+- test: bext-01
+ desc: >
+ riscv test - bext-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/bext-01.S
+ config: riscv-arch-tests
+
+- test: bexti-01
+ desc: >
+ riscv test - bexti-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/bexti-01.S
+ config: riscv-arch-tests
+
+- test: binv-01
+ desc: >
+ riscv test - binv-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/binv-01.S
+ config: riscv-arch-tests
+
+- test: binvi-01
+ desc: >
+ riscv test - binvi-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/binvi-01.S
+ config: riscv-arch-tests
+
+- test: bset-01
+ desc: >
+ riscv test - bset-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/bset-01.S
+ config: riscv-arch-tests
+
+- test: bseti-01
+ desc: >
+ riscv test - bseti-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/bseti-01.S
+ config: riscv-arch-tests
+
+- test: clmul-01
+ desc: >
+ riscv test - clmul-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/clmul-01.S
+ config: riscv-arch-tests
+
+- test: clmulh-01
+ desc: >
+ riscv test - clmulh-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/clmulh-01.S
+ config: riscv-arch-tests
+
+- test: clmulr-01
+ desc: >
+ riscv test - clmulr-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/clmulr-01.S
+ config: riscv-arch-tests
+
+- test: clz-01
+ desc: >
+ riscv test - clz-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/clz-01.S
+ config: riscv-arch-tests
+
+- test: cpop-01
+ desc: >
+ riscv test - cpop-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/cpop-01.S
+ config: riscv-arch-tests
+
+- test: ctz-01
+ desc: >
+ riscv test - ctz-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/ctz-01.S
+ config: riscv-arch-tests
+
+- test: max-01
+ desc: >
+ riscv test - max-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/max-01.S
+ config: riscv-arch-tests
+
+- test: maxu-01
+ desc: >
+ riscv test - maxu-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/maxu-01.S
+ config: riscv-arch-tests
+
+- test: min-01
+ desc: >
+ riscv test - min-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/min-01.S
+ config: riscv-arch-tests
+
+- test: minu-01
+ desc: >
+ riscv test - minu-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/minu-01.S
+ config: riscv-arch-tests
+
+- test: orcb_32-01
+ desc: >
+ riscv test - orcb_32-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/orcb_32-01.S
+ config: riscv-arch-tests
+
+- test: orn-01
+ desc: >
+ riscv test - orn-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/orn-01.S
+ config: riscv-arch-tests
+
+- test: rev8_32-01
+ desc: >
+ riscv test - rev8_32-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/rev8_32-01.S
+ config: riscv-arch-tests
+
+- test: rol-01
+ desc: >
+ riscv test - rol-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/rol-01.S
+ config: riscv-arch-tests
+
+- test: ror-01
+ desc: >
+ riscv test - ror-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/ror-01.S
+ config: riscv-arch-tests
+
+- test: rori-01
+ desc: >
+ riscv test - rori-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/rori-01.S
+ config: riscv-arch-tests
+
+- test: sext-b-01
+ desc: >
+ riscv test - sext-b-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/sext-b-01.S
+ config: riscv-arch-tests
+
+- test: sext-h-01
+ desc: >
+ riscv test - sext-h-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/sext-h-01.S
+ config: riscv-arch-tests
+
+- test: sh1add-01
+ desc: >
+ riscv test - sh1add-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/sh1add-01.S
+ config: riscv-arch-tests
+
+- test: sh2add-01
+ desc: >
+ riscv test - sh2add-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/sh2add-01.S
+ config: riscv-arch-tests
+
+- test: sh3add-01
+ desc: >
+ riscv test - sh3add-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/sh3add-01.S
+ config: riscv-arch-tests
+
+- test: xnor-01
+ desc: >
+ riscv test - xnor-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/xnor-01.S
+ config: riscv-arch-tests
+
+- test: zext-h_32-01
+ desc: >
+ riscv test - zext-h_32-01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-arch-tests/riscv-test-suite/rv32i_m/B/src/zext-h_32-01.S
+ config: riscv-arch-tests
+
+# Test-suite: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml0_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp0_mml1_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml0_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb0_mmwp1_mml1_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml0_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp0_mml1_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml0_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock00_rlb1_mmwp1_mml1_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml0_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp0_mml1_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml0_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb0_mmwp1_mml1_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml0_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp0_mml1_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml0_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock01_rlb1_mmwp1_mml1_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml0_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp0_mml1_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml0_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb0_mmwp1_mml1_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml0_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp0_mml1_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml0_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_07.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_11
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_11
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_11.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_12
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_12
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_12.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_13
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_13
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_13.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_14
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_14
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_14.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_15
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_15
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_15.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_16
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_16
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_16.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_17
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_17
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_pmp_17.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_00
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_00
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_00.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_01
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_01
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_01.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_02
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_02
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_02.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_03
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_03
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_03.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_04
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_04
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_04.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_05
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_05
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_05.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_06
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_06
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_06.c
+ config: epmp-tests
+
+- test: test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_07
+ desc: >
+ riscv test - test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_07
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_csr_1_lock10_rlb1_mmwp1_mml1_sec_07.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x0_l0_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x0_l0_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x0_l0_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x0_l0_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x0_l0_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x0_l0_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x0_l0_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x0_l0_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x0_l0_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x0_l0_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x0_l0_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x0_l0_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x0_l0_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x0_l0_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x0_l0_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x0_l0_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x0_l0_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x0_l0_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x0_l0_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x0_l0_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x0_l0_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x0_l0_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x0_l0_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x0_l0_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x0_l1_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x0_l1_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x0_l1_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x0_l1_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x0_l1_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x0_l1_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x0_l1_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x0_l1_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x0_l1_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x0_l1_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x0_l1_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x0_l1_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x0_l1_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x0_l1_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x0_l1_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x0_l1_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x0_l1_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x0_l1_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x0_l1_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x0_l1_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x0_l1_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x0_l1_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x0_l1_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x0_l1_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x1_l0_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x1_l0_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x1_l0_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x1_l0_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x1_l0_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x1_l0_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x1_l0_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x1_l0_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x1_l0_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x1_l0_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x1_l0_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x1_l0_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x1_l0_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x1_l0_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x1_l0_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x1_l0_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x1_l0_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x1_l0_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x1_l0_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x1_l0_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x1_l0_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x1_l0_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x1_l0_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x1_l0_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x1_l1_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x1_l1_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x1_l1_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x1_l1_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x1_l1_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x1_l1_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x1_l1_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x1_l1_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x1_l1_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x1_l1_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x1_l1_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x1_l1_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x1_l1_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x1_l1_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x1_l1_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x1_l1_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x1_l1_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x1_l1_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x1_l1_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x1_l1_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x1_l1_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw00_x1_l1_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw00_x1_l1_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw00_x1_l1_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x0_l0_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x0_l0_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x0_l0_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x0_l0_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x0_l0_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x0_l0_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x0_l0_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x0_l0_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x0_l0_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x0_l0_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x0_l0_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x0_l0_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x0_l0_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x0_l0_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x0_l0_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x0_l0_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x0_l0_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x0_l0_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x0_l0_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x0_l0_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x0_l0_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x0_l0_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x0_l0_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x0_l0_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x0_l1_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x0_l1_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x0_l1_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x0_l1_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x0_l1_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x0_l1_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x0_l1_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x0_l1_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x0_l1_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x0_l1_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x0_l1_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x0_l1_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x0_l1_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x0_l1_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x0_l1_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x0_l1_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x0_l1_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x0_l1_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x0_l1_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x0_l1_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x0_l1_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x0_l1_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x0_l1_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x0_l1_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x1_l0_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x1_l0_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x1_l0_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x1_l0_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x1_l0_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x1_l0_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x1_l0_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x1_l0_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x1_l0_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x1_l0_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x1_l0_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x1_l0_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x1_l0_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x1_l0_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x1_l0_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x1_l0_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x1_l0_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x1_l0_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x1_l0_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x1_l0_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x1_l0_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x1_l0_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x1_l0_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x1_l0_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x1_l1_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x1_l1_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x1_l1_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x1_l1_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x1_l1_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x1_l1_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x1_l1_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x1_l1_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x1_l1_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x1_l1_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x1_l1_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x1_l1_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x1_l1_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x1_l1_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x1_l1_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x1_l1_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x1_l1_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x1_l1_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x1_l1_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x1_l1_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x1_l1_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw10_x1_l1_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw10_x1_l1_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw10_x1_l1_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x0_l0_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x0_l0_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x0_l0_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x0_l0_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x0_l0_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x0_l0_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x0_l0_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x0_l0_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x0_l0_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x0_l0_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x0_l0_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x0_l0_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x0_l0_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x0_l0_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x0_l0_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x0_l0_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x0_l0_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x0_l0_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x0_l0_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x0_l0_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x0_l0_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x0_l0_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x0_l0_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x0_l0_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x0_l1_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x0_l1_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x0_l1_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x0_l1_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x0_l1_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x0_l1_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x0_l1_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x0_l1_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x0_l1_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x0_l1_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x0_l1_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x0_l1_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x0_l1_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x0_l1_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x0_l1_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x0_l1_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x0_l1_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x0_l1_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x0_l1_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x0_l1_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x0_l1_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x0_l1_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x0_l1_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x0_l1_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x1_l0_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x1_l0_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x1_l0_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x1_l0_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x1_l0_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x1_l0_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x1_l0_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x1_l0_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x1_l0_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x1_l0_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x1_l0_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x1_l0_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x1_l0_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x1_l0_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x1_l0_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x1_l0_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x1_l0_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x1_l0_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x1_l0_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x1_l0_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x1_l0_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x1_l0_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x1_l0_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x1_l0_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x1_l1_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x1_l1_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x1_l1_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x1_l1_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x1_l1_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x1_l1_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x1_l1_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x1_l1_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x1_l1_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x1_l1_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x1_l1_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x1_l1_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x1_l1_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x1_l1_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x1_l1_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x1_l1_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x1_l1_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x1_l1_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x1_l1_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x1_l1_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x1_l1_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u0_rw11_x1_l1_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u0_rw11_x1_l1_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u0_rw11_x1_l1_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x0_l0_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x0_l0_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x0_l0_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x0_l0_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x0_l0_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x0_l0_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x0_l0_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x0_l0_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x0_l0_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x0_l0_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x0_l0_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x0_l0_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x0_l0_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x0_l0_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x0_l0_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x0_l0_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x0_l0_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x0_l0_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x0_l0_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x0_l0_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x0_l0_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x0_l0_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x0_l0_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x0_l0_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x0_l1_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x0_l1_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x0_l1_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x0_l1_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x0_l1_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x0_l1_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x0_l1_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x0_l1_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x0_l1_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x0_l1_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x0_l1_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x0_l1_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x0_l1_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x0_l1_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x0_l1_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x0_l1_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x0_l1_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x0_l1_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x0_l1_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x0_l1_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x0_l1_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x0_l1_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x0_l1_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x0_l1_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x1_l0_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x1_l0_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x1_l0_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x1_l0_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x1_l0_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x1_l0_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x1_l0_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x1_l0_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x1_l0_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x1_l0_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x1_l0_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x1_l0_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x1_l0_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x1_l0_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x1_l0_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x1_l0_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x1_l0_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x1_l0_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x1_l0_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x1_l0_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x1_l0_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x1_l0_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x1_l0_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x1_l0_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x1_l1_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x1_l1_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x1_l1_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x1_l1_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x1_l1_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x1_l1_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x1_l1_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x1_l1_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x1_l1_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x1_l1_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x1_l1_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x1_l1_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x1_l1_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x1_l1_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x1_l1_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x1_l1_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x1_l1_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x1_l1_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x1_l1_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x1_l1_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x1_l1_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw00_x1_l1_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw00_x1_l1_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw00_x1_l1_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x0_l0_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x0_l0_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x0_l0_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x0_l0_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x0_l0_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x0_l0_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x0_l0_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x0_l0_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x0_l0_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x0_l0_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x0_l0_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x0_l0_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x0_l0_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x0_l0_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x0_l0_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x0_l0_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x0_l0_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x0_l0_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x0_l0_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x0_l0_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x0_l0_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x0_l0_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x0_l0_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x0_l0_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x0_l1_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x0_l1_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x0_l1_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x0_l1_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x0_l1_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x0_l1_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x0_l1_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x0_l1_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x0_l1_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x0_l1_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x0_l1_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x0_l1_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x0_l1_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x0_l1_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x0_l1_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x0_l1_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x0_l1_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x0_l1_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x0_l1_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x0_l1_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x0_l1_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x0_l1_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x0_l1_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x0_l1_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x1_l0_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x1_l0_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x1_l0_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x1_l0_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x1_l0_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x1_l0_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x1_l0_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x1_l0_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x1_l0_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x1_l0_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x1_l0_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x1_l0_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x1_l0_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x1_l0_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x1_l0_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x1_l0_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x1_l0_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x1_l0_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x1_l0_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x1_l0_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x1_l0_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x1_l0_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x1_l0_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x1_l0_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x1_l1_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x1_l1_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x1_l1_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x1_l1_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x1_l1_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x1_l1_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x1_l1_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x1_l1_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x1_l1_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x1_l1_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x1_l1_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x1_l1_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x1_l1_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x1_l1_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x1_l1_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x1_l1_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x1_l1_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x1_l1_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x1_l1_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x1_l1_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x1_l1_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw10_x1_l1_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw10_x1_l1_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw10_x1_l1_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x0_l0_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x0_l0_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x0_l0_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x0_l0_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x0_l0_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x0_l0_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x0_l0_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x0_l0_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x0_l0_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x0_l0_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x0_l0_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x0_l0_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x0_l0_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x0_l0_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x0_l0_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x0_l0_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x0_l0_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x0_l0_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x0_l0_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x0_l0_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x0_l0_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x0_l0_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x0_l0_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x0_l0_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x0_l1_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x0_l1_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x0_l1_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x0_l1_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x0_l1_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x0_l1_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x0_l1_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x0_l1_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x0_l1_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x0_l1_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x0_l1_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x0_l1_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x0_l1_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x0_l1_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x0_l1_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x0_l1_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x0_l1_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x0_l1_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x0_l1_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x0_l1_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x0_l1_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x0_l1_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x0_l1_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x0_l1_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x1_l0_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x1_l0_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x1_l0_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x1_l0_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x1_l0_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x1_l0_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x1_l0_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x1_l0_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x1_l0_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x1_l0_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x1_l0_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x1_l0_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x1_l0_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x1_l0_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x1_l0_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x1_l0_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x1_l0_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x1_l0_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x1_l0_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x1_l0_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x1_l0_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x1_l0_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x1_l0_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x1_l0_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x1_l1_match0_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x1_l1_match0_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x1_l1_match0_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x1_l1_match0_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x1_l1_match0_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x1_l1_match0_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x1_l1_match0_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x1_l1_match0_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x1_l1_match0_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x1_l1_match0_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x1_l1_match0_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x1_l1_match0_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x1_l1_match1_mmwp0_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x1_l1_match1_mmwp0_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x1_l1_match1_mmwp0_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x1_l1_match1_mmwp0_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x1_l1_match1_mmwp0_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x1_l1_match1_mmwp0_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x1_l1_match1_mmwp1_mml0
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x1_l1_match1_mmwp1_mml0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x1_l1_match1_mmwp1_mml0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_1_u1_rw11_x1_l1_match1_mmwp1_mml1
+ desc: >
+ riscv test - test_pmp_ok_1_u1_rw11_x1_l1_match1_mmwp1_mml1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_1_u1_rw11_x1_l1_match1_mmwp1_mml1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r0_x0_cfgl0_typex0_umode0
+ desc: >
+ riscv test - test_pmp_ok_share_1_r0_x0_cfgl0_typex0_umode0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r0_x0_cfgl0_typex0_umode0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r0_x0_cfgl0_typex0_umode1
+ desc: >
+ riscv test - test_pmp_ok_share_1_r0_x0_cfgl0_typex0_umode1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r0_x0_cfgl0_typex0_umode1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r0_x0_cfgl0_typex1_umode0
+ desc: >
+ riscv test - test_pmp_ok_share_1_r0_x0_cfgl0_typex1_umode0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r0_x0_cfgl0_typex1_umode0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r0_x0_cfgl0_typex1_umode1
+ desc: >
+ riscv test - test_pmp_ok_share_1_r0_x0_cfgl0_typex1_umode1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r0_x0_cfgl0_typex1_umode1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r0_x0_cfgl1_typex0_umode0
+ desc: >
+ riscv test - test_pmp_ok_share_1_r0_x0_cfgl1_typex0_umode0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r0_x0_cfgl1_typex0_umode0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r0_x0_cfgl1_typex0_umode1
+ desc: >
+ riscv test - test_pmp_ok_share_1_r0_x0_cfgl1_typex0_umode1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r0_x0_cfgl1_typex0_umode1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r0_x0_cfgl1_typex1_umode0
+ desc: >
+ riscv test - test_pmp_ok_share_1_r0_x0_cfgl1_typex1_umode0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r0_x0_cfgl1_typex1_umode0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r0_x0_cfgl1_typex1_umode1
+ desc: >
+ riscv test - test_pmp_ok_share_1_r0_x0_cfgl1_typex1_umode1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r0_x0_cfgl1_typex1_umode1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r0_x1_cfgl0_typex0_umode0
+ desc: >
+ riscv test - test_pmp_ok_share_1_r0_x1_cfgl0_typex0_umode0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r0_x1_cfgl0_typex0_umode0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r0_x1_cfgl0_typex0_umode1
+ desc: >
+ riscv test - test_pmp_ok_share_1_r0_x1_cfgl0_typex0_umode1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r0_x1_cfgl0_typex0_umode1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r0_x1_cfgl0_typex1_umode0
+ desc: >
+ riscv test - test_pmp_ok_share_1_r0_x1_cfgl0_typex1_umode0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r0_x1_cfgl0_typex1_umode0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r0_x1_cfgl0_typex1_umode1
+ desc: >
+ riscv test - test_pmp_ok_share_1_r0_x1_cfgl0_typex1_umode1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r0_x1_cfgl0_typex1_umode1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r0_x1_cfgl1_typex0_umode0
+ desc: >
+ riscv test - test_pmp_ok_share_1_r0_x1_cfgl1_typex0_umode0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r0_x1_cfgl1_typex0_umode0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r0_x1_cfgl1_typex0_umode1
+ desc: >
+ riscv test - test_pmp_ok_share_1_r0_x1_cfgl1_typex0_umode1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r0_x1_cfgl1_typex0_umode1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r0_x1_cfgl1_typex1_umode0
+ desc: >
+ riscv test - test_pmp_ok_share_1_r0_x1_cfgl1_typex1_umode0
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r0_x1_cfgl1_typex1_umode0.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r0_x1_cfgl1_typex1_umode1
+ desc: >
+ riscv test - test_pmp_ok_share_1_r0_x1_cfgl1_typex1_umode1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r0_x1_cfgl1_typex1_umode1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r1_x0_cfgl0_typex0_umode1
+ desc: >
+ riscv test - test_pmp_ok_share_1_r1_x0_cfgl0_typex0_umode1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r1_x0_cfgl0_typex0_umode1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r1_x0_cfgl0_typex1_umode1
+ desc: >
+ riscv test - test_pmp_ok_share_1_r1_x0_cfgl0_typex1_umode1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r1_x0_cfgl0_typex1_umode1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r1_x0_cfgl1_typex0_umode1
+ desc: >
+ riscv test - test_pmp_ok_share_1_r1_x0_cfgl1_typex0_umode1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r1_x0_cfgl1_typex0_umode1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r1_x0_cfgl1_typex1_umode1
+ desc: >
+ riscv test - test_pmp_ok_share_1_r1_x0_cfgl1_typex1_umode1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r1_x0_cfgl1_typex1_umode1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r1_x1_cfgl0_typex0_umode1
+ desc: >
+ riscv test - test_pmp_ok_share_1_r1_x1_cfgl0_typex0_umode1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r1_x1_cfgl0_typex0_umode1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r1_x1_cfgl0_typex1_umode1
+ desc: >
+ riscv test - test_pmp_ok_share_1_r1_x1_cfgl0_typex1_umode1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r1_x1_cfgl0_typex1_umode1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r1_x1_cfgl1_typex0_umode1
+ desc: >
+ riscv test - test_pmp_ok_share_1_r1_x1_cfgl1_typex0_umode1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r1_x1_cfgl1_typex0_umode1.c
+ config: epmp-tests
+
+- test: test_pmp_ok_share_1_r1_x1_cfgl1_typex1_umode1
+ desc: >
+ riscv test - test_pmp_ok_share_1_r1_x1_cfgl1_typex1_umode1
+ iterations: 1
+ test_srcs: ../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/outputs/test_pmp_ok_share_1_r1_x1_cfgl1_typex1_umode1.c
+ config: epmp-tests
diff --git a/dv/uvm/core_ibex/directed_tests/empty/empty.S b/dv/uvm/core_ibex/directed_tests/empty/empty.S
new file mode 100644
index 00000000..4c21e042
--- /dev/null
+++ b/dv/uvm/core_ibex/directed_tests/empty/empty.S
@@ -0,0 +1,31 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+###############################################################################
+# Description:
+# Empty test to check the sanity of directed test flow. It can be used as a
+# sample test.
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64M
+RVTEST_CODE_BEGIN
+
+ j pass
+
+RVTEST_CODE_END
+
+pass:
+ RVTEST_PASS
+
+fail:
+ RVTEST_FAIL
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/dv/uvm/core_ibex/directed_tests/gen_testlist.py b/dv/uvm/core_ibex/directed_tests/gen_testlist.py
new file mode 100644
index 00000000..209904ea
--- /dev/null
+++ b/dv/uvm/core_ibex/directed_tests/gen_testlist.py
@@ -0,0 +1,488 @@
+#!/usr/bin/env python3
+"""
+Generating testlists for following opensource test suites
+ - riscv-tests
+ - riscv-arch-tests
+ - ePMP directed tests
+"""
+
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+import os
+import argparse
+import sys
+
+def add_configs_and_handwritten_directed_tests():
+ testlist_string = '''# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+##########################################################
+
+# This file is generated by gen_testlist.py script and largely copies
+# the formatting of the testlist.yaml used by riscv-dv, but only specifies
+# directed tests.
+#
+# - All paths are relative to THIS FILE.
+# - Each 'test' can specify a config by name to re-use common configuration
+# - If a test redefines a key already in the config, the test option takes priority.
+
+##########################################################
+
+- config: riscv-tests
+ ld_script: link.ld
+ includes: .
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ rtl_test: core_ibex_base_test
+ rtl_params:
+ PMPEnable: 1
+ timeout_s: 300
+
+- config: riscv-arch-tests
+ ld_script: link.ld
+ includes: .
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-arch-tests/riscv-test-suite/env/
+ -I../../../vendor/riscv-isa-sim/arch_test_target/spike/
+ rtl_test: core_ibex_base_test
+ rtl_params:
+ PMPEnable: 1
+ timeout_s: 300
+
+- config: epmp-tests
+ ld_script: ../../../../vendor/riscv-isa-sim/tests/mseccfg/mseccfg_test.ld
+ includes: .
+ gcc_opts: -march=rv32imc -O2 -I . -I ./. -I ../softfloat -I ../riscv -fno-builtin-printf
+ -fdata-sections -fno-section-anchors -DPRINTF_SUPPORTED=1
+ ../../../vendor/riscv-isa-sim/tests/mseccfg/crt.S
+ ../../../vendor/riscv-isa-sim/tests/mseccfg/syscalls.c
+ -mcmodel=medany -static -nostdlib -nostartfiles -lm -lgcc
+ -Wl,-M -Wl,-Map=link.log
+ rtl_test: core_ibex_base_test
+ rtl_params:
+ PMPEnable: 1
+ timeout_s: 300
+'''
+ # Populate any handwritten directed tests below
+ # and with suitable config
+ available_directed_tests = '''
+# Custom directed tests
+
+- test: empty
+ desc: >
+ Empty directed test
+ iterations: 1
+ test_srcs: empty/empty.S
+ config: riscv-tests
+
+- test: pmp_mseccfg_test_rlb1_l0_0_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DPMP_REGION=4 -DRLB -DSET_PMP_L=0 -DSET_PMP_L_PREV=0
+
+- test: pmp_mseccfg_test_rlb1_l0_1_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DPMP_REGION=4 -DRLB -DSET_PMP_L=1 -DSET_PMP_L_PREV=0
+
+- test: pmp_mseccfg_test_rlb1_l1_0_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DPMP_REGION=4 -DRLB -DSET_PMP_L=0 -DSET_PMP_L_PREV=1
+
+- test: pmp_mseccfg_test_rlb1_l1_1_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DPMP_REGION=4 -DRLB -DSET_PMP_L=1 -DSET_PMP_L_PREV=1
+
+- test: pmp_mseccfg_test_rlb0_l0_0_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DPMP_REGION=4 -DSET_PMP_L=0 -DSET_PMP_L_PREV=0
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_r1_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_R1
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_w1_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_W1
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_x1_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_X1
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_r1_w1_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_R1_W1
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_r1_x1_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_R1_X1
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_w1_x1_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_W1_X1
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_r1_w1_x1_u0
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_R1_W1_X1
+
+- test: pmp_mseccfg_test_rlb1_l0_0_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DPMP_REGION=4 -DRLB -DSET_PMP_L=0 -DSET_PMP_L_PREV=0 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb1_l0_1_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DPMP_REGION=4 -DRLB -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb1_l1_0_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DPMP_REGION=4 -DRLB -DSET_PMP_L=0 -DSET_PMP_L_PREV=1 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb1_l1_1_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DPMP_REGION=4 -DRLB -DSET_PMP_L=1 -DSET_PMP_L_PREV=1 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb0_l0_0_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DPMP_REGION=4 -DSET_PMP_L=0 -DSET_PMP_L_PREV=0 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_r1_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_R1 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_w1_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_W1 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_x1_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_X1 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_r1_w1_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_R1_W1 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_r1_x1_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_R1_X1 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_w1_x1_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_W1_X1 -DU_MODE
+
+- test: pmp_mseccfg_test_rlb0_l0_1_next_l1_r1_w1_x1_u1
+ desc: >
+ mseccfg test
+ iterations: 1
+ test_srcs: pmp_mseccfg_test/pmp_mseccfg_test.S
+ config: riscv-tests
+ gcc_opts: -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles
+ -I../../../vendor/riscv-test-env/
+ -I../../../vendor/riscv-test-env/p/
+ -I../../../vendor/riscv-tests/isa/macros/scalar/
+ -DSET_PMP_L=1 -DSET_PMP_L_PREV=0 -DPMP_NEXT_L1_R1_W1_X1 -DU_MODE
+
+- test: access_pmp_overlap
+ desc: >
+ PMP access basic test
+ iterations: 1
+ test_srcs: access_pmp_overlap/access_pmp_overlap.S
+ config: riscv-tests
+
+- test: u_mode_exec_test
+ desc: >
+ PMP U mode exec test
+ iterations: 1
+ test_srcs: u_mode_exec_test/u_mode_exec_test.S
+ config: riscv-tests
+'''
+ testlist_string += available_directed_tests
+ with open('directed_testlist.yaml', "a") as f:
+ f.write(testlist_string)
+
+def append_directed_testlist(tests, test_suite, test_suite_name, is_assembly):
+ testlist_string = '''
+# Test-suite: {test_suite_name}
+'''.format(test_suite_name = test_suite_name)
+ extension = '.S' if is_assembly else '.c'
+ extension_grep = ' | egrep .S' if is_assembly else ' | egrep .c'
+
+ for test_group_name in tests:
+ available_tests = os.popen('ls '+test_suite+test_group_name+extension_grep).read()
+ available_testlist = []
+ for test in available_tests.split('\n')[:-1]:
+ available_testlist.append(test)
+ for test_name_str in available_testlist:
+ test_name = test_name_str.split(extension)[0]
+ testlist_string = testlist_string + '''
+- test: {test_name}
+ desc: >
+ riscv test - {test_name}
+ iterations: 1
+ test_srcs: {test_suite}{test_group_name}/{test_name}{extension}
+ config: {config}
+'''.format(test_name = test_name, test_group_name = test_group_name, test_suite = test_suite,
+ config = test_suite_name, extension = extension)
+
+ with open('directed_testlist.yaml', "a") as f:
+ f.write(testlist_string)
+
+def list_tests(dir):
+ testlist_str = os.popen('ls '+dir).read()
+ testlist = []
+ for test in testlist_str.split('\n')[:-1]:
+ testlist.append(test)
+ print(testlist)
+ return testlist
+
+def _main() -> int:
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--add_tests',
+ type=str, required=True,
+ help='''List test-suite name(s) from following:
+ 1) riscv-tests
+ 2) riscv-arch-tests
+ 3) epmp-tests
+
+ e.g. --add_tests=riscv-tests,epmp_tests
+ ''')
+
+ args = parser.parse_args()
+ test_suite = args.add_tests
+ test_suite_list = test_suite.split(',')
+
+ # remove any previous yaml file
+ with open('directed_testlist.yaml','r+') as file:
+ file.truncate(0)
+
+ # add headers and configs, also adding any handwritten directed tests
+ add_configs_and_handwritten_directed_tests()
+
+ if 'riscv-tests' in test_suite_list or test_suite == 'all':
+ isa_tests = {'rv32mi', 'rv32uc', 'rv32ui', 'rv32um'}
+ append_directed_testlist(isa_tests, '../../../../vendor/riscv-tests/isa/', 'riscv-tests', 1)
+
+ if 'riscv-arch-tests' in test_suite_list or test_suite == 'all':
+ arch_tests = {'rv32i_m/B/src', 'rv32i_m/C/src', 'rv32i_m/I/src', 'rv32i_m/M/src', 'rv32i_m/Zifencei/src'}
+ append_directed_testlist(arch_tests, '../../../../vendor/riscv-arch-tests/riscv-test-suite/', 'riscv-arch-tests', 1)
+
+ if 'epmp-tests' in test_suite_list or test_suite == 'all':
+ append_directed_testlist({'outputs'}, '../../../../vendor/riscv-isa-sim/tests/mseccfg/gengen_src/', 'epmp-tests', 0)
+
+ # Always return 0 (success), even if the test failed. We've successfully
+ # generated a comparison log either way and we don't want to stop Make from
+ # gathering them all up for us.
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(_main())
diff --git a/dv/uvm/core_ibex/directed_tests/ibex_macros.h b/dv/uvm/core_ibex/directed_tests/ibex_macros.h
new file mode 100644
index 00000000..ac105dc4
--- /dev/null
+++ b/dv/uvm/core_ibex/directed_tests/ibex_macros.h
@@ -0,0 +1,37 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// Ibex specific macros
+#define SIGNATURE_ADDR 0x8ffffff8
+
+// signatue type - should be stored at sign_addr[7:0]
+#define CORE_STATUS 0x0
+#define TEST_RESULT 0x1
+#define WRITE_GPR 0x2
+#define WRITE_CSR 0x3
+
+// core status - should be stored at sign_addr[12:8]
+#define INITIALIZED 0x0
+#define IN_DEBUG_MODE 0x1
+#define IN_MACHINE_MODE 0x2
+#define IN_HYPERVISOR_MODE 0x3
+#define IN_SUPERVISOR_MODE 0x4
+#define IN_USER_MODE 0x5
+#define HANDLING_IRQ 0x6
+#define FINISHED_IRQ 0x7
+#define HANDLING_EXCEPTION 0x8
+#define INSTR_FAULT_EXCEPTION 0x9
+#define ILLEGAL_INSTR_EXCEPTION 0xa
+#define LOAD_FAULT_EXCEPTION 0xb
+#define STORE_FAULT_EXCEPTION 0xc
+#define EBREAK_EXCEPTION 0xd
+
+// test result - should be stored at sign_addr[8]
+#define TEST_PASS 0x0
+#define TEST_FAIL 0x1
+
+#define CSR_MSECCFG 0x747
+#define MSECCFG_MML 0x1
+#define MSECCFG_MMWP 0x2
+#define MSECCFG_RLB 0x4
diff --git a/dv/uvm/core_ibex/directed_tests/link.ld b/dv/uvm/core_ibex/directed_tests/link.ld
new file mode 100644
index 00000000..b3e315e7
--- /dev/null
+++ b/dv/uvm/core_ibex/directed_tests/link.ld
@@ -0,0 +1,17 @@
+OUTPUT_ARCH( "riscv" )
+ENTRY(_start)
+
+SECTIONS
+{
+ . = 0x80000000;
+ .text.init : { *(.text.init) }
+ . = ALIGN(0x1000);
+ .tohost : { *(.tohost) }
+ . = ALIGN(0x1000);
+ .text : { *(.text) }
+ . = ALIGN(0x1000);
+ .data : { *(.data) }
+ .bss : { *(.bss) }
+ _end = .;
+}
+
diff --git a/dv/uvm/core_ibex/directed_tests/pmp_mseccfg_test/pmp_mseccfg_test.S b/dv/uvm/core_ibex/directed_tests/pmp_mseccfg_test/pmp_mseccfg_test.S
new file mode 100644
index 00000000..3ee1ed39
--- /dev/null
+++ b/dv/uvm/core_ibex/directed_tests/pmp_mseccfg_test/pmp_mseccfg_test.S
@@ -0,0 +1,225 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+###############################################################################
+# Description:
+# Setting mseccfg.mml 1 and mseccfg.rlb 0/1 with different PMP.LXWR
+# permissions and check R/w access to that specific region. Access is
+# at start, mid and end of the PMP region.
+# Target of test is to achieve functional coverage for rewriting
+# permissions in PMP regions with RLB 0/1.
+# Test accesses in both M-mode and U-mode.
+
+#include "riscv_test.h"
+#include "test_macros.h"
+#include "custom_macros.h"
+
+#define PMP_GRAN 0x1000
+
+#if SET_PMP_L == 1
+ #define SET_PMP_L_BIT PMP_L
+#else
+ #define SET_PMP_L_BIT 0
+#endif
+
+#if SET_PMP_L_PREV == 1
+ #define SET_PMP_L_PREV PMP_L
+#else
+ #define SET_PMP_L_PREV 0
+#endif
+
+# Test specific macros
+#define SET_PMP_AND_ACCESS_TOR(pmp_permissions, region_high, region_low) \
+ SET_PMP_TOR(pmp_region_end, pmp_region_start, pmp_permissions | PMP_TOR, region_high, region_low) \
+ RW_ACCESSES(pmp_region_start, PMP_GRAN)
+
+#define ACCESS_REGION(region, offset) \
+ la t0, region; \
+ jalr a0, offset(t0);
+
+#define EXEC_ACCESS_IN_M_MODE(region) \
+ ACCESS_REGION(region, 0); \
+ ACCESS_REGION(region, -2);
+
+#define EXEC_ACCESS_IN_U_MODE(region) \
+ SWITCH_TO_U_MODE_LABEL(region); \
+ la s0, region; \
+ addi s0, s0, -2; \
+ SWITCH_TO_U_MODE_REG(s0);
+
+#ifdef U_MODE
+ #define EXEC_ACCESS(region) \
+ EXEC_ACCESS_IN_U_MODE(region)
+#else
+ #define EXEC_ACCESS(region) \
+ EXEC_ACCESS_IN_M_MODE(region)
+#endif
+
+#define SET_PMP_AND_ACCESS_NAPOT(pmp_permissions, region) \
+ SET_PMP_NAPOT(pmp_region_start, PMP_GRAN, pmp_permissions | PMP_NAPOT, region) \
+ RW_ACCESSES(pmp_region_start, PMP_GRAN) \
+ EXEC_ACCESS(pmp_region_start)
+
+#define SET_DIFF_PMP_CFG(pmp_region, pmp_l, pmp_l_prev) \
+ PREV_PMP_CFG(pmp_l_prev, pmp_region, pmp_l) \
+ PREV_PMP_CFG(pmp_l_prev | PMP_R, pmp_region, pmp_l) \
+ PREV_PMP_CFG(pmp_l_prev | PMP_W, pmp_region, pmp_l) \
+ PREV_PMP_CFG(pmp_l_prev | PMP_X, pmp_region, pmp_l) \
+ PREV_PMP_CFG(pmp_l_prev | PMP_R | PMP_W, pmp_region, pmp_l) \
+ PREV_PMP_CFG(pmp_l_prev | PMP_R | PMP_X, pmp_region, pmp_l) \
+ PREV_PMP_CFG(pmp_l_prev | PMP_W | PMP_X, pmp_region, pmp_l) \
+ PREV_PMP_CFG(pmp_l_prev | PMP_R | PMP_W | PMP_X, pmp_region, pmp_l)
+
+#define PREV_PMP_CFG(prev_pmp, pmp_region, pmp_l) \
+ SET_PMP_AND_ACCESS_NAPOT(prev_pmp, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(pmp_l, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(prev_pmp, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(pmp_l | PMP_R, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(prev_pmp, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(pmp_l | PMP_W, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(prev_pmp, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(pmp_l | PMP_X, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(prev_pmp, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(pmp_l | PMP_R | PMP_W, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(prev_pmp, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(pmp_l | PMP_R | PMP_X, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(prev_pmp, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(pmp_l | PMP_W | PMP_X, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(prev_pmp, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(pmp_l | PMP_R | PMP_W | PMP_X, pmp_region)
+
+#ifdef PMP_NEXT_L1
+ #define PREV_PMP_CFG_UNIQUE(prev_pmp, pmp_region, pmp_l) \
+ SET_PMP_AND_ACCESS_NAPOT(prev_pmp, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(pmp_l, pmp_region)
+#endif
+
+#ifdef PMP_NEXT_L1_R1
+ #define PREV_PMP_CFG_UNIQUE(prev_pmp, pmp_region, pmp_l) \
+ SET_PMP_AND_ACCESS_NAPOT(prev_pmp, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(pmp_l | PMP_R, pmp_region)
+#endif
+
+#ifdef PMP_NEXT_L1_W1
+ #define PREV_PMP_CFG_UNIQUE(prev_pmp, pmp_region, pmp_l) \
+ SET_PMP_AND_ACCESS_NAPOT(prev_pmp, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(pmp_l | PMP_W, pmp_region)
+#endif
+
+#ifdef PMP_NEXT_L1_X1
+ #define PREV_PMP_CFG_UNIQUE(prev_pmp, pmp_region, pmp_l) \
+ SET_PMP_AND_ACCESS_NAPOT(prev_pmp, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(pmp_l | PMP_X, pmp_region)
+#endif
+
+#ifdef PMP_NEXT_L1_R1_W1
+ #define PREV_PMP_CFG_UNIQUE(prev_pmp, pmp_region, pmp_l) \
+ SET_PMP_AND_ACCESS_NAPOT(prev_pmp, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(pmp_l | PMP_R | PMP_W, pmp_region)
+#endif
+
+#ifdef PMP_NEXT_L1_R1_X1
+ #define PREV_PMP_CFG_UNIQUE(prev_pmp, pmp_region, pmp_l) \
+ SET_PMP_AND_ACCESS_NAPOT(prev_pmp, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(pmp_l | PMP_R | PMP_X, pmp_region)
+#endif
+
+#ifdef PMP_NEXT_L1_W1_X1
+ #define PREV_PMP_CFG_UNIQUE(prev_pmp, pmp_region, pmp_l) \
+ SET_PMP_AND_ACCESS_NAPOT(prev_pmp, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(pmp_l | PMP_W | PMP_X, pmp_region)
+#endif
+
+#ifdef PMP_NEXT_L1_R1_W1_X1
+ #define PREV_PMP_CFG_UNIQUE(prev_pmp, pmp_region, pmp_l) \
+ SET_PMP_AND_ACCESS_NAPOT(prev_pmp, pmp_region) \
+ SET_PMP_AND_ACCESS_NAPOT(pmp_l | PMP_R | PMP_W | PMP_X, pmp_region)
+#endif
+
+RVTEST_RV64M
+RVTEST_CODE_BEGIN
+
+ # setting machine handler
+ la t0, mtvec_handler
+ csrw mtvec, t0
+
+ # resetting all PMP regions and mseccfg
+ RESET_PMP
+
+ # placing 0xffffffff just before pmp_region_start so in
+ # order to deal with boundary instsr as uncompressed
+ li t0, 0xffffffff
+ la t1, pmp_region_start
+ sw t0, -4(t1)
+
+#ifdef RLB
+ SET_MSECCFG(MSECCFG_RLB)
+#endif
+
+ # setting M mode permissions as unmatched regions would be ignored when mml 1
+ SET_PMP_TOR(pmp_region_start, _start, PMP_L | PMP_R | PMP_X | PMP_TOR, 0, 0)
+
+ # MML 1
+ SET_MSECCFG(MSECCFG_MML)
+
+ # If RLB 1, PMP locked regions would be modifiable
+#ifdef RLB
+ SET_DIFF_PMP_CFG(PMP_REGION, SET_PMP_L_BIT, SET_PMP_L_PREV)
+#else
+ #if SET_PMP_L == 1
+ # If RLB 0, then once locked, not modifiable hence have to use
+ # different PMP regions to cover all transitions
+ PREV_PMP_CFG_UNIQUE(SET_PMP_L_PREV, 4, SET_PMP_L_BIT)
+ PREV_PMP_CFG_UNIQUE(SET_PMP_L_PREV | PMP_R, 5, SET_PMP_L_BIT)
+ PREV_PMP_CFG_UNIQUE(SET_PMP_L_PREV | PMP_W, 6, SET_PMP_L_BIT)
+ PREV_PMP_CFG_UNIQUE(SET_PMP_L_PREV | PMP_X, 7, SET_PMP_L_BIT)
+ PREV_PMP_CFG_UNIQUE(SET_PMP_L_PREV | PMP_R | PMP_W, 8, SET_PMP_L_BIT)
+ PREV_PMP_CFG_UNIQUE(SET_PMP_L_PREV | PMP_R | PMP_X, 9, SET_PMP_L_BIT)
+ PREV_PMP_CFG_UNIQUE(SET_PMP_L_PREV | PMP_W | PMP_X, 10, SET_PMP_L_BIT)
+ PREV_PMP_CFG_UNIQUE(SET_PMP_L_PREV | PMP_R | PMP_W | PMP_X, 11, SET_PMP_L_BIT)
+ #else
+ # If not locked, PMPCFG would be writable
+ SET_DIFF_PMP_CFG(PMP_REGION, SET_PMP_L_BIT, SET_PMP_L_PREV)
+ #endif
+#endif
+
+ j pass
+
+ TEST_PASSFAIL
+
+.balign 256
+mtvec_handler:
+ csrr t0, mcause
+ li t1, CAUSE_FETCH_ACCESS
+ beq t0, t1, restore_to_pc_before_access_fault
+ # jump to a valid PC if illegal instruction
+ # which would be when PMP has execute permissions
+ # in pmp_region_start
+ li t1, CAUSE_ILLEGAL_INSTRUCTION
+ beq t0, t1, restore_to_pc_before_access_fault
+ SKIP_PC
+ j ret_from_mhandler
+
+restore_to_pc_before_access_fault:
+ csrw mepc, a0
+
+ret_from_mhandler:
+ # always return to m-mode
+ li t0, MSTATUS_MPP
+ csrs mstatus, t0
+ mret
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+.balign PMP_GRAN
+pmp_region_start:
+ jr a0
+ .zero (PMP_GRAN-4)
+pmp_region_end:
+ TEST_DATA
+
+RVTEST_DATA_END
diff --git a/dv/uvm/core_ibex/directed_tests/u_mode_exec_test/u_mode_exec_test.S b/dv/uvm/core_ibex/directed_tests/u_mode_exec_test/u_mode_exec_test.S
new file mode 100644
index 00000000..79b18858
--- /dev/null
+++ b/dv/uvm/core_ibex/directed_tests/u_mode_exec_test/u_mode_exec_test.S
@@ -0,0 +1,71 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+# Tests U-mode execution across all of the locked non-MML PMP permission
+# configurations
+
+#include "riscv_test.h"
+#include "test_macros.h"
+#include "custom_macros.h"
+
+RVTEST_RV64M
+RVTEST_CODE_BEGIN
+ RESET_PMP
+ # Setup region that can be fully accessed by U mode
+ SET_PMP_NAPOT(test_code, 4096, PMP_R | PMP_W | PMP_X, 15)
+
+ # Setup exception handler
+ la t0, mtvec_handler
+ csrw mtvec, t0
+
+ j test_code
+
+test_end:
+ j pass
+
+ TEST_PASSFAIL
+
+.balign 4096
+test_code:
+ # As we cannot modify locked regions setup new regions with increase priority
+ # (lower numbered regions take priority). Run a U-mode execution after every
+ # every new region to setup to test its configuration before moving to the
+ # next.
+ SET_PMP_NAPOT(test_exec_region, 256, PMP_NAPOT, 14)
+ SWITCH_TO_U_MODE_LABEL(test_exec_region)
+ SET_PMP_NAPOT(test_exec_region, 256, PMP_L | PMP_NAPOT, 13)
+ SWITCH_TO_U_MODE_LABEL(test_exec_region)
+ SET_PMP_NAPOT(test_exec_region, 256, PMP_L | PMP_R| PMP_NAPOT, 12)
+ SWITCH_TO_U_MODE_LABEL(test_exec_region)
+ SET_PMP_NAPOT(test_exec_region, 256, PMP_L | PMP_R | PMP_W| PMP_NAPOT, 11)
+ SWITCH_TO_U_MODE_LABEL(test_exec_region)
+ SET_PMP_NAPOT(test_exec_region, 256, PMP_L | PMP_X | PMP_R | PMP_W | PMP_NAPOT, 10)
+ SWITCH_TO_U_MODE_LABEL(test_exec_region)
+ SET_PMP_NAPOT(test_exec_region, 256, PMP_L | PMP_X | PMP_R | PMP_NAPOT, 9)
+ SWITCH_TO_U_MODE_LABEL(test_exec_region)
+ SET_PMP_NAPOT(test_exec_region, 256, PMP_L | PMP_X | PMP_NAPOT, 8)
+ SWITCH_TO_U_MODE_LABEL(test_exec_region)
+
+ j test_end
+
+.balign 256
+test_exec_region:
+ add t0, t0, t0
+ # Jump to exception handler to return to M-mode where U mode exec succeeds
+ unimp
+
+.balign 256
+mtvec_handler:
+ csrw mepc, a0
+ # always return to m-mode
+ li t0, MSTATUS_MPP
+ csrs mstatus, t0
+ mret
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+ TEST_DATA
+RVTEST_DATA_END
diff --git a/dv/uvm/core_ibex/env/core_ibex_dut_probe_if.sv b/dv/uvm/core_ibex/env/core_ibex_dut_probe_if.sv
index 5f8b8cbc..b63065f5 100644
--- a/dv/uvm/core_ibex/env/core_ibex_dut_probe_if.sv
+++ b/dv/uvm/core_ibex/env/core_ibex_dut_probe_if.sv
@@ -4,17 +4,54 @@
// Interface to probe DUT internal signal
interface core_ibex_dut_probe_if(input logic clk);
- logic reset;
- logic illegal_instr;
- logic ecall;
- logic wfi;
- logic ebreak;
- logic dret;
- logic mret;
- logic fetch_enable;
- logic core_sleep;
- logic debug_req;
- ibex_pkg::priv_lvl_e priv_mode;
+
+ import uvm_pkg::*;
+
+ logic reset;
+ logic illegal_instr;
+ logic ecall;
+ logic wfi;
+ logic ebreak;
+ logic dret;
+ logic mret;
+ ibex_pkg::ibex_mubi_t fetch_enable;
+ logic core_sleep;
+ logic alert_minor;
+ logic alert_major_internal;
+ logic alert_major_bus;
+ logic debug_req;
+ logic [ibex_pkg::IC_NUM_WAYS-1:0] ic_tag_req;
+ logic ic_tag_write;
+ logic [ibex_pkg::IC_INDEX_W-1:0] ic_tag_addr;
+ logic [ibex_pkg::IC_NUM_WAYS-1:0] ic_data_req;
+ logic ic_data_write;
+ logic [ibex_pkg::IC_INDEX_W-1:0] ic_data_addr;
+ ibex_pkg::priv_lvl_e priv_mode;
+ ibex_pkg::ctrl_fsm_e ctrl_fsm_cs;
+ logic debug_mode;
+ logic double_fault_seen;
+ logic rf_ren_a;
+ logic rf_ren_b;
+ logic rf_rd_a_wb_match;
+ logic rf_rd_b_wb_match;
+ logic rf_write_wb;
+ logic sync_exc_seen;
+ logic irq_exc_seen;
+ logic csr_save_cause;
+ ibex_pkg::exc_cause_t exc_cause;
+ logic wb_exception;
+
+ always @(posedge clk or posedge reset) begin
+ if (reset) begin
+ irq_exc_seen <= 1'b0;
+ end else begin
+ if (ctrl_fsm_cs == ibex_pkg::IRQ_TAKEN) begin
+ irq_exc_seen <= 1'b1;
+ end else if (mret) begin
+ irq_exc_seen <= 1'b0;
+ end
+ end
+ end
clocking dut_cb @(posedge clk);
output fetch_enable;
@@ -27,11 +64,44 @@ interface core_ibex_dut_probe_if(input logic clk);
input dret;
input mret;
input core_sleep;
+ input alert_minor;
+ input alert_major_internal;
+ input alert_major_bus;
+ input ic_tag_req;
+ input ic_tag_write;
+ input ic_tag_addr;
+ input ic_data_req;
+ input ic_data_write;
+ input ic_data_addr;
input priv_mode;
+ input ctrl_fsm_cs;
+ input debug_mode;
+ input double_fault_seen;
+ input rf_ren_a;
+ input rf_ren_b;
+ input rf_rd_a_wb_match;
+ input rf_rd_b_wb_match;
+ input rf_write_wb;
+ input sync_exc_seen;
+ input irq_exc_seen;
+ input wb_exception;
endclocking
initial begin
debug_req = 1'b0;
end
+ `DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_rf_ren_a, rf_ren_a)
+ `DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_rf_ren_b, rf_ren_b)
+ `DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_rf_rd_a_wb_match, rf_rd_a_wb_match)
+ `DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_rf_rd_b_wb_match, rf_rd_b_wb_match)
+ `DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_rf_write_wb, rf_write_wb)
+ `DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_alert_minor, alert_minor)
+ `DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_ic_tag_req, ic_tag_req)
+ `DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_ic_tag_write, ic_tag_write)
+ `DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_ic_tag_addr, ic_tag_addr)
+ `DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_ic_data_req, ic_data_req)
+ `DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_ic_data_write, ic_data_write)
+ `DV_CREATE_SIGNAL_PROBE_FUNCTION(signal_probe_ic_data_addr, ic_data_addr)
+
endinterface
diff --git a/dv/uvm/core_ibex/env/core_ibex_env.sv b/dv/uvm/core_ibex/env/core_ibex_env.sv
index 4140d309..753b5604 100644
--- a/dv/uvm/core_ibex/env/core_ibex_env.sv
+++ b/dv/uvm/core_ibex/env/core_ibex_env.sv
@@ -9,9 +9,12 @@ class core_ibex_env extends uvm_env;
ibex_mem_intf_response_agent data_if_response_agent;
ibex_mem_intf_response_agent instr_if_response_agent;
- irq_request_agent irq_agent;
- core_ibex_vseqr vseqr;
- core_ibex_env_cfg cfg;
+ irq_request_agent irq_agent;
+ ibex_cosim_agent cosim_agent;
+ core_ibex_vseqr vseqr;
+ core_ibex_env_cfg cfg;
+ scrambling_key_agent scrambling_key_agent_h;
+ core_ibex_scoreboard scoreboard;
`uvm_component_utils(core_ibex_env)
`uvm_component_new
@@ -21,13 +24,30 @@ class core_ibex_env extends uvm_env;
if (!uvm_config_db#(core_ibex_env_cfg)::get(this, "", "cfg", cfg)) begin
`uvm_fatal(get_full_name(), "Cannot get cfg")
end
+ if (!uvm_config_db#(virtual clk_rst_if)::get(this, "", "clk_if",
+ cfg.ibex_clk_vif)) begin
+ `uvm_fatal(`gfn, "failed to get ibex clk_if from uvm_config_db")
+ end
+ if (!uvm_config_db#(virtual core_ibex_dut_probe_if)::get(this, "", "dut_if",
+ cfg.ibex_dut_vif)) begin
+ `uvm_fatal(`gfn, "failed to get ibex dut_if from uvm_config_db")
+ end
data_if_response_agent = ibex_mem_intf_response_agent::type_id::
create("data_if_response_agent", this);
instr_if_response_agent = ibex_mem_intf_response_agent::type_id::
create("instr_if_response_agent", this);
irq_agent = irq_request_agent::type_id::create("irq_agent", this);
+ cosim_agent = ibex_cosim_agent::type_id::create("cosim_agent", this);
+
+ scrambling_key_agent_h = scrambling_key_agent::type_id::create("scrambling_key_agent_h", this);
+ uvm_config_db#(scrambling_key_agent_cfg)::set(this, "scrambling_key_agent_h", "cfg",
+ cfg.scrambling_key_cfg);
+ cfg.scrambling_key_cfg.agent_type = push_pull_agent_pkg::PullAgent;
+ cfg.scrambling_key_cfg.if_mode = dv_utils_pkg::Device;
// Create virtual sequencer
vseqr = core_ibex_vseqr::type_id::create("vseqr", this);
+ // Create scoreboard
+ scoreboard = core_ibex_scoreboard::type_id::create("scoreboard", this);
endfunction : build_phase
function void connect_phase(uvm_phase phase);
@@ -35,11 +55,20 @@ class core_ibex_env extends uvm_env;
vseqr.data_if_seqr = data_if_response_agent.sequencer;
vseqr.instr_if_seqr = instr_if_response_agent.sequencer;
vseqr.irq_seqr = irq_agent.sequencer;
+ data_if_response_agent.monitor.item_collected_port.connect(
+ cosim_agent.dmem_port);
+ instr_if_response_agent.monitor.item_collected_port.connect(
+ cosim_agent.imem_port);
+ if (cfg.enable_double_fault_detector) begin
+ cosim_agent.rvfi_monitor.item_collected_port.connect(
+ scoreboard.rvfi_port.analysis_export);
+ end
endfunction : connect_phase
function void reset();
data_if_response_agent.reset();
instr_if_response_agent.reset();
+ cosim_agent.reset();
endfunction
endclass
diff --git a/dv/uvm/core_ibex/env/core_ibex_env_cfg.sv b/dv/uvm/core_ibex/env/core_ibex_env_cfg.sv
index 4152230d..1d59338b 100644
--- a/dv/uvm/core_ibex/env/core_ibex_env_cfg.sv
+++ b/dv/uvm/core_ibex/env/core_ibex_env_cfg.sv
@@ -4,35 +4,77 @@
class core_ibex_env_cfg extends uvm_object;
- bit enable_irq_single_seq;
- bit enable_irq_multiple_seq;
- bit enable_nested_irq;
- bit enable_debug_seq;
- bit[31:0] max_interval;
- bit require_signature_addr;
- string signature_addr_str;
- bit[31:0] signature_addr;
+ virtual clk_rst_if ibex_clk_vif;
+ virtual core_ibex_dut_probe_if ibex_dut_vif;
+
+ bit enable_mem_intg_err;
+ bit enable_irq_single_seq;
+ bit enable_irq_multiple_seq;
+ bit enable_irq_nmi_seq;
+ bit enable_nested_irq;
+ bit enable_debug_seq;
+ bit disable_fetch_enable_seq;
+ bit disable_cosim;
+ bit[31:0] max_interval;
+ bit require_signature_addr;
+ string signature_addr_str;
+ bit[31:0] signature_addr;
+ rand scrambling_key_agent_cfg scrambling_key_cfg;
+
+ // Double-Fault detection in scoreboard
+ bit enable_double_fault_detector = 1;
+ int unsigned double_fault_threshold_consecutive = 100;
+ int unsigned double_fault_threshold_total = 1000;
+ // If '1', reaching either threshold fatally ends the test.
+ // If '0', we end the test with a pass.
+ bit is_double_fault_detected_fatal = 1;
+ // If '1', reaching the timeout in seconds fatally ends the test.
+ // If '0', we end the test with a pass.
+ bit is_timeout_s_fatal = 1;
+ // If '1' core_ibex_vseq will randomly choose to enable spurious responses in the data side memory
+ // agent. This will also disable assertions that check the memory interface protocol as spurious
+ // responses violate them.
+ bit enable_spurious_dside_responses = 1;
+
+ // If spurious responses are enabled what percentage of tests will enable them
+ int unsigned spurious_response_pct = 20;
+
`uvm_object_utils_begin(core_ibex_env_cfg)
+ `uvm_field_int(enable_double_fault_detector, UVM_DEFAULT)
+ `uvm_field_int(is_double_fault_detected_fatal, UVM_DEFAULT)
+ `uvm_field_int(enable_mem_intg_err, UVM_DEFAULT)
`uvm_field_int(enable_irq_single_seq, UVM_DEFAULT)
`uvm_field_int(enable_irq_multiple_seq, UVM_DEFAULT)
+ `uvm_field_int(enable_irq_nmi_seq, UVM_DEFAULT)
`uvm_field_int(enable_nested_irq, UVM_DEFAULT)
`uvm_field_int(enable_debug_seq, UVM_DEFAULT)
+ `uvm_field_int(disable_fetch_enable_seq, UVM_DEFAULT)
+ `uvm_field_int(disable_cosim, UVM_DEFAULT)
`uvm_field_int(max_interval, UVM_DEFAULT)
`uvm_field_int(require_signature_addr, UVM_DEFAULT)
`uvm_field_int(signature_addr, UVM_DEFAULT)
+ `uvm_field_object(scrambling_key_cfg, UVM_DEFAULT)
`uvm_object_utils_end
function new(string name = "");
super.new(name);
+ void'($value$plusargs("enable_double_fault_detector=%0d", enable_double_fault_detector));
+ void'($value$plusargs("is_double_fault_detected_fatal=%0d", is_double_fault_detected_fatal));
+ void'($value$plusargs("is_timeout_s_fatal=%0d", is_timeout_s_fatal));
+ void'($value$plusargs("enable_mem_intg_err=%0d", enable_mem_intg_err));
void'($value$plusargs("enable_irq_single_seq=%0d", enable_irq_single_seq));
void'($value$plusargs("enable_irq_multiple_seq=%0d", enable_irq_multiple_seq));
+ void'($value$plusargs("enable_irq_nmi_seq=%0d", enable_irq_nmi_seq));
void'($value$plusargs("enable_nested_irq=%0d", enable_nested_irq));
void'($value$plusargs("enable_debug_seq=%0d", enable_debug_seq));
+ void'($value$plusargs("disable_fetch_enable_seq=%0d", disable_fetch_enable_seq));
+ void'($value$plusargs("disable_cosim=%0d", disable_cosim));
void'($value$plusargs("max_interval=%0d", max_interval));
void'($value$plusargs("require_signature_addr=%0d", require_signature_addr));
void'($value$plusargs("signature_addr=%s", signature_addr_str));
signature_addr = signature_addr_str.atohex();
+ scrambling_key_cfg = scrambling_key_agent_cfg::type_id::create("scrambling_key_cfg");
endfunction
endclass
diff --git a/dv/uvm/core_ibex/env/core_ibex_env_pkg.sv b/dv/uvm/core_ibex/env/core_ibex_env_pkg.sv
index 437c96b6..6a213da3 100644
--- a/dv/uvm/core_ibex/env/core_ibex_env_pkg.sv
+++ b/dv/uvm/core_ibex/env/core_ibex_env_pkg.sv
@@ -11,9 +11,19 @@ package core_ibex_env_pkg;
import uvm_pkg::*;
import ibex_mem_intf_agent_pkg::*;
import irq_agent_pkg::*;
+ import ibex_cosim_agent_pkg::*;
+ import push_pull_agent_pkg::*;
+
+ typedef push_pull_agent#(
+ .DeviceDataWidth(ibex_pkg::SCRAMBLE_NONCE_W + ibex_pkg::SCRAMBLE_KEY_W)
+ ) scrambling_key_agent;
+ typedef push_pull_agent_cfg#(
+ .DeviceDataWidth(ibex_pkg::SCRAMBLE_NONCE_W + ibex_pkg::SCRAMBLE_KEY_W)
+ ) scrambling_key_agent_cfg;
`include "core_ibex_vseqr.sv"
`include "core_ibex_env_cfg.sv"
+ `include "core_ibex_scoreboard.sv"
`include "core_ibex_env.sv"
endpackage
diff --git a/dv/uvm/core_ibex/env/core_ibex_instr_monitor_if.sv b/dv/uvm/core_ibex/env/core_ibex_instr_monitor_if.sv
index 9db8df37..08daae43 100644
--- a/dv/uvm/core_ibex/env/core_ibex_instr_monitor_if.sv
+++ b/dv/uvm/core_ibex/env/core_ibex_instr_monitor_if.sv
@@ -13,7 +13,9 @@ interface core_ibex_instr_monitor_if #(
);
// ID stage
+ logic reset;
logic valid_id;
+ logic instr_new_id;
logic err_id;
logic is_compressed_id;
logic [15:0] instr_compressed_id;
@@ -23,9 +25,12 @@ interface core_ibex_instr_monitor_if #(
logic [DATA_WIDTH-1:0] branch_target_id;
logic stall_id;
logic jump_set_id;
+ logic [63:0] rvfi_order_id;
clocking instr_cb @(posedge clk);
+ input reset;
input valid_id;
+ input instr_new_id;
input err_id;
input is_compressed_id;
input instr_compressed_id;
@@ -35,6 +40,7 @@ interface core_ibex_instr_monitor_if #(
input branch_target_id;
input stall_id;
input jump_set_id;
+ input rvfi_order_id;
endclocking
endinterface
diff --git a/dv/uvm/core_ibex/env/core_ibex_rvfi_if.sv b/dv/uvm/core_ibex/env/core_ibex_rvfi_if.sv
index f006c909..0199b87f 100644
--- a/dv/uvm/core_ibex/env/core_ibex_rvfi_if.sv
+++ b/dv/uvm/core_ibex/env/core_ibex_rvfi_if.sv
@@ -4,6 +4,7 @@
// Interface to probe Ibex RVFI interface
interface core_ibex_rvfi_if(input logic clk);
+ logic reset;
logic valid;
logic [63:0] order;
logic [31:0] insn;
@@ -25,4 +26,57 @@ interface core_ibex_rvfi_if(input logic clk);
logic [3:0] mem_wmask;
logic [31:0] mem_rdata;
logic [31:0] mem_wdata;
+ logic [31:0] ext_pre_mip;
+ logic [31:0] ext_post_mip;
+ logic ext_nmi;
+ logic ext_nmi_int;
+ logic [31:0] ext_debug_req;
+ logic [31:0] ext_rf_wr_suppress;
+ logic [63:0] ext_mcycle;
+ logic ext_irq_valid;
+
+ logic [31:0] ext_mhpmcounters [10];
+ logic [31:0] ext_mhpmcountersh [10];
+
+ logic ext_ic_scr_key_valid;
+
+ clocking monitor_cb @(posedge clk);
+ input reset;
+ input valid;
+ input order;
+ input insn;
+ input trap;
+ input halt;
+ input intr;
+ input mode;
+ input ixl;
+ input rs1_addr;
+ input rs2_addr;
+ input rs1_rdata;
+ input rs2_rdata;
+ input rd_addr;
+ input rd_wdata;
+ input pc_rdata;
+ input pc_wdata;
+ input mem_addr;
+ input mem_rmask;
+ input mem_wmask;
+ input mem_rdata;
+ input mem_wdata;
+ input ext_pre_mip;
+ input ext_post_mip;
+ input ext_nmi;
+ input ext_nmi_int;
+ input ext_debug_req;
+ input ext_rf_wr_suppress;
+ input ext_mcycle;
+ input ext_mhpmcounters;
+ input ext_mhpmcountersh;
+ input ext_ic_scr_key_valid;
+ input ext_irq_valid;
+ endclocking
+
+ task automatic wait_clks(input int num);
+ repeat (num) @(posedge clk);
+ endtask
endinterface
diff --git a/dv/uvm/core_ibex/env/core_ibex_scoreboard.sv b/dv/uvm/core_ibex/env/core_ibex_scoreboard.sv
new file mode 100644
index 00000000..b84e8dd9
--- /dev/null
+++ b/dv/uvm/core_ibex/env/core_ibex_scoreboard.sv
@@ -0,0 +1,113 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class core_ibex_scoreboard extends uvm_scoreboard;
+
+ uvm_tlm_analysis_fifo #(ibex_rvfi_seq_item) rvfi_port;
+ core_ibex_env_cfg cfg;
+
+ // Events for Double-Fault detection
+ uvm_event fault_threshold_consecutive_reached, fault_threshold_total_reached;
+
+ `uvm_component_utils(core_ibex_scoreboard)
+ `uvm_component_new
+
+ function void build_phase(uvm_phase phase);
+ super.build_phase(phase);
+ if (!uvm_config_db#(core_ibex_env_cfg)::get(this, "", "cfg", cfg)) begin
+ `uvm_fatal(get_full_name(), "Cannot get cfg")
+ end
+ rvfi_port = new("rvfi_port_scoreboard", this);
+ endfunction : build_phase
+
+ task run_phase(uvm_phase phase);
+ super.run_phase(phase);
+ fork
+ double_fault_detector();
+ join_none
+ endtask
+
+ task double_fault_detector();
+ int unsigned double_fault_cnt_total = 0;
+ int unsigned double_fault_cnt_consecutive = 0;
+ bit double_fault_pulse_seen = 1'b0;
+
+ ibex_rvfi_seq_item rvfi_instr;
+
+ fault_threshold_consecutive_reached = new();
+ fault_threshold_total_reached = new();
+
+ // There are two observable side-effects of a double fault in the Ibex:
+ // - CPUCTRL.double_fault_seen is set to '1
+ // - The top-level output double_fault_seen_o is asserted for one cycle
+
+ fork
+ // Increment a counter whenever a double_fault was indicated for the last
+ // rvfi_seq_item created. When the counter reaches a threshold, create an event.
+ begin
+ forever begin
+ rvfi_port.get(rvfi_instr);
+ if (double_fault_pulse_seen) begin
+ // There must have been a double_fault during the previous retired insn.
+ double_fault_pulse_seen = 1'b0;
+ double_fault_cnt_total++;
+ double_fault_cnt_consecutive++;
+ end else begin
+ // Reset the consecutive counter.
+ double_fault_cnt_consecutive = 0;
+ end
+
+ // Create an event if either counter reaches its threshold value, then reset the counter.
+ if (double_fault_cnt_consecutive == cfg.double_fault_threshold_consecutive) begin
+ fault_threshold_consecutive_reached.trigger();
+ double_fault_cnt_consecutive = 0;
+ end
+ if (double_fault_cnt_total == cfg.double_fault_threshold_total) begin
+ fault_threshold_total_reached.trigger();
+ double_fault_cnt_total = 0;
+ end
+
+ end
+ end
+ // Latch the 'double_fault_seen_o' signal to catch the fault.
+ // The single pulse may be receieved sometime before the rvfi_seq_item
+ // corresponding to the faulting instruction is generated. Hence we
+ // latch that pulse when it is seen, and then reset above when the
+ // seq_item arrives.
+ // https://github.com/lowRISC/ibex/pull/1848#discussion_r995903762
+ begin
+ forever begin
+ @(posedge cfg.ibex_dut_vif.dut_cb.double_fault_seen);
+ double_fault_pulse_seen = 1'b1;
+ cfg.ibex_clk_vif.wait_clks(1);
+ end
+ end
+ join_none
+
+ endtask // double_fault_detector
+
+ // Helper method which returns if either of the counter thresholds are reached.
+ virtual task dfd_wait_for_pass_events();
+ fork begin : isolation_fork
+ fork
+ begin
+ fault_threshold_total_reached.wait_trigger();
+ `uvm_info(`gfn,
+ $sformatf({"double_fault detector : reached threshold [%0d] ",
+ "for total double faults seen."}, cfg.double_fault_threshold_total),
+ UVM_LOW)
+ end
+ begin
+ fault_threshold_consecutive_reached.wait_trigger();
+ `uvm_info(`gfn,
+ $sformatf({"double_fault detector : reached threshold [%0d] ",
+ "for consecutive double faults seen."}, cfg.double_fault_threshold_consecutive),
+ UVM_LOW)
+ end
+ join_any
+ disable fork;
+ end join
+ endtask
+
+endclass
diff --git a/dv/uvm/core_ibex/env/core_ibex_vseqr.sv b/dv/uvm/core_ibex/env/core_ibex_vseqr.sv
index ba981efc..7f6e6e5f 100644
--- a/dv/uvm/core_ibex/env/core_ibex_vseqr.sv
+++ b/dv/uvm/core_ibex/env/core_ibex_vseqr.sv
@@ -9,7 +9,7 @@ class core_ibex_vseqr extends uvm_sequencer;
ibex_mem_intf_response_sequencer data_if_seqr;
ibex_mem_intf_response_sequencer instr_if_seqr;
- irq_request_sequencer irq_seqr;
+ irq_request_sequencer irq_seqr;
`uvm_component_utils(core_ibex_vseqr)
`uvm_component_new
diff --git a/dv/uvm/core_ibex/fcov/core_ibex_csr_categories.svh b/dv/uvm/core_ibex/fcov/core_ibex_csr_categories.svh
new file mode 100644
index 00000000..af6d77f4
--- /dev/null
+++ b/dv/uvm/core_ibex/fcov/core_ibex_csr_categories.svh
@@ -0,0 +1,119 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// List of CSRs to ignore for coverage purposes. These CSRs are ignored as they
+// are less critical and achieving full coverage isn't necessary.
+`define IGNORED_CSRS \
+ // Performance counter control \
+ CSR_MCOUNTINHIBIT, \
+ CSR_MCOUNTEREN, \
+ CSR_MHPMEVENT3, \
+ CSR_MHPMEVENT4, \
+ CSR_MHPMEVENT5, \
+ CSR_MHPMEVENT6, \
+ CSR_MHPMEVENT7, \
+ CSR_MHPMEVENT8, \
+ CSR_MHPMEVENT9, \
+ CSR_MHPMEVENT10, \
+ CSR_MHPMEVENT11, \
+ CSR_MHPMEVENT12, \
+ CSR_MHPMEVENT13, \
+ CSR_MHPMEVENT14, \
+ CSR_MHPMEVENT15, \
+ CSR_MHPMEVENT16, \
+ CSR_MHPMEVENT17, \
+ CSR_MHPMEVENT18, \
+ CSR_MHPMEVENT19, \
+ CSR_MHPMEVENT20, \
+ CSR_MHPMEVENT21, \
+ CSR_MHPMEVENT22, \
+ CSR_MHPMEVENT23, \
+ CSR_MHPMEVENT24, \
+ CSR_MHPMEVENT25, \
+ CSR_MHPMEVENT26, \
+ CSR_MHPMEVENT27, \
+ CSR_MHPMEVENT28, \
+ CSR_MHPMEVENT29, \
+ CSR_MHPMEVENT30, \
+ CSR_MHPMEVENT31, \
+ // Performance counters \
+ CSR_MCYCLE, \
+ CSR_MINSTRET, \
+ CSR_MHPMCOUNTER3, \
+ CSR_MHPMCOUNTER4, \
+ CSR_MHPMCOUNTER5, \
+ CSR_MHPMCOUNTER6, \
+ CSR_MHPMCOUNTER7, \
+ CSR_MHPMCOUNTER8, \
+ CSR_MHPMCOUNTER9, \
+ CSR_MHPMCOUNTER10, \
+ CSR_MHPMCOUNTER11, \
+ CSR_MHPMCOUNTER12, \
+ CSR_MHPMCOUNTER13, \
+ CSR_MHPMCOUNTER14, \
+ CSR_MHPMCOUNTER15, \
+ CSR_MHPMCOUNTER16, \
+ CSR_MHPMCOUNTER17, \
+ CSR_MHPMCOUNTER18, \
+ CSR_MHPMCOUNTER19, \
+ CSR_MHPMCOUNTER20, \
+ CSR_MHPMCOUNTER21, \
+ CSR_MHPMCOUNTER22, \
+ CSR_MHPMCOUNTER23, \
+ CSR_MHPMCOUNTER24, \
+ CSR_MHPMCOUNTER25, \
+ CSR_MHPMCOUNTER26, \
+ CSR_MHPMCOUNTER27, \
+ CSR_MHPMCOUNTER28, \
+ CSR_MHPMCOUNTER29, \
+ CSR_MHPMCOUNTER30, \
+ CSR_MHPMCOUNTER31, \
+ CSR_MCYCLEH, \
+ CSR_MINSTRETH, \
+ CSR_MHPMCOUNTER3H, \
+ CSR_MHPMCOUNTER4H, \
+ CSR_MHPMCOUNTER5H, \
+ CSR_MHPMCOUNTER6H, \
+ CSR_MHPMCOUNTER7H, \
+ CSR_MHPMCOUNTER8H, \
+ CSR_MHPMCOUNTER9H, \
+ CSR_MHPMCOUNTER10H, \
+ CSR_MHPMCOUNTER11H, \
+ CSR_MHPMCOUNTER12H, \
+ CSR_MHPMCOUNTER13H, \
+ CSR_MHPMCOUNTER14H, \
+ CSR_MHPMCOUNTER15H, \
+ CSR_MHPMCOUNTER16H, \
+ CSR_MHPMCOUNTER17H, \
+ CSR_MHPMCOUNTER18H, \
+ CSR_MHPMCOUNTER19H, \
+ CSR_MHPMCOUNTER20H, \
+ CSR_MHPMCOUNTER21H, \
+ CSR_MHPMCOUNTER22H, \
+ CSR_MHPMCOUNTER23H, \
+ CSR_MHPMCOUNTER24H, \
+ CSR_MHPMCOUNTER25H, \
+ CSR_MHPMCOUNTER26H, \
+ CSR_MHPMCOUNTER27H, \
+ CSR_MHPMCOUNTER28H, \
+ CSR_MHPMCOUNTER29H, \
+ CSR_MHPMCOUNTER30H, \
+ CSR_MHPMCOUNTER31H, \
+ CSR_MENVCFGH, \
+ CSR_MSECCFGH, \
+ CSR_MCONTEXT, \
+ CSR_MSCONTEXT, \
+ CSR_SCONTEXT, \
+ CSR_TDATA3
+
+// Debug related CSRs
+`define DEBUG_CSRS \
+ CSR_DCSR, \
+ CSR_DPC, \
+ CSR_DSCRATCH0, \
+ CSR_DSCRATCH1, \
+ CSR_TSELECT, \
+ CSR_TDATA1, \
+ CSR_TDATA2, \
+ CSR_TDATA3
diff --git a/dv/uvm/core_ibex/fcov/core_ibex_fcov_bind.sv b/dv/uvm/core_ibex/fcov/core_ibex_fcov_bind.sv
new file mode 100644
index 00000000..d4b94e5c
--- /dev/null
+++ b/dv/uvm/core_ibex/fcov/core_ibex_fcov_bind.sv
@@ -0,0 +1,17 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+module core_ibex_fcov_bind;
+ bind ibex_core core_ibex_fcov_if u_fcov_bind (
+ .*
+ );
+
+ bind ibex_core core_ibex_pmp_fcov_if
+ #(.PMPGranularity(PMPGranularity),
+ .PMPNumRegions(PMPNumRegions),
+ .PMPEnable(PMPEnable))
+ u_pmp_fcov_bind (
+ .*
+ );
+endmodule
diff --git a/dv/uvm/core_ibex/fcov/core_ibex_fcov_if.sv b/dv/uvm/core_ibex/fcov/core_ibex_fcov_if.sv
new file mode 100644
index 00000000..3c844da7
--- /dev/null
+++ b/dv/uvm/core_ibex/fcov/core_ibex_fcov_if.sv
@@ -0,0 +1,854 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+`include "prim_assert.sv"
+`include "core_ibex_csr_categories.svh"
+
+interface core_ibex_fcov_if import ibex_pkg::*; (
+ input clk_i,
+ input rst_ni,
+
+ input priv_lvl_e priv_mode_id,
+ input priv_lvl_e priv_mode_lsu,
+
+ input debug_mode,
+
+ input fcov_csr_read_only,
+ input fcov_csr_write,
+
+ input fcov_rf_ecc_err_a_id,
+ input fcov_rf_ecc_err_b_id,
+
+ input ibex_mubi_t fetch_enable_i,
+
+ input instr_req_o,
+ input instr_gnt_i,
+ input instr_rvalid_i,
+
+ input data_req_o,
+ input data_gnt_i,
+ input data_rvalid_i
+);
+ `include "dv_fcov_macros.svh"
+ import uvm_pkg::*;
+
+ typedef enum {
+ InstrCategoryALU,
+ InstrCategoryMul,
+ InstrCategoryDiv,
+ InstrCategoryBranch,
+ InstrCategoryJump,
+ InstrCategoryLoad,
+ InstrCategoryStore,
+ InstrCategoryCSRAccess,
+ InstrCategoryEBreakDbg,
+ InstrCategoryEBreakExc,
+ InstrCategoryECall,
+ InstrCategoryMRet,
+ InstrCategoryDRet,
+ InstrCategoryWFI,
+ InstrCategoryFence,
+ InstrCategoryFenceI,
+ InstrCategoryNone,
+ InstrCategoryFetchError,
+ InstrCategoryCompressedIllegal,
+ InstrCategoryUncompressedIllegal,
+ InstrCategoryCSRIllegal,
+ InstrCategoryPrivIllegal,
+ InstrCategoryOtherIllegal,
+ // Category not in coverage plan, it should never be seen. An instruction given the Other
+ // category should either be classified under an existing category or a new category should be
+ // created as appropriate.
+ InstrCategoryOther
+ } instr_category_e;
+
+ typedef enum {
+ IdStallTypeNone,
+ IdStallTypeInstr,
+ IdStallTypeLdHz,
+ IdStallTypeMem
+ } id_stall_type_e;
+
+ instr_category_e id_instr_category;
+ // Set `id_instr_category` to the appropriate category for the uncompressed instruction in the
+ // ID/EX stage. Compressed instructions are not handled (`id_stage_i.instr_rdata_i` is always
+ // uncompressed). When the `id_stage.instr_valid_i` isn't set `InstrCategoryNone` is the given
+ // instruction category.
+ always_comb begin
+ id_instr_category = InstrCategoryOther;
+
+ case (id_stage_i.instr_rdata_i[6:0])
+ ibex_pkg::OPCODE_LUI: id_instr_category = InstrCategoryALU;
+ ibex_pkg::OPCODE_AUIPC: id_instr_category = InstrCategoryALU;
+ ibex_pkg::OPCODE_JAL: id_instr_category = InstrCategoryJump;
+ ibex_pkg::OPCODE_JALR: id_instr_category = InstrCategoryJump;
+ ibex_pkg::OPCODE_BRANCH: id_instr_category = InstrCategoryBranch;
+ ibex_pkg::OPCODE_LOAD: id_instr_category = InstrCategoryLoad;
+ ibex_pkg::OPCODE_STORE: id_instr_category = InstrCategoryStore;
+ ibex_pkg::OPCODE_OP_IMM: id_instr_category = InstrCategoryALU;
+ ibex_pkg::OPCODE_OP: begin
+ if ({id_stage_i.instr_rdata_i[26], id_stage_i.instr_rdata_i[13:12]} == {1'b1, 2'b01}) begin
+ id_instr_category = InstrCategoryALU; // reg-reg/reg-imm ops
+ end else if (id_stage_i.instr_rdata_i[31:25] inside {7'b000_0000, 7'b010_0000, 7'b011_0000,
+ 7'b011_0100, 7'b001_0100, 7'b001_0000, 7'b000_0101, 7'b000_0100, 7'b010_0100}) begin
+ id_instr_category = InstrCategoryALU; // RV32I and RV32B reg-reg/reg-imm ops
+ end else if (id_stage_i.instr_rdata_i[31:25] == 7'b000_0001) begin
+ if (id_stage_i.instr_rdata_i[14]) begin
+ id_instr_category = InstrCategoryDiv; // DIV*
+ end else begin
+ id_instr_category = InstrCategoryMul; // MUL*
+ end
+ end
+ end
+ ibex_pkg::OPCODE_SYSTEM: begin
+ if (id_stage_i.instr_rdata_i[14:12] == 3'b000) begin
+ case (id_stage_i.instr_rdata_i[31:20])
+ 12'h000: id_instr_category = InstrCategoryECall;
+ 12'h001: begin
+ if (id_stage_i.debug_ebreakm_i && priv_mode_id == PRIV_LVL_M) begin
+ id_instr_category = InstrCategoryEBreakDbg;
+ end else if (id_stage_i.debug_ebreaku_i && priv_mode_id == PRIV_LVL_U) begin
+ id_instr_category = InstrCategoryEBreakDbg;
+ end else begin
+ id_instr_category = InstrCategoryEBreakExc;
+ end
+ end
+ 12'h302: id_instr_category = InstrCategoryMRet;
+ 12'h7b2: id_instr_category = InstrCategoryDRet;
+ 12'h105: id_instr_category = InstrCategoryWFI;
+ endcase
+ end else begin
+ id_instr_category = InstrCategoryCSRAccess;
+ end
+ end
+ ibex_pkg::OPCODE_MISC_MEM: begin
+ case (id_stage_i.instr_rdata_i[14:12])
+ 3'b000: id_instr_category = InstrCategoryFence;
+ 3'b001: id_instr_category = InstrCategoryFenceI;
+ endcase
+ end
+ default: id_instr_category = InstrCategoryOther;
+ endcase
+
+ if (id_stage_i.instr_valid_i) begin
+ if (id_stage_i.instr_fetch_err_i) begin
+ id_instr_category = InstrCategoryFetchError;
+ end else if (id_stage_i.illegal_c_insn_i) begin
+ id_instr_category = InstrCategoryCompressedIllegal;
+ end else if (id_stage_i.illegal_insn_dec) begin
+ id_instr_category = InstrCategoryUncompressedIllegal;
+ end else if (id_stage_i.illegal_csr_insn_i) begin
+ if (cs_registers_i.illegal_csr_priv || cs_registers_i.illegal_csr_dbg) begin
+ id_instr_category = InstrCategoryPrivIllegal;
+ end else begin
+ id_instr_category = InstrCategoryCSRIllegal;
+ end
+ end else if (id_stage_i.illegal_insn_o) begin
+ if (id_stage_i.illegal_dret_insn || id_stage_i.illegal_umode_insn) begin
+ id_instr_category = InstrCategoryPrivIllegal;
+ end else begin
+ id_instr_category = InstrCategoryOtherIllegal;
+ end
+ end
+ end else begin
+ id_instr_category = InstrCategoryNone;
+ end
+ end
+
+ // Check instruction categories calculated from instruction bits match what decoder has produced.
+
+ // The ALU category is tricky as there's no specific ALU enable and instructions that actively use
+ // the result of the ALU but aren't themselves ALU operations (such as load/store and JALR). This
+ // categorizes anything that selects the ALU as the source of register write data and enables
+ // register writes minus some exclusions as an ALU operation.
+ `ASSERT(InstrCategoryALUCorrect, id_instr_category == InstrCategoryALU |->
+ (id_stage_i.rf_wdata_sel == RF_WD_EX) && id_stage_i.rf_we_dec && ~id_stage_i.mult_sel_ex_o &&
+ ~id_stage_i.div_sel_ex_o && ~id_stage_i.lsu_req_dec && ~id_stage_i.jump_in_dec)
+
+ `ASSERT(InstrCategoryMulCorrect,
+ id_instr_category == InstrCategoryMul |-> id_stage_i.mult_sel_ex_o)
+
+ `ASSERT(InstrCategoryDivCorrect,
+ id_instr_category == InstrCategoryDiv |-> id_stage_i.div_sel_ex_o)
+
+ `ASSERT(InstrCategoryBranchCorrect,
+ id_instr_category == InstrCategoryBranch |-> id_stage_i.branch_in_dec)
+
+ `ASSERT(InstrCategoryJumpCorrect,
+ id_instr_category == InstrCategoryJump |-> id_stage_i.jump_in_dec)
+
+ `ASSERT(InstrCategoryLoadCorrect,
+ id_instr_category == InstrCategoryLoad |-> id_stage_i.lsu_req_dec && !id_stage_i.lsu_we)
+
+ `ASSERT(InstrCategoryStoreCorrect,
+ id_instr_category == InstrCategoryStore |-> id_stage_i.lsu_req_dec && id_stage_i.lsu_we)
+
+ `ASSERT(InstrCategoryCSRAccessCorrect,
+ id_instr_category == InstrCategoryCSRAccess |-> id_stage_i.csr_access_o)
+ `ASSERT(InstrCategoryEBreakDbgCorrect, id_instr_category == InstrCategoryEBreakDbg |->
+ id_stage_i.ebrk_insn && id_stage_i.controller_i.ebreak_into_debug)
+
+ `ASSERT(InstrCategoryEBreakExcCorrect, id_instr_category == InstrCategoryEBreakExc |->
+ id_stage_i.ebrk_insn && !id_stage_i.controller_i.ebreak_into_debug)
+
+ `ASSERT(InstrCategoryECallCorrect,
+ id_instr_category == InstrCategoryECall |-> id_stage_i.ecall_insn_dec)
+
+ `ASSERT(InstrCategoryMRetCorrect,
+ id_instr_category == InstrCategoryMRet |-> id_stage_i.mret_insn_dec)
+
+ `ASSERT(InstrCategoryDRetCorrect,
+ id_instr_category == InstrCategoryDRet |-> id_stage_i.dret_insn_dec)
+
+ `ASSERT(InstrCategoryWFICorrect,
+ id_instr_category == InstrCategoryWFI |-> id_stage_i.wfi_insn_dec)
+
+ `ASSERT(InstrCategoryFenceICorrect,
+ id_instr_category == InstrCategoryFenceI && id_stage_i.instr_first_cycle |->
+ id_stage_i.icache_inval_o)
+
+
+
+ id_stall_type_e id_stall_type;
+
+ // Set `id_stall_type` to the appropriate type based on signals in the ID/EX stage
+ always_comb begin
+ id_stall_type = IdStallTypeNone;
+
+ if (id_stage_i.instr_valid_i) begin
+ if (id_stage_i.stall_mem) begin
+ id_stall_type = IdStallTypeMem;
+ end
+
+ if (id_stage_i.stall_ld_hz) begin
+ id_stall_type = IdStallTypeLdHz;
+ end
+
+ if (id_stage_i.stall_multdiv || id_stage_i.stall_branch ||
+ id_stage_i.stall_jump) begin
+ id_stall_type = IdStallTypeInstr;
+ end
+ end
+ end
+
+ // IF specific state enum
+ typedef enum {
+ IFStageFullAndFetching,
+ IFStageFullAndIdle,
+ IFStageEmptyAndFetching,
+ IFStageEmptyAndIdle
+ } if_stage_state_e;
+
+ // ID/EX and WB have the same state enum
+ typedef enum {
+ PipeStageFullAndStalled,
+ PipeStageFullAndUnstalled,
+ PipeStageEmpty
+ } pipe_stage_state_e;
+
+ if_stage_state_e if_stage_state;
+ pipe_stage_state_e id_stage_state;
+ pipe_stage_state_e wb_stage_state;
+
+ always_comb begin
+ if_stage_state = IFStageEmptyAndIdle;
+
+ if (if_stage_i.if_instr_valid) begin
+ if (if_stage_i.req_i) begin
+ if_stage_state = IFStageFullAndFetching;
+ end else begin
+ if_stage_state = IFStageFullAndIdle;
+ end
+ end else if(if_stage_i.req_i) begin
+ if_stage_state = IFStageEmptyAndFetching;
+ end
+ end
+
+ always_comb begin
+ id_stage_state = PipeStageEmpty;
+
+ if (id_stage_i.instr_valid_i) begin
+ if (id_stage_i.id_in_ready_o) begin
+ id_stage_state = PipeStageFullAndUnstalled;
+ end else begin
+ id_stage_state = PipeStageFullAndStalled;
+ end
+ end
+ end
+
+ always_comb begin
+ wb_stage_state = PipeStageEmpty;
+
+ if (wb_stage_i.fcov_wb_valid) begin
+ if (wb_stage_i.ready_wb_o) begin
+ wb_stage_state = PipeStageFullAndUnstalled;
+ end else begin
+ wb_stage_state = PipeStageFullAndStalled;
+ end
+ end
+ end
+
+ // This latch is needed because if we cannot register this condition being true
+ // with a clock. Being in the sleep mode implies that we don't have an active clock.
+ // So, we need to catch the condition, latch it and keep it until we wake up and decode
+ // an instruction (which guarantees we have a clock in the core)
+ logic kept_wfi_with_irq;
+
+ always_latch begin
+ if (id_stage_i.controller_i.ctrl_fsm_cs == DECODE) begin
+ kept_wfi_with_irq = 1'b0;
+ end else if (id_stage_i.controller_i.ctrl_fsm_cs == SLEEP &&
+ id_stage_i.controller_i.ctrl_fsm_ns == SLEEP &&
+ (|cs_registers_i.mip)) begin
+ kept_wfi_with_irq = 1'b1;
+ end
+ end
+
+ logic instr_id_matches_trigger_d, instr_id_matches_trigger_q;
+
+ assign instr_id_matches_trigger_d = id_stage_i.controller_i.trigger_match_i &&
+ id_stage_i.controller_i.fcov_debug_entry_if;
+
+ // Delay instruction matching trigger point since it is catched in IF stage.
+ // We would want to cross it with decoded instruction categories and it does not matter
+ // when exactly we are hitting the condition.
+ always @(posedge clk_i or negedge rst_ni) begin
+ if (!rst_ni) begin
+ instr_id_matches_trigger_q <= 1'b0;
+ end else begin
+ instr_id_matches_trigger_q <= instr_id_matches_trigger_d;
+ end
+ end
+
+ // Keep track of previous data addr of Store to catch RAW hazard caused by STORE->LOAD
+ logic [31:0] prev_store_addr;
+ logic [31:0] data_addr_incr;
+ logic [31:0] curr_data_addr;
+ logic raw_hz;
+
+ always @(posedge clk_i or negedge rst_ni) begin
+ if (!rst_ni) begin
+ prev_store_addr <= 1'b0;
+ end else if (load_store_unit_i.data_we_o) begin
+ // It does not matter if the store we executed before load is misaligned or not. Because
+ // even if it is misaligned, we would catch the "corrected" version (2nd access) before
+ // doing the RAW hazard check.
+ prev_store_addr <= load_store_unit_i.data_addr_o;
+ end
+ end
+
+ // Calculate the corrected version of the new data addr at the same time while LOAD instruction
+ // gets decoded.
+ always_comb begin
+ if (load_store_unit_i.split_misaligned_access) begin
+ data_addr_incr = load_store_unit_i.data_addr + 4;
+ curr_data_addr = {data_addr_incr[2+:30],2'b00};
+ end else begin
+ curr_data_addr = load_store_unit_i.data_addr;
+ end
+ end
+
+ // If we have LOAD at ID/EX stage and STORE at WB stage, compare the calculated address for LOAD
+ // and the saved STORE address. If they are matching we would have RAW hazard.
+ assign raw_hz = wb_stage_i.outstanding_store_wb_o &&
+ id_instr_category == InstrCategoryLoad &&
+ prev_store_addr == curr_data_addr;
+
+ // Collect all the interrupts for collecting them in different bins.
+ logic [5:0] fcov_irqs;
+
+ assign fcov_irqs = {id_stage_i.controller_i.irq_nm_ext_i,
+ id_stage_i.controller_i.irq_nm_int,
+ (|id_stage_i.controller_i.irqs_i.irq_fast),
+ id_stage_i.controller_i.irqs_i.irq_external,
+ id_stage_i.controller_i.irqs_i.irq_software,
+ id_stage_i.controller_i.irqs_i.irq_timer};
+
+ logic instr_unstalled;
+ logic instr_unstalled_last;
+ logic id_stall_type_last_valid;
+ id_stall_type_e id_stall_type_last;
+ instr_category_e id_instr_category_last;
+
+ // Keep track of previous values for some signals. These are used for some of the crosses relating
+ // to exception and debug entry. We want to cross different instruction categories and stalling
+ // behaviour with exception and debug entry but signals indicating entry occur a cycle after the
+ // relevant information is flushed from the pipeline.
+ always @(posedge clk_i or negedge rst_ni) begin
+ if (!rst_ni) begin
+ // First cycle out of reset there is no last stall, use valid bit to deal with this case
+ id_stall_type_last_valid <= 1'b0;
+ id_stall_type_last <= IdStallTypeNone;
+ instr_unstalled_last <= 1'b0;
+ id_instr_category_last <= InstrCategoryNone;
+ end else begin
+ id_stall_type_last_valid <= 1'b1;
+ id_stall_type_last <= id_stall_type;
+ instr_unstalled_last <= instr_unstalled;
+ id_instr_category_last <= id_instr_category;
+ end
+ end
+
+ assign instr_unstalled =
+ (id_stall_type == IdStallTypeNone) && (id_stall_type_last != IdStallTypeNone) &&
+ id_stall_type_last_valid;
+
+ // V2S Related Probes for Top-Level
+ logic rf_we_glitch_err;
+ logic lockstep_glitch_err;
+
+ logic imem_single_cycle_response, dmem_single_cycle_response;
+
+ mem_monitor_if iside_mem_monitor(
+ .clk_i,
+ .rst_ni,
+ .req_i(instr_req_o),
+ .gnt_i(instr_gnt_i),
+ .rvalid_i(instr_rvalid_i),
+ .outstanding_requests_o(),
+ .single_cycle_response_o(imem_single_cycle_response)
+ );
+
+ mem_monitor_if dside_mem_monitor(
+ .clk_i,
+ .rst_ni,
+ .req_i(data_req_o),
+ .gnt_i(data_gnt_i),
+ .rvalid_i(data_rvalid_i),
+ .outstanding_requests_o(),
+ .single_cycle_response_o(dmem_single_cycle_response)
+ );
+
+ covergroup uarch_cg @(posedge clk_i);
+ option.per_instance = 1;
+ option.name = "uarch_cg";
+
+ cp_id_instr_category: coverpoint id_instr_category {
+ // Not certain if InstrCategoryOtherIllegal can occur. Put it in illegal_bins for now and
+ // revisit if any issues are seen
+ illegal_bins illegal = {InstrCategoryOther, InstrCategoryOtherIllegal};
+ }
+
+ cp_id_instr_category_last: coverpoint id_instr_category_last {
+ // Not certain if InstrCategoryOtherIllegal can occur. Put it in illegal_bins for now and
+ // revisit if any issues are seen
+ illegal_bins illegal = {InstrCategoryOther, InstrCategoryOtherIllegal};
+ }
+
+ cp_stall_type_id: coverpoint id_stall_type;
+
+ cp_wb_reg_no_load_hz: coverpoint id_stage_i.fcov_rf_rd_wb_hz &&
+ !wb_stage_i.outstanding_load_wb_o;
+
+ cp_mem_raw_hz: coverpoint raw_hz;
+
+ cp_mprv: coverpoint cs_registers_i.mstatus_q.mprv;
+
+ cp_ls_error_exception: coverpoint load_store_unit_i.fcov_ls_error_exception;
+ cp_ls_pmp_exception: coverpoint load_store_unit_i.fcov_ls_pmp_exception;
+
+ cp_branch_taken: coverpoint id_stage_i.fcov_branch_taken;
+ cp_branch_not_taken: coverpoint id_stage_i.fcov_branch_not_taken;
+
+ cp_priv_mode_id: coverpoint priv_mode_id {
+ illegal_bins illegal = {PRIV_LVL_H, PRIV_LVL_S};
+ }
+ cp_priv_mode_lsu: coverpoint priv_mode_lsu {
+ illegal_bins illegal = {PRIV_LVL_H, PRIV_LVL_S};
+ }
+
+ cp_if_stage_state : coverpoint if_stage_state;
+ cp_id_stage_state : coverpoint id_stage_state;
+ cp_wb_stage_state : coverpoint wb_stage_state;
+
+ // V2S Coverpoints
+ cp_data_ind_timing: coverpoint cs_registers_i.data_ind_timing_o;
+ cp_data_ind_timing_instr: coverpoint id_instr_category iff (cs_registers_i.data_ind_timing_o) {
+ // Not certain if InstrCategoryOtherIllegal can occur. Put it in illegal_bins for now and
+ // revisit if any issues are seen
+ illegal_bins illegal = {InstrCategoryOther, InstrCategoryOtherIllegal};
+ }
+
+ cp_dummy_instr_en: coverpoint cs_registers_i.dummy_instr_en_o;
+ cp_dummy_instr_mask: coverpoint cs_registers_i.dummy_instr_mask_o;
+ cp_dummy_instr_type: coverpoint if_stage_i.fcov_dummy_instr_type;
+ cp_dummy_instr: coverpoint id_instr_category iff (cs_registers_i.dummy_instr_en_o) {
+ // Not certain if InstrCategoryOtherIllegal can occur. Put it in illegal_bins for now and
+ // revisit if any issues are seen
+ illegal_bins illegal = {InstrCategoryOther, InstrCategoryOtherIllegal};
+ }
+
+ // Each stage sees a dummy instruction.
+ cp_dummy_instr_if_stage: coverpoint if_stage_i.fcov_insert_dummy_instr;
+ cp_dummy_instr_id_stage: coverpoint if_stage_i.dummy_instr_id_o;
+ cp_dummy_instr_wb_stage: coverpoint wb_stage_i.dummy_instr_wb_o;
+
+ `DV_FCOV_EXPR_SEEN(rf_a_ecc_err, fcov_rf_ecc_err_a_id)
+ `DV_FCOV_EXPR_SEEN(rf_b_ecc_err, fcov_rf_ecc_err_b_id)
+
+ `DV_FCOV_EXPR_SEEN(icache_ecc_err, if_stage_i.icache_ecc_error_o)
+
+ `DV_FCOV_EXPR_SEEN(mem_load_ecc_err, load_store_unit_i.load_resp_intg_err_o)
+ `DV_FCOV_EXPR_SEEN(mem_store_ecc_err, load_store_unit_i.store_resp_intg_err_o)
+
+ `DV_FCOV_EXPR_SEEN(lockstep_err, lockstep_glitch_err)
+ `DV_FCOV_EXPR_SEEN(rf_we_glitch_err, rf_we_glitch_err)
+ `DV_FCOV_EXPR_SEEN(pc_mismatch_err, if_stage_i.pc_mismatch_alert_o)
+
+ cp_fetch_enable: coverpoint fetch_enable_i {
+ bins fetch_on = {IbexMuBiOn};
+ bins fetch_off = {IbexMuBiOff};
+ bins fetch_inval = default;
+ }
+
+ // TODO: MRET/WFI in debug mode?
+ // Specific cover points for these as `id_instr_category` will be InstrCategoryPrivIllegal when
+ // executing these instructions in U-mode.
+ `DV_FCOV_EXPR_SEEN(mret_in_umode, id_stage_i.mret_insn_dec && priv_mode_id == PRIV_LVL_U)
+ `DV_FCOV_EXPR_SEEN(wfi_in_umode, id_stage_i.wfi_insn_dec && priv_mode_id == PRIV_LVL_U)
+
+ // Unsupported writes to WARL type CSRs
+ `DV_FCOV_EXPR_SEEN(warl_check_mstatus,
+ fcov_csr_write &&
+ (cs_registers_i.u_mstatus_csr.wr_data_i !=
+ cs_registers_i.csr_wdata_int))
+
+ `DV_FCOV_EXPR_SEEN(warl_check_mie,
+ fcov_csr_write &&
+ (cs_registers_i.u_mie_csr.wr_data_i !=
+ cs_registers_i.csr_wdata_int))
+
+ `DV_FCOV_EXPR_SEEN(warl_check_mtvec,
+ fcov_csr_write &&
+ (cs_registers_i.u_mtvec_csr.wr_data_i !=
+ cs_registers_i.csr_wdata_int))
+
+ `DV_FCOV_EXPR_SEEN(warl_check_mepc,
+ fcov_csr_write &&
+ (cs_registers_i.u_mepc_csr.wr_data_i !=
+ cs_registers_i.csr_wdata_int))
+
+ `DV_FCOV_EXPR_SEEN(warl_check_mtval,
+ fcov_csr_write &&
+ (cs_registers_i.u_mtval_csr.wr_data_i !=
+ cs_registers_i.csr_wdata_int))
+
+ `DV_FCOV_EXPR_SEEN(warl_check_dcsr,
+ fcov_csr_write &&
+ (cs_registers_i.u_dcsr_csr.wr_data_i !=
+ cs_registers_i.csr_wdata_int))
+
+ `DV_FCOV_EXPR_SEEN(warl_check_cpuctrl,
+ fcov_csr_write &&
+ (cs_registers_i.u_cpuctrlsts_part_csr.wr_data_i !=
+ cs_registers_i.csr_wdata_int))
+
+ `DV_FCOV_EXPR_SEEN(double_fault, cs_registers_i.cpuctrlsts_part_d.double_fault_seen)
+ `DV_FCOV_EXPR_SEEN(icache_enable, cs_registers_i.cpuctrlsts_part_d.icache_enable)
+
+ cp_irq_pending: coverpoint id_stage_i.irq_pending_i | id_stage_i.irq_nm_i;
+ cp_debug_req: coverpoint id_stage_i.controller_i.fcov_debug_req;
+
+ cp_csr_read_only: coverpoint cs_registers_i.csr_addr_i iff (fcov_csr_read_only) {
+ ignore_bins ignore = {`IGNORED_CSRS};
+ }
+
+ cp_csr_write: coverpoint cs_registers_i.csr_addr_i iff (fcov_csr_write) {
+ ignore_bins ignore = {`IGNORED_CSRS};
+ }
+
+ `DV_FCOV_EXPR_SEEN(csr_invalid_read_only, fcov_csr_read_only && cs_registers_i.illegal_csr)
+ `DV_FCOV_EXPR_SEEN(csr_invalid_write, fcov_csr_write && cs_registers_i.illegal_csr)
+
+ cp_debug_mode: coverpoint debug_mode;
+
+ `DV_FCOV_EXPR_SEEN(debug_wakeup, id_stage_i.controller_i.fcov_debug_wakeup)
+ `DV_FCOV_EXPR_SEEN(all_debug_req, id_stage_i.controller_i.fcov_all_debug_req)
+ `DV_FCOV_EXPR_SEEN(debug_entry_if, id_stage_i.controller_i.fcov_debug_entry_if)
+ `DV_FCOV_EXPR_SEEN(debug_entry_id, id_stage_i.controller_i.fcov_debug_entry_id)
+ `DV_FCOV_EXPR_SEEN(pipe_flush, id_stage_i.controller_i.fcov_pipe_flush)
+ `DV_FCOV_EXPR_SEEN(single_step_taken, id_stage_i.controller_i.fcov_debug_single_step_taken)
+ `DV_FCOV_EXPR_SEEN(single_step_exception, id_stage_i.controller_i.do_single_step_d &&
+ id_stage_i.controller_i.fcov_pipe_flush)
+ `DV_FCOV_EXPR_SEEN(insn_trigger_enter_debug, instr_id_matches_trigger_q)
+
+ cp_nmi_taken: coverpoint ((fcov_irqs[5] || fcov_irqs[4])) iff
+ (id_stage_i.controller_i.fcov_interrupt_taken);
+
+ cp_interrupt_taken: coverpoint fcov_irqs iff (id_stage_i.controller_i.fcov_interrupt_taken){
+ wildcard bins nmi_external = {6'b1?????};
+ wildcard bins nmi_internal = {6'b01????};
+ wildcard bins irq_fast = {6'b001???};
+ wildcard bins irq_external = {6'b0001??};
+ wildcard bins irq_software = {6'b00001?};
+ wildcard bins irq_timer = {6'b000001};
+ }
+
+ cp_controller_fsm: coverpoint id_stage_i.controller_i.ctrl_fsm_cs {
+ bins out_of_reset = (RESET => BOOT_SET);
+ bins out_of_boot_set = (BOOT_SET => FIRST_FETCH);
+ bins out_of_first_fetch0 = (FIRST_FETCH => DECODE);
+ bins out_of_first_fetch1 = (FIRST_FETCH => IRQ_TAKEN);
+ bins out_of_first_fetch2 = (FIRST_FETCH => DBG_TAKEN_IF);
+ bins out_of_decode0 = (DECODE => FLUSH);
+ bins out_of_decode1 = (DECODE => DBG_TAKEN_IF);
+ bins out_of_decode2 = (DECODE => IRQ_TAKEN);
+ bins out_of_irq_taken = (IRQ_TAKEN => DECODE);
+ bins out_of_debug_taken_if = (DBG_TAKEN_IF => DECODE);
+ bins out_of_debug_taken_id = (DBG_TAKEN_ID => DECODE);
+ bins out_of_flush0 = (FLUSH => DECODE);
+ bins out_of_flush1 = (FLUSH => DBG_TAKEN_ID);
+ bins out_of_flush2 = (FLUSH => WAIT_SLEEP);
+ bins out_of_flush3 = (FLUSH => DBG_TAKEN_IF);
+ bins out_of_wait_sleep = (WAIT_SLEEP => SLEEP);
+ bins out_of_sleep = (SLEEP => FIRST_FETCH);
+ // TODO: VCS does not implement default sequence so illegal_bins will be empty
+ illegal_bins illegal_transitions = default sequence;
+ }
+
+ cp_controller_fsm_sleep: coverpoint id_stage_i.controller_i.ctrl_fsm_cs {
+ bins out_of_sleep = (SLEEP => FIRST_FETCH);
+ bins enter_sleep = (WAIT_SLEEP => SLEEP);
+ // TODO: VCS does not implement default sequence so illegal_bins will be empty
+ illegal_bins illegal_transitions = default sequence;
+ }
+
+ // This will only be seen when specific interrupt is disabled by MIE CSR
+ `DV_FCOV_EXPR_SEEN(irq_continue_sleep, kept_wfi_with_irq)
+
+ cp_single_step_instr: coverpoint id_instr_category iff
+ (id_stage_i.controller_i.fcov_debug_single_step_taken) {
+ // Not certain if InstrCategoryOtherIllegal can occur. Put it in illegal_bins for now and
+ // revisit if any issues are seen
+ illegal_bins illegal =
+ {InstrCategoryOther, InstrCategoryNone, InstrCategoryOtherIllegal
+ // [Debug Spec v1.0.0-STABLE, p.95]
+ // > dret is an instruction which only has meaning while Debug Mode
+ // We want to step over this to at-least specify how the Ibex does behave.
+ //
+ // [Debug Spec v1.0.0-STABLE, p.50]
+ // > If the instruction being stepped over is wfi and would normally stall the hart,
+ // > then instead the instruction is treated as nop.
+ // Again this will be useful coverage to verify we are testing this behaviour.
+ };
+ }
+
+ // Only sample the bus error from the first access of misaligned load/store when we are in
+ // the data phase of the second access. Without this, we cannot sample the case when both
+ // first and second access fails.
+ cp_misaligned_first_data_bus_err: coverpoint load_store_unit_i.fcov_mis_bus_err_1_q iff
+ (load_store_unit_i.fcov_mis_rvalid_2);
+
+ cp_misaligned_second_data_bus_err: coverpoint load_store_unit_i.data_bus_err_i iff
+ (load_store_unit_i.fcov_mis_rvalid_2);
+
+ cp_imem_response_latency: coverpoint imem_single_cycle_response iff (instr_rvalid_i) {
+ bins single_cycle = {1'b1};
+ bins multi_cycle = {1'b0};
+ }
+
+ `DV_FCOV_EXPR_SEEN(imem_req_gnt_rvalid, instr_rvalid_i & instr_req_o & instr_gnt_i)
+
+ cp_dmem_response_latency: coverpoint dmem_single_cycle_response iff (data_rvalid_i) {
+ bins single_cycle = {1'b1};
+ bins multi_cycle = {1'b0};
+ }
+
+ `DV_FCOV_EXPR_SEEN(dmem_req_gnt_rvalid, data_rvalid_i & data_req_o & data_gnt_i)
+
+ misaligned_data_bus_err_cross: cross cp_misaligned_first_data_bus_err,
+ cp_misaligned_second_data_bus_err {
+ // Cannot see both bus errors together as they're signalled at different states of the load
+ // store unit FSM
+ illegal_bins illegal = binsof(cp_misaligned_first_data_bus_err) intersect {1'b1} &&
+ binsof(cp_misaligned_second_data_bus_err) intersect {1'b1};
+ }
+
+ misaligned_insn_bus_err_cross: cross id_stage_i.instr_fetch_err_i,
+ id_stage_i.instr_fetch_err_plus2_i;
+
+ // Include both mstatus.mie enabled/disabled because it should not affect wakeup condition
+ irq_wfi_cross: cross cp_controller_fsm_sleep, cs_registers_i.mstatus_q.mie iff
+ (id_stage_i.irq_pending_i | id_stage_i.irq_nm_i);
+
+ debug_wfi_cross: cross cp_controller_fsm_sleep, cp_all_debug_req iff
+ (id_stage_i.controller_i.fcov_all_debug_req);
+
+ priv_mode_instr_cross: cross cp_priv_mode_id, cp_id_instr_category {
+ // No un-privileged CSRs on Ibex so no InstrCategoryCSRAccess in U mode (any CSR instruction
+ // becomes InstrCategoryCSRIllegal).
+ illegal_bins umode_csr_access_illegal =
+ binsof(cp_id_instr_category) intersect {InstrCategoryCSRAccess} &&
+ binsof(cp_priv_mode_id) intersect {PRIV_LVL_U};
+ }
+
+ priv_mode_irq_cross: cross cp_priv_mode_id, cp_interrupt_taken, cs_registers_i.mstatus_q.mie {
+ // No interrupt would be taken in M-mode when its mstatus.MIE = 0 unless it's an NMI
+ illegal_bins mmode_mstatus_mie =
+ binsof(cs_registers_i.mstatus_q.mie) intersect {1'b0} &&
+ binsof(cp_priv_mode_id) intersect {PRIV_LVL_M} with (cp_interrupt_taken >> 4 == 6'd0);
+ }
+
+ priv_mode_exception_cross: cross cp_priv_mode_id, cp_ls_pmp_exception, cp_ls_error_exception {
+ illegal_bins pmp_and_error_exeption_both =
+ (binsof(cp_ls_pmp_exception) intersect {1'b1} &&
+ binsof(cp_ls_error_exception) intersect {1'b1});
+ }
+
+ stall_cross: cross cp_id_instr_category, cp_stall_type_id {
+ illegal_bins illegal =
+ // Only Div, Mul, Branch and Jump instructions can see an instruction stall
+ (!binsof(cp_id_instr_category) intersect {InstrCategoryDiv, InstrCategoryMul,
+ InstrCategoryBranch, InstrCategoryJump,
+ InstrCategoryFenceI} &&
+ binsof(cp_stall_type_id) intersect {IdStallTypeInstr})
+ ||
+ // Only ALU, Mul, Div, Branch, Jump, Load, Store and CSR Access can see a load hazard stall
+ (!binsof(cp_id_instr_category) intersect {InstrCategoryALU, InstrCategoryMul,
+ InstrCategoryDiv, InstrCategoryBranch,
+ InstrCategoryJump, InstrCategoryLoad,
+ InstrCategoryStore, InstrCategoryCSRAccess} &&
+ binsof(cp_stall_type_id) intersect {IdStallTypeLdHz});
+ }
+
+ wb_reg_no_load_hz_instr_cross: cross cp_id_instr_category, cp_wb_reg_no_load_hz {
+ // Only ALU, Mul, Div, Branch, Jump, Load, Store and CSRAccess instructions can see a WB
+ // register hazard
+ illegal_bins illegal =
+ !binsof(cp_id_instr_category) intersect {InstrCategoryALU, InstrCategoryMul,
+ InstrCategoryDiv, InstrCategoryBranch, InstrCategoryJump, InstrCategoryLoad,
+ InstrCategoryStore, InstrCategoryCSRAccess} &&
+ binsof(cp_wb_reg_no_load_hz) intersect {1'b1};
+ }
+
+ pipe_cross: cross cp_id_instr_category, cp_if_stage_state, cp_id_stage_state, wb_stage_state {
+ // When ID stage is empty the only legal instruction category is InstrCategoryNone. Conversly
+ // when the instruction category is InstrCategoryNone the only legal ID stage state is
+ // PipeStageEmpty.
+ illegal_bins illegal = (!binsof(cp_id_instr_category) intersect {InstrCategoryNone} &&
+ binsof(cp_id_stage_state) intersect {PipeStageEmpty}) ||
+ (binsof(cp_id_instr_category) intersect {InstrCategoryNone} &&
+ !binsof(cp_id_stage_state) intersect {PipeStageEmpty});
+ }
+
+ interrupt_taken_instr_cross: cross cp_nmi_taken, instr_unstalled_last,
+ cp_id_instr_category_last iff (id_stage_i.controller_i.fcov_interrupt_taken);
+
+ debug_instruction_cross: cross cp_debug_mode, cp_id_instr_category;
+
+ debug_entry_if_instr_cross: cross cp_debug_entry_if, instr_unstalled_last,
+ cp_id_instr_category_last;
+ pipe_flush_instr_cross: cross cp_pipe_flush, instr_unstalled, cp_id_instr_category;
+
+ exception_stall_instr_cross: cross cp_ls_pmp_exception, cp_ls_error_exception,
+ cp_id_instr_category, cp_stall_type_id, instr_unstalled, cp_irq_pending, cp_debug_req {
+ illegal_bins illegal =
+ // Only Div, Mul, Branch and Jump instructions can see an instruction stall
+ (!binsof(cp_id_instr_category) intersect {InstrCategoryDiv, InstrCategoryMul,
+ InstrCategoryBranch, InstrCategoryJump,
+ InstrCategoryFenceI} &&
+ binsof(cp_stall_type_id) intersect {IdStallTypeInstr})
+ ||
+ // Only ALU, Mul, Div, Branch, Jump, Load, Store and CSR Access can see a load hazard stall
+ (!binsof(cp_id_instr_category) intersect {InstrCategoryALU, InstrCategoryMul,
+ InstrCategoryDiv, InstrCategoryBranch,
+ InstrCategoryJump, InstrCategoryLoad,
+ InstrCategoryStore, InstrCategoryCSRAccess} &&
+ binsof(cp_stall_type_id) intersect {IdStallTypeLdHz});
+
+ // Cannot have a memory stall when we see an LS exception unless it is a load or store
+ // instruction or a fetch error (the raw instruction decode can still indicate a load or store
+ // which produces a stall, though won't cause any load or store to occur due to the fetch
+ // error).
+ illegal_bins mem_stall_illegal =
+ (!binsof(cp_id_instr_category) intersect {InstrCategoryLoad, InstrCategoryStore,
+ InstrCategoryFetchError} &&
+ binsof(cp_stall_type_id) intersect {IdStallTypeMem}) with
+ (cp_ls_pmp_exception == 1'b1 || cp_ls_error_exception == 1'b1);
+
+ // When pipeline has unstalled stall type will always be none
+ illegal_bins unstalled_illegal =
+ !binsof(cp_stall_type_id) intersect {IdStallTypeNone} with (instr_unstalled == 1'b1);
+ }
+
+ csr_read_only_priv_cross: cross cp_csr_read_only, cp_priv_mode_id;
+ csr_write_priv_cross: cross cp_csr_write, cp_priv_mode_id;
+
+ csr_read_only_debug_cross: cross cp_csr_read_only, cp_debug_mode {
+ // Only care about specific debug CSRs
+ ignore_bins ignore = !binsof(cp_csr_read_only) intersect {`DEBUG_CSRS};
+ }
+
+ csr_write_debug_cross: cross cp_csr_write, cp_debug_mode {
+ // Only care about specific debug CSRs
+ ignore_bins ignore = !binsof(cp_csr_write) intersect {`DEBUG_CSRS};
+ }
+
+ // V2S Crosses
+
+ dummy_instr_config_cross: cross cp_dummy_instr_type, cp_dummy_instr_mask
+ iff (cs_registers_i.dummy_instr_en_o);
+
+ rf_ecc_err_cross: cross fcov_rf_ecc_err_a_id, fcov_rf_ecc_err_b_id
+ iff (id_stage_i.instr_valid_i);
+
+ // Each stage sees a debug request while executing a dummy instruction.
+ debug_req_dummy_instr_if_stage_cross: cross cp_debug_req, cp_dummy_instr_if_stage;
+ debug_req_dummy_instr_id_stage_cross: cross cp_debug_req, cp_dummy_instr_id_stage;
+ debug_req_dummy_instr_wb_stage_cross: cross cp_debug_req, cp_dummy_instr_wb_stage;
+
+ // Each stage sees an interrupt request while executing a dummy instruction.
+ irq_pending_dummy_instr_if_stage_cross: cross cp_irq_pending, cp_dummy_instr_if_stage;
+ irq_pending_dummy_instr_id_stage_cross: cross cp_irq_pending, cp_dummy_instr_id_stage;
+ irq_pending_dummy_instr_wb_stage_cross: cross cp_irq_pending, cp_dummy_instr_wb_stage;
+
+ endgroup
+
+ bit en_uarch_cov;
+
+ initial begin
+ void'($value$plusargs("enable_ibex_fcov=%d", en_uarch_cov));
+ end
+
+ `DV_FCOV_INSTANTIATE_CG(uarch_cg, en_uarch_cov)
+endinterface
+
+interface mem_monitor_if (
+ input clk_i,
+ input rst_ni,
+
+ input req_i,
+ input gnt_i,
+ input rvalid_i,
+
+ output int outstanding_requests_o,
+ output logic single_cycle_response_o
+);
+
+ int outstanding_requests;
+ logic outstanding_requests_inc, outstanding_requests_dec;
+ logic no_outstanding_requests_last_cycle;
+
+ assign outstanding_requests_inc = req_i & gnt_i;
+ assign outstanding_requests_dec = rvalid_i;
+
+ always_ff @(posedge clk_i or negedge rst_ni) begin
+ if (~rst_ni) begin
+ outstanding_requests <= 0;
+ no_outstanding_requests_last_cycle <= 1'b0;
+ end else begin
+ if (outstanding_requests_inc && !outstanding_requests_dec) begin
+ outstanding_requests <= outstanding_requests + 1;
+ end else if (!outstanding_requests_inc && outstanding_requests_dec) begin
+ outstanding_requests <= outstanding_requests - 1;
+ end
+
+ no_outstanding_requests_last_cycle <= (outstanding_requests == 0) ||
+ ((outstanding_requests == 1) && outstanding_requests_dec);
+ end
+ end
+
+ assign outstanding_requests_o = outstanding_requests;
+ assign single_cycle_response_o = no_outstanding_requests_last_cycle & rvalid_i;
+endinterface
diff --git a/dv/uvm/core_ibex/fcov/core_ibex_pmp_fcov_if.sv b/dv/uvm/core_ibex/fcov/core_ibex_pmp_fcov_if.sv
new file mode 100644
index 00000000..4bd469eb
--- /dev/null
+++ b/dv/uvm/core_ibex/fcov/core_ibex_pmp_fcov_if.sv
@@ -0,0 +1,717 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+`include "prim_assert.sv"
+
+interface core_ibex_pmp_fcov_if import ibex_pkg::*; #(
+ parameter bit PMPEnable = 1'b0,
+ // Granularity of NAPOT access,
+ // 0 = No restriction, 1 = 8 byte, 2 = 16 byte, 3 = 32 byte, etc.
+ parameter int unsigned PMPGranularity = 0,
+ // Number of implemented regions
+ parameter int unsigned PMPNumRegions = 4
+) (
+ input clk_i,
+ input rst_ni,
+
+ input ibex_pkg::pmp_cfg_t csr_pmp_cfg [PMPNumRegions],
+ input logic[33:0] csr_pmp_addr [PMPNumRegions],
+ input logic pmp_req_err [3],
+ input pmp_mseccfg_t csr_pmp_mseccfg,
+
+ input logic data_req_out,
+
+ input fcov_csr_write
+);
+ localparam int unsigned PMPNumChan = 3;
+
+ `include "dv_fcov_macros.svh"
+ import uvm_pkg::*;
+
+ // Enum to give more readable coverage results for privilege bits. 4 bits are from the pmpcfg CSF
+ // (L, X, W, R) and the 5th is the MML bit. Setting the MML bit changes the meaning of the other
+ // 4 bits
+ typedef enum logic [4:0] {
+ NONE = 5'b00000,
+ R = 5'b00001,
+ W = 5'b00010,
+ WR = 5'b00011,
+ X = 5'b00100,
+ XR = 5'b00101,
+ XW = 5'b00110,
+ XWR = 5'b00111,
+ L = 5'b01000,
+ LR = 5'b01001,
+ LW = 5'b01010,
+ LWR = 5'b01011,
+ LX = 5'b01100,
+ LXR = 5'b01101,
+ LXW = 5'b01110,
+ LXWR = 5'b01111,
+ MML_NONE = 5'b10000,
+ MML_RU = 5'b10001,
+ MML_WRM_RU = 5'b10010,
+ MML_WRU = 5'b10011,
+ MML_XU = 5'b10100,
+ MML_XRU = 5'b10101,
+ MML_WRM_WRU = 5'b10110,
+ MML_XWRU = 5'b10111,
+ MML_L = 5'b11000,
+ MML_RM = 5'b11001,
+ MML_XM_XU = 5'b11010,
+ MML_WRM = 5'b11011,
+ MML_XM = 5'b11100,
+ MML_XRM = 5'b11101,
+ MML_XRM_XU = 5'b11110,
+ MML_RM_RU = 5'b11111
+ } pmp_priv_bits_e;
+
+ // Break out PMP signals into individually named signals for direct use in `cross` as it cannot
+ // deal with hierarchical references or unpacked arrays.
+ logic pmp_iside_req_err;
+ logic pmp_iside2_req_err;
+ logic pmp_dside_req_err;
+
+ assign pmp_iside_req_err = pmp_req_err[PMP_I];
+ assign pmp_iside2_req_err = pmp_req_err[PMP_I2];
+ assign pmp_dside_req_err = pmp_req_err[PMP_D];
+
+ logic [PMPNumRegions-1:0] current_priv_perm_check;
+ bit en_pmp_fcov;
+
+ logic csr_wdata_mseccfg_rlb;
+ logic csr_wdata_mseccfg_mmwp;
+ logic csr_wdata_mseccfg_mml;
+
+ assign csr_wdata_mseccfg_rlb = cs_registers_i.csr_wdata_int[CSR_MSECCFG_RLB_BIT];
+ assign csr_wdata_mseccfg_mmwp = cs_registers_i.csr_wdata_int[CSR_MSECCFG_MMWP_BIT];
+ assign csr_wdata_mseccfg_mml = cs_registers_i.csr_wdata_int[CSR_MSECCFG_MML_BIT];
+
+ initial begin
+ if (PMPEnable) begin
+ void'($value$plusargs("enable_ibex_fcov=%d", en_pmp_fcov));
+ end else begin
+ en_pmp_fcov = 1'b0;
+ end
+ end
+
+ if (PMPEnable) begin : g_pmp_cgs
+ logic [PMPNumRegions-1:0] pmp_iside_match;
+ logic [PMPNumRegions-1:0] pmp_iside2_match;
+ logic [PMPNumRegions-1:0] pmp_dside_match;
+ logic [PMPNumRegions-1:0] pmp_dside_match_last;
+
+ logic pmp_iside_nomatch;
+ logic pmp_iside2_nomatch;
+ logic pmp_dside_nomatch;
+
+ logic pmp_iside_boundary_cross;
+ logic pmp_dside_boundary_cross;
+
+ logic misaligned_pmp_err_last;
+
+ logic [31:0] pmp_addr_napot_valid [PMPNumRegions];
+
+ assign pmp_iside_match = g_pmp.pmp_i.region_match_all[PMP_I];
+ assign pmp_iside2_match = g_pmp.pmp_i.region_match_all[PMP_I2];
+ assign pmp_dside_match = g_pmp.pmp_i.region_match_all[PMP_D];
+
+ assign pmp_iside_nomatch = ~|pmp_iside_match;
+ assign pmp_iside2_nomatch = ~|pmp_iside2_match;
+ assign pmp_dside_nomatch = ~|pmp_dside_match;
+
+ // Store the Data Channel PMP match info from the first request to calculate boundary cross
+ always @(posedge clk_i or negedge rst_ni) begin
+ if (!rst_ni) begin
+ pmp_dside_match_last <= '0;
+ misaligned_pmp_err_last <= 1'b0;
+ end else if (load_store_unit_i.fcov_ls_first_req) begin
+ pmp_dside_match_last <= pmp_dside_match;
+ misaligned_pmp_err_last <= load_store_unit_i.data_pmp_err_i;
+ end
+ end
+
+ assign pmp_iside_boundary_cross = |(pmp_iside_match ^ pmp_iside2_match);
+ assign pmp_dside_boundary_cross = |(pmp_dside_match ^ pmp_dside_match_last) &
+ load_store_unit_i.fcov_ls_second_req;
+
+ for (genvar i_region = 0; i_region < PMPNumRegions; i_region += 1) begin : g_pmp_region_fcov
+ pmp_priv_bits_e pmp_region_priv_bits;
+ pmp_priv_bits_e pmp_region_priv_bits_wr;
+
+ assign pmp_region_priv_bits = pmp_priv_bits_e'({csr_pmp_mseccfg.mml,
+ csr_pmp_cfg[i_region].lock,
+ csr_pmp_cfg[i_region].exec,
+ csr_pmp_cfg[i_region].write,
+ csr_pmp_cfg[i_region].read});
+ assign pmp_region_priv_bits_wr =
+ pmp_priv_bits_e'({csr_pmp_mseccfg.mml,
+ cs_registers_i.g_pmp_registers.pmp_cfg_wdata[i_region].lock,
+ cs_registers_i.g_pmp_registers.pmp_cfg_wdata[i_region].exec,
+ cs_registers_i.g_pmp_registers.pmp_cfg_wdata[i_region].write,
+ cs_registers_i.g_pmp_registers.pmp_cfg_wdata[i_region].read});
+
+ // Do the permission check for Data channel with the privilege level from Instruction channels.
+ // This way we can check the effect of mstatus.mprv changing privilege levels for LSU related
+ // operations.
+ assign current_priv_perm_check[i_region] =
+ g_pmp.pmp_i.perm_check_wrapper(csr_pmp_mseccfg.mml,
+ csr_pmp_cfg[i_region],
+ g_pmp.pmp_i.pmp_req_type_i[PMP_D],
+ cs_registers_i.priv_mode_id_o,
+ g_pmp.pmp_i.region_basic_perm_check[PMP_D][i_region]);
+
+ // Each cycle this assignment creates either the value 0 if the mode is not NAPOT or 1 bit is
+ // set based on how large the NAPOT region is. The size of the NAPOT region is essentially
+ // encoded by how many consecutive ones there are after the last 0. This encoding is
+ // specified in the "Physical Memory Protection" section of the RISC-V privileged spec.
+ for (genvar i = 0; i < 32; i += 1) begin : g_pmp_napot_region_fcov
+ assign pmp_addr_napot_valid[i_region][i] = csr_pmp_cfg[i_region].mode == PMP_MODE_NAPOT &&
+ (csr_pmp_addr[i_region][i+2:2] == {1'b0, {i{1'b1}}});
+ end
+
+ covergroup pmp_region_cg @(posedge clk_i);
+ option.per_instance = 1;
+ option.name = "pmp_region_cg";
+
+ // This coverpoint converts pmp_add_napot_valid into 32 bins. The onehot call makes sure
+ // that when the entry is not in NAPOT mode, then no bin is selected. The clog2 call
+ // converts the value 0...010...0 to the index of the one bit that is set.
+ cp_napot_addr_modes : coverpoint $clog2(pmp_addr_napot_valid[i_region])
+ iff ($onehot(pmp_addr_napot_valid[i_region])) {
+ bins napot_addr[] = { [0:31] };
+ }
+
+ cp_warl_check_pmpcfg : coverpoint
+ g_pmp_fcov_signals.g_pmp_region_fcov[i_region].fcov_warl_check_pmpcfg;
+
+ cp_region_mode : coverpoint csr_pmp_cfg[i_region].mode;
+
+ cp_region_priv_bits : coverpoint pmp_region_priv_bits {
+ wildcard illegal_bins illegal = {5'b0??10};
+ }
+
+ cp_priv_lvl_iside : coverpoint g_pmp.pmp_priv_lvl[PMP_I] {
+ illegal_bins illegal = {PRIV_LVL_H, PRIV_LVL_S};
+ }
+
+ cp_req_type_iside : coverpoint g_pmp.pmp_req_type[PMP_I] {
+ illegal_bins illegal = {PMP_ACC_WRITE, PMP_ACC_READ};
+ }
+
+ cp_priv_lvl_iside2 : coverpoint g_pmp.pmp_priv_lvl[PMP_I2] {
+ illegal_bins illegal = {PRIV_LVL_H, PRIV_LVL_S};
+ }
+
+ cp_req_type_iside2 : coverpoint g_pmp.pmp_req_type[PMP_I2] {
+ illegal_bins illegal = {PMP_ACC_WRITE, PMP_ACC_READ};
+ }
+
+ cp_priv_lvl_dside : coverpoint g_pmp.pmp_priv_lvl[PMP_D] {
+ illegal_bins illegal = {PRIV_LVL_H, PRIV_LVL_S};
+ }
+
+ cp_req_type_dside : coverpoint g_pmp.pmp_req_type[PMP_D] {
+ illegal_bins illegal = {PMP_ACC_EXEC};
+ }
+
+ // Wildcards in crosses are not supported by VCS. As a workaround we are using `with`
+ // keyword and basic logic expressions to constraint the condition as appropriate.
+ pmp_iside_mode_cross : cross cp_region_mode, pmp_iside_req_err
+ iff (g_pmp_fcov_signals.g_pmp_region_fcov[i_region].fcov_pmp_region_ichan_access) {
+ illegal_bins illegal_off_mode_match = binsof(cp_region_mode) intersect {PMP_MODE_OFF};
+ }
+
+ pmp_iside2_mode_cross : cross cp_region_mode, pmp_iside2_req_err
+ iff (g_pmp_fcov_signals.g_pmp_region_fcov[i_region].fcov_pmp_region_ichan2_access) {
+ illegal_bins illegal_off_mode_match = binsof(cp_region_mode) intersect {PMP_MODE_OFF};
+ }
+
+ pmp_dside_mode_cross : cross cp_region_mode, pmp_dside_req_err
+ iff (g_pmp_fcov_signals.g_pmp_region_fcov[i_region].fcov_pmp_region_dchan_access) {
+ illegal_bins illegal_off_mode_match = binsof(cp_region_mode) intersect {PMP_MODE_OFF};
+ }
+
+ pmp_iside_priv_bits_cross :
+ cross cp_region_priv_bits, cp_req_type_iside, cp_priv_lvl_iside, pmp_iside_req_err
+ iff (g_pmp_fcov_signals.g_pmp_region_fcov[i_region].fcov_pmp_region_ichan_access &&
+ g_pmp_fcov_signals.fcov_pmp_region_ichan_priority[i_region] &&
+ csr_pmp_cfg[i_region].mode != PMP_MODE_OFF) {
+
+ // Will never see a succesful exec access when execute is disallowed
+ illegal_bins illegal_allow_exec =
+ // Ensuring MML is low and we are not in a X allowed configuration
+ (binsof(cp_region_priv_bits) intersect {NONE, R, W, WR, L, LR, LW, LWR} &&
+ binsof(cp_req_type_iside) intersect {PMP_ACC_EXEC} &&
+ binsof(pmp_iside_req_err) intersect {0}) with (cp_priv_lvl_iside == PRIV_LVL_U ||
+ (|(cp_region_priv_bits & 5'b01000)));
+ illegal_bins illegal_machine_allow_exec =
+ // Ensuring MML is high and we are not in a X allowed configuration in Machine Mode
+ (binsof(cp_region_priv_bits) intersect {MML_NONE, MML_RU, MML_WRM_RU, MML_WRU, MML_XU,
+ MML_XRU, MML_WRM_WRU, MML_XWRU, MML_L, MML_RM,
+ MML_WRM, MML_RM_RU} &&
+ binsof(cp_priv_lvl_iside) intersect {PRIV_LVL_M} &&
+ binsof(cp_req_type_iside) intersect {PMP_ACC_EXEC} &&
+ binsof(pmp_iside_req_err) intersect {0});
+ illegal_bins illegal_user_allow_exec =
+ // Ensuring MML is high and we are not in a X allowed configuration in User Mode
+ (binsof(cp_region_priv_bits) intersect {MML_NONE, MML_RU, MML_WRM_RU, MML_WRU,
+ MML_WRM_WRU, MML_L, MML_RM, MML_WRM,
+ MML_XM, MML_XRM, MML_RM_RU} &&
+ binsof(cp_priv_lvl_iside) intersect {PRIV_LVL_U} &&
+ binsof(cp_req_type_iside) intersect {PMP_ACC_EXEC} &&
+ binsof(pmp_iside_req_err) intersect {0});
+ // Will never see an exec access denied when executed is allowed
+ illegal_bins illegal_deny_exec =
+ // Ensuring MML is low and we are in a X allowed configuration
+ (binsof(cp_req_type_iside) intersect {PMP_ACC_EXEC} &&
+ binsof(cp_region_priv_bits) intersect {X, XW, XR, XWR, LX, LXW, LXR, LXWR} &&
+ binsof(pmp_iside_req_err) intersect {1});
+ illegal_bins illegal_deny_exec_machine_unlocked =
+ // Ensuring in machine mode when MML is low, we are in X allowed configuration
+ (binsof(cp_region_priv_bits) intersect {R, W, WR} &&
+ binsof(cp_req_type_iside) intersect {PMP_ACC_EXEC} &&
+ binsof(cp_priv_lvl_iside) intersect {PRIV_LVL_M} &&
+ binsof(pmp_iside_req_err) intersect {1});
+ illegal_bins illegal_machine_deny_exec =
+ // Ensuring MML is high and we are in a X allowed configuration in Machine Mode
+ (binsof(cp_region_priv_bits) intersect {NONE, MML_XM_XU, MML_XRM_XU, MML_XRM,
+ MML_XM} &&
+ binsof(cp_priv_lvl_iside) intersect {PRIV_LVL_M} &&
+ binsof(cp_req_type_iside) intersect {PMP_ACC_EXEC} &&
+ binsof(pmp_iside_req_err) intersect {1});
+ illegal_bins illegal_user_deny_exec =
+ // Ensuring MML is high and we are in a X allowed configuration in User Mode
+ (binsof(cp_region_priv_bits) intersect {MML_XM_XU, MML_XRM_XU, MML_XRU, MML_XU,
+ MML_XWRU} &&
+ binsof(cp_priv_lvl_iside) intersect {PRIV_LVL_U} &&
+ binsof(cp_req_type_iside) intersect {PMP_ACC_EXEC} &&
+ binsof(pmp_iside_req_err) intersect {1});
+ }
+
+ pmp_iside2_priv_bits_cross :
+ cross cp_region_priv_bits, cp_req_type_iside2, cp_priv_lvl_iside2, pmp_iside2_req_err
+ iff (g_pmp_fcov_signals.g_pmp_region_fcov[i_region].fcov_pmp_region_ichan2_access &&
+ g_pmp_fcov_signals.fcov_pmp_region_ichan2_priority[i_region] &&
+ csr_pmp_cfg[i_region].mode != PMP_MODE_OFF) {
+
+ // Will never see a succesful exec access when execute is disallowed
+ illegal_bins illegal_allow_exec =
+ // Ensuring MML is low and we are not in a X allowed configuration
+ (binsof(cp_region_priv_bits) intersect {NONE, R, W, WR, L, LR, LW, LWR} &&
+ binsof(cp_req_type_iside2) intersect {PMP_ACC_EXEC} &&
+ binsof(pmp_iside2_req_err) intersect {0}) with (cp_priv_lvl_iside2 == PRIV_LVL_U ||
+ (cp_region_priv_bits & 5'b01000));
+ illegal_bins illegal_machine_allow_exec =
+ // Ensuring MML is high and we are not in a X allowed configuration in Machine Mode
+ (binsof(cp_region_priv_bits) intersect {MML_NONE, MML_RU, MML_WRM_RU, MML_WRU, MML_XU,
+ MML_XRU, MML_WRM_WRU, MML_XWRU, MML_L, MML_RM,
+ MML_WRM, MML_RM_RU} &&
+ binsof(cp_priv_lvl_iside2) intersect {PRIV_LVL_M} &&
+ binsof(cp_req_type_iside2) intersect {PMP_ACC_EXEC} &&
+ binsof(pmp_iside2_req_err) intersect {0});
+ illegal_bins illegal_user_allow_exec =
+ // Ensuring MML is high and we are not in a X allowed configuration in User Mode
+ (binsof(cp_region_priv_bits) intersect {MML_NONE, MML_RU, MML_WRM_RU, MML_WRU,
+ MML_WRM_WRU, MML_L, MML_RM, MML_WRM,
+ MML_XM, MML_XRM, MML_RM_RU} &&
+ binsof(cp_priv_lvl_iside2) intersect {PRIV_LVL_U} &&
+ binsof(cp_req_type_iside2) intersect {PMP_ACC_EXEC} &&
+ binsof(pmp_iside2_req_err) intersect {0});
+
+ // Will never see an exec access denied when execute is allowed
+ illegal_bins illegal_deny_exec =
+ // Ensuring MML is low and we are in a X allowed configuration
+ (binsof(cp_region_priv_bits) intersect {X, XW, XR, XWR, LX, LXW, LXR, LXWR} &&
+ binsof(cp_req_type_iside2) intersect {PMP_ACC_EXEC} &&
+ binsof(pmp_iside2_req_err) intersect {1});
+ illegal_bins illegal_deny_exec_machine_unlocked =
+ // Ensuring in machine mode when MML is low, we are in X allowed configuration
+ (binsof(cp_region_priv_bits) intersect {R, W, WR} &&
+ binsof(cp_req_type_iside2) intersect {PMP_ACC_EXEC} &&
+ binsof(cp_priv_lvl_iside2) intersect {PRIV_LVL_M} &&
+ binsof(pmp_iside2_req_err) intersect {1});
+ illegal_bins illegal_machine_deny_exec =
+ // Ensuring MML is high and we are in a X allowed configuration in Machine Mode
+ (binsof(cp_region_priv_bits) intersect {NONE, MML_XM_XU, MML_XRM_XU, MML_XRM, MML_XM} &&
+ binsof(cp_priv_lvl_iside2) intersect {PRIV_LVL_M} &&
+ binsof(cp_req_type_iside2) intersect {PMP_ACC_EXEC} &&
+ binsof(pmp_iside2_req_err) intersect {1});
+ illegal_bins illegal_user_deny_exec =
+ // Ensuring MML is high and we are in a X allowed configuration in User Mode
+ (binsof(cp_region_priv_bits) intersect {MML_XM_XU, MML_XRM_XU, MML_XRU, MML_XU,
+ MML_XWRU} &&
+ binsof(cp_priv_lvl_iside2) intersect {PRIV_LVL_U} &&
+ binsof(cp_req_type_iside2) intersect {PMP_ACC_EXEC} &&
+ binsof(pmp_iside2_req_err) intersect {1});
+ }
+
+ pmp_dside_priv_bits_cross :
+ cross cp_region_priv_bits, cp_req_type_dside, cp_priv_lvl_dside, pmp_dside_req_err
+ iff (g_pmp_fcov_signals.g_pmp_region_fcov[i_region].fcov_pmp_region_dchan_access &&
+ g_pmp_fcov_signals.fcov_pmp_region_dchan_priority[i_region] &&
+ csr_pmp_cfg[i_region].mode != PMP_MODE_OFF) {
+
+ // Will never see a succesful read access when read is disallowed
+ illegal_bins illegal_allow_read =
+ // Ensuring MML is low and we are not in a R allowed configuration
+ (binsof(cp_region_priv_bits) intersect {NONE, W, X, XW, L, LW, LX, LXW} &&
+ binsof(cp_req_type_dside) intersect {PMP_ACC_READ} &&
+ binsof(pmp_dside_req_err) intersect {0})
+ with (cp_priv_lvl_dside == PRIV_LVL_U || (cp_region_priv_bits & 5'b01000));
+ illegal_bins illegal_machine_allow_read =
+ // Ensuring MML is high and we are not in a R allowed configuration in Machine Mode
+ (binsof(cp_region_priv_bits) intersect {MML_NONE, MML_RU, MML_WRU, MML_XU, MML_XRU,
+ MML_XWRU, MML_L, MML_XM_XU, MML_XM} &&
+ binsof(cp_priv_lvl_dside) intersect {PRIV_LVL_M} &&
+ binsof(cp_req_type_dside) intersect {PMP_ACC_READ} &&
+ binsof(pmp_dside_req_err) intersect {0});
+ illegal_bins illegal_user_allow_read =
+ // Ensuring MML is high and we are not in a R allowed configuration in User Mode
+ (binsof(cp_region_priv_bits) intersect {MML_NONE, MML_XU, MML_L, MML_RM, MML_XM_XU,
+ MML_WRM, MML_XM, MML_XRM, MML_XRM_XU} &&
+ binsof(cp_priv_lvl_dside) intersect {PRIV_LVL_U} &&
+ binsof(cp_req_type_dside) intersect {PMP_ACC_READ} &&
+ binsof(pmp_dside_req_err) intersect {0});
+
+ // Will never see a read access denied when read is allowed
+ illegal_bins illegal_deny_read =
+ // Ensuring MML is low and we are in a R allowed configuration
+ (binsof(cp_region_priv_bits) intersect {R, WR, XR, XWR, LR, LWR, LXR, LXWR} &&
+ binsof(cp_req_type_dside) intersect {PMP_ACC_READ} &&
+ binsof(pmp_dside_req_err) intersect {1});
+ illegal_bins illegal_machine_deny_read =
+ // Ensuring MML is high and we are in a R allowed configuration in Machine Mode
+ (binsof(cp_region_priv_bits) intersect {MML_WRM_RU, MML_WRM_WRU, MML_RM_RU, MML_RM,
+ MML_WRM, MML_XRM, MML_XRM_XU, NONE,
+ W, X, XW} &&
+ binsof(cp_priv_lvl_dside) intersect {PRIV_LVL_M} &&
+ binsof(cp_req_type_dside) intersect {PMP_ACC_READ} &&
+ binsof(pmp_dside_req_err) intersect {1});
+ illegal_bins illegal_user_deny_read =
+ // Ensuring MML is high and we are not in a R allowed configuration in User Mode
+ (binsof(cp_region_priv_bits) intersect {MML_WRM_RU, MML_WRM_WRU, MML_RM_RU, MML_RU,
+ MML_WRU, MML_XRU, MML_XWRU} &&
+ binsof(cp_priv_lvl_dside) intersect {PRIV_LVL_U} &&
+ binsof(cp_req_type_dside) intersect {PMP_ACC_READ} &&
+ binsof(pmp_dside_req_err) intersect {1});
+
+ // Will never see a succesful write access when write is disallowed
+ illegal_bins illegal_allow_write =
+ // Ensuring MML is low and we are not in a W allowed configuration
+ (binsof(cp_region_priv_bits) intersect {NONE, R, X, XR, L, LR, LX, LXR} &&
+ binsof(cp_req_type_dside) intersect {PMP_ACC_WRITE} &&
+ binsof(pmp_dside_req_err) intersect {0})
+ with (cp_priv_lvl_dside == PRIV_LVL_U || (cp_region_priv_bits & 5'b01000));
+ illegal_bins illegal_machine_allow_write =
+ // Ensuring MML is high and we are not in a W allowed configuration in Machine Mode
+ (binsof(cp_region_priv_bits) intersect {MML_NONE, MML_RU, MML_WRU, MML_XU, MML_XRU,
+ MML_XWRU, MML_L, MML_RM, MML_XM_XU, MML_XM,
+ MML_XRM, MML_XRM_XU, MML_RM_RU} &&
+ binsof(cp_priv_lvl_dside) intersect {PRIV_LVL_M} &&
+ binsof(cp_req_type_dside) intersect {PMP_ACC_WRITE} &&
+ binsof(pmp_dside_req_err) intersect {0});
+ illegal_bins illegal_user_allow_write =
+ // Ensuring MML is high and we are not in a W allowed configuration in User Mode
+ (binsof(cp_region_priv_bits) intersect {MML_NONE, MML_RU, MML_WRM_RU, MML_XU, MML_XRU,
+ MML_L, MML_RM, MML_XM_XU, MML_WRM, MML_XM,
+ MML_XRM, MML_XRM_XU, MML_RM_RU} &&
+ binsof(cp_priv_lvl_dside) intersect {PRIV_LVL_U} &&
+ binsof(cp_req_type_dside) intersect {PMP_ACC_WRITE} &&
+ binsof(pmp_dside_req_err) intersect {0});
+
+ // Will never see a write access denied when write is allowed
+ illegal_bins illegal_deny_write =
+ // Ensuring MML is low and we are in a W allowed configuration
+ (binsof(cp_region_priv_bits) intersect {W, WR, XW, XWR, LW, LWR, LXW, LXWR} &&
+ binsof(cp_req_type_dside) intersect {PMP_ACC_WRITE} &&
+ binsof(pmp_dside_req_err) intersect {1});
+ illegal_bins illegal_machine_deny_write =
+ // Ensuring MML is high and we are in a W allowed configuration in Machine Mode
+ (binsof(cp_region_priv_bits) intersect {MML_WRM_WRU, MML_WRM_RU, MML_WRM, NONE,
+ R, X, XR, XW} &&
+ binsof(cp_priv_lvl_dside) intersect {PRIV_LVL_M} &&
+ binsof(cp_req_type_dside) intersect {PMP_ACC_WRITE} &&
+ binsof(pmp_dside_req_err) intersect {1});
+ // Ensuring MML is high and we are in a W allowed configuration in User Mode
+ illegal_bins illegal_user_deny_write =
+ (binsof(cp_region_priv_bits) intersect {MML_WRM_WRU, MML_WRU, MML_XWRU} &&
+ binsof(cp_priv_lvl_dside) intersect {PRIV_LVL_U} &&
+ binsof(cp_req_type_dside) intersect {PMP_ACC_WRITE} &&
+ binsof(pmp_dside_req_err) intersect {1});
+ }
+
+ `DV_FCOV_EXPR_SEEN(edit_locked_pmpcfg,
+ fcov_csr_write &&
+ csr_pmp_cfg[i_region].lock &&
+ cs_registers_i.g_pmp_registers.g_pmp_csrs[i_region].u_pmp_cfg_csr.wr_en_i &&
+ csr_pmp_mseccfg.rlb)
+
+ `DV_FCOV_EXPR_SEEN(edit_locked_pmpaddr,
+ fcov_csr_write &&
+ csr_pmp_cfg[i_region].lock &&
+ cs_registers_i.g_pmp_registers.g_pmp_csrs[i_region].u_pmp_addr_csr.wr_en_i &&
+ csr_pmp_mseccfg.rlb)
+
+ // Only sample this cross when we attempt to write to a PMP config that doesn't currently
+ // allow execution with MML enabled
+ pmp_wr_exec_region :
+ cross pmp_region_priv_bits, pmp_region_priv_bits_wr, csr_pmp_mseccfg.rlb iff
+ (fcov_csr_write &&
+ csr_pmp_mseccfg.mml &&
+ cs_registers_i.csr_we_int &&
+ cs_registers_i.csr_addr == (CSR_OFF_PMP_CFG + (i_region[11:0] >> 2)) &&
+ ((!pmp_region_priv_bits[2] && pmp_region_priv_bits != MML_XM_XU) ||
+ pmp_region_priv_bits inside {MML_WRM_WRU, MML_RM_RU})) {
+
+ // Only interested in MML configuration, so ignore anything where the top bit is not set
+ ignore_bins non_mml_in =
+ binsof(pmp_region_priv_bits) with (pmp_region_priv_bits >> 4 == 5'b0);
+
+ ignore_bins non_mml_out =
+ binsof(pmp_region_priv_bits_wr) with (pmp_region_priv_bits_wr >> 4 == 5'b0);
+
+ // Only interested in starting configs that weren't executable so ignore executable
+ // regions
+ ignore_bins from_exec_bins = binsof(pmp_region_priv_bits) intersect {MML_XU, MML_XRU,
+ MML_XWRU, MML_XM_XU, MML_XM, MML_XRM, MML_XRM_XU};
+
+ // Only interested in writes that give executable regions so ignore non executable regions
+ ignore_bins to_non_exec_bins = binsof(pmp_region_priv_bits_wr) intersect {MML_NONE,
+ MML_RU, MML_WRM_RU, MML_WRU, MML_WRM_WRU, MML_L, MML_RM, MML_WRM, MML_RM_RU};
+ }
+ endgroup
+
+ `DV_FCOV_INSTANTIATE_CG(pmp_region_cg, en_pmp_fcov)
+ end
+
+ // Current Priv means the privilege level of Instruction channels and Ibex in general. Note that
+ // the privilege level of PMP data channel can be set something different than this using MSTATUS.MPRV
+ // and MSTATUS.MPP.
+ logic pmp_current_priv_req_err;
+ assign pmp_current_priv_req_err =
+ g_pmp.pmp_i.access_fault_check(csr_pmp_mseccfg.mmwp,
+ csr_pmp_mseccfg.mml,
+ g_pmp.pmp_i.pmp_req_type_i[PMP_D],
+ g_pmp.pmp_i.region_match_all[PMP_D],
+ cs_registers_i.priv_mode_id_o,
+ current_priv_perm_check);
+
+ covergroup pmp_top_cg @(posedge clk_i);
+ option.per_instance = 1;
+ option.name = "pmp_top_cg";
+
+ cp_rlb : coverpoint csr_pmp_mseccfg.rlb{
+ bins on = {1'b1};
+ bins off = {1'b0};
+ }
+
+ cp_mmwp : coverpoint csr_pmp_mseccfg.mmwp{
+ bins on = {1'b1};
+ bins off = {1'b0};
+ }
+
+ cp_mml : coverpoint csr_pmp_mseccfg.mml{
+ bins on = {1'b1};
+ bins off = {1'b0};
+ }
+
+ cp_wdata_rlb: coverpoint csr_wdata_mseccfg_rlb{
+ bins on = {1'b1};
+ bins off = {1'b0};
+ }
+
+ cp_wdata_mmwp: coverpoint csr_wdata_mseccfg_mmwp{
+ bins on = {1'b1};
+ bins off = {1'b0};
+ }
+
+ cp_wdata_mml: coverpoint csr_wdata_mseccfg_mml{
+ bins on = {1'b1};
+ bins off = {1'b0};
+ }
+
+ //////// Redundant coverpoints for nomatch crosses ///////////
+ cp_priv_lvl_iside : coverpoint g_pmp.pmp_priv_lvl[PMP_I] {
+ illegal_bins illegal = {PRIV_LVL_H, PRIV_LVL_S};
+ }
+
+ cp_req_type_iside : coverpoint g_pmp.pmp_req_type[PMP_I] {
+ illegal_bins illegal = {PMP_ACC_WRITE, PMP_ACC_READ};
+ }
+
+ cp_priv_lvl_iside2 : coverpoint g_pmp.pmp_priv_lvl[PMP_I2] {
+ illegal_bins illegal = {PRIV_LVL_H, PRIV_LVL_S};
+ }
+
+ cp_req_type_iside2 : coverpoint g_pmp.pmp_req_type[PMP_I2] {
+ illegal_bins illegal = {PMP_ACC_WRITE, PMP_ACC_READ};
+ }
+
+ cp_priv_lvl_dside : coverpoint g_pmp.pmp_priv_lvl[PMP_D] {
+ illegal_bins illegal = {PRIV_LVL_H, PRIV_LVL_S};
+ }
+
+ cp_req_type_dside : coverpoint g_pmp.pmp_req_type[PMP_D] {
+ illegal_bins illegal = {PMP_ACC_EXEC};
+ }
+ //////////////////////////////////////////////////////////////
+
+ rlb_csr_cross : cross cp_rlb, cp_wdata_rlb
+ iff (fcov_csr_write && cs_registers_i.csr_addr_i == CSR_MSECCFG) {
+ // Trying to enable RLB when RLB is disabled and locked regions present will result
+ // with an ignored write
+ bins sticky = binsof(cp_rlb) intersect {0} && binsof(cp_wdata_rlb) intersect {1}
+ iff (cs_registers_i.g_pmp_registers.any_pmp_entry_locked);
+ }
+
+ mmwp_csr_cross : cross cp_mmwp, cp_wdata_mmwp
+ iff (fcov_csr_write && cs_registers_i.csr_addr_i == CSR_MSECCFG) {
+ bins sticky = binsof(cp_wdata_mmwp) intersect {0} && binsof(cp_mmwp) intersect {1};
+ }
+
+ mml_sticky_cross : cross cp_mml, cp_wdata_mml
+ iff (fcov_csr_write && cs_registers_i.csr_addr_i == CSR_MSECCFG) {
+ bins sticky = binsof(cp_wdata_mml) intersect {0} && binsof(cp_mml) intersect {1};
+ }
+
+ pmp_iside_nomatch_cross :
+ cross cp_req_type_iside, cp_priv_lvl_iside, pmp_iside_req_err, cp_mmwp, cp_mml
+ iff (pmp_iside_nomatch) {
+ // Will never see a succesful exec access when execute is disallowed
+ illegal_bins illegal_user_allow_exec =
+ // In User mode - no match case, we should always deny
+ (binsof(cp_priv_lvl_iside) intersect {PRIV_LVL_U} &&
+ binsof(cp_req_type_iside) intersect {PMP_ACC_EXEC} &&
+ binsof(pmp_iside_req_err) intersect {0});
+ illegal_bins illegal_machine_allow_exec =
+ // In Machine mode - no match case, we should deny always except MML=0 & MMWP=0
+ (binsof(cp_priv_lvl_iside) intersect {PRIV_LVL_M} &&
+ binsof(cp_req_type_iside) intersect {PMP_ACC_EXEC} &&
+ (binsof(cp_mmwp) intersect {1} ||
+ binsof(cp_mml) intersect {1}) &&
+ binsof(pmp_iside_req_err) intersect {0});
+ // Will never see an exec access denied when executed is ignored
+ illegal_bins illegal_deny_exec =
+ // Ignore Exec in MML=0, MMWP=0 and in Machine mode
+ (binsof(cp_priv_lvl_iside) intersect {PRIV_LVL_M} &&
+ binsof(cp_req_type_iside) intersect {PMP_ACC_EXEC} &&
+ binsof(cp_mmwp) intersect {0} &&
+ binsof(cp_mml) intersect {0} &&
+ binsof(pmp_iside_req_err) intersect {1});
+ }
+
+ pmp_iside2_nomatch_cross :
+ cross cp_req_type_iside2, cp_priv_lvl_iside2, pmp_iside2_req_err, cp_mmwp, cp_mml
+ iff (pmp_iside2_nomatch) {
+ // Will never see a succesful exec access when execute is disallowed
+ illegal_bins illegal_user_allow_exec =
+ // In User mode - no match case, we should always deny
+ (binsof(cp_priv_lvl_iside2) intersect {PRIV_LVL_U} &&
+ binsof(cp_req_type_iside2) intersect {PMP_ACC_EXEC} &&
+ binsof(pmp_iside2_req_err) intersect {0});
+ illegal_bins illegal_machine_allow_exec =
+ // In Machine mode - no match case, we should deny always except MML=0 & MMWP=0
+ (binsof(cp_priv_lvl_iside2) intersect {PRIV_LVL_M} &&
+ binsof(cp_req_type_iside2) intersect {PMP_ACC_EXEC} &&
+ (binsof(cp_mmwp) intersect {1} ||
+ binsof(cp_mml) intersect {1}) &&
+ binsof(pmp_iside2_req_err) intersect {0});
+ // Will never see an exec access denied when executed is ignored
+ illegal_bins illegal_deny_exec =
+ // Ignore Exec in MML=0, MMWP=0 and in Machine mode
+ (binsof(cp_priv_lvl_iside2) intersect {PRIV_LVL_M} &&
+ binsof(cp_req_type_iside2) intersect {PMP_ACC_EXEC} &&
+ binsof(cp_mmwp) intersect {0} &&
+ binsof(cp_mml) intersect {0} &&
+ binsof(pmp_iside2_req_err) intersect {1});
+ }
+
+ pmp_dside_nomatch_cross :
+ cross cp_req_type_dside, cp_priv_lvl_dside, pmp_dside_req_err, cp_mmwp, cp_mml
+ iff (pmp_dside_nomatch) {
+
+ // Will never see a succesful write/read access when it should be denied
+ illegal_bins illegal_machine_allow_wr =
+ // Deny WR when MMWP = 1 in Machine mode
+ (binsof(cp_priv_lvl_dside) intersect {PRIV_LVL_M} &&
+ binsof(cp_req_type_dside) intersect {PMP_ACC_READ, PMP_ACC_WRITE} &&
+ binsof(cp_mmwp) intersect {1} &&
+ binsof(pmp_dside_req_err) intersect {0});
+ illegal_bins illegal_user_allow_wr =
+ // Deny WR everytime in User mode
+ (binsof(cp_priv_lvl_dside) intersect {PRIV_LVL_U} &&
+ binsof(cp_req_type_dside) intersect {PMP_ACC_READ, PMP_ACC_WRITE} &&
+ binsof(pmp_dside_req_err) intersect {0});
+
+ // Will never see a write/read access denied when write/read is ignored
+ illegal_bins illegal_deny_wr =
+ // Ignore WR when MMWP = 0 in Machine mode
+ (binsof(cp_priv_lvl_dside) intersect {PRIV_LVL_M} &&
+ binsof(cp_req_type_dside) intersect {PMP_ACC_READ, PMP_ACC_WRITE} &&
+ binsof(cp_mmwp) intersect {0} &&
+ binsof(pmp_dside_req_err) intersect {1});
+ }
+
+ cp_pmp_iside_region_override :
+ coverpoint g_pmp.pmp_i.g_access_check[PMP_I].fcov_pmp_region_override
+ iff (if_stage_i.if_id_pipe_reg_we);
+
+ cp_pmp_iside2_region_override :
+ coverpoint g_pmp.pmp_i.g_access_check[PMP_I2].fcov_pmp_region_override
+ iff (if_stage_i.if_id_pipe_reg_we);
+
+ cp_pmp_dside_region_override :
+ coverpoint g_pmp.pmp_i.g_access_check[PMP_D].fcov_pmp_region_override iff (data_req_out);
+
+ cp_mprv: coverpoint cs_registers_i.mstatus_q.mprv;
+
+ mprv_effect_cross: cross cs_registers_i.mstatus_q.mpp,
+ cs_registers_i.priv_mode_id_o, pmp_current_priv_req_err,
+ pmp_dside_req_err iff
+ (id_stage_i.instr_rdata_i[6:0] inside
+ {ibex_pkg::OPCODE_LOAD, ibex_pkg::OPCODE_STORE} &&
+ cs_registers_i.mstatus_q.mprv){
+ ignore_bins SamePriv =
+ (binsof(cs_registers_i.mstatus_q.mpp) intersect {PRIV_LVL_M} &&
+ binsof(cs_registers_i.priv_mode_id_o) intersect {PRIV_LVL_M}) ||
+ (binsof(cs_registers_i.mstatus_q.mpp) intersect {PRIV_LVL_U} &&
+ binsof(cs_registers_i.priv_mode_id_o) intersect {PRIV_LVL_U});
+
+ ignore_bins SameErr =
+ (binsof(pmp_current_priv_req_err) intersect {0} &&
+ binsof(pmp_dside_req_err) intersect {0}) ||
+ (binsof(pmp_current_priv_req_err) intersect {1} &&
+ binsof(pmp_dside_req_err) intersect {1});
+
+ // Ibex does not support H or S mode.
+ ignore_bins unsupported_priv_lvl =
+ binsof(cs_registers_i.mstatus_q.mpp) intersect {PRIV_LVL_H, PRIV_LVL_S} ||
+ binsof(cs_registers_i.priv_mode_id_o) intersect {PRIV_LVL_H, PRIV_LVL_S};
+
+ // Cannot have mprv set in U mode (as it is cleared when executing an `mret` which takes the
+ // hart into U mode).
+ illegal_bins no_mrpv_in_umode =
+ binsof(cs_registers_i.priv_mode_id_o) intersect {PRIV_LVL_U};
+ }
+
+ pmp_instr_edge_cross: cross if_stage_i.instr_is_compressed_out,
+ pmp_iside_req_err, pmp_iside2_req_err
+ iff (pmp_iside_boundary_cross) {
+ // Compressed instruction cannot see an error over the boundary as it only ever does
+ // a single 16-bit fetch.
+ illegal_bins no_iside2_err_on_compressed =
+ binsof(if_stage_i.instr_is_compressed_out) intersect {1'b1} &&
+ binsof(pmp_iside2_req_err) intersect {1'b1};
+ }
+
+ misaligned_lsu_access_cross: cross misaligned_pmp_err_last,
+ load_store_unit_i.fcov_ls_mis_pmp_err_2
+ iff (pmp_dside_boundary_cross);
+ endgroup
+
+ `DV_FCOV_INSTANTIATE_CG(pmp_top_cg, en_pmp_fcov)
+ end
+
+endinterface
diff --git a/dv/uvm/core_ibex/ibex_dv.f b/dv/uvm/core_ibex/ibex_dv.f
index 08bab062..c8ec489e 100644
--- a/dv/uvm/core_ibex/ibex_dv.f
+++ b/dv/uvm/core_ibex/ibex_dv.f
@@ -2,31 +2,75 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
-// Boot address specified in decimal to avoid single quote in number, which
-// causes parsing errors of this file in Riviera.
-+define+BOOT_ADDR=2147483648 // 32'h8000_0000
+// The boot address is specified as a hex number and is used in SystemVerilog
+// code like this: 32'h `BOOT_ADDR.
+//
+// We can't put a ' character in the constant, because Riviera's TCL machinery
+// doesn't support them in defines. We also can't just use the decimal value
+// (2147483648), because an undecorated integer literal is interpreted as a
+// signed 32-bit integer.
++define+BOOT_ADDR=8000_0000
+define+TRACE_EXECUTION
+define+RVFI
-
-// Shared lowRISC code
-+incdir+${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl
-${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_assert.sv
-${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_lfsr.sv
-${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_secded_28_22_enc.sv
-${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_secded_28_22_dec.sv
-${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_secded_39_32_enc.sv
-${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_secded_39_32_dec.sv
-${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_secded_72_64_enc.sv
-${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_secded_72_64_dec.sv
++define+UVM
// Until this list is generated by FuseSoC, we have to use manually generated
// wrappers around the prim_* modules to instantiate the prim_generic_* ones,
// see https://github.com/lowRISC/ibex/issues/893.
++incdir+${LOWRISC_IP_DIR}/ip/prim/rtl
${PRJ_DIR}/dv/uvm/core_ibex/common/prim/prim_pkg.sv
-${PRJ_DIR}/vendor/lowrisc_ip/ip/prim_generic/rtl/prim_generic_ram_1p.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_assert.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_util_pkg.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_count_pkg.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_count.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_pkg.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_22_16_dec.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_22_16_enc.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_64_57_dec.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_64_57_enc.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_hamming_22_16_dec.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_hamming_22_16_enc.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_hamming_39_32_dec.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_hamming_39_32_enc.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_hamming_72_64_dec.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_hamming_72_64_enc.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_mubi_pkg.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_ram_1p_pkg.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_ram_1p_adv.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_ram_1p_scr.sv
+${LOWRISC_IP_DIR}/ip/prim_generic/rtl/prim_generic_ram_1p.sv
${PRJ_DIR}/dv/uvm/core_ibex/common/prim/prim_ram_1p.sv
-${PRJ_DIR}/vendor/lowrisc_ip/ip/prim_generic/rtl/prim_generic_clock_gating.sv
+${LOWRISC_IP_DIR}/ip/prim_generic/rtl/prim_generic_clock_gating.sv
${PRJ_DIR}/dv/uvm/core_ibex/common/prim/prim_clock_gating.sv
+${LOWRISC_IP_DIR}/ip/prim_generic/rtl/prim_generic_buf.sv
+${PRJ_DIR}/dv/uvm/core_ibex/common/prim/prim_buf.sv
+${LOWRISC_IP_DIR}/ip/prim_generic/rtl/prim_generic_clock_mux2.sv
+${PRJ_DIR}/dv/uvm/core_ibex/common/prim/prim_clock_mux2.sv
+${LOWRISC_IP_DIR}/ip/prim_generic/rtl/prim_generic_flop.sv
+${PRJ_DIR}/dv/uvm/core_ibex/common/prim/prim_flop.sv
+${LOWRISC_IP_DIR}/ip/prim_generic/rtl/prim_generic_and2.sv
+${PRJ_DIR}/dv/uvm/core_ibex/common/prim/prim_and2.sv
+
+// Shared lowRISC code
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_cipher_pkg.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_lfsr.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_inv_28_22_enc.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_inv_28_22_dec.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_inv_39_32_enc.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_inv_39_32_dec.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_inv_72_64_enc.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_inv_72_64_dec.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_prince.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_subst_perm.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_28_22_enc.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_28_22_dec.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_39_32_enc.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_39_32_dec.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_72_64_enc.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_secded_72_64_dec.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_onehot_check.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_onehot_enc.sv
+${LOWRISC_IP_DIR}/ip/prim/rtl/prim_onehot_mux.sv
// ibex CORE RTL files
+incdir+${PRJ_DIR}/rtl
@@ -48,6 +92,7 @@ ${PRJ_DIR}/rtl/ibex_id_stage.sv
${PRJ_DIR}/rtl/ibex_icache.sv
${PRJ_DIR}/rtl/ibex_if_stage.sv
${PRJ_DIR}/rtl/ibex_load_store_unit.sv
+${PRJ_DIR}/rtl/ibex_lockstep.sv
${PRJ_DIR}/rtl/ibex_multdiv_slow.sv
${PRJ_DIR}/rtl/ibex_multdiv_fast.sv
${PRJ_DIR}/rtl/ibex_prefetch_buffer.sv
@@ -57,32 +102,56 @@ ${PRJ_DIR}/rtl/ibex_register_file_fpga.sv
${PRJ_DIR}/rtl/ibex_register_file_latch.sv
${PRJ_DIR}/rtl/ibex_pmp.sv
${PRJ_DIR}/rtl/ibex_core.sv
-${PRJ_DIR}/rtl/ibex_core_tracing.sv
+${PRJ_DIR}/rtl/ibex_top.sv
+${PRJ_DIR}/rtl/ibex_top_tracing.sv
// Core DV files
++incdir+${PRJ_DIR}/dv/uvm/core_ibex/common
+${PRJ_DIR}/dv/uvm/core_ibex/common/date.c
${PRJ_DIR}/vendor/google_riscv-dv/src/riscv_signature_pkg.sv
++incdir+${LOWRISC_IP_DIR}/dv/sv/dv_utils
++incdir+${LOWRISC_IP_DIR}/dv/sv/dv_base_reg
++incdir+${LOWRISC_IP_DIR}/dv/sv/csr_utils
++incdir+${LOWRISC_IP_DIR}/dv/sv/dv_lib
++incdir+${LOWRISC_IP_DIR}/dv/sv/mem_model
++incdir+${LOWRISC_IP_DIR}/dv/sv/push_pull_agent
++incdir+${LOWRISC_IP_DIR}/dv/sv/push_pull_agent/seq_lib
++incdir+${LOWRISC_IP_DIR}/dv/sv/str_utils
+incdir+${PRJ_DIR}/dv/uvm/core_ibex/env
++incdir+${PRJ_DIR}/dv/uvm/core_ibex/fcov
+incdir+${PRJ_DIR}/dv/uvm/core_ibex/tests
+incdir+${PRJ_DIR}/dv/uvm/core_ibex/common/ibex_mem_intf_agent
+incdir+${PRJ_DIR}/dv/uvm/core_ibex/common/irq_agent
-+incdir+${PRJ_DIR}/vendor/lowrisc_ip/dv/sv/mem_model
-+incdir+${PRJ_DIR}/vendor/lowrisc_ip/dv/sv/dv_utils
-+incdir+${PRJ_DIR}/vendor/lowrisc_ip/dv/sv/str_utils
++incdir+${PRJ_DIR}/dv/uvm/core_ibex/common/ibex_cosim_agent
++incdir+${PRJ_DIR}/dv/cosim
${PRJ_DIR}/dv/uvm/bus_params_pkg/bus_params_pkg.sv
-${PRJ_DIR}/vendor/lowrisc_ip/dv/sv/common_ifs/clk_rst_if.sv
-${PRJ_DIR}/vendor/lowrisc_ip/dv/sv/common_ifs/pins_if.sv
-${PRJ_DIR}/vendor/lowrisc_ip/dv/sv/str_utils/str_utils_pkg.sv
-${PRJ_DIR}/vendor/lowrisc_ip/dv/sv/dv_utils/dv_test_status_pkg.sv
-${PRJ_DIR}/vendor/lowrisc_ip/dv/sv/dv_utils/dv_utils_pkg.sv
-${PRJ_DIR}/vendor/lowrisc_ip/dv/sv/mem_model/mem_model_pkg.sv
+${LOWRISC_IP_DIR}/dv/sv/common_ifs/common_ifs_pkg.sv
+${LOWRISC_IP_DIR}/dv/sv/common_ifs/clk_rst_if.sv
+${LOWRISC_IP_DIR}/dv/sv/common_ifs/pins_if.sv
+${LOWRISC_IP_DIR}/dv/sv/str_utils/str_utils_pkg.sv
+${LOWRISC_IP_DIR}/dv/sv/dv_utils/dv_test_status_pkg.sv
+${LOWRISC_IP_DIR}/dv/sv/dv_utils/dv_utils_pkg.sv
+${LOWRISC_IP_DIR}/dv/sv/dv_base_reg/dv_base_reg_pkg.sv
+${LOWRISC_IP_DIR}/dv/sv/csr_utils/csr_utils_pkg.sv
+${LOWRISC_IP_DIR}/dv/sv/dv_lib/dv_lib_pkg.sv
+${LOWRISC_IP_DIR}/dv/sv/mem_model/mem_model_pkg.sv
+${LOWRISC_IP_DIR}/dv/sv/push_pull_agent/push_pull_if.sv
+${LOWRISC_IP_DIR}/dv/sv/push_pull_agent/push_pull_agent_pkg.sv
${PRJ_DIR}/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf.sv
-${PRJ_DIR}/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_agent_pkg.sv
+${PRJ_DIR}/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_pkg.sv
${PRJ_DIR}/dv/uvm/core_ibex/common/irq_agent/irq_if.sv
${PRJ_DIR}/dv/uvm/core_ibex/common/irq_agent/irq_agent_pkg.sv
+${PRJ_DIR}/dv/uvm/core_ibex/env/core_ibex_rvfi_if.sv
+${PRJ_DIR}/dv/uvm/core_ibex/common/ibex_cosim_agent/core_ibex_ifetch_if.sv
+${PRJ_DIR}/dv/uvm/core_ibex/common/ibex_cosim_agent/core_ibex_ifetch_pmp_if.sv
+${PRJ_DIR}/dv/uvm/core_ibex/common/ibex_cosim_agent/ibex_cosim_agent_pkg.sv
+${PRJ_DIR}/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_agent_pkg.sv
${PRJ_DIR}/dv/uvm/core_ibex/env/core_ibex_instr_monitor_if.sv
${PRJ_DIR}/dv/uvm/core_ibex/env/core_ibex_dut_probe_if.sv
-${PRJ_DIR}/dv/uvm/core_ibex/env/core_ibex_rvfi_if.sv
${PRJ_DIR}/dv/uvm/core_ibex/env/core_ibex_csr_if.sv
${PRJ_DIR}/dv/uvm/core_ibex/env/core_ibex_env_pkg.sv
${PRJ_DIR}/dv/uvm/core_ibex/tests/core_ibex_test_pkg.sv
+${PRJ_DIR}/dv/uvm/core_ibex/fcov/core_ibex_fcov_if.sv
+${PRJ_DIR}/dv/uvm/core_ibex/fcov/core_ibex_fcov_bind.sv
+${PRJ_DIR}/dv/uvm/core_ibex/fcov/core_ibex_pmp_fcov_if.sv
${PRJ_DIR}/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv
diff --git a/dv/uvm/core_ibex/ibex_dv_cosim_dpi.f b/dv/uvm/core_ibex/ibex_dv_cosim_dpi.f
new file mode 100644
index 00000000..29941302
--- /dev/null
+++ b/dv/uvm/core_ibex/ibex_dv_cosim_dpi.f
@@ -0,0 +1,7 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+${PRJ_DIR}/dv/uvm/core_ibex/common/ibex_cosim_agent/spike_cosim_dpi.cc
+${PRJ_DIR}/dv/cosim/cosim_dpi.cc
+${PRJ_DIR}/dv/cosim/spike_cosim.cc
diff --git a/dv/uvm/core_ibex/riscv_dv_extension/csr_description.yaml b/dv/uvm/core_ibex/riscv_dv_extension/csr_description.yaml
index 905684d7..8e7ccdad 100644
--- a/dv/uvm/core_ibex/riscv_dv_extension/csr_description.yaml
+++ b/dv/uvm/core_ibex/riscv_dv_extension/csr_description.yaml
@@ -39,27 +39,81 @@
# - ...
+# TODO: Enable multiple configurations for CSR test. MISA read value will depend
+# on whether B and M are available. https://github.com/lowRISC/ibex/issues/1333
# Ibex MISA CSR
-- csr: misa
- description: >
- Machine ISA Register
- address: 0x301
- privilege_mode: M
- rv32:
- - field_name: MXL
- description: >
- Encodes native base ISA width
- type: R
- reset_val: 1
- msb: 31
- lsb: 30
- - field_name: Extensions
- description: >
- Encodes all supported ISA extensions
- type: R
- reset_val: 0x101104
- msb: 25
- lsb: 0
+#- csr: misa
+# description: >
+# Machine ISA Register
+# address: 0x301
+# privilege_mode: M
+# rv32:
+# - field_name: MXL
+# description: >
+# Encodes native base ISA width
+# type: R
+# reset_val: 1
+# msb: 31
+# lsb: 30
+# - field_name: Extensions
+# description: >
+# Encodes all supported ISA extensions
+# type: R
+# reset_val: 0x101106
+# msb: 25
+# lsb: 0
+
+# CSR test generation cannot deal with read-only fields. Leaving these here
+# commented out so they can be used once the read-only issue is fixed.
+# https://github.com/lowRISC/ibex/issues/1337 tracks the required improvements
+#- csr: mvendorid
+# description: >
+# Machine Vendor ID Register providing JEDEC manufacturer ID
+# address: 0xF11
+# privilege_mode: M
+# rv32:
+# - field_name: Bank
+# description: >
+# Number of continuation codes in JEDEC ID
+# type: R
+# reset_val: 0
+# msb: 31
+# lsb: 7
+# - field_name: Offset
+# description: >
+# JEDEC ID final byte
+# type: R
+# reset_val: 0
+# msb: 6
+# lsb: 0
+#
+#- csr: marchid
+# description: >
+# Machine Architecture ID Register
+# address: 0xF12
+# privilege_mode: M
+# rv32:
+# - field_name: Architecture ID
+# description: >
+# ID indicating the base microarchitecture
+# type: R
+# reset_val: 22
+# msb: 31
+# lsb: 0
+#
+#- csr: mimpid
+# description: >
+# Machine Implementation ID Register
+# address: 0xF13
+# privilege_mode: M
+# rv32:
+# - field_name: Implementation
+# description: >
+# Unique encoding of processor implementation version
+# type: R
+# reset_val: 0
+# msb: 31
+# lsb: 0
# Ibex's implementation of MHARTID is read-only
# MHARTID
@@ -88,47 +142,52 @@
# fields need to be constrained such that their value after every operation is within the allowed
# range of values - too much complexity for the current format
# MSTATUS
-#- csr: mstatus
-# description: >
-# Controls hart's current operating state
-# address: 0x300
-# privilege_mode: M
-# rv32:
-# - field_name: tw
-# description: >
-# Timeout Wait (WFI from U-mode will trap to M-mode)
-# type: WARL
-# reset_val: 0
-# msb: 21
-# lsb: 21
-# - field_name: mprv
-# description: >
-# Modify Privilege (Loads and stores use MPP for privilege checking)
-# type: WARL
-# reset_val: 0
-# msb: 17
-# lsb: 17
-# - field_name: mpp
-# desription : >
-# Previous privilege mode
-# type: R
-# reset_val: 0
-# msb: 12
-# lsb: 11
-# - field_name: mpie
-# description: >
-# Previous value of interrupt-enable bit
-# type: WARL
-# reset_val: 1
-# msb: 7
-# lsb: 7
-# - field_name: mie
-# description: >
-# M-mode interrupt enable
-# type: WARL
-# reset_val: 0
-# msb: 3
-# lsb: 3
+- csr: mstatus
+ description: >
+ Controls hart's current operating state
+ address: 0x300
+ privilege_mode: M
+ rv32:
+ - field_name: tw
+ description: >
+ Timeout Wait (WFI from U-mode will trap to M-mode)
+ type: WARL
+ reset_val: 0
+ msb: 21
+ lsb: 21
+ - field_name: mprv
+ description: >
+ Modify Privilege (Loads and stores use MPP for privilege checking)
+ type: WARL
+ reset_val: 0
+ msb: 17
+ lsb: 17
+ - field_name: mpp
+ desription : >
+ Previous privilege mode
+ type: WARL
+ reset_val: 0
+ msb: 12
+ lsb: 11
+ warl_legalize: |
+ if val_in == 0b11 or val_in == 0b00:
+ val_out = val_in
+ else:
+ val_out = 0b00
+ - field_name: mpie
+ description: >
+ Previous value of interrupt-enable bit
+ type: WARL
+ reset_val: 1
+ msb: 7
+ lsb: 7
+ - field_name: mie
+ description: >
+ M-mode interrupt enable
+ type: WARL
+ reset_val: 0
+ msb: 3
+ lsb: 3
# MIP
- csr: mip
@@ -232,6 +291,8 @@
msb: 31
lsb: 1
+# TODO: Add support for WARL fields to CSR test generator allowing this CSR to
+# be tested.
# MCAUSE
- csr: mcause
description: >
@@ -239,13 +300,22 @@
address: 0x342
privilege_mode: M
rv32:
- - field_name: Interrupt
+ - field_name: Interrupt info
description: >
- Indicates if trap caused by interrupt
+ Indicates if trap caused by interrupt and if that interrupt was internal
+ or external
type: WARL
reset_val: 0
msb: 31
- lsb: 31
+ lsb: 5
+ warl_legalize: |
+ if val_in & 0x4000000:
+ if val_in & 0x2000000:
+ val_out = 0x7ffffff
+ else:
+ val_out = 0x4000000
+ else:
+ val_out = 0x0000000
- field_name: Exception Code
type: WLRL
reset_val: 0
@@ -296,43 +366,60 @@
msb: 1
lsb: 0
-# CPUCTRL
+# TODO: Bit 8 of this CSR is whether the icache scramble key is valid. This
+# could be 0 or 1 depending upon the Ibex config and depending upon the current
+# state of the scramble key. We need a way for the CSR test generator to deal
+# with fields where it cannot predict the value. Until then leave this CSR out.
#
-# TODO : change fields to WARL type once SecureIbex parameter is enabled
-- csr: cpuctrl
- description: >
- CPU control register (custom)
- address: 0x7C0
- privilege_mode: M
- rv32:
- - field_name: dumm_instr_mask
- description: >
- Mask to control frequency of dummy instruction insertion
- type: R
- reset_val: 0
- msb: 5
- lsb: 3
- - field_name: dummy_instr_en
- description: >
- Enable or disable dummy instruction insertion
- type: R
- reset_val: 0
- msb: 2
- lsb: 2
- - field_name: data_ind_timing
- description: >
- Enable or disable data-independent timing features
- type: R
- reset_val: 0
- msb: 1
- lsb: 1
- - field_name: icache_enable
- description: >
- Enable or disable the instruction cache
- type: WARL
- reset_val: 0
- msb: 0
- lsb: 0
+# CPUCTRLSTS
+#- csr: cpuctrlsts
+# description: >
+# CPU control register (custom)
+# address: 0x7C0
+# privilege_mode: M
+# rv32:
+# - field_name: double_fault_seen
+# description: >
+# A synchronous exception was observed when the sync_exc_seen field was set
+# type: RW
+# reset_val: 0
+# msb: 7
+# lsb: 7
+# - field_name: sync_exc_seen
+# description: >
+# A synchronous exception has been observed
+# type: RW
+# reset_val: 0
+# msb: 6
+# lsb: 6
+# - field_name: dumm_instr_mask
+# description: >
+# Mask to control frequency of dummy instruction insertion
+# type: WARL
+# reset_val: 0
+# msb: 5
+# lsb: 3
+# - field_name: dummy_instr_en
+# description: >
+# Enable or disable dummy instruction insertion
+# type: WARL
+# reset_val: 0
+# msb: 2
+# lsb: 2
+# - field_name: data_ind_timing
+# description: >
+# Enable or disable data-independent timing features
+# type: WARL
+# reset_val: 0
+# msb: 1
+# lsb: 1
+# - field_name: icache_enable
+# description: >
+# Enable or disable the instruction cache
+# type: WARL
+# reset_val: 0
+# msb: 0
+# lsb: 0
# SECURESEED
- csr: secureseed
diff --git a/dv/uvm/core_ibex/riscv_dv_extension/ibex_asm_program_gen.sv b/dv/uvm/core_ibex/riscv_dv_extension/ibex_asm_program_gen.sv
index 8d09e067..244d80fa 100644
--- a/dv/uvm/core_ibex/riscv_dv_extension/ibex_asm_program_gen.sv
+++ b/dv/uvm/core_ibex/riscv_dv_extension/ibex_asm_program_gen.sv
@@ -11,9 +11,81 @@ class ibex_asm_program_gen extends riscv_asm_program_gen;
`uvm_object_utils(ibex_asm_program_gen)
`uvm_object_new
+ virtual function void gen_program();
+ bit disable_pmp_exception_handler = 0;
+
+ default_include_csr_write = {
+ MSCRATCH,
+ MVENDORID,
+ MARCHID,
+ MHARTID,
+ MCONFIGPTR,
+ MENVCFG,
+ MSTATUSH,
+ MIMPID,
+ MCYCLE,
+ MCYCLEH,
+ MHPMEVENT3,
+ MHPMEVENT4,
+ MHPMEVENT5,
+ MHPMEVENT6,
+ MHPMEVENT7,
+ MHPMEVENT8,
+ MHPMEVENT9,
+ MHPMEVENT10,
+ MHPMCOUNTER3,
+ MHPMCOUNTER4,
+ MHPMCOUNTER5,
+ MHPMCOUNTER6,
+ MHPMCOUNTER7,
+ MHPMCOUNTER8,
+ MHPMCOUNTER9,
+ MHPMCOUNTER10,
+ MHPMCOUNTER3H,
+ MHPMCOUNTER4H,
+ MHPMCOUNTER5H,
+ MHPMCOUNTER6H,
+ MHPMCOUNTER7H,
+ MHPMCOUNTER8H,
+ MHPMCOUNTER9H,
+ MHPMCOUNTER10H,
+ 12'h7c1 // SECURESEED
+ };
+
+ riscv_csr_instr::create_csr_filter(cfg);
+
+ if ($value$plusargs("disable_pmp_exception_handler=%d", disable_pmp_exception_handler) &&
+ disable_pmp_exception_handler) begin
+ cfg.pmp_cfg.enable_pmp_exception_handler = 0;
+ end
+
+ super.gen_program();
+ endfunction
+
+ // ECALL trap handler
+ // For riscv-dv in Ibex, ECALL is no-longer used to end the test.
+ // Hence, redefine a simple version here that just increments
+ // MEPC+4 then calls 'mret'. (ECALL is always 4-bytes in RV32)
+ virtual function void gen_ecall_handler(int hart);
+ string instr[$];
+ dump_perf_stats(instr);
+ gen_register_dump(instr);
+ instr = {instr,
+ $sformatf("csrr x%0d, 0x%0x", cfg.gpr[0], MEPC),
+ $sformatf("addi x%0d, x%0d, 4", cfg.gpr[0], cfg.gpr[0]),
+ $sformatf("csrw 0x%0x, x%0d", MEPC, cfg.gpr[0])
+ };
+ instr.push_back("mret");
+ gen_section(get_label("ecall_handler", hart), instr);
+ endfunction
+
virtual function void gen_program_header();
+ // Override the mstatus_mprv config because there is no current way to randomize writing to
+ // mstatus.mprv in riscv-dv (it's constrained by set_mstatus_mprv argument to have either
+ // 1 or 0 for the duration of the run)
+ if (cfg.set_mstatus_mprv)
+ cfg.mstatus_mprv = $urandom_range(1);
// Override the cfg value, below fields are not supported by ibex
- cfg.mstatus_mprv = 0;
cfg.mstatus_mxr = 0;
cfg.mstatus_sum = 0;
cfg.mstatus_tvm = 0;
@@ -39,4 +111,64 @@ class ibex_asm_program_gen extends riscv_asm_program_gen;
instr.push_back("csrwi 0x7c0, 1");
endfunction
+ // Re-define gen_test_done() to override the base-class with an empty implementation.
+ // Then, our own overrided gen_program() can append new test_done code.
+ virtual function void gen_test_done();
+ // empty
+ endfunction
+
+ // The test is ended from the UVM testbench, which awaits the following write to
+ // the special test-control signature address (signature_addr - 0x4).
+ // #FIXME# The existing ECALL trap handler will handle the clean up procedure
+ // while awaiting the simulation to be ended.
+ virtual function void gen_test_end(input test_result_t result,
+ ref string instr[$]);
+ bit [XLEN-1:0] test_control_addr;
+ string str;
+ string i = indent; // lint-hack
+ test_control_addr = cfg.signature_addr - 4'h4;
+
+ if (cfg.bare_program_mode) begin
+ str = {i, "j write_tohost", "\n"};
+ end else begin
+ // The testbench will await a write of TEST_PASS, and use that to end the test.
+ str = {
+ {i, $sformatf( "li x%0d, 0x%0h", cfg.gpr[1], test_control_addr), "\n"},
+ {i, $sformatf( "li x%0d, 0x%0h", cfg.gpr[0], result), "\n"},
+ {i, $sformatf("slli x%0d, x%0d, 8", cfg.gpr[0], cfg.gpr[0]), "\n"},
+ {i, $sformatf("addi x%0d, x%0d, 0x%0h", cfg.gpr[0], cfg.gpr[0], TEST_RESULT), "\n"},
+ {i, $sformatf( "sw x%0d, 0(x%0d)", cfg.gpr[0], cfg.gpr[1]), "\n"},
+ // Still add the ecall insn, to go to the ecall_handler code as before.
+ {i, "ecall", "\n"}
+ };
+ end
+
+ instr.push_back(str);
+ endfunction
+
+ virtual function void gen_init_section(int hart);
+ // This is a good location to put the test done and fail because PMP tests expect these
+ // sequences to be before the main function.
+ string instr[$];
+
+ super.gen_init_section(hart);
+
+ // RISCV-DV assumes main is immediately after init when riscv_instr_pkg::support_pmp isn't set.
+ // This override of gen_init_section breaks that assumption so add a jump to main here so the
+ // test starts correctly for configurations that don't support PMP.
+ if (!riscv_instr_pkg::support_pmp) begin
+ instr_stream.push_back({indent, "j main"});
+ end
+
+ gen_test_end(.result(TEST_PASS), .instr(instr));
+ instr_stream = {instr_stream,
+ {format_string("test_done:", LABEL_STR_LEN)},
+ instr};
+ instr.delete();
+ gen_test_end(.result(TEST_FAIL), .instr(instr));
+ instr_stream = {instr_stream,
+ {format_string("test_fail:", LABEL_STR_LEN)},
+ instr};
+ endfunction
+
endclass
diff --git a/dv/uvm/core_ibex/riscv_dv_extension/ibex_debug_triggers_overrides.sv b/dv/uvm/core_ibex/riscv_dv_extension/ibex_debug_triggers_overrides.sv
new file mode 100644
index 00000000..1bc53c13
--- /dev/null
+++ b/dv/uvm/core_ibex/riscv_dv_extension/ibex_debug_triggers_overrides.sv
@@ -0,0 +1,137 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class ibex_hardware_triggers_debug_rom_gen extends riscv_debug_rom_gen;
+
+ `uvm_object_utils(ibex_hardware_triggers_debug_rom_gen)
+ `uvm_object_new
+
+ int unsigned ibex_trigger_idx = 0; // See. [DbgHwBreakNum]
+
+ virtual function void gen_program();
+ string instr[$];
+
+ // Don't save off GPRs (ie. this WILL modify program flow)
+ // (We want to capture a register value (gpr[1]) from the directed_instr_streams in
+ // main() that contains the address for our next trigger.)
+ // This works in tandem with 'ibex_breakpoint_stream' which stores the address of
+ // the instruction to trigger on in a fixed register, then executes an EBREAK to
+ // enter debug mode via the dcsr.ebreakm=1 functionality. The debug rom code
+ // then sets up the breakpoint trigger to this address, and returns, allowing main
+ // to continue executing until we hit the trigger.
+
+ // riscv-debug-1.0.0-STABLE
+ // 5.5 Trigger Registers
+ // <..>
+ // As as result, a debugger can write any supported trigger as follows..
+ //
+ // 1. Write 0 to TDATA1. (This will result in TDATA1 containing a non-zero value,
+ // since the register is WARL).
+ // 2. Write desired values to TDATA2 and TDATA3.
+ // 3. Write desired value to TDATA1.
+ // <..>
+
+ instr = {// Check DCSR.cause (DCSR[8:6]) to branch to the next block of code.
+ $sformatf("csrr x%0d, 0x%0x", cfg.scratch_reg, DCSR),
+ $sformatf("slli x%0d, x%0d, 0x17", cfg.scratch_reg, cfg.scratch_reg),
+ $sformatf("srli x%0d, x%0d, 0x1d", cfg.scratch_reg, cfg.scratch_reg),
+ $sformatf("li x%0d, 0x1", cfg.gpr[0]), // EBREAK = 1
+ $sformatf("beq x%0d, x%0d, 1f", cfg.scratch_reg, cfg.gpr[0]),
+ $sformatf("li x%0d, 0x2", cfg.gpr[0]), // TRIGGER = 2
+ $sformatf("beq x%0d, x%0d, 2f", cfg.scratch_reg, cfg.gpr[0]),
+ $sformatf("li x%0d, 0x3", cfg.gpr[0]), // HALTREQ = 3
+ $sformatf("beq x%0d, x%0d, 3f", cfg.scratch_reg, cfg.gpr[0]),
+
+ // DCSR.cause == EBREAK
+ "1: nop",
+ // 'ibex_breakpoint_stream' inserts EBREAKs such that cfg.gpr[1]
+ // now contain the address of the next trigger.
+ // Enable the trigger and set to this address.
+ $sformatf("csrrwi zero, 0x%0x, %0d", TSELECT, ibex_trigger_idx),
+ $sformatf("csrrw zero, 0x%0x, x0", TDATA1),
+ $sformatf("csrrw zero, 0x%0x, x%0d", TDATA2, cfg.gpr[1]),
+ $sformatf("csrrwi zero, 0x%0x, 5", TDATA1),
+ // Increment the PC + 4 (EBREAK does not do this for you.)
+ $sformatf("csrr x%0d, 0x%0x", cfg.gpr[0], DPC),
+ $sformatf("addi x%0d, x%0d, 4", cfg.gpr[0], cfg.gpr[0]),
+ $sformatf("csrw 0x%0x, x%0d", DPC, cfg.gpr[0]),
+ "j 4f",
+
+ // DCSR.cause == TRIGGER
+ "2: nop",
+ // Disable the trigger until the next breakpoint is known.
+ $sformatf("csrrwi zero, 0x%0x, %0d", TSELECT, ibex_trigger_idx),
+ $sformatf("csrrw zero, 0x%0x, x0", TDATA1),
+ $sformatf("csrrw zero, 0x%0x, x0", TDATA2),
+ "j 4f",
+
+ // DCSR.cause == HALTREQ
+ "3: nop",
+ // Use this once near the start of the test to configure ebreakm/u to enter debug mode
+ // Set DCSR.ebreakm (DCSR[15]) = 1
+ // Set DCSR.ebreaku (DCSR[12]) = 1
+ $sformatf("li x%0d, 0x9000", cfg.scratch_reg),
+ $sformatf("csrs 0x%0x, x%0d", DCSR, cfg.scratch_reg),
+
+ "4: nop"
+ };
+
+ debug_main = {instr,
+ $sformatf("la x%0d, debug_end", cfg.scratch_reg),
+ $sformatf("jalr x0, x%0d, 0", cfg.scratch_reg)
+ };
+ format_section(debug_main);
+ gen_section($sformatf("%0sdebug_rom", hart_prefix(hart)), debug_main);
+
+ debug_end = {dret};
+ format_section(debug_end);
+ gen_section($sformatf("%0sdebug_end", hart_prefix(hart)), debug_end);
+
+ gen_debug_exception_handler();
+ endfunction
+
+
+ // If we get an exception in debug_mode, fail the test immediately.
+ // (something has gone wrong with our stimulus generation)
+ virtual function void gen_debug_exception_handler();
+ string instr[$];
+ instr = {$sformatf("la x%0d, test_fail", cfg.scratch_reg),
+ $sformatf("jalr x1, x%0d, 0", cfg.scratch_reg)};
+ format_section(instr);
+ gen_section($sformatf("%0sdebug_exception", hart_prefix(hart)), instr);
+ endfunction
+
+endclass
+
+class ibex_hardware_triggers_asm_program_gen extends ibex_asm_program_gen;
+
+ `uvm_object_utils(ibex_hardware_triggers_asm_program_gen)
+ `uvm_object_new
+
+ // Same implementation as the parent class, except substitute for our custom debug_rom class.
+ virtual function void gen_debug_rom(int hart);
+ `uvm_info(`gfn, "Creating debug ROM", UVM_LOW)
+ debug_rom = ibex_hardware_triggers_debug_rom_gen::
+ type_id::create("debug_rom", , {"uvm_test_top", ".", `gfn});
+ debug_rom.cfg = cfg;
+ debug_rom.hart = hart;
+ debug_rom.gen_program();
+ instr_stream = {instr_stream, debug_rom.instr_stream};
+ endfunction
+
+endclass
+
+
+class ibex_hardware_triggers_illegal_instr extends riscv_illegal_instr;
+
+ `uvm_object_utils(ibex_hardware_triggers_illegal_instr)
+ `uvm_object_new
+
+ // Make it super-obvious where the illegal instructions are in the assembly.
+ function void post_randomize();
+ super.post_randomize();
+ comment = "INVALID";
+ endfunction
+
+endclass // ibex_illegal_instr
diff --git a/dv/uvm/core_ibex/riscv_dv_extension/ibex_directed_instr_lib.sv b/dv/uvm/core_ibex/riscv_dv_extension/ibex_directed_instr_lib.sv
new file mode 100644
index 00000000..36a13df4
--- /dev/null
+++ b/dv/uvm/core_ibex/riscv_dv_extension/ibex_directed_instr_lib.sv
@@ -0,0 +1,413 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+
+// Define a short riscv-dv directed instruction stream to setup hardware breakpoints
+// (TSELECT/TDATA), and then trigger on an instruction at the end of this stream.
+class ibex_breakpoint_stream extends riscv_directed_instr_stream;
+
+ riscv_pseudo_instr la_instr;
+ riscv_instr ebreak_insn;
+ rand int unsigned num_of_instr;
+
+ constraint instr_c {
+ num_of_instr inside {[5:10]};
+ }
+
+ `uvm_object_utils(ibex_breakpoint_stream)
+
+ function new(string name = "");
+ super.new(name);
+ endfunction
+
+ function void post_randomize();
+ riscv_instr instr;
+ string trigger_label, gn;
+
+ // Setup a randomized main body of instructions.
+ initialize_instr_list(num_of_instr);
+ setup_allowed_instr(1, 1); // no_branch=1/no_load_store=1
+ foreach(instr_list[i]) begin
+ instr = riscv_instr::type_id::create("instr");
+ randomize_instr(instr);
+ instr_list[i] = instr;
+ // Copy this from the base-class behaviour
+ instr_list[i].atomic = 1'b1;
+ instr_list[i].has_label = 1'b0;
+ end
+
+ // Give the last insn of the main body a label, then set the breakpoint address to that label.
+ gn = get_name();
+ trigger_label = {gn};
+ instr_list[$].label = trigger_label;
+ instr_list[$].has_label = 1'b1;
+
+ // Load the address of the trigger point as the (last insn of the stream + 4)
+ // Store in gpr[1] ()
+ la_instr = riscv_pseudo_instr::type_id::create("la_instr");
+ la_instr.pseudo_instr_name = LA;
+ la_instr.imm_str = $sformatf("%0s+4", trigger_label);
+ la_instr.rd = cfg.gpr[1];
+
+ // Create the ebreak insn which will cause us to enter debug mode, and run the
+ // special code in the debugrom.
+ ebreak_insn = riscv_instr::get_instr(EBREAK);
+
+ // Add the instructions into the stream.
+ instr_list = {la_instr,
+ ebreak_insn,
+ instr_list};
+ endfunction
+
+endclass
+
+// Define a short riscv-dv directed instruction stream to write random values to MSECCFG CSR
+class ibex_rand_mseccfg_stream extends riscv_directed_instr_stream;
+
+ `uvm_object_utils(ibex_rand_mseccfg_stream)
+
+ function new(string name = "");
+ super.new(name);
+ endfunction
+
+ function void post_randomize();
+ riscv_instr csrrw_instr;
+ // This stream consists of a single instruction
+ initialize_instr_list(1);
+
+ csrrw_instr = riscv_instr::get_instr(CSRRWI);
+ csrrw_instr.atomic = 1'b0;
+ csrrw_instr.csr = MSECCFG;
+ csrrw_instr.rd = '0;
+ // Randomize between 3'b000 and 3'b111 to hit every combination of RLB/MMWP/MML bits.
+ csrrw_instr.imm_str = $sformatf("0x%0x", $urandom_range(7,0));
+ instr_list = {csrrw_instr};
+ endfunction
+
+endclass
+
+// Stream to randomly toggle different Ibex specific feature enables in cpuctrlsts
+class ibex_rand_cpuctrlsts_stream extends riscv_directed_instr_stream;
+
+ `uvm_object_utils(ibex_rand_cpuctrlsts_stream)
+
+ function new(string name = "");
+ super.new(name);
+ endfunction
+
+ function void post_randomize();
+ riscv_instr instrs[4];
+ bit toggle_dit;
+ bit toggle_dummy_instr;
+ bit toggle_icache;
+ bit icache_en;
+ bit dit_en;
+ bit dummy_instr_en;
+ bit [2:0] dummy_instr_mask;
+ bit [8:0] cpuctrlsts_mask;
+ bit [5:0] cpuctrlsts_val;
+
+ if (cfg.init_privileged_mode != MACHINE_MODE) begin
+ // Cannot write to cpuctrlsts when we're doing a U mode test
+ return;
+ end
+
+ // DIT is Data Independent Timing
+ if (!$value$plusargs("toggle_dit=%d", toggle_dit)) begin
+ toggle_dit = 1'b0;
+ end
+
+ if (!$value$plusargs("toggle_dummy_instr=%d", toggle_dummy_instr)) begin
+ toggle_dummy_instr = 1'b0;
+ end
+
+ if (!$value$plusargs("toggle_icache=%d", toggle_icache)) begin
+ toggle_icache = 1'b0;
+ end
+
+ `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(icache_en, if (!toggle_icache) icache_en == 0;);
+ `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(dit_en, if (!toggle_dit) dit_en == 0;);
+ `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(dummy_instr_en,
+ if (!toggle_dummy_instr) dummy_instr_en == 0;);
+ `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(dummy_instr_mask,
+ if (!toggle_dummy_instr) dummy_instr_mask == 0;);
+
+ cpuctrlsts_mask = {3'b111, {4{!dummy_instr_en}}, !dit_en, !icache_en};
+ cpuctrlsts_val = {dummy_instr_mask, dummy_instr_en, dit_en, icache_en};
+
+ initialize_instr_list(4);
+
+ instrs[0] = riscv_instr::get_instr(CSRRSI);
+ instrs[0].atomic = 1'b0;
+ instrs[0].csr = 12'h7c0;
+ instrs[0].rd = cfg.gpr[0];
+ instrs[0].imm_str = "0";
+
+ instrs[1] = riscv_instr::get_instr(ANDI);
+ instrs[1].atomic = 1'b0;
+ instrs[1].rs1 = cfg.gpr[0];
+ instrs[1].rd = cfg.gpr[0];
+ instrs[1].imm_str = $sformatf("0x%0x", cpuctrlsts_mask);
+
+ instrs[2] = riscv_instr::get_instr(ORI);
+ instrs[2].atomic = 1'b0;
+ instrs[2].rs1 = cfg.gpr[0];
+ instrs[2].rd = cfg.gpr[0];
+ instrs[2].imm_str = $sformatf("0x%0x", cpuctrlsts_val);
+
+ instrs[3] = riscv_instr::get_instr(CSRRW);
+ instrs[3].atomic = 1'b0;
+ instrs[3].csr = 12'h7c0;
+ instrs[3].rd = '0;
+ instrs[3].rs1 = cfg.gpr[0];
+
+ instr_list = instrs;
+ endfunction
+
+endclass
+
+// Define a short riscv-dv directed instruction stream to set a valid NA4 address/config
+class ibex_valid_na4_stream extends riscv_directed_instr_stream;
+
+ `uvm_object_utils(ibex_valid_na4_stream)
+
+ function new(string name = "");
+ super.new(name);
+ endfunction
+
+ function void post_randomize();
+ string instr_label, gn;
+ riscv_pseudo_instr la_instr;
+ riscv_instr addr_csrrw_instr;
+ riscv_instr srli_instr;
+ riscv_instr nop_instr;
+ riscv_instr cfg_csrrw_instr;
+
+ // Inserted stream will consist of five instructions
+ initialize_instr_list(5);
+
+ cfg_csrrw_instr = riscv_instr::get_instr(CSRRSI);
+ cfg_csrrw_instr.atomic = 1'b1;
+ cfg_csrrw_instr.has_label = 1'b0;
+ cfg_csrrw_instr.csr = PMPCFG0;
+ cfg_csrrw_instr.rd = '0;
+ cfg_csrrw_instr.imm_str = $sformatf("%0d", $urandom_range(16,23));
+
+ // Use a label to use it for setting pmpaddr CSR.
+ instr_label = $sformatf("na4_addr_stream_%0x", $urandom());
+
+ nop_instr = riscv_instr::get_instr(NOP);
+ nop_instr.label = instr_label;
+ nop_instr.has_label = 1'b1;
+ nop_instr.atomic = 1'b1;
+
+ // Load the address of the instruction after this whole stream
+ la_instr = riscv_pseudo_instr::type_id::create("la_instr");
+ la_instr.pseudo_instr_name = LA;
+ la_instr.has_label = 1'b0;
+ la_instr.atomic = 1'b1;
+ la_instr.imm_str = $sformatf("%0s+16", instr_label);
+ la_instr.rd = cfg.gpr[1];
+
+ srli_instr = riscv_instr::get_instr(SRLI);
+ srli_instr.has_label = 1'b0;
+ srli_instr.atomic = 1'b1;
+ srli_instr.rs1 = cfg.gpr[1];
+ srli_instr.rd = cfg.gpr[1];
+ srli_instr.imm_str = $sformatf("2");
+
+ addr_csrrw_instr = riscv_instr::get_instr(CSRRW);
+ addr_csrrw_instr.has_label = 1'b0;
+ addr_csrrw_instr.atomic = 1'b1;
+ addr_csrrw_instr.csr = PMPADDR0;
+ addr_csrrw_instr.rs1 = cfg.gpr[1];
+ addr_csrrw_instr.rd = '0;
+ instr_list = {cfg_csrrw_instr, nop_instr, la_instr, srli_instr, addr_csrrw_instr};
+ endfunction
+
+endclass
+
+class ibex_cross_pmp_region_mem_access_stream extends riscv_directed_instr_stream;
+ `uvm_object_utils(ibex_cross_pmp_region_mem_access_stream)
+
+ int unsigned pmp_region;
+ int unsigned region_mask;
+ int unsigned region_size;
+
+ function new (string name = "");
+ super.new(name);
+ endfunction
+
+ function void calc_region_params();
+ int unsigned cur_addr = cfg.pmp_cfg.pmp_cfg[pmp_region].addr;
+
+ region_size = 8;
+ region_mask = 32'hfffffffe;
+
+ for (int i = 0; i < 29; ++i) begin
+ if ((cur_addr & 1) == 0) break;
+ region_size *= 2;
+ cur_addr >>= 1;
+ region_mask <<= 1;
+ end
+ endfunction
+
+ function int unsigned pmp_region_top_addr();
+ return ((cfg.pmp_cfg.pmp_cfg[pmp_region].addr & region_mask) << 2) + region_size;
+ endfunction
+
+ function int unsigned pmp_region_bottom_addr();
+ return ((cfg.pmp_cfg.pmp_cfg[pmp_region].addr & region_mask) << 2);
+ endfunction
+
+ function void post_randomize();
+ int unsigned target_addr;
+ int unsigned offset;
+ riscv_pseudo_instr la_instr;
+ riscv_instr mem_instr;
+ bit access_at_top;
+
+ if (!std::randomize(pmp_region) with {
+ pmp_region > 1;
+ pmp_region < cfg.pmp_cfg.pmp_num_regions;
+ cfg.pmp_cfg.pmp_cfg[pmp_region].a == NAPOT;
+ })
+ begin
+ `uvm_info(`gfn,
+ {"WARNING: Cannot choose random NAPOT PMP region, skipping cross PMP region access ",
+ "generation"}, UVM_LOW)
+ return;
+ end
+
+ initialize_instr_list(2);
+
+ calc_region_params();
+
+ mem_instr = riscv_instr::get_load_store_instr({LH, LHU, LW, SH, SW});
+
+ std::randomize(access_at_top);
+
+ if (mem_instr.instr_name inside {LW, SW}) begin
+ std::randomize(offset) with {offset < 3;offset > 0;};
+ end else begin
+ offset = 1;
+ end
+
+ if (access_at_top) begin
+ target_addr = pmp_region_top_addr() - offset;
+ end else begin
+ target_addr = pmp_region_bottom_addr() - offset;
+ end
+
+ la_instr = riscv_pseudo_instr::type_id::create("la_instr");
+ la_instr.pseudo_instr_name = LA;
+ la_instr.has_label = 1'b0;
+ la_instr.atomic = 1'b1;
+ la_instr.imm_str = $sformatf("0x%x", target_addr);
+ la_instr.rd = cfg.gpr[1];
+
+ randomize_gpr(mem_instr);
+ mem_instr.has_imm = 0;
+ mem_instr.imm_str = "0";
+ mem_instr.rs1 = cfg.gpr[1];
+
+ instr_list = {la_instr, mem_instr};
+
+ super.post_randomize();
+ endfunction
+endclass
+
+class ibex_make_pmp_region_exec_stream extends riscv_directed_instr_stream;
+ `uvm_object_utils(ibex_make_pmp_region_exec_stream)
+
+ int unsigned pmp_region;
+
+ function new (string name = "");
+ super.new(name);
+ endfunction
+
+ function void post_randomize();
+ riscv_pseudo_instr li_bit_instr;
+ riscv_pseudo_instr li_cfg_instr;
+ riscv_instr instrs[7];
+ bit [31:0] pmpcfg_bits;
+ bit [31:0] pmpcfg_mask;
+ bit [3:0] new_cfg;
+ int pmpcfg_num;
+
+ if (cfg.init_privileged_mode != MACHINE_MODE) begin
+ // Cannot write to pmpcfgX CSRs in U Mode so skip inserting this sequence
+ return;
+ end
+
+ `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(pmp_region,
+ pmp_region > 1; pmp_region < cfg.pmp_cfg.pmp_num_regions;)
+
+ // Choose a new config which is executable when MML is set
+ // 4 config bits are {L, X, W, R}
+ `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(new_cfg, new_cfg inside {4'b0100, 4'b0101, 4'b0111,
+ 4'b1100, 4'b1010, 4'b1110, 4'b1101};)
+
+ pmpcfg_num = pmp_region / 4;
+ pmpcfg_bits = {new_cfg[3], 4'b0, new_cfg[2:0]} << ((pmp_region % 4) * 8);
+ pmpcfg_mask = 32'b10000111 << ((pmp_region % 4) * 8);
+ pmpcfg_mask = ~pmpcfg_mask;
+
+ initialize_instr_list(7);
+
+ // Read the current PMP config masking out the bits we want to change an AND, adding the bits we
+ // want with an OR then write back to the CSR.
+ li_bit_instr = riscv_pseudo_instr::type_id::create("li_bit_instr");
+ li_bit_instr.pseudo_instr_name = LI;
+ li_bit_instr.has_label = 1'b0;
+ li_bit_instr.atomic = 1'b1;
+ li_bit_instr.imm_str = $sformatf("0x%x", pmpcfg_bits);
+ li_bit_instr.rd = cfg.gpr[0];
+ instrs[0] = li_bit_instr;
+
+ li_cfg_instr = riscv_pseudo_instr::type_id::create("li_cfg_instr");
+ li_cfg_instr.pseudo_instr_name = LI;
+ li_cfg_instr.has_label = 1'b0;
+ li_cfg_instr.atomic = 1'b1;
+ li_cfg_instr.imm_str = $sformatf("0x%x", pmpcfg_mask);
+ li_cfg_instr.rd = cfg.gpr[1];
+ instrs[1] = li_cfg_instr;
+
+ instrs[2] = riscv_instr::get_instr(CSRRSI);
+ instrs[2].atomic = 1'b0;
+ instrs[2].csr = PMPCFG0 + pmpcfg_num;
+ instrs[2].rd = cfg.gpr[2];
+ instrs[2].imm_str = "0";
+
+ instrs[3] = riscv_instr::get_instr(AND);
+ instrs[3].atomic = 1'b0;
+ instrs[3].rs1 = cfg.gpr[2];
+ instrs[3].rs2 = cfg.gpr[1];
+ instrs[3].rd = cfg.gpr[2];
+
+ instrs[4] = riscv_instr::get_instr(OR);
+ instrs[4].atomic = 1'b0;
+ instrs[4].rs1 = cfg.gpr[2];
+ instrs[4].rs2 = cfg.gpr[0];
+ instrs[4].rd = cfg.gpr[2];
+
+ instrs[5] = riscv_instr::get_instr(CSRRW);
+ instrs[5].atomic = 1'b0;
+ instrs[5].csr = PMPCFG0 + pmpcfg_num;
+ instrs[5].rd = '0;
+ instrs[5].rs1 = cfg.gpr[2];
+
+ // Immediately read back what we wrote, to check it has been dealt with correctly (i.e. write
+ // suppressed where it should be suppressed), as co-sim currently doesn't check CSR writes.
+ instrs[6] = riscv_instr::get_instr(CSRRS);
+ instrs[6].atomic = 1'b0;
+ instrs[6].csr = PMPCFG0 + pmpcfg_num;
+ instrs[6].rd = cfg.gpr[0];
+ instrs[6].rs1 = 0;
+
+ instr_list = instrs;
+
+ super.post_randomize();
+ endfunction
+endclass
diff --git a/dv/uvm/core_ibex/riscv_dv_extension/ibex_log_to_trace_csv.py b/dv/uvm/core_ibex/riscv_dv_extension/ibex_log_to_trace_csv.py
index 050748bd..cb5372d0 100644
--- a/dv/uvm/core_ibex/riscv_dv_extension/ibex_log_to_trace_csv.py
+++ b/dv/uvm/core_ibex/riscv_dv_extension/ibex_log_to_trace_csv.py
@@ -24,10 +24,12 @@ try:
get_imm_hex_val)
from lib import RET_FATAL, gpr_to_abi, sint_to_hex, convert_pseudo_instr
import logging
+ logger = logging.getLogger(__name__)
finally:
sys.path = _OLD_SYS_PATH
+from test_run_result import Failure_Modes
INSTR_RE = \
re.compile(r"^\s*(?P