Merge pull request #2168 from openhwgroup/cva6/dev

Merging of cva6/dev to master
This commit is contained in:
Mike Thompson 2023-09-06 13:20:30 -04:00 committed by GitHub
commit d5e2c2206c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
600 changed files with 28601 additions and 17465 deletions

View file

@ -104,6 +104,7 @@ cva6:
- project: '$CI_PROJECT_NAMESPACE/setup-ci'
ref: '$SETUP_CI_CVA6_BRANCH'
file: 'cva6/core-v-verif-cva6.yml'
- local: .gitlab-ci/core-v-verif-cva6.yml
strategy: depend
variables:
TAGS_RUNNER: $TAGS_RUNNER

252
.gitlab-ci/README.md Normal file
View file

@ -0,0 +1,252 @@
<!--
Copyright 2023 Thales Silicon Security
Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
You may obtain a copy of the License at https://solderpad.org/licenses/
Original Author: Côme ALLART - Thales
-->
# GitLab CI for core-v-verif + CVA6
This document describes the different steps performed automatically when a branch is pushed to a repository.
It is not meant to be a complete description.
It is an entry point to help to understand the structure of the pipelines; to find the information your are looking for / the part of the CI you want to edit.
Please refer to the mentioned files for more details.
Only the GitLab-related tasks are described here.
## Before the branch reaches GitLab
CVA6 and core-v-verif repositories are mirrored into GitLab repositories owned by Thales, to perform regression tests on pull requests.
> Note: in CVA6 regression tests are also run on the `master` branch, and in core-v-verif on the `cva6/dev` branch.
## Pipeline boot
When a branch is pushed, the entry point of the CI is the `.gitlab-ci.yml` file at the repository root.
> See [`core-v-verif/.gitlab-ci.yml`] and [`cva6/.gitlab-ci.yml`]
[`core-v-verif/.gitlab-ci.yml`]: https://github.com/openhwgroup/core-v-verif/blob/cva6/dev/.gitlab-ci.yml
[`cva6/.gitlab-ci.yml`]: https://github.com/openhwgroup/cva6/blob/master/.gitlab-ci.yml
Both source files from a `setup-ci` project (to locate tools etc.), define workflow rules and perform a small environment check.
All pipelines need both CVA6 and core-v-verif to run tests.
By default the branches used are:
- The one from the PR
- The main branch from the other repository.
The main branch is defined in `setup-ci` (`master` for CVA6 and `cva6/dev` for core-v-verif).
However, the entry points also detect the `cvvdev/*` pattern in the branch name to run CVA6 and core-v-verif pipelines on branches with the same name.
It is useful to consistently test PRs impacting both repositories.
In the CVA6 pipeline:
1. The `core-v-verif-build` job gets the current commit hash of core-v-verif to set it as an environment variable.
It gets the list of tests to run [`core-v-verif/.gitlab-ci/cva6.yml`] (see next steps).
2. The `core-v-verif` job triggers a child pipeline using:
- [`core-v-verif/.gitlab-ci/cva6.yml`] fetched by `core-v-verif-build`
- [`cva6/.gitlab-ci/core-v-verif-cva6.yml`] which defines a `before_script` and an `after_script` to `cd` the core-v-verif repository with the hash defined by `core-v-verif-build`
[`core-v-verif/.gitlab-ci/cva6.yml`]: https://github.com/openhwgroup/core-v-verif/blob/cva6/dev/.gitlab-ci/cva6.yml
[`cva6/.gitlab-ci/core-v-verif-cva6.yml`]: https://github.com/openhwgroup/cva6/blob/master/.gitlab-ci/core-v-verif-cva6.yml
In core-v-verif pipelines, the `cva6` job triggers a child pipeline using:
- [`core-v-verif/.gitlab-ci/cva6.yml`] (the list of tests)
- [`core-v-verif/.gitlab-ci/core-v-verif-cva6.yml`] (global `before_script` and `after_script`).
[`core-v-verif/.gitlab-ci/core-v-verif-cva6.yml`]: https://github.com/openhwgroup/core-v-verif/blob/cva6/dev/.gitlab-ci/core-v-verif-cva6.yml
## Running the tests
Thanks to the previous step, in pipelines from both CVA6 and core-v-verif, the current working directory is core-v-verif, with CVA6 checked out in `core-v-cores/cva6`.
The tests are described in [`core-v-verif/.gitlab-ci/cva6.yml`].
Stages are defined as below (order matters):
- `init env`: only contains `pub_initjob`, which sets a hash for CVA6 as an environment variable, so that it is the same one for all jobs of this pipeline.
It is only run in core-v-verif pipelines as CVA6 pipelines already have the CVA6 commit hash of the pipeline!
- `build tools`: `pub_build_tools` build Spike and `pub_check_env` prints some environment variable for debugging.
- `smoke tests`: `pub_smoke` runs smoke tests.
- `verif tests`: many jobs runs different verif tests.
The template for them is described later in this document.
- `backend tests`: jobs which use results of `verif tests`, often synthesis results.
- `report`: `merge reports` merges all reports into a single yaml.
### Adding a verif test
A simple test looks like this:
```yml
pub_<name>:
extends:
- .verif_test
- .template_job_short_ci
variables:
DASHBOARD_JOB_TITLE: "<title for dashboard>"
DASHBOARD_JOB_DESCRIPTION: "<description for dashboard>"
DASHBOARD_SORT_INDEX: <index to sort jobs in dashboard>
DASHBOARD_JOB_CATEGORY: "<job category for dashboard>"
script:
- source cva6/regress/<my-script>.sh
- python3 .gitlab-ci/scripts/report_<kind>.py <args...>
```
- `.verif_test` tells that:
- The job goes in `verif tests` stage
- Before running the script part, additionally to the global `before_script`:
- Spike is got from `pub_build_tools`
- Artifacts are cleaned, `artifacts/reports` and `artifacts/logs` are created
- A "failure" report is created by default (in case the script exists early)
- `$SYN_VCS_BASHRC` is sourced
- All the contents of the `artifacts/` folder will be considered as artifacts (even if the job fails)
- `.template_job_short_ci` tells in which pipeline mode the job should run
- `variables` defines environment variables.
The 4 above are needed to generate the report for the dashboard.
- `script` defines the script to run:
1. Run the test, for instance sourcing a script in `cva6/regress/`
2. Generate a report running a script from `.gitlab-ci/scripts/reports_*.py`
> Notes:
>
> You can add more environment variables such as:
>
> ```yml
> variables:
> DV_SIMULATORS: "veri-testharness,spike"
> DV_TESTLISTS: "../tests/testlist_riscv-tests-$DV_TARGET-p.yaml"
> ```
>
> You can also have several jobs running in parallel with variables taking different values:
>
> ```yml
> parallel:
> matrix:
> - DV_TARGET: [cv64a6_imafdc_sv39, cv32a60x]
> ```
### Adding a backend test
```yml
pub_<name>:
needs:
- *initjob
- pub_<other_job>
- <...>
extends:
- .backend_test
- .template_job_always_manual
variables:
<same as for verif tests>
script:
- <mv spike from artifacts if you need it>
- <your script>
- python3 .gitlab-ci/scripts/report_<kind>.py <args...>
```
Backend tests are like verif tests, differences are:
- `needs` list is needed to specify in which conditions the test is run (with `.template_job_*`).
It contains:
- `*initjob` to be sure the correct CVA6 commit is used.
Without a `needs` list, all jobs from all previous stages are considered as needed.
However, when a `needs` list is declared, all useful dependencies must be specified by hand, which is more complex.
- `pub_build_tools` if you need spike (don't forget to `mv` it from the artifacts!)
- The jobs you need artifacts from
- `.backend_test` indicates that:
- The job goes in `backend tests` stage
- It performs the same steps than `.backend_test`, except that:
- it does not source VCS (so you have to do it if you need it)
- it does not move spike (so you have to do it if you need it)
## Generating a report
You might want to use `.gitlab-ci/scripts/report_simu.py`.
If it does not suit your needs, below are snippets to help you write a report generator using our python library.
```python
import report_builder as rb
# Create metrics
metric = rb.TableMetric('Metric name')
metric.add_value('colomn 1', 'colomn 2', 'etc')
# Gather them into a report
report = rb.Report('report label')
report.add_metric(metric)
# Create the report file in the artifacts
report.dump()
```
There are 3 kinds of metric:
```python
# A simple table
metric = rb.TableMetric('Metric name, actually not displayed yet')
metric.add_value('colomn 1', 'colomn 2', 'etc')
# A table with a pass/fail label on each line
metric = rb.TableStatusMetric('Metric name, actually not displayed yet')
metric.add_pass('colomn 1', 'colomn 2', 'etc')
metric.add_fail('colomn 1', 'colomn 2', 'etc')
# A log
metric = rb.LogMetric('Metric name, actually not displayed yet')
metric.add_value("one line (no need to add a backslash n)")
metric.values += ["one line (no need to add a backslash n)"] # same as above
metric.values = ["line1", "line2", "etc"] # also works
# You can fail a metric of any kind at any moment
metric.fail()
```
Failures are propagated:
- one fail in a `TableStatusMetric` fails the whole metric
- one failed metric fails the whole report
- one failed report fails the whole pipeline report
## Dashboard
The `merge reports` job merges the report from all jobs of the pipeline into a single file.
It pushes this file to a repository.
This repository has a CI which produces HTML dashboard pages from the latest files.
These HTML pages are published on <https://riscv-ci.pages.thales-invia.fr/dashboard/>
- Main pages [`dashboard_cva6_0.html`] and [`dashboard_core-v-verif_0.html`] gather results from all processed pipelines.
- Each page `dashboard_<project>_<PR id>.html` gathers results from all pipelines of one PR.
[`dashboard_cva6_0.html`]: https://riscv-ci.pages.thales-invia.fr/dashboard/dashboard_cva6_0.html
[`dashboard_core-v-verif_0.html`]: https://riscv-ci.pages.thales-invia.fr/dashboard/dashboard_core-v-verif_0.html
## PR comment
The `merge reports` job gets the list of open PRs.
It compares the name of the current branch with the name of each PR branch to find the PR.
If a PR matches, it triggers the GitHub workflow `dashboard-done.yml` in this repository, providing the PR number and the success/fail status.
> See [`core-v-verif/.github/workflows/dashboard-done.yml`] and [`cva6/.github/workflows/dashboard-done.yml`]
[`core-v-verif/.github/workflows/dashboard-done.yml`]: https://github.com/openhwgroup/core-v-verif/blob/cva6/dev/.github/workflows/dashboard-done.yml
[`cva6/.github/workflows/dashboard-done.yml`]: https://github.com/openhwgroup/cva6/blob/master/.github/workflows/dashboard-done.yml
This GitHub workflow creates a comment in the PR with the success/fail status and a link to the dashboard page.
However, the dashboard page may not be available right at this moment, as page generation, performed later, takes time.

View file

@ -0,0 +1,5 @@
before_script:
- echo no need to enter core-v-verif, already in it
after_script:
- echo no need to move artifacts, already in core-v-verif

View file

@ -14,6 +14,8 @@
# - In this pipeline, do not define before_script and after_script in the global section (avoid in job too).
# - Please prefix all jobs in this file with "pub_" which stands for "public" job.
# Please refer to .gitlab-ci/README.md to add jobs
variables:
GIT_STRATEGY: fetch
@ -63,37 +65,60 @@ variables:
- when: manual
allow_failure: true
stages:
- .pre
- build_tools
- one
- two
- three
- init env
- build tools
- smoke tests
- verif tests
- backend tests
- find failures
- report
.verif_test:
stage: verif tests
before_script:
- !reference [before_script]
- mv artifacts/tools/spike tools
- rm -rf artifacts/
- mkdir -p artifacts/{reports,logs}
- python3 .gitlab-ci/scripts/report_fail.py
- echo $SYN_VCS_BASHRC; source $SYN_VCS_BASHRC
artifacts: &artifacts
when: always
paths:
- artifacts/
.initjob: &initjob
job: pub_initjob
optional: true
.backend_test:
stage: backend tests
before_script:
- !reference [before_script]
- mkdir -p artifacts/{reports,logs}
- python3 .gitlab-ci/scripts/report_fail.py
artifacts: *artifacts
# In the scope of a CI triggered by core-v-verif repository:
# This job will get the HASH of the given CVA6 branch
# This HASH will be used by the next jobs instead of the CVA6 given BRANCH name
# This prevents CI to not use the same version of CVA6 in case of new commit in CVA6 branch during the execution of the CI
initjob:
stage: .pre
pub_initjob:
stage: init env
extends:
- .template_job_low_footprint
- .template_job_init_cva6
needs: []
script:
- '[[ -e ./cva6 ]] && rm -rf cva6'
- git clone $CVA6_REPO -b $CVA6_BRANCH --depth=1 cva6
- cd cva6
- echo CVA6_HASH=$(git rev-parse origin/$CVA6_BRANCH) > ../.env
- cd ..
- echo CVA6_HASH=$(git -C cva6 rev-parse origin/$CVA6_BRANCH) > .env
artifacts:
reports:
dotenv: .env
pub_check_env:
stage: .pre
stage: build tools
extends:
- .template_job_low_footprint
- .template_job_full_ci
@ -136,10 +161,9 @@ pub_check_env:
- echo $LIB_VERILOG
pub_build_tools:
stage: build_tools
stage: build tools
extends:
- .template_job_full_ci
needs: []
script:
# ROOT_PROJECT is used by Spike installer and designates the toplevel of core-v-verif tree.
- 'export ROOT_PROJECT=$(pwd)'
@ -152,19 +176,18 @@ pub_build_tools:
# If initially set to "__local__", SPIKE_INSTALL_DIR will be resolved
# to an absolute path by the installation script.
- source cva6/regress/install-spike.sh
# Strip locally built binaries and customext library to reduce artifact size.
- '[ -f $(pwd)/tools/spike/bin/spike ] && strip $(pwd)/tools/spike/bin/spike* $(pwd)/tools/spike/lib/libcustomext.so'
# Strip locally built binaries and libraries to reduce artifact size.
- '[ -f $(pwd)/tools/spike/bin/spike ] && strip $(pwd)/tools/spike/bin/spike* $(pwd)/tools/spike/lib/lib*.*'
- mkdir -p artifacts/tools/
- mv tools/spike artifacts/tools/
artifacts:
paths:
- tools/spike/
- artifacts/tools/spike/*
pub_smoke:
stage: one
stage: smoke tests
extends:
- .template_job_full_ci
needs:
- job: pub_build_tools
artifacts: true
parallel:
matrix:
- DV_SIMULATORS: ["veri-testharness,spike","vcs-testharness,spike","vcs-uvm,spike" ]
@ -173,10 +196,9 @@ pub_smoke:
DASHBOARD_JOB_DESCRIPTION: "Short tests to challenge most architectures with most testbenchs configurations"
DASHBOARD_SORT_INDEX: 0
DASHBOARD_JOB_CATEGORY: "Basic"
before_script:
- !reference [.verif_test, before_script]
script:
- mkdir -p artifacts/reports artifacts/logs
- python3 .gitlab-ci/scripts/report_fail.py
- echo $SYN_VCS_BASHRC; source $SYN_VCS_BASHRC
# In order to capture logs in case of test failure, the test script cannot fail.
- source cva6/regress/smoke-tests.sh || true
# The list of files must NOT fail on various DV_SIMULATORS values, so use 'v*_sim' to match
@ -184,21 +206,36 @@ pub_smoke:
# at least until new RTL simulator configurations are added.)
- for i in cva6/sim/*/v*_sim/*.log.iss ; do head -10000 $i > artifacts/logs/$(basename $i).head ; done
- python3 .gitlab-ci/scripts/report_simu.py cva6/sim/logfile.log
artifacts:
when: always
paths:
- artifacts/reports/*.yml
- artifacts/logs/*.log.iss.head
artifacts: *artifacts
pub_gen_smoke:
stage: smoke tests
extends:
- .template_job_full_ci
parallel:
matrix:
- DV_SIMULATORS: ["vcs-uvm,spike"]
variables:
DASHBOARD_JOB_TITLE: "Smoke Generated test $DV_SIMULATORS"
DASHBOARD_JOB_DESCRIPTION: "Short generated tests to challenge the CVA6-DV on STEP1 configuration"
DASHBOARD_SORT_INDEX: 0
DASHBOARD_JOB_CATEGORY: "Basic"
before_script:
- !reference [.verif_test, before_script]
script:
# In order to capture logs in case of test failure, the test script cannot fail.
- source cva6/regress/smoke-gen_tests.sh || true
# The list of files must NOT fail on various DV_SIMULATORS values, so use 'v*_sim' to match
# 'veri-testharness_sim', 'vcs-testharness_sim' and 'vcs-uvm_sim' (one of them always applies,
# at least until new RTL simulator configurations are added.)
- for i in cva6/sim/*/v*_sim/*.log.iss ; do head -10000 $i > artifacts/logs/$(basename $i).head ; done
- python3 .gitlab-ci/scripts/report_simu.py cva6/sim/logfile.log
artifacts: *artifacts
pub_riscv_arch_test:
stage: two
extends:
- .verif_test
- .template_job_short_ci
needs:
- job: pub_build_tools
artifacts: true
- job: pub_smoke
artifacts: false
parallel:
matrix:
- DV_TARGET: [cv64a6_imafdc_sv39, cv32a60x]
@ -209,25 +246,13 @@ pub_riscv_arch_test:
DASHBOARD_SORT_INDEX: 0
DASHBOARD_JOB_CATEGORY: "Test suites"
script:
- mkdir -p artifacts/reports
- python3 .gitlab-ci/scripts/report_fail.py
- echo $SYN_VCS_BASHRC; source $SYN_VCS_BASHRC
- source cva6/regress/dv-riscv-arch-test.sh
- python3 .gitlab-ci/scripts/report_simu.py cva6/sim/logfile.log
artifacts:
when: always
paths:
- "artifacts/reports/*.yml"
csr_test:
stage: two
extends:
- .verif_test
- .template_job_short_ci
needs:
- job: pub_build_tools
artifacts: true
- job: pub_smoke
artifacts: false
parallel:
matrix:
- DV_TARGET: [cv32a60x]
@ -238,55 +263,31 @@ csr_test:
DASHBOARD_SORT_INDEX: 0
DASHBOARD_JOB_CATEGORY: "Test suites"
script:
- mkdir -p artifacts/reports
- python3 .gitlab-ci/scripts/report_fail.py
- echo $SYN_VCS_BASHRC; source $SYN_VCS_BASHRC
- source cva6/regress/dv-riscv-csr-access-test.sh
- python3 .gitlab-ci/scripts/report_simu.py cva6/sim/logfile.log
artifacts:
when: always
paths:
- "artifacts/reports/*.yml"
pub_hwconfig:
stage: two
extends:
- .verif_test
- .template_job_short_ci
needs:
- job: pub_build_tools
artifacts: true
- job: pub_smoke
artifacts: false
parallel:
matrix:
- DV_SIMULATORS: ["veri-testharness,spike"]
DV_HWCONFIG_OPTS: ["--default_config=cv32a60x --isa=rv32imac --a_ext=1",
"--default_config=cv32a60x --isa=rv32imc --RenameEn=1"]
DV_HWCONFIG_OPTS:
- "--default_config=cv32a60x --isa=rv32imac --RenameEn=1"
variables:
DASHBOARD_JOB_TITLE: "HW config $DV_SIMULATORS $DV_HWCONFIG_OPTS"
DASHBOARD_JOB_DESCRIPTION: "Short tests to challenge target configurations"
DASHBOARD_SORT_INDEX: 1
DASHBOARD_JOB_CATEGORY: "Basic"
script:
- mkdir -p artifacts/reports
- python3 .gitlab-ci/scripts/report_fail.py
- echo $SYN_VCS_BASHRC; source $SYN_VCS_BASHRC
- source ./cva6/regress/hwconfig_tests.sh
- python3 .gitlab-ci/scripts/report_pass.py
artifacts:
when: always
paths:
- artifacts/reports/*.yml
pub_compliance:
stage: two
extends:
- .verif_test
- .template_job_short_ci
needs:
- job: pub_build_tools
artifacts: true
- job: pub_smoke
artifacts: false
parallel:
matrix:
- DV_TARGET: [cv64a6_imafdc_sv39, cv32a60x]
@ -297,26 +298,13 @@ pub_compliance:
DASHBOARD_SORT_INDEX: 2
DASHBOARD_JOB_CATEGORY: "Test suites"
script:
- mkdir -p artifacts/reports
- python3 .gitlab-ci/scripts/report_fail.py
- echo $SYN_VCS_BASHRC; source $SYN_VCS_BASHRC
- source cva6/regress/dv-riscv-compliance.sh
- python3 .gitlab-ci/scripts/report_simu.py cva6/sim/logfile.log
artifacts:
when: always
paths:
- "artifacts/reports/*.yml"
pub_tests-v:
stage: two
extends:
- .verif_test
- .template_job_short_ci
needs:
- job: pub_build_tools
artifacts: true
- job: pub_smoke
artifacts: false
parallel:
matrix:
- DV_TARGET: [cv64a6_imafdc_sv39]
@ -328,26 +316,13 @@ pub_tests-v:
DASHBOARD_SORT_INDEX: 3
DASHBOARD_JOB_CATEGORY: "Test suites"
script:
- mkdir -p artifacts/reports
- python3 .gitlab-ci/scripts/report_fail.py
- echo $SYN_VCS_BASHRC; source $SYN_VCS_BASHRC
- source cva6/regress/dv-riscv-tests.sh
- python3 .gitlab-ci/scripts/report_simu.py cva6/sim/logfile.log
artifacts:
when: always
paths:
- "artifacts/reports/*.yml"
pub_tests-p:
stage: two
extends:
- .verif_test
- .template_job_short_ci
needs:
- job: pub_build_tools
artifacts: true
- job: pub_smoke
artifacts: false
parallel:
matrix:
- DV_TARGET: [cv64a6_imafdc_sv39, cv32a60x]
@ -359,43 +334,28 @@ pub_tests-p:
DASHBOARD_SORT_INDEX: 4
DASHBOARD_JOB_CATEGORY: "Test suites"
script:
- mkdir -p artifacts/reports
- python3 .gitlab-ci/scripts/report_fail.py
- echo $SYN_VCS_BASHRC; source $SYN_VCS_BASHRC
- source cva6/regress/dv-riscv-tests.sh
- python3 .gitlab-ci/scripts/report_simu.py cva6/sim/logfile.log
artifacts:
when: always
paths:
- "artifacts/reports/*.yml"
pub_synthesis:
stage: two
pub_synthesis_others:
timeout: 2 hours
extends:
- .verif_test
- .template_job_always_manual
needs:
- job: pub_smoke
artifacts: false
parallel:
matrix:
- TARGET: [cv64a6_imafdc_sv39]
PERIOD: ["1.1"]
- TARGET: [cv32a60x]
PERIOD: ["0.95"]
- TARGET: [cv32a6_embedded]
PERIOD: ["0.85"]
variables:
variables: &synth_vars
INPUT_DELAY: "0.46"
OUTPUT_DELAY: "0.11"
DASHBOARD_JOB_TITLE: "ASIC Synthesis $TARGET"
DASHBOARD_JOB_DESCRIPTION: "Synthesis indicator with specific Techno"
DASHBOARD_SORT_INDEX: 5
DASHBOARD_JOB_CATEGORY: "Synthesis"
script:
- mkdir -p artifacts/reports
- python3 .gitlab-ci/scripts/report_fail.py
script: &synth_script
#ack trick to manage float gitlab-ci variables that seems to support only string or integer
- echo $(echo $SYNTH_PERIOD)
- echo $(echo $INPUT_DELAY)
@ -410,31 +370,38 @@ pub_synthesis:
- make -C core-v-cores/cva6/pd/synth cva6_synth PERIOD=$(echo $PERIOD) NAND2_AREA=$(echo $NAND2_AREA) FOUNDRY_PATH=$FOUNDRY_PATH TECH_NAME=$TECH_NAME INPUT_DELAY=$(echo $INPUT_DELAY) OUTPUT_DELAY=$(echo $OUTPUT_DELAY) TARGET=$TARGET
- mv core-v-cores/cva6/pd/synth/cva6_${TARGET}_synth_modified.v artifacts/cva6_${TARGET}_synth_modified.v
- python3 .gitlab-ci/scripts/report_synth.py core-v-cores/cva6/pd/synth/cva6_${TARGET}/reports/$PERIOD/cva6_$(echo $TECH_NAME)_synth_area.rpt core-v-cores/cva6/pd/synth/synthesis_batch.log
artifacts:
when: always
paths:
- artifacts/cva6_${TARGET}_synth_modified.v
- "artifacts/reports/*.yml"
rules:
- when: manual
allow_failure: true
pub_synthesis:
timeout: 2 hours
extends:
- .verif_test
- .template_job_always_manual
variables:
<<: *synth_vars
TARGET: cv32a6_embedded
PERIOD: "0.85"
script: *synth_script
pub_smoke-gate:
stage: three
extends:
- .backend_test
- .template_job_always_manual
needs:
- job: pub_synthesis
artifacts: true
parallel:
matrix:
- TARGET: [cv64a6_imafdc_sv39, cv32a60x]
- *initjob
- pub_build_tools
- pub_synthesis
variables:
DASHBOARD_JOB_TITLE: "Smoke Gate $TARGET"
DASHBOARD_JOB_DESCRIPTION: "Simple test to check netlist from ASIC synthesis"
DASHBOARD_SORT_INDEX: 6
DASHBOARD_JOB_CATEGORY: "Post Synthesis"
TARGET: cv32a6_embedded
script:
- mkdir -p artifacts/reports
- python3 .gitlab-ci/scripts/report_fail.py
- mv artifacts/tools/spike tools
- echo $SYN_VCS_BASHRC; source $SYN_VCS_BASHRC
- echo $LIB_VERILOG
- echo $FOUNDRY_PATH
- echo $PERIOD
@ -443,182 +410,86 @@ pub_smoke-gate:
- source ./cva6/regress/install-riscv-dv.sh
- source ./cva6/regress/install-riscv-tests.sh
- mv artifacts/cva6_${TARGET}_synth_modified.v core-v-cores/cva6/pd/synth/cva6_${TARGET}_synth_modified.v
- echo $SYN_VCS_BASHRC; source $SYN_VCS_BASHRC
- cd cva6/sim
- make vcs_clean_all
- python3 cva6.py --testlist=../tests/testlist_riscv-tests-cv32a60x-p.yaml --test rv32ui-p-lw --iss_yaml cva6.yaml --target $TARGET --iss=spike,vcs-gate $DV_OPTS
- cd ../..
- cd -
- python3 .gitlab-ci/scripts/report_simu.py cva6/sim/logfile.log
artifacts:
when: always
paths:
- "artifacts/reports/*.yml"
pub_benchmarks:
stage: three
timeout: 2 hours
extends:
- .template_job_always_manual
variables:
DV_TARGET: "cv64a6_imafdc_sv39"
DV_SIMULATORS: "veri-testharness,spike"
DASHBOARD_JOB_TITLE: "BenchMark $DV_TARGET"
DASHBOARD_JOB_DESCRIPTION: "Performance indicator of some benchmark"
DASHBOARD_SORT_INDEX: 7
DASHBOARD_JOB_CATEGORY: "Test suites"
needs:
- job: pub_build_tools
artifacts: true
script:
- mkdir -p artifacts/reports
- python3 .gitlab-ci/scripts/report_fail.py
- source ./cva6/regress/install-cva6.sh
- source ./cva6/regress/install-riscv-dv.sh
- source ./cva6/regress/install-riscv-tests.sh
- source ./cva6/regress/benchmark.sh
- python3 .gitlab-ci/scripts/report_pass.py
artifacts:
when: always
paths:
- "artifacts/reports/*.yml"
pub_coremark:
stage: two
extends:
- .verif_test
- .template_job_full_ci
needs:
- job: pub_build_tools
artifacts: true
- job: pub_smoke
artifacts: false
variables:
DASHBOARD_JOB_TITLE: "CoreMark"
DASHBOARD_JOB_DESCRIPTION: "Performance indicator"
DASHBOARD_SORT_INDEX: 5
DASHBOARD_JOB_CATEGORY: "Performance"
script:
- mkdir -p artifacts/reports
- python3 .gitlab-ci/scripts/report_fail.py
- bash cva6/regress/coremark.sh --no-print
- python3 .gitlab-ci/scripts/report_benchmark.py --coremark cva6/sim/out_*/veri-testharness_sim/core_main.log
artifacts:
when: always
paths:
- "artifacts/reports/*.yml"
pub_dhrystone:
stage: two
extends:
- .verif_test
- .template_job_full_ci
needs:
- job: pub_build_tools
artifacts: true
- job: pub_smoke
artifacts: false
variables:
DASHBOARD_JOB_TITLE: "Dhrystone"
DASHBOARD_JOB_DESCRIPTION: "Performance indicator"
DASHBOARD_SORT_INDEX: 5
DASHBOARD_JOB_CATEGORY: "Performance"
script:
- mkdir -p artifacts/reports
- python3 .gitlab-ci/scripts/report_fail.py
- bash cva6/regress/dhrystone.sh
- python3 .gitlab-ci/scripts/report_benchmark.py --dhrystone cva6/sim/out_*/veri-testharness_sim/dhrystone_main.log
artifacts:
when: always
paths:
- "artifacts/reports/*.yml"
pub_wb_dcache:
stage: three
extends:
- .template_job_always_manual
needs:
- job: pub_build_tools
artifacts: true
variables:
DASHBOARD_JOB_TITLE: "Writeback Data Cache test"
DASHBOARD_JOB_DESCRIPTION: "Test of IP wb_dcache"
DASHBOARD_SORT_INDEX: 8
DASHBOARD_JOB_CATEGORY: "Test suites"
script:
- mkdir -p artifacts/reports
- python3 .gitlab-ci/scripts/report_fail.py
- source ./cva6/regress/install-cva6.sh
- cd core-v-cores/cva6
- source ci/make-tmp.sh
- source ci/build-riscv-tests.sh
- cd ../../../
# Use 'verilator --no-timing' until the timing issues in corev_apu RTL are fixed.
- make verilator="verilator --no-timing" run-asm-tests-verilator defines=WB_DCACHE
- cd ../..
- python3 .gitlab-ci/scripts/report_pass.py
artifacts:
when: always
paths:
- "artifacts/reports/*.yml"
pub_fpga-build:
stage: two
timeout: 90 minutes
extends:
- .verif_test
- .template_job_short_ci
needs:
- job: pub_smoke
artifacts: false
variables:
DASHBOARD_JOB_TITLE: "FPGA Build $TARGET"
DASHBOARD_JOB_DESCRIPTION: "Test of FPGA build flow"
DASHBOARD_SORT_INDEX: 9
DASHBOARD_JOB_CATEGORY: "Synthesis"
parallel:
matrix:
- TARGET: [cv64a6_imafdc_sv39, cv32a60x]
TARGET: cv32a60x
script:
- mkdir -p artifacts/reports
- python3 .gitlab-ci/scripts/report_fail.py
- source $VIVADO_SETUP
- source cva6/regress/install-cva6.sh
- make -C core-v-cores/cva6 fpga target=$TARGET
- mkdir -p artifacts/reports
- mv core-v-cores/cva6/corev_apu/fpga/work-fpga/ariane_xilinx.bit artifacts/ariane_xilinx_$TARGET.bit
- python3 .gitlab-ci/scripts/report_fpga.py core-v-cores/cva6/corev_apu/fpga/reports/ariane.utilization.rpt
artifacts:
when: always
paths:
- "artifacts/ariane_xilinx_$TARGET.bit"
- "artifacts/reports/*.yml"
pub_generated_tests:
stage: two
tags: [$TAGS_RUNNER]
needs:
- job: pub_build_tools
artifacts: true
- job: pub_smoke
artifacts: false
extends:
- .verif_test
variables:
DASHBOARD_SORT_INDEX: 11
DASHBOARD_JOB_CATEGORY: "Code Coverage"
parallel:
matrix:
- list_num: 0
DASHBOARD_JOB_TITLE: "Generated Random tests"
DASHBOARD_JOB_DESCRIPTION: "Generate Random tests using the RISCV-DV"
- list_num: 1
DASHBOARD_JOB_TITLE: "Generated Arithmetic tests"
DASHBOARD_JOB_DESCRIPTION: "Generate Random Arithmetic tests using the RISCV-DV"
DASHBOARD_JOB_TITLE: "Generated Random Arithmetic tests"
DASHBOARD_JOB_DESCRIPTION: "Generate Random Arithmetic tests using CVA6-DV"
- list_num: 2
DASHBOARD_JOB_TITLE: "Generated Hazard Arithmetic tests"
DASHBOARD_JOB_DESCRIPTION: "Generate Hazard register (RAW) Arithmetic tests using CVA6-DV"
- list_num: 3
DASHBOARD_JOB_TITLE: "Generated CSR tests"
DASHBOARD_JOB_DESCRIPTION: "Generate Random CSR tests using the RISCV-DV"
DASHBOARD_JOB_DESCRIPTION: "Generate Random CSR tests using CVA6-DV"
- list_num: 4
DASHBOARD_JOB_TITLE: "Generated MMU tests"
DASHBOARD_JOB_DESCRIPTION: "Generate Random MMU tests using CVA6-DV"
- list_num: 5
DASHBOARD_JOB_TITLE: "Generated Random Load_store tests"
DASHBOARD_JOB_DESCRIPTION: "Generate Random Load_store tests using CVA6-DV"
- list_num: 6
DASHBOARD_JOB_TITLE: "Generated Jump tests"
DASHBOARD_JOB_DESCRIPTION: "Generate Random Arithmetic Jump tests using CVA6-DV"
script:
- mkdir -p artifacts/coverage
- mkdir -p artifacts/reports
- python3 .gitlab-ci/scripts/report_fail.py
- echo $SYN_VCS_BASHRC; source $SYN_VCS_BASHRC
- echo $SYN_VERDI_BASHRC; source $SYN_VERDI_BASHRC
- DV_TARGET=cv64a6_imafdc_sv39 #Specification target
- source ./cva6/regress/dv-generated-tests.sh
- mv cva6/sim/vcs_results/default/vcs.d/simv.vdb artifacts/coverage
- mv cva6/sim/seedlist.yaml artifacts/coverage
@ -628,75 +499,155 @@ pub_generated_tests:
allow_failure: true
timeout: 4h
artifacts:
when: always
paths:
- artifacts/coverage/simv.vdb
- artifacts/coverage/seedlist.yaml
- "artifacts/reports/*.yml"
expire_in: 3 week
pub_generated_xif_tests:
tags: [$TAGS_RUNNER]
extends:
- .verif_test
variables:
DASHBOARD_SORT_INDEX: 12
DASHBOARD_JOB_CATEGORY: "Code Coverage"
parallel:
matrix:
- list_num: 1
DASHBOARD_JOB_TITLE: "Generated Random xif tests"
DASHBOARD_JOB_DESCRIPTION: "Generate Random tests for cvxif using CVA6-DV"
script:
- mkdir -p artifacts/coverage
- source ./cva6/regress/dv-generated-xif-tests.sh
- mv cva6/sim/vcs_results/default/vcs.d/simv.vdb artifacts/coverage
- mv cva6/sim/seedlist.yaml artifacts/coverage
- python3 .gitlab-ci/scripts/report_pass.py
rules:
- when: manual
allow_failure: true
timeout: 4h
artifacts:
expire_in: 3 week
pub_directed_isacov-tests:
tags: [$TAGS_RUNNER]
extends:
- .verif_test
variables:
DASHBOARD_SORT_INDEX: 13
DASHBOARD_JOB_CATEGORY: "Functional Coverage"
parallel:
matrix:
- list_num: 0
DASHBOARD_JOB_TITLE: "Directed tests"
DASHBOARD_JOB_DESCRIPTION: "Execute directed tests to improve functional coverage of ISA"
script:
- mkdir -p artifacts/coverage
- source ./cva6/regress/dv-generated-tests.sh
- mv cva6/sim/vcs_results/default/vcs.d/simv.vdb artifacts/coverage
- python3 .gitlab-ci/scripts/report_pass.py
rules:
- when: manual
allow_failure: true
timeout: 4h
artifacts:
expire_in: 3 week
pub_directed_xif-tests:
tags: [$TAGS_RUNNER]
extends:
- .verif_test
variables:
DASHBOARD_SORT_INDEX: 15
DASHBOARD_JOB_CATEGORY: "Functional Coverage"
parallel:
matrix:
- list_num: 0
DASHBOARD_JOB_TITLE: "Directed tests"
DASHBOARD_JOB_DESCRIPTION: "Execute directed tests to improve functional coverage of cvxif"
script:
- mkdir -p artifacts/coverage
- source ./cva6/regress/dv-generated-xif-tests.sh
- mv cva6/sim/vcs_results/default/vcs.d/simv.vdb artifacts/coverage
- python3 .gitlab-ci/scripts/report_pass.py
rules:
- when: manual
allow_failure: true
timeout: 4h
artifacts:
expire_in: 3 week
pub_fpga-boot:
stage: three
tags: [fpga,shell]
extends:
- .backend_test
needs:
- job: pub_fpga-build
artifacts: true
- *initjob
- pub_build_tools
- pub_fpga-build
variables:
VERILATOR_INSTALL_DIR: "NO" # Skip install and checks of verilator
SPIKE_ROOT: "NO" # Skip install and checks of spike
DASHBOARD_JOB_TITLE: "FPGA Linux64 Boot "
DASHBOARD_JOB_DESCRIPTION: "Test of Linux 64 bits boot on FPGA Genesys2"
DASHBOARD_JOB_TITLE: "FPGA Linux32 Boot "
DASHBOARD_JOB_DESCRIPTION: "Test of Linux 32 bits boot on FPGA Genesys2"
DASHBOARD_SORT_INDEX: 10
DASHBOARD_JOB_CATEGORY: "Synthesis"
script:
- mkdir -p artifacts/reports
- python3 .gitlab-ci/scripts/report_fail.py
- source cva6/regress/install-cva6.sh
- source $VIVADO2022_SETUP
- mkdir -p core-v-cores/cva6/corev_apu/fpga/work-fpga
- mv artifacts/ariane_xilinx_cv64a6_imafdc_sv39.bit core-v-cores/cva6/corev_apu/fpga/work-fpga/ariane_xilinx.bit
- mv artifacts/ariane_xilinx_cv32a60x.bit core-v-cores/cva6/corev_apu/fpga/work-fpga/ariane_xilinx.bit
- cd core-v-cores/cva6/corev_apu/fpga/scripts
- source check_fpga_boot.sh
- cd -
- python3 .gitlab-ci/scripts/report_fpga_boot.py core-v-cores/cva6/corev_apu/fpga/scripts/fpga_boot.rpt
artifacts:
when: always
paths:
- "artifacts/reports/*.yml"
code_coverage-report:
stage: three
tags: [$TAGS_RUNNER]
extends:
- .backend_test
needs:
- job: pub_generated_tests
artifacts: true
- *initjob
- pub_generated_tests
- pub_directed_isacov-tests
- pub_generated_xif_tests
- pub_directed_xif-tests
variables:
DASHBOARD_JOB_TITLE: "Report merge coverage"
DASHBOARD_JOB_DESCRIPTION: "Report merge coverage of generated tests"
DASHBOARD_SORT_INDEX: 12
DASHBOARD_SORT_INDEX: 14
DASHBOARD_JOB_CATEGORY: "Code Coverage"
script:
- mkdir -p artifacts/reports
- python3 .gitlab-ci/scripts/report_fail.py
- echo $SYN_VCS_BASHRC; source $SYN_VCS_BASHRC
- mkdir -p artifacts/cov_reports/
- mkdir -p cva6/sim/vcs_results/default/vcs.d
- mv artifacts/coverage/simv.vdb cva6/sim/vcs_results/default/vcs.d/
- mv artifacts/coverage/seedlist.yaml cva6/sim/seedlist.yaml
- echo $SYN_VCS_BASHRC; source $SYN_VCS_BASHRC
- echo $SYN_VERDI_BASHRC; source $SYN_VERDI_BASHRC
- make -C cva6/sim generate_cov_dash
- mv cva6/sim/urgReport artifacts/cov_reports/
- python3 .gitlab-ci/scripts/report_pass.py
rules:
- when: on_success
artifacts:
when: always
paths:
- "artifacts/cov_reports/urgReport"
- "artifacts/reports/*.yml"
expire_in: 3 week
merge_report:
stage: .post
check gitlab jobs status:
stage: find failures
tags: [$TAGS_RUNNER]
rules:
- if: '$DASHBOARD_URL'
when: on_failure
- when: never
variables:
DASHBOARD_JOB_TITLE: "Environment check"
DASHBOARD_JOB_DESCRIPTION: "Detect environment issues"
DASHBOARD_SORT_INDEX: 0
DASHBOARD_JOB_CATEGORY: "Environment"
script:
- rm -rf artifacts/
- mkdir -p artifacts/reports
- python3 .gitlab-ci/scripts/report_envfail.py
artifacts: *artifacts
merge reports:
stage: report
tags: [$TAGS_RUNNER]
rules:
- if: '$DASHBOARD_URL'
@ -710,4 +661,3 @@ merge_report:
when: always
paths:
- "artifacts/reports/pipeline_report_$CI_PIPELINE_ID.yml"

View file

@ -17,8 +17,8 @@ iterations = None
# Keep it up-to-date with compiler version and core performance improvements
# Will fail if the number of cycles is different from this one
valid_cycles = {
'dhrystone': 221425,
'coremark': 697868,
'dhrystone': 217900,
'coremark': 670777,
}
for arg in sys.argv[1:]:

View file

@ -0,0 +1,17 @@
# Copyright 2023 Thales Silicon Security
#
# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
# You may obtain a copy of the License at https://solderpad.org/licenses/
#
# Original Author: Côme ALLART - Thales
import report_builder as rb
metric = rb.TableStatusMetric('')
metric.add_fail('Environment failure detected. Some reports might be missing')
report = rb.Report()
report.add_metric(metric)
report.dump()

View file

@ -10,15 +10,20 @@
import re
import sys
import os
import yaml
import report_builder as rb
with open(str(sys.argv[1]), 'r') as f:
log_path = str(sys.argv[1])
with open(log_path, 'r') as f:
log = f.read()
with open(str(sys.argv[2]), 'r') as f:
synthesis_log = f.read()
kgate_ratio = int(os.environ["NAND2_AREA"])
path_re = r'^core-v-cores/cva6/pd/synth/cva6_([^/]+)'
with open("core-v-cores/cva6/.gitlab-ci/expected_synth.yml", "r") as f:
expected = yaml.safe_load(f)
#Compile & elaborate log:
log_metric = rb.LogMetric('Synthesis full log')
@ -49,11 +54,24 @@ hier = pattern.findall(log)
total_area = float(hier[0][1])
result_metric = rb.TableMetric('Global results')
label = f'{int(total_area/kgate_ratio)} kGates'
result_metric.add_value("Total area", label)
kgates = total_area / kgate_ratio
gates = int(kgates * 1000)
result_metric.add_value("Total area", f'{gates} Gates')
for i in global_val:
rel_area = 0 if total_area == 0 else int(float(i[1]) / total_area * 100)
result_metric.add_value(i[0], f'{rel_area} %')
match = re.match(path_re, log_path)
if match:
target = match.group(1)
if target in expected:
diff = gates - expected[target]['gates']
if abs(diff) >= 300:
result_metric.fail()
else:
raise Exception("unexpected target: {target}")
else:
raise Exception("unexpected file name: {log_path}")
hier_metric = rb.TableMetric('Hierarchies details')
for i in hier:
@ -66,6 +84,7 @@ for i in hier:
#int(float(i[5]))/int(float(i[1])*100), # % black box
)
report = rb.Report(label)
report = rb.Report(f'{int(kgates)} kGates')
report.add_metric(result_metric, hier_metric, log_metric)
report.dump()

View file

@ -19,13 +19,25 @@ There are README files in each directory with additional information.
## Prerequisites
To execute tests on CVA6 core, you need a RISC-V toolchain.
For instance, you can use the gcc 10 toolchain.
To build and install it, use scripts located at
https://github.com/ThalesGroup/cva6-tools
Be aware that only gcc 11.1.0 or newer are supported in core-v-verif repository.
To build and install riscv gcc compiler in local, you can use the following commands :
Once the toolchain is installed, set the `RISCV` environment variable
to your toolchain installation path e.g. `RISCV = /path/to/gcc-10.2`
to run the test scripts.
- `git clone https://github.com/riscv-collab/riscv-gnu-toolchain`
- `cd riscv-gnu-toolchain`
- `git clone https://github.com/gcc-mirror/gcc -b releases/gcc-13 gcc-13`
- ```./configure prefix:/path/to/installation/directory --with-multilib-generator="rv32e-ilp32e--;rv32i-ilp32--;rv32im-ilp32--;rv32iac-ilp32--;rv32imac-ilp32--;rv32imafc-ilp32f--;rv32imafdc-ilp32d--;rv64i-lp64--;rv64ic-lp64--;rv64iac-lp64--;rv64imac-lp64--;rv64imafdc-lp64d--;rv64im-lp64--;" --with-gcc-src=`pwd`/gcc-13```
- `make j32`
These commands will install the riscv gcc 13.1.0 compiler which is the latest version.
Once running the previous commands, your environment must be updated with :
- `export RISCV=/path/to/installation/directory`
- `export RISCV_PREFIX=/path/to/installation/directory/bin/riscv64-unknown-`
- `export RISCV_GCC=/path/to/installation/directory/bin/riscv64-unknown-gcc`
- `export CV_SW_PREFIX=riscv64-unknown-elf-`
This 4 variables will ensure you use correctly the new gcc compiler you have just installed.
You will now be able to run the test scripts.
## Test execution
Run one of the shell scripts:

View file

@ -1,998 +0,0 @@
(VIssue Interface
p0
ccopy_reg
_reconstructor
p1
(cvp_pack
Ip
p2
c__builtin__
object
p3
Ntp4
Rp5
(dp6
Vprop_count
p7
I9
sVname
p8
g0
sVprop_list
p9
(dp10
sVip_num
p11
I0
sVwid_order
p12
I0
sVrfu_dict
p13
(dp14
sVrfu_list
p15
(lp16
(V000_issue_req signals stable
p17
g1
(cvp_pack
Prop
p18
g3
Ntp19
Rp20
(dp21
Vitem_count
p22
I1
sg8
g17
sVtag
p23
VVP_CVXIF_F000_S000
p24
sVitem_list
p25
(dp26
sg12
I0
sg15
(lp27
(V000
p28
g1
(cvp_pack
Item
p29
g3
Ntp30
Rp31
(dp32
g8
V000
p33
sg23
VVP_CVXIF_F000_S000_I000
p34
sVdescription
p35
VThe \u201cinstr\u201d and \u201cmode\u201d signals remain stable during an Issue request transaction.
p36
sVpurpose
p37
V
p38
sVverif_goals
p39
VCheck that \u201cmode\u201d and \u201cinstr\u201d are stable during an issue transaction (cannot be modified by an instruction when transaction issue is in process)
p40
sVcoverage_loc
p41
g38
sVref_mode
p42
Vpage
p43
sVref_page
p44
g38
sVref_section
p45
g38
sVref_viewer
p46
Vfirefox
p47
sVpfc
p48
I4
sVtest_type
p49
I3
sVcov_method
p50
I2
sVcores
p51
I56
sVcomments
p52
g38
sVstatus
p53
g38
sVsimu_target_list
p54
(lp55
sg15
(lp56
sVrfu_list_2
p57
(lp58
sg13
(dp59
Vlock_status
p60
I0
ssbtp61
asVrfu_list_1
p62
(lp63
sg57
(lp64
sg13
(dp65
sbtp66
a(V001_mode signal value
p67
g1
(g18
g3
Ntp68
Rp69
(dp70
g22
I2
sg8
g67
sg23
VVP_CVXIF_F000_S001
p71
sg25
(dp72
sg12
I1
sg15
(lp73
(V000
p74
g1
(g29
g3
Ntp75
Rp76
(dp77
g8
V000
p78
sg23
VVP_CVXIF_F000_S001_I000
p79
sg35
VWhen issue transaction starts, instruction and current CPU mode are provided
p80
sg37
g38
sg39
VCheck that a mode modification coming from execution of a first instruction is well provided to the following offloaded instruction
p81
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I3
sg49
I3
sg50
I1
sg51
I56
sg52
g38
sg53
g38
sg54
(lp82
sg15
(lp83
sg57
(lp84
sg13
(dp85
g60
I0
ssbtp86
a(V001
p87
g1
(g29
g3
Ntp88
Rp89
(dp90
g8
V001
p91
sg23
VVP_CVXIF_F000_S001_I001
p92
sg35
VCheck \u201cmode\u201d signal values.
p93
sg37
g38
sg39
VCheck that mode take a value that the CPU supports : Privilege level (2\u2019b00 = User, 2\u2019b01 = Supervisor, 2\u2019b10 = Reserved,\u000a 2\u2019b11 = Machine).
p94
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I-1
sg49
I-1
sg50
I-1
sg51
I56
sg52
g38
sg53
g38
sg54
(lp95
sg15
(lp96
sg57
(lp97
sg13
(dp98
g60
I0
ssbtp99
asg62
(lp100
sg57
(lp101
sg13
(dp102
sbtp103
a(V002_rs_valid signal transition order
p104
g1
(g18
g3
Ntp105
Rp106
(dp107
g22
I1
sg8
g104
sg23
VVP_CVXIF_F000_S002
p108
sg25
(dp109
sg12
I2
sg15
(lp110
(V000
p111
g1
(g29
g3
Ntp112
Rp113
(dp114
g8
V000
p115
sg23
VVP_CVXIF_F000_S002_I000
p116
sg35
VDuring a transaction, each bit of \u201crs_valid\u201d can transition from 0 to 1 but are not allowed to transition back to 0.
p117
sg37
g38
sg39
VFor issue transaction which lasts more than one cycle, check that asserted \u201crs_valid\u201d signals do not transition back to 0.(for i in [0;2] if rs_valid[i] = 1 then rs_valid[i] \u2192 0 cannot happen)
p118
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I4
sg49
I3
sg50
I2
sg51
I56
sg52
g38
sg53
g38
sg54
(lp119
sg15
(lp120
sg57
(lp121
sg13
(dp122
g60
I0
ssbtp123
asg62
(lp124
sg57
(lp125
sg13
(dp126
sbtp127
a(V003_rs signal value
p128
g1
(g18
g3
Ntp129
Rp130
(dp131
g22
I3
sg8
g128
sg23
VVP_CVXIF_F000_S003
p132
sg25
(dp133
sg12
I3
sg15
(lp134
(V000
p135
g1
(g29
g3
Ntp136
Rp137
(dp138
g8
V000
p139
sg23
VVP_CVXIF_F000_S003_I000
p140
sg35
VIf XLEN = X_RFR_WIDTH, then rs[X_NUM_RS-1:0] correspond to rs1 and rs2 CPU registers (and rs3 if X_NUM_RS = 3).
p141
sg37
g38
sg39
VFor every issue transaction check that rs signal correspond to rs1,rs2(rs3) value in CPU register file.
p142
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I3
sg49
I3
sg50
I1
sg51
I56
sg52
g38
sg53
g38
sg54
(lp143
sg15
(lp144
sg57
(lp145
sg13
(dp146
g60
I0
ssbtp147
a(V001
p148
g1
(g29
g3
Ntp149
Rp150
(dp151
g8
V001
p152
sg23
VVP_CVXIF_F000_S003_I001
p153
sg35
Vrs signals are only required to be stable during the part of a transaction in which these signals are considered to be valid.
p154
sg37
g38
sg39
VCheck that rs signals are stable when issue_valid==1 && the corresponding bit in rs_valid is 1.
p155
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I4
sg49
I-1
sg50
I2
sg51
I56
sg52
g38
sg53
g38
sg54
(lp156
sg15
(lp157
sg57
(lp158
sg13
(dp159
g60
I0
ssbtp160
a(V002
p161
g1
(g29
g3
Ntp162
Rp163
(dp164
g8
V002
p165
sg23
VVP_CVXIF_F000_S003_I002
p166
sg35
VIf XLEN != X_RFR_WIDTH , then rs[X_NUM_RS-1:0] correspond to even/odd register pair with rs1, rs2, (rs3) are even register and even register is provided in the 32 lower bits of rs signal.
p167
sg37
g38
sg39
VFor every issue transaction check that rs signal correspond to the concatenation of rs1/rs1+1,rs2/rs2+1, (rs3/rs3+1) value in CPU register file and even register is in the 32 lower bits of rs.
p168
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I-1
sg49
I-1
sg50
I-1
sg51
I56
sg52
g38
sg53
g38
sg54
(lp169
sg15
(lp170
sg57
(lp171
sg13
(dp172
g60
I0
ssbtp173
asg62
(lp174
sg57
(lp175
sg13
(dp176
sbtp177
a(V004_Default value for unaccepted instruction
p178
g1
(g18
g3
Ntp179
Rp180
(dp181
g22
I1
sg8
g178
sg23
VVP_CVXIF_F000_S004
p182
sg25
(dp183
sg12
I4
sg15
(lp184
(V000
p185
g1
(g29
g3
Ntp186
Rp187
(dp188
g8
V000
p189
sg23
VVP_CVXIF_F000_S004_I000
p190
sg35
VIf accept == 0 :\u000aWriteback == 0; dualwrite == 0; dualread == 0; loadstore == 0; exc = 0.
p191
sg37
g38
sg39
VCheck that for writeback; dualwrite; dualread; loadstore; exc signals if accept == 0 then all those signals are 0.
p192
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I4
sg49
I3
sg50
I2
sg51
I56
sg52
g38
sg53
g38
sg54
(lp193
sg15
(lp194
sg57
(lp195
sg13
(dp196
g60
I0
ssbtp197
asg62
(lp198
sg57
(lp199
sg13
(dp200
sbtp201
a(V005_Illegal Instruction causes
p202
g1
(g18
g3
Ntp203
Rp204
(dp205
g22
I1
sg8
g202
sg23
VVP_CVXIF_F000_S005
p206
sg25
(dp207
sg12
I5
sg15
(lp208
(V000
p209
g1
(g29
g3
Ntp210
Rp211
(dp212
g8
V000
p213
sg23
VVP_CVXIF_F000_S005_I000
p214
sg35
VThe CPU shall cause an illegal instruction if:\u000a- an instruction is considered to be valid by the CPU and accepted by the coprocessor (accept = 1)\u000a- neither to be valid by the CPU nor accepted by the coprocessor (accept = 0)
p215
sg37
g38
sg39
V- CPU causes illegal instruction for instruction accepted by the core and the coprocessor.\u000a- CPU causes illegal instruction exception for instruction that are not valid for coprocessor and CPU
p216
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I3
sg49
I3
sg50
I1
sg51
I56
sg52
g38
sg53
g38
sg54
(lp217
sg15
(lp218
sg57
(lp219
sg13
(dp220
g60
I0
ssbtp221
asg62
(lp222
sg57
(lp223
sg13
(dp224
sbtp225
a(V006_issue uniquness
p226
g1
(g18
g3
Ntp227
Rp228
(dp229
g22
I1
sg8
g226
sg23
VVP_CVXIF_F000_S006
p230
sg25
(dp231
sg12
I6
sg15
(lp232
(V000
p233
g1
(g29
g3
Ntp234
Rp235
(dp236
g8
V000
p237
sg23
VVP_CVXIF_F000_S006_I000
p238
sg35
VCheck for issue id validity.
p239
sg37
g38
sg39
VCheck that the issue interface doesn't issue an "id" that isn't legal to be used (has not fully completed).
p240
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I11
sg49
I3
sg50
I10
sg51
I56
sg52
g38
sg53
g38
sg54
(lp241
sg15
(lp242
sg57
(lp243
sg13
(dp244
g60
I0
ssbtp245
asg62
(lp246
sg57
(lp247
sg13
(dp248
sbtp249
a(V007_coprocessor decoding
p250
g1
(g18
g3
Ntp251
Rp252
(dp253
g22
I1
sg8
g250
sg23
VVP_CVXIF_F000_S007
p254
sg25
(dp255
sg12
I7
sg15
(lp256
(V000
p257
g1
(g29
g3
Ntp258
Rp259
(dp260
g8
V000
p261
sg23
VVP_CVXIF_F000_S007_I000
p262
sg35
VAccept = 1 if: \u000a- coprocessor can handle the instruction based on decoding \u201cinstr\u201dand "mode".\u000a- \u201cissue_valid\u201d == 1 and required bit(s) of \u201crs_valid\u201d are 1.
p263
sg37
g38
sg39
VTo be checked in coprocessor.
p264
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I3
sg49
I3
sg50
I1
sg51
I56
sg52
g38
sg53
g38
sg54
(lp265
sg15
(lp266
sg57
(lp267
sg13
(dp268
g60
I0
ssbtp269
asg62
(lp270
sg57
(lp271
sg13
(dp272
sbtp273
a(V008_Transaction definition
p274
g1
(g18
g3
Ntp275
Rp276
(dp277
g22
I1
sg8
g274
sg23
VVP_CVXIF_F000_S008
p278
sg25
(dp279
sg12
I8
sg15
(lp280
(V000
p281
g1
(g29
g3
Ntp282
Rp283
(dp284
g8
V000
p285
sg23
VVP_CVXIF_F000_S008_I000
p286
sg35
V\u201cissue_resp\u201d signals and \u201cissue_req\u201d signals are accepted when \u201cissue_valid\u201d == \u201cissue_ready\u201d == 1\u000a\u201cissue_resp\u201d is valid when "valid==ready==1".\u000a\u201cissue_req\u201d is valid when "valid==1"
p287
sg37
g38
sg39
VThe definition of a transaction. \u000aNot to be verified.
p288
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I11
sg49
I10
sg50
I10
sg51
I56
sg52
g38
sg53
g38
sg54
(lp289
sg15
(lp290
sg57
(lp291
sg13
(dp292
g60
I0
ssbtp293
asg62
(lp294
sg57
(lp295
sg13
(dp296
sbtp297
asVrfu_list_0
p298
(lp299
sg62
(lp300
sVvptool_gitrev
p301
V$Id: a782de3eec3de5ff99661fb165c09f541b4228d0 $
p302
sVio_fmt_gitrev
p303
V$Id: 2f6f9e7bc800d8b831382463dc706473c6c6ad8c $
p304
sVconfig_gitrev
p305
V$Id: 0422e19126dae20ffc4d5a84e4ce3de0b6eb4eb5 $
p306
sVymlcfg_gitrev
p307
V$Id: 286c689bd48b7a58f9a37754267895cffef1270c $
p308
sbtp309
.

View file

@ -0,0 +1,285 @@
!Feature
next_elt_id: 9
name: Issue Interface
id: 0
display_order: 0
subfeatures: !!omap
- 000_issue_req signals stable: !Subfeature
name: 000_issue_req signals stable
tag: VP_CVXIF_F000_S000
next_elt_id: 1
display_order: 0
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F000_S000_I000
description: The “instr” and “mode” signals remain stable during an Issue
request transaction.
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: Check that “mode” and “instr” are stable during an issue transaction
(cannot be modified by an instruction when transaction issue is in process)
pfc: 4
test_type: 3
cov_method: 2
cores: 56
coverage_loc: ''
comments: ''
- 001_mode signal value: !Subfeature
name: 001_mode signal value
tag: VP_CVXIF_F000_S001
next_elt_id: 2
display_order: 1
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F000_S001_I000
description: When issue transaction starts, instruction and current CPU mode
are provided
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: Check that a mode modification coming from execution of a first
instruction is well provided to the following offloaded instruction
pfc: 3
test_type: 3
cov_method: 1
cores: 56
coverage_loc: ''
comments: ''
- '001': !VerifItem
name: '001'
tag: VP_CVXIF_F000_S001_I001
description: Check “mode” signal values.
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: "Check that mode take a value that the CPU supports : Privilege\
\ level (2b00 = User, 2b01 = Supervisor, 2b10 = Reserved,\n 2b11 = Machine)."
pfc: -1
test_type: -1
cov_method: -1
cores: 56
coverage_loc: ''
comments: ''
- 002_rs_valid signal transition order: !Subfeature
name: 002_rs_valid signal transition order
tag: VP_CVXIF_F000_S002
next_elt_id: 1
display_order: 2
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F000_S002_I000
description: During a transaction, each bit of “rs_valid” can transition from
0 to 1 but are not allowed to transition back to 0.
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: For issue transaction which lasts more than one cycle, check
that asserted “rs_valid” signals do not transition back to 0.(for i in [0;2]
if rs_valid[i] = 1 then rs_valid[i] → 0 cannot happen)
pfc: 4
test_type: 3
cov_method: 2
cores: 56
coverage_loc: ''
comments: ''
- 003_rs signal value: !Subfeature
name: 003_rs signal value
tag: VP_CVXIF_F000_S003
next_elt_id: 3
display_order: 3
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F000_S003_I000
description: If XLEN = X_RFR_WIDTH, then rs[X_NUM_RS-1:0] correspond to rs1
and rs2 CPU registers (and rs3 if X_NUM_RS = 3).
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: For every issue transaction check that rs signal correspond to
rs1,rs2(rs3) value in CPU register file.
pfc: 3
test_type: 3
cov_method: 1
cores: 56
coverage_loc: ''
comments: ''
- '001': !VerifItem
name: '001'
tag: VP_CVXIF_F000_S003_I001
description: rs signals are only required to be stable during the part of
a transaction in which these signals are considered to be valid.
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: Check that rs signals are stable when issue_valid==1 && the corresponding
bit in rs_valid is 1.
pfc: 4
test_type: -1
cov_method: 2
cores: 56
coverage_loc: ''
comments: ''
- '002': !VerifItem
name: '002'
tag: VP_CVXIF_F000_S003_I002
description: If XLEN != X_RFR_WIDTH , then rs[X_NUM_RS-1:0] correspond to
even/odd register pair with rs1, rs2, (rs3) are even register and even register
is provided in the 32 lower bits of rs signal.
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: "For every issue transaction check that rs signal correspond\
\ to the concatenation of rs1/rs1+1,rs2/rs2+1, (rs3/rs3+1) value in CPU\
\ register file and even register is in the 32 lower bits of rs.\n\nCan't\
\ be check XLEN == X_RFR_WIDTH"
pfc: -1
test_type: -1
cov_method: -1
cores: 56
coverage_loc: ''
comments: ''
- 004_Default value for unaccepted instruction: !Subfeature
name: 004_Default value for unaccepted instruction
tag: VP_CVXIF_F000_S004
next_elt_id: 1
display_order: 4
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F000_S004_I000
description: "If accept == 0 :\nWriteback == 0; dualwrite == 0; dualread ==\
\ 0; loadstore == 0; exc = 0."
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: Check that for writeback; dualwrite; dualread; loadstore; exc
signals if accept == 0 then all those signals are 0.
pfc: 4
test_type: 3
cov_method: 2
cores: 56
coverage_loc: ''
comments: ''
- 005_Illegal Instruction causes: !Subfeature
name: 005_Illegal Instruction causes
tag: VP_CVXIF_F000_S005
next_elt_id: 1
display_order: 5
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F000_S005_I000
description: "The CPU shall cause an illegal instruction if:\n- an instruction\
\ is considered to be valid by the CPU and accepted by the coprocessor (accept\
\ = 1)\n- neither to be valid by the CPU nor accepted by the coprocessor\
\ (accept = 0)"
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: "- CPU causes illegal instruction for instruction accepted by\
\ the core and the coprocessor.\n- CPU causes illegal instruction exception\
\ for instruction that are not valid for coprocessor and CPU"
pfc: 3
test_type: 3
cov_method: 1
cores: 56
coverage_loc: ''
comments: ''
- 006_issue uniquness: !Subfeature
name: 006_issue uniquness
tag: VP_CVXIF_F000_S006
next_elt_id: 1
display_order: 6
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F000_S006_I000
description: Check for issue id validity.
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: Check that the issue interface doesn't issue an "id" that isn't
legal to be used (has not fully completed).
pfc: 11
test_type: 3
cov_method: 10
cores: 56
coverage_loc: ''
comments: ''
- 007_coprocessor decoding: !Subfeature
name: 007_coprocessor decoding
tag: VP_CVXIF_F000_S007
next_elt_id: 1
display_order: 7
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F000_S007_I000
description: "Accept = 1 if: \n- coprocessor can handle the instruction based\
\ on decoding “instr” and \"mode\".\n- “issue_valid” == 1 and required bit(s)\
\ of “rs_valid” are 1."
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: To be checked in coprocessor.
pfc: 3
test_type: 3
cov_method: 1
cores: 56
coverage_loc: ''
comments: ''
- 008_Transaction definition: !Subfeature
name: 008_Transaction definition
tag: VP_CVXIF_F000_S008
next_elt_id: 1
display_order: 8
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F000_S008_I000
description: "“issue_resp” signals and “issue_req” signals are accepted when\
\ “issue_valid” == “issue_ready” == 1\n“issue_resp” is valid when \"valid==ready==1\"\
.\n“issue_req” is valid when \"valid==1\""
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: "The definition of a transaction. \nNot to be verified."
pfc: 11
test_type: 10
cov_method: 10
cores: 56
coverage_loc: ''
comments: ''
vptool_gitrev: '$Id: b0efb3ae3f9057b71a577d43c2b77f1cfb2ef82f $'
io_fmt_gitrev: '$Id: 7ee5d68801f5498a957bcbe23fcad87817a364c5 $'
config_gitrev: '$Id: 0422e19126dae20ffc4d5a84e4ce3de0b6eb4eb5 $'
ymlcfg_gitrev: '$Id: 286c689bd48b7a58f9a37754267895cffef1270c $'

View file

@ -1,418 +0,0 @@
(VCommit Interface
p0
ccopy_reg
_reconstructor
p1
(cvp_pack
Ip
p2
c__builtin__
object
p3
Ntp4
Rp5
(dp6
Vprop_count
p7
I4
sVname
p8
g0
sVprop_list
p9
(dp10
sVip_num
p11
I1
sVwid_order
p12
I1
sVrfu_dict
p13
(dp14
sVrfu_list
p15
(lp16
(V000_commit_valid pulse
p17
g1
(cvp_pack
Prop
p18
g3
Ntp19
Rp20
(dp21
Vitem_count
p22
I1
sg8
g17
sVtag
p23
VVP_CVXIF_F001_S000
p24
sVitem_list
p25
(dp26
sg12
I0
sg15
(lp27
(V000
p28
g1
(cvp_pack
Item
p29
g3
Ntp30
Rp31
(dp32
g8
V000
p33
sg23
VVP_CVXIF_F001_S000_I000
p34
sVdescription
p35
VThe \u201ccommit_valid\u201d == 1 exactly one clk cycle for every offloaded Instruction by the coprocessor (whether accepted or not).
p36
sVpurpose
p37
V
p38
sVverif_goals
p39
VFor every offloaded instruction, check that commit_valid is asserted exactly one clk cycle ( is a pulse ).
p40
sVcoverage_loc
p41
g38
sVref_mode
p42
Vpage
p43
sVref_page
p44
g38
sVref_section
p45
g38
sVref_viewer
p46
Vfirefox
p47
sVpfc
p48
I4
sVtest_type
p49
I3
sVcov_method
p50
I2
sVcores
p51
I56
sVcomments
p52
g38
sVstatus
p53
g38
sVsimu_target_list
p54
(lp55
sg15
(lp56
sVrfu_list_2
p57
(lp58
sg13
(dp59
Vlock_status
p60
I0
ssbtp61
asVrfu_list_1
p62
(lp63
sg57
(lp64
sg13
(dp65
sbtp66
a(V001_commit transaction uniquness
p67
g1
(g18
g3
Ntp68
Rp69
(dp70
g22
I1
sg8
g67
sg23
VVP_CVXIF_F001_S001
p71
sg25
(dp72
sg12
I1
sg15
(lp73
(V000
p74
g1
(g29
g3
Ntp75
Rp76
(dp77
g8
V000
p78
sg23
VVP_CVXIF_F001_S001_I000
p79
sg35
VThere is a unique commit transaction for every issue transaction (unique until an instruction has "fully completed" = its result has been submitted).
p80
sg37
g38
sg39
VCheck that the commit interface doesn't commit an "id" that isn't legal to be used (hasn't been seen in earlier stages, or has not fully completed).
p81
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I1
sg49
I10
sg50
I10
sg51
I56
sg52
g38
sg53
g38
sg54
(lp82
sg15
(lp83
sg57
(lp84
sg13
(dp85
g60
I0
ssbtp86
asg62
(lp87
sg57
(lp88
sg13
(dp89
sbtp90
a(V002_commit transaction for every issue transaction
p91
g1
(g18
g3
Ntp92
Rp93
(dp94
g22
I1
sg8
g91
sg23
VVP_CVXIF_F001_S002
p95
sg25
(dp96
sg12
I2
sg15
(lp97
(V000
p98
g1
(g29
g3
Ntp99
Rp100
(dp101
g8
V000
p102
sg23
VVP_CVXIF_F001_S002_I000
p103
sg35
V- The CPU shall perform a commit transaction for every issue transaction, independent of the accept value of the issue transaction.\u000a- For each offloaded and accepted instruction the core is guaranteed to (eventually) signal that such an instruction is either no longer speculative and can be committed (commit_valid is 1 and commit_kill is 0) or that the instruction must be killed (commit_valid is 1 and commit_kill is 1).
p104
sg37
g38
sg39
VCheck that for each issue transaction, the commit transaction is sent at the same clock cycle than the issue transaction, or at any clock cycle after the issue transaction.
p105
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I4
sg49
I3
sg50
I2
sg51
I56
sg52
g38
sg53
g38
sg54
(lp106
sg15
(lp107
sg57
(lp108
sg13
(dp109
g60
I0
ssbtp110
asg62
(lp111
sg57
(lp112
sg13
(dp113
sbtp114
a(V003_Transaction definition
p115
g1
(g18
g3
Ntp116
Rp117
(dp118
g22
I1
sg8
g115
sg23
VVP_CVXIF_F001_S003
p119
sg25
(dp120
sg12
I3
sg15
(lp121
(V000
p122
g1
(g29
g3
Ntp123
Rp124
(dp125
g8
V000
p126
sg23
VVP_CVXIF_F001_S003_I000
p127
sg35
VThe signals in commit are valid when commit_valid is 1.
p128
sg37
g38
sg39
VThe definition of a transaction.\u000aNot to be verified.
p129
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I11
sg49
I-1
sg50
I10
sg51
I56
sg52
g38
sg53
g38
sg54
(lp130
sg15
(lp131
sg57
(lp132
sg13
(dp133
g60
I0
ssbtp134
asg62
(lp135
sg57
(lp136
sg13
(dp137
sbtp138
asVrfu_list_0
p139
(lp140
sg62
(lp141
sVvptool_gitrev
p142
V$Id: a782de3eec3de5ff99661fb165c09f541b4228d0 $
p143
sVio_fmt_gitrev
p144
V$Id: 2f6f9e7bc800d8b831382463dc706473c6c6ad8c $
p145
sVconfig_gitrev
p146
V$Id: 0422e19126dae20ffc4d5a84e4ce3de0b6eb4eb5 $
p147
sVymlcfg_gitrev
p148
V$Id: 286c689bd48b7a58f9a37754267895cffef1270c $
p149
sbtp150
.

View file

@ -0,0 +1,110 @@
!Feature
next_elt_id: 4
name: Commit Interface
id: 1
display_order: 1
subfeatures: !!omap
- 000_commit_valid pulse: !Subfeature
name: 000_commit_valid pulse
tag: VP_CVXIF_F001_S000
next_elt_id: 1
display_order: 0
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F001_S000_I000
description: The “commit_valid” == 1 exactly one clk cycle for every offloaded Instruction
by the coprocessor (whether accepted or not).
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: For every offloaded instruction, check that commit_valid is
asserted exactly one clk cycle ( is a pulse ).
pfc: 4
test_type: 3
cov_method: 2
cores: 56
coverage_loc: ''
comments: ''
- 001_commit transaction uniquness: !Subfeature
name: 001_commit transaction uniquness
tag: VP_CVXIF_F001_S001
next_elt_id: 1
display_order: 1
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F001_S001_I000
description: There is a unique commit transaction for every issue transaction
(unique until an instruction has "fully completed" = its result has been
submitted).
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: Check that the commit interface doesn't commit an "id" that isn't
legal to be used (hasn't been seen in earlier stages, or has not fully completed).
pfc: 1
test_type: 10
cov_method: 10
cores: 56
coverage_loc: ''
comments: ''
- 002_commit transaction for every issue transaction: !Subfeature
name: 002_commit transaction for every issue transaction
tag: VP_CVXIF_F001_S002
next_elt_id: 1
display_order: 2
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F001_S002_I000
description: "- The CPU shall perform a commit transaction for every issue\
\ transaction, independent of the accept value of the issue transaction.\n\
- For each offloaded and accepted instruction the core is guaranteed to\
\ (eventually) signal that such an instruction is either no longer speculative\
\ and can be committed (commit_valid is 1 and commit_kill is 0) or that\
\ the instruction must be killed (commit_valid is 1 and commit_kill is 1)."
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: Check that for each issue transaction, the commit transaction
is sent at the same clock cycle than the issue transaction, or at any clock
cycle after the issue transaction.
pfc: 4
test_type: 3
cov_method: 2
cores: 56
coverage_loc: ''
comments: ''
- 003_Transaction definition: !Subfeature
name: 003_Transaction definition
tag: VP_CVXIF_F001_S003
next_elt_id: 1
display_order: 3
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F001_S003_I000
description: The signals in commit are valid when commit_valid is 1.
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: "The definition of a transaction.\nNot to be verified."
pfc: 11
test_type: -1
cov_method: 10
cores: 56
coverage_loc: ''
comments: ''
vptool_gitrev: '$Id: b0efb3ae3f9057b71a577d43c2b77f1cfb2ef82f $'
io_fmt_gitrev: '$Id: 7ee5d68801f5498a957bcbe23fcad87817a364c5 $'
config_gitrev: '$Id: 0422e19126dae20ffc4d5a84e4ce3de0b6eb4eb5 $'
ymlcfg_gitrev: '$Id: 286c689bd48b7a58f9a37754267895cffef1270c $'

View file

@ -1,860 +0,0 @@
(VResult Interface
p0
ccopy_reg
_reconstructor
p1
(cvp_pack
Ip
p2
c__builtin__
object
p3
Ntp4
Rp5
(dp6
Vprop_count
p7
I8
sVname
p8
g0
sVprop_list
p9
(dp10
sVip_num
p11
I2
sVwid_order
p12
I2
sVrfu_dict
p13
(dp14
sVrfu_list
p15
(lp16
(V000_no speculative result transaction
p17
g1
(cvp_pack
Prop
p18
g3
Ntp19
Rp20
(dp21
Vitem_count
p22
I1
sg8
g17
sVtag
p23
VVP_CVXIF_F002_S000
p24
sVitem_list
p25
(dp26
sg12
I0
sg15
(lp27
(V000
p28
g1
(cvp_pack
Item
p29
g3
Ntp30
Rp31
(dp32
g8
V000
p33
sg23
VVP_CVXIF_F002_S000_I000
p34
sVdescription
p35
VA coprocessor is not allowed to perform speculative result transactions.
p36
sVpurpose
p37
V
p38
sVverif_goals
p39
VThere is no result transaction for instructions that haven't been committed. Check that Result valid is only asserted for instructions that were committed (commit_valid == 1 && commit_kill == 0).
p40
sVcoverage_loc
p41
g38
sVref_mode
p42
Vpage
p43
sVref_page
p44
g38
sVref_section
p45
g38
sVref_viewer
p46
Vfirefox
p47
sVpfc
p48
I11
sVtest_type
p49
I10
sVcov_method
p50
I10
sVcores
p51
I56
sVcomments
p52
g38
sVstatus
p53
g38
sVsimu_target_list
p54
(lp55
sg15
(lp56
sVrfu_list_2
p57
(lp58
sg13
(dp59
Vlock_status
p60
I0
ssbtp61
asVrfu_list_1
p62
(lp63
sg57
(lp64
sg13
(dp65
sbtp66
a(V001_out of order result transaction
p67
g1
(g18
g3
Ntp68
Rp69
(dp70
g22
I1
sg8
g67
sg23
VVP_CVXIF_F002_S001
p71
sg25
(dp72
sg12
I1
sg15
(lp73
(V000
p74
g1
(g29
g3
Ntp75
Rp76
(dp77
g8
V000
p78
sg23
VVP_CVXIF_F002_S001_I000
p79
sg35
VA coprocessor is allowed to provide results to the core in an out of order fashion.
p80
sg37
g38
sg39
VCheck that the CPU is able to receive the result in an out of order fashion.
p81
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I3
sg49
I3
sg50
I1
sg51
I56
sg52
g38
sg53
g38
sg54
(lp82
sg15
(lp83
sg57
(lp84
sg13
(dp85
g60
I0
ssbtp86
asg62
(lp87
sg57
(lp88
sg13
(dp89
sbtp90
a(V002_result transaction uniquness
p91
g1
(g18
g3
Ntp92
Rp93
(dp94
g22
I1
sg8
g91
sg23
VVP_CVXIF_F002_S002
p95
sg25
(dp96
sg12
I2
sg15
(lp97
(V000
p98
g1
(g29
g3
Ntp99
Rp100
(dp101
g8
V000
p102
sg23
VVP_CVXIF_F002_S002_I000
p103
sg35
VEach accepted offloaded (committed and not killed) instruction shall have exactly one result group transaction (even if no data needs to be written back to the CPU\u2019s register file).
p104
sg37
g38
sg39
VThere is an unique result transaction for every accepted and commit instruction.
p105
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I11
sg49
I10
sg50
I10
sg51
I56
sg52
g38
sg53
g38
sg54
(lp106
sg15
(lp107
sg57
(lp108
sg13
(dp109
g60
I0
ssbtp110
asg62
(lp111
sg57
(lp112
sg13
(dp113
sbtp114
a(V003_result packet stability
p115
g1
(g18
g3
Ntp116
Rp117
(dp118
g22
I1
sg8
g115
sg23
VVP_CVXIF_F002_S003
p119
sg25
(dp120
sg12
I3
sg15
(lp121
(V000
p122
g1
(g29
g3
Ntp123
Rp124
(dp125
g8
V000
p126
sg23
VVP_CVXIF_F002_S003_I000
p127
sg35
VThe signals in result shall remain stable during a result transaction (except data ...)
p128
sg37
g38
sg39
VCheck that result signals (except data) are stable during result transaction (result_valid==1 jusqu'à valid==ready ==1)
p129
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I4
sg49
I3
sg50
I2
sg51
I56
sg52
g38
sg53
g38
sg54
(lp130
sg15
(lp131
sg57
(lp132
sg13
(dp133
g60
I0
ssbtp134
asg62
(lp135
sg57
(lp136
sg13
(dp137
sbtp138
a(V004_data stability
p139
g1
(g18
g3
Ntp140
Rp141
(dp142
g22
I1
sg8
g139
sg23
VVP_CVXIF_F002_S004
p143
sg25
(dp144
sg12
I4
sg15
(lp145
(V000
p146
g1
(g29
g3
Ntp147
Rp148
(dp149
g8
V000
p150
sg23
VVP_CVXIF_F002_S004_I000
p151
sg35
VData is only required to remain stable during result transactions in which "we" is not 0.
p152
sg37
g38
sg39
VCheck that "data" remains stable when we==1.
p153
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I4
sg49
I3
sg50
I2
sg51
I56
sg52
g38
sg53
g38
sg54
(lp154
sg15
(lp155
sg57
(lp156
sg13
(dp157
g60
I0
ssbtp158
asg62
(lp159
sg57
(lp160
sg13
(dp161
sbtp162
a(V005_synchronous exception
p163
g1
(g18
g3
Ntp164
Rp165
(dp166
g22
I3
sg8
g163
sg23
VVP_CVXIF_F002_S005
p167
sg25
(dp168
sg12
I5
sg15
(lp169
(V000
p170
g1
(g29
g3
Ntp171
Rp172
(dp173
g8
V000
p174
sg23
VVP_CVXIF_F002_S005_I000
p175
sg35
VThe exc is used to signal synchronous exceptions. A synchronous exception will lead to a trap in CPU unless the corresponding instruction is killed.
p176
sg37
g38
sg39
VCheck that synchronous exception (exc ==1) leads to a trap in the CPU if the instruction is committed.
p177
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I3
sg49
I3
sg50
I1
sg51
I56
sg52
g38
sg53
g38
sg54
(lp178
sg15
(lp179
sg57
(lp180
sg13
(dp181
g60
I0
ssbtp182
a(V001
p183
g1
(g29
g3
Ntp184
Rp185
(dp186
g8
V001
p187
sg23
VVP_CVXIF_F002_S005_I001
p188
sg35
Vexccode provides the least significant bits of the exception code bitfield of the mcause CSR.
p189
sg37
g38
sg39
VCheck that exccode signal is the value of the mcause CSR when exc == 1.
p190
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I-1
sg49
I-1
sg50
I-1
sg51
I56
sg52
g38
sg53
g38
sg54
(lp191
sg15
(lp192
sg57
(lp193
sg13
(dp194
g60
I0
ssbtp195
a(V002
p196
g1
(g29
g3
Ntp197
Rp198
(dp199
g8
V002
p200
sg23
VVP_CVXIF_F002_S005_I002
p201
sg35
V "we" shall be driven to 0 by the coprocessor for synchronous exceptions.
p202
sg37
g38
sg39
VCheck that "we" signal == 0 when exc == 1.
p203
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I4
sg49
I-1
sg50
I2
sg51
I56
sg52
g38
sg53
g38
sg54
(lp204
sg15
(lp205
sg57
(lp206
sg13
(dp207
g60
I0
ssbtp208
asg62
(lp209
sg57
(lp210
sg13
(dp211
sbtp212
a(V006_"we" value when dualwrite
p213
g1
(g18
g3
Ntp214
Rp215
(dp216
g22
I1
sg8
g213
sg23
VVP_CVXIF_F002_S006
p217
sg25
(dp218
sg12
I6
sg15
(lp219
(V000
p220
g1
(g29
g3
Ntp221
Rp222
(dp223
g8
V000
p224
sg23
VVP_CVXIF_F002_S006_I000
p225
sg35
Vwe is 2 bits wide when XLEN` = 32 and X_RFW_WIDTH = 64, and 1 bit wide otherwise. If "we" is 2 bits wide, then we[1] is only allowed to be 1 if we[0] is 1 as well (i.e. for dual writeback).
p226
sg37
g38
sg39
VFor dualwrite instruction, check that we[1]==1 is only allowed if we[0] == 1.
p227
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I4
sg49
I3
sg50
I2
sg51
I56
sg52
g38
sg53
g38
sg54
(lp228
sg15
(lp229
sg57
(lp230
sg13
(dp231
g60
I0
ssbtp232
asg62
(lp233
sg57
(lp234
sg13
(dp235
sbtp236
a(V007_proper result transaction
p237
g1
(g18
g3
Ntp238
Rp239
(dp240
g22
I1
sg8
g237
sg23
VVP_CVXIF_F002_S007
p241
sg25
(dp242
sg12
I7
sg15
(lp243
(V000
p244
g1
(g29
g3
Ntp245
Rp246
(dp247
g8
V000
p248
sg23
VVP_CVXIF_F002_S007_I000
p249
sg35
VResult transaction starts in the cycle that result_valid = 1 and ends in the cycle that both result_valid == result_ready == 1.
p250
sg37
g38
sg39
VCheck that result transaction ends properly.
p251
sg41
g38
sg42
g43
sg44
g38
sg45
g38
sg46
g47
sg48
I4
sg49
I3
sg50
I2
sg51
I56
sg52
g38
sg53
g38
sg54
(lp252
sg15
(lp253
sg57
(lp254
sg13
(dp255
g60
I0
ssbtp256
asg62
(lp257
sg57
(lp258
sg13
(dp259
sbtp260
asVrfu_list_0
p261
(lp262
sg62
(lp263
sVvptool_gitrev
p264
V$Id: a782de3eec3de5ff99661fb165c09f541b4228d0 $
p265
sVio_fmt_gitrev
p266
V$Id: 2f6f9e7bc800d8b831382463dc706473c6c6ad8c $
p267
sVconfig_gitrev
p268
V$Id: 0422e19126dae20ffc4d5a84e4ce3de0b6eb4eb5 $
p269
sVymlcfg_gitrev
p270
V$Id: 286c689bd48b7a58f9a37754267895cffef1270c $
p271
sbtp272
.

View file

@ -0,0 +1,238 @@
!Feature
next_elt_id: 8
name: Result Interface
id: 2
display_order: 2
subfeatures: !!omap
- 000_no speculative result transaction: !Subfeature
name: 000_no speculative result transaction
tag: VP_CVXIF_F002_S000
next_elt_id: 1
display_order: 0
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F002_S000_I000
description: A coprocessor is not allowed to perform speculative result transactions.
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: There is no result transaction for instructions that haven't
been committed. Check that Result valid is only asserted for instructions
that were committed (commit_valid == 1 && commit_kill == 0).
pfc: 11
test_type: 10
cov_method: 10
cores: 56
coverage_loc: ''
comments: ''
- 001_out of order result transaction: !Subfeature
name: 001_out of order result transaction
tag: VP_CVXIF_F002_S001
next_elt_id: 1
display_order: 1
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F002_S001_I000
description: A coprocessor is allowed to provide results to the core in an
out of order fashion.
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: Check that the CPU is able to receive the result in an out of
order fashion.
pfc: 3
test_type: 3
cov_method: 1
cores: 56
coverage_loc: ''
comments: ''
- 002_result transaction uniquness: !Subfeature
name: 002_result transaction uniquness
tag: VP_CVXIF_F002_S002
next_elt_id: 1
display_order: 2
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F002_S002_I000
description: Each accepted offloaded (committed and not killed) instruction
shall have exactly one result group transaction (even if no data needs to
be written back to the CPUs register file).
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: There is an unique result transaction for every accepted and
commit instruction.
pfc: 11
test_type: 10
cov_method: 10
cores: 56
coverage_loc: ''
comments: ''
- 003_result packet stability: !Subfeature
name: 003_result packet stability
tag: VP_CVXIF_F002_S003
next_elt_id: 1
display_order: 3
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F002_S003_I000
description: The signals in result shall remain stable during a result transaction
(except data ...)
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: Check that result signals (except data) are stable during result
transaction (result_valid==1 jusqu'à valid==ready ==1)
pfc: 4
test_type: 3
cov_method: 2
cores: 56
coverage_loc: ''
comments: ''
- 004_data stability: !Subfeature
name: 004_data stability
tag: VP_CVXIF_F002_S004
next_elt_id: 1
display_order: 4
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F002_S004_I000
description: Data is only required to remain stable during result transactions
in which "we" is not 0.
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: Check that "data" remains stable when we==1.
pfc: 4
test_type: 3
cov_method: 2
cores: 56
coverage_loc: ''
comments: ''
- 005_synchronous exception: !Subfeature
name: 005_synchronous exception
tag: VP_CVXIF_F002_S005
next_elt_id: 3
display_order: 5
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F002_S005_I000
description: The exc is used to signal synchronous exceptions. A synchronous
exception will lead to a trap in CPU unless the corresponding instruction
is killed.
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: Check that synchronous exception (exc ==1) leads to a trap in
the CPU if the instruction is committed.
pfc: 3
test_type: 3
cov_method: 1
cores: 56
coverage_loc: ''
comments: ''
- '001': !VerifItem
name: '001'
tag: VP_CVXIF_F002_S005_I001
description: exccode provides the least significant bits of the exception
code bitfield of the mcause CSR.
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: Check that exccode signal is the value of the mcause CSR when
exc == 1.
pfc: -1
test_type: -1
cov_method: -1
cores: 56
coverage_loc: ''
comments: ''
- '002': !VerifItem
name: '002'
tag: VP_CVXIF_F002_S005_I002
description: '"we" shall be driven to 0 by the coprocessor for synchronous
exceptions.'
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: Check that "we" signal == 0 when exc == 1.
pfc: 4
test_type: -1
cov_method: 2
cores: 56
coverage_loc: ''
comments: ''
- 006_"we" value when dualwrite: !Subfeature
name: 006_"we" value when dualwrite
tag: VP_CVXIF_F002_S006
next_elt_id: 1
display_order: 6
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F002_S006_I000
description: we is 2 bits wide when XLEN = 32 and X_RFW_WIDTH = 64, and 1
bit wide otherwise. If "we" is 2 bits wide, then we[1] is only allowed to
be 1 if we[0] is 1 as well (i.e. for dual writeback).
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: "For dualwrite instruction, check that we[1]==1 is only allowed\
\ if we[0] == 1.\n\nDualwrite not supported (for now)"
pfc: 4
test_type: 3
cov_method: 2
cores: 56
coverage_loc: ''
comments: ''
- 007_proper result transaction: !Subfeature
name: 007_proper result transaction
tag: VP_CVXIF_F002_S007
next_elt_id: 1
display_order: 7
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F002_S007_I000
description: Result transaction starts in the cycle that result_valid = 1
and ends in the cycle that both result_valid == result_ready == 1.
reqt_doc: https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: Check that result transaction ends properly.
pfc: 4
test_type: 3
cov_method: 2
cores: 56
coverage_loc: ''
comments: ''
vptool_gitrev: '$Id: b0efb3ae3f9057b71a577d43c2b77f1cfb2ef82f $'
io_fmt_gitrev: '$Id: 7ee5d68801f5498a957bcbe23fcad87817a364c5 $'
config_gitrev: '$Id: 0422e19126dae20ffc4d5a84e4ce3de0b6eb4eb5 $'
ymlcfg_gitrev: '$Id: 286c689bd48b7a58f9a37754267895cffef1270c $'

View file

@ -0,0 +1,402 @@
!Feature
next_elt_id: 8
name: Custom Instructions
id: 3
display_order: 3
subfeatures: !!omap
- 000_CUS_ADD: !Subfeature
name: 000_CUS_ADD
tag: VP_CVXIF_F003_S000
next_elt_id: 4
display_order: 0
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F003_S000_I000
description: "cus_add rd, rs1, rs2\nrd = rs1 + rs2\ncus_add works in all privilege\
\ modes"
reqt_doc: ./custom_instruction.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: "Register operands:\n\nAll possible rs1 registers are used.\n\
All possible rs2 registers are used.\nAll possible rd registers are used.\n\
All possible register combinations where rs1 == rd are used\nAll possible\
\ register combinations where rs2 == rd are used"
pfc: 3
test_type: 3
cov_method: 1
cores: 56
coverage_loc: ''
comments: ''
- '001': !VerifItem
name: '001'
tag: VP_CVXIF_F003_S000_I001
description: "cus_add rd, rs1, rs2\nrd = rs1 + rs2\ncus_add works in all privilege\
\ modes"
reqt_doc: ./custom_instruction.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: "Input operands:\n\nrs1 value is +ve, -ve and zero\nrs2 value\
\ is +ve, -ve and zero\nAll combinations of rs1 and rs2 +ve, -ve, and zero\
\ values are used\nAll bits of rs1 are toggled\nAll bits of rs2 are toggled"
pfc: -1
test_type: -1
cov_method: -1
cores: 56
coverage_loc: ''
comments: ''
- '002': !VerifItem
name: '002'
tag: VP_CVXIF_F003_S000_I002
description: "cus_add rd, rs1, rs2\nrd = rs1 + rs2\ncus_add works in all privilege\
\ modes"
reqt_doc: ./custom_instruction.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: "Output result:\n\nrd value is +ve, -ve and zero\nAll bits of\
\ rd are toggled"
pfc: -1
test_type: -1
cov_method: -1
cores: 56
coverage_loc: ''
comments: ''
- 001_CUS_NOP: !Subfeature
name: 001_CUS_NOP
tag: VP_CVXIF_F003_S001
next_elt_id: 1
display_order: 1
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F003_S001_I000
description: No operation Instruction
reqt_doc: ./custom_instruction.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: Instruction executed
pfc: 3
test_type: 3
cov_method: 1
cores: 56
coverage_loc: ''
comments: ''
- 003_CUS_S_ADD: !Subfeature
name: 003_CUS_S_ADD
tag: VP_CVXIF_F003_S003
next_elt_id: 3
display_order: 3
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F003_S003_I000
description: "cus_s_add rd, rs1, rs2\nrd = rs1 + rs2\ncus_s_add works in supervisor\
\ privilege mode"
reqt_doc: ./custom_instruction.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: "Register operands:\n\nif (mode == s)\nAll possible rs1 registers\
\ are used.\nAll possible rs2 registers are used.\nAll possible rd registers\
\ are used.\nAll possible register combinations where rs1 == rd are used\n\
All possible register combinations where rs2 == rd are used\n\nelse if (mode\
\ != s)\nillegal exception raised on hte CPU"
pfc: 3
test_type: 3
cov_method: 1
cores: 56
coverage_loc: ''
comments: ''
- '001': !VerifItem
name: '001'
tag: VP_CVXIF_F003_S003_I001
description: "cus_s_add rd, rs1, rs2\nrd = rs1 + rs2\ncus_s_add works in supervisor\
\ privilege mode"
reqt_doc: ./custom_instruction.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: "Input operands:\n\nif (mode == s)\nrs1 value is +ve, -ve and\
\ zero\nrs2 value is +ve, -ve and zero\nAll combinations of rs1 and rs2\
\ +ve, -ve, and zero values are used\nAll bits of rs1 are toggled\nAll bits\
\ of rs2 are toggled\n\nelse if (mode != s)\nillegal exception raised on\
\ the CPU"
pfc: -1
test_type: -1
cov_method: -1
cores: 56
coverage_loc: ''
comments: ''
- '002': !VerifItem
name: '002'
tag: VP_CVXIF_F003_S003_I002
description: "cus_s_add rd, rs1, rs2\nrd = rs1 + rs2\ncus_s_add works in supervisor\
\ privilege mode"
reqt_doc: ./custom_instruction.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: "Output operands:\n\nif (mode == s)\nrd value is +ve, -ve and\
\ zero\nAll bits of rd are toggled\n\nelse if (mode != s)\nillegal exception\
\ raised on the CPU"
pfc: -1
test_type: -1
cov_method: -1
cores: 56
coverage_loc: ''
comments: ''
- 004_CUS_U_ADD: !Subfeature
name: 004_CUS_U_ADD
tag: VP_CVXIF_F003_S004
next_elt_id: 3
display_order: 4
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F003_S004_I000
description: "cus_u_add rd, rs1, rs2\nrd = rs1 + rs2\ncus_u_add works in User\
\ privilege mode"
reqt_doc: ./custom_instruction.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: "Register operands:\n\nif (mode == u)\nAll possible rs1 registers\
\ are used.\nAll possible rs2 registers are used.\nAll possible rd registers\
\ are used.\nAll possible register combinations where rs1 == rd are used\n\
All possible register combinations where rs2 == rd are used\n\nelse if (mode\
\ != u)\nillegal exception raised on hte CPU"
pfc: 3
test_type: 3
cov_method: 1
cores: 56
coverage_loc: ''
comments: ''
- '001': !VerifItem
name: '001'
tag: VP_CVXIF_F003_S004_I001
description: "cus_u_add rd, rs1, rs2\nrd = rs1 + rs2\ncus_u_add works in User\
\ privilege mode"
reqt_doc: ./custom_instruction.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: "Input operands:\n\nif (mode == u)\nrs1 value is +ve, -ve and\
\ zero\nrs2 value is +ve, -ve and zero\nAll combinations of rs1 and rs2\
\ +ve, -ve, and zero values are used\nAll bits of rs1 are toggled\nAll bits\
\ of rs2 are toggled\n\nelse if (mode != u)\nillegal exception raised on\
\ the CPU"
pfc: -1
test_type: -1
cov_method: -1
cores: 56
coverage_loc: ''
comments: ''
- '002': !VerifItem
name: '002'
tag: VP_CVXIF_F003_S004_I002
description: "cus_u_add rd, rs1, rs2\nrd = rs1 + rs2\ncus_u_add works in User\
\ privilege mode"
reqt_doc: ./custom_instruction.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: "Output operands:\n\nif (mode == u)\nrd value is +ve, -ve and\
\ zero\nAll bits of rd are toggled\n\nelse if (mode != u)\nillegal exception\
\ raised on the CPU"
pfc: -1
test_type: -1
cov_method: -1
cores: 56
coverage_loc: ''
comments: ''
- 005_CUS_ADD_MULTI: !Subfeature
name: 005_CUS_ADD_MULTI
tag: VP_CVXIF_F003_S005
next_elt_id: 4
display_order: 5
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F003_S005_I000
description: "cus_add_multi rd, rs1, rs2\nrd = rs1 + rs2\ncus_add_multi works\
\ in all privilege modes"
reqt_doc: ./custom_instruction.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: "Register operands:\n\nAll possible rs1 registers are used.\n\
All possible rs2 registers are used.\nAll possible rd registers are used.\n\
All possible register combinations where rs1 == rd are used\nAll possible\
\ register combinations where rs2 == rd are used"
pfc: 3
test_type: 3
cov_method: 1
cores: 56
coverage_loc: ''
comments: ''
- '001': !VerifItem
name: '001'
tag: VP_CVXIF_F003_S005_I001
description: "cus_add_multi rd, rs1, rs2\nrd = rs1 + rs2\ncus_add_multi works\
\ in all privilege modes"
reqt_doc: ./custom_instruction.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: "Input operands:\n\nrs1 value is +ve, -ve and zero\nrs2 value\
\ is +ve, -ve and zero\nAll combinations of rs1 and rs2 +ve, -ve, and zero\
\ values are used\nAll bits of rs1 are toggled\nAll bits of rs2 are toggled"
pfc: -1
test_type: -1
cov_method: -1
cores: 56
coverage_loc: ''
comments: ''
- '002': !VerifItem
name: '002'
tag: VP_CVXIF_F003_S005_I002
description: "cus_add_multi rd, rs1, rs2\nrd = rs1 + rs2\ncus_add_multi works\
\ in all privilege modes"
reqt_doc: ./custom_instruction.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: "Output result:\n\nrd value is +ve, -ve and zero\nAll bits of\
\ rd are toggled"
pfc: -1
test_type: -1
cov_method: -1
cores: 56
coverage_loc: ''
comments: ''
- '003': !VerifItem
name: '003'
tag: VP_CVXIF_F003_S005_I003
description: "cus_add_multi rd, rs1, rs2\nrd = rs1 + rs2\ncus_add_multi works\
\ in all privilege modes"
reqt_doc: ./custom_instruction.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: Check all delays from min to max
pfc: 3
test_type: 3
cov_method: 1
cores: 56
coverage_loc: ''
comments: ''
- 006_CUS_EXC: !Subfeature
name: 006_CUS_EXC
tag: VP_CVXIF_F003_S006
next_elt_id: 1
display_order: 6
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F003_S006_I000
description: "cus_exc imm[5:0]\nmcause[5:0] = imm[5:0]\ncus_exc raise an exception\
\ on the CPU base on the imm value"
reqt_doc: ./custom_instruction.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: Check all possible imm value
pfc: -1
test_type: -1
cov_method: -1
cores: 56
coverage_loc: ''
comments: ''
- 007_CUS_ADD_RS3: !Subfeature
name: 007_CUS_ADD_RS3
tag: VP_CVXIF_F003_S007
next_elt_id: 3
display_order: 7
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_CVXIF_F003_S007_I000
description: "cus_add_rs3 rd, rs1, rs2, rs3\nrd = rs1 + rs2 + rs3\ncus_add_rs3\
\ works in all privilege modes\n\nX_NUM_RS == 3"
reqt_doc: ./custom_instruction.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: "Register operands:\n\nif (X_NUM_RS == 3)\nAll possible rs1 registers\
\ are used.\nAll possible rs2 registers are used.\nAll possible rs3 registers\
\ are used.\nAll possible rd registers are used.\nAll possible register\
\ combinations where rs1 == rd are used\nAll possible register combinations\
\ where rs2 == rd are used\nAll possible register combinations where rs3\
\ == rd are used\n\n\nelse if (X_NUM_RS != 3)\nillegal exception raised\
\ on the CPU"
pfc: 3
test_type: 3
cov_method: 1
cores: 56
coverage_loc: ''
comments: ''
- '001': !VerifItem
name: '001'
tag: VP_CVXIF_F003_S007_I001
description: "cus_add_rs3 rd, rs1, rs2, rs3\nrd = rs1 + rs2 + rs3\ncus_add_rs3\
\ works in all privilege modes\n\nX_NUM_RS == 3"
reqt_doc: ./custom_instruction.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: "Input operands:\n\nif (X_NUS_RS == 3)\nrs1 value is +ve, -ve\
\ and zero\nrs2 value is +ve, -ve and zero\nrs3 value is +ve, -ve and zero\n\
All combinations of rs1, rs2 and rs3 +ve, -ve, and zero values are used\n\
All bits of rs1 are toggled\nAll bits of rs2 are toggled\nAll bits of rs3\
\ are toggled\n\nelse if (X_NUM_RS != 3)\nillegal exception raised on the\
\ CPU"
pfc: -1
test_type: -1
cov_method: -1
cores: -1
coverage_loc: ''
comments: ''
- '002': !VerifItem
name: '002'
tag: VP_CVXIF_F003_S007_I002
description: "cus_add_rs3 rd, rs1, rs2, rs3\nrd = rs1 + rs2 + rs3\ncus_add_rs3\
\ works in all privilege modes\n\nX_NUM_RS == 3"
reqt_doc: ./custom_instruction.rst
ref_mode: page
ref_page: ''
ref_section: ''
ref_viewer: firefox
verif_goals: "Output operands:\n\nif (X_NUM_RS == 3)\nrd value is +ve, -ve\
\ and zero\nAll bits of rd are toggled\n\nelse if (X_NUM_RS != 3)\nillegal\
\ exception raised on the CPU"
pfc: -1
test_type: -1
cov_method: -1
cores: 56
coverage_loc: ''
comments: ''
vptool_gitrev: '$Id: b0efb3ae3f9057b71a577d43c2b77f1cfb2ef82f $'
io_fmt_gitrev: '$Id: 7ee5d68801f5498a957bcbe23fcad87817a364c5 $'
config_gitrev: '$Id: 0422e19126dae20ffc4d5a84e4ce3de0b6eb4eb5 $'
ymlcfg_gitrev: '$Id: 286c689bd48b7a58f9a37754267895cffef1270c $'

View file

@ -0,0 +1,100 @@
..
Copyright (c) 2023 OpenHW Group
Copyright (c) 2023 Thales DIS SAS
SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
..
Custom Instruction to challenge CV-X-IF protocol
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This section describes some custom instruction, for stress or challenge the CV-X-IF protocol for the 3 implemented interfaces, it's just to interact with the cvxif agent.
All instructions use opcode `CUSTOM_3`(0x7b, 0b111_1011).
- **CUS_ADD**: Custom Add
**Format**: cus_add rd, rs1, rs2 -> |0000000|rs2|rs1|001|rd|111_1011|
**Description**: add register rs1 to rs2, and store the result in rd (works for all privilege modes).
**Pseudocode**: x[rd] = x[rs1] + x[rs2]
**Invalid values**: NONE
**Exception raised**: Illegal instruction exception is raised if rs_valid != 2'b11 && rs_valid != 3'b111.
- **CUS_NOP**: Custom No Operation
**Format**: cus_nop -> |0000000000000000000000000|111_1011|
**Description**: do nothing, it's just a hint instruction.
**Pseudocode**: cus_nop
**Invalid values**: NONE
**Exception raised**: NONE
- **CUS_ADD_RS3**: Custom Add
**Format**: cus_add_rs3 rd, rs1, rs2, rs3 -> |rs3|01|rs2|rs1|000|rd|111_1011|
**Description**: add register rs1 to rs2 then the result to rs3, and store the result in register rd (works for all privilege modes).
**Pseudocode**: x[rd] = x[rs1] + x[rs2] + x[rs3]
**Invalid values**: NONE
**Exception raised**: Illegal instruction exception is raised if rs_valid != 3'b111.
- **CUS_S_ADD**: Custom Supervisor Add
**Format**: add rd, rs1, rs2 -> |0000110|rs2|rs1|000|rd|111_1011|
**Description**: add register rs1 to rs2, and store the result in register rd (works only in Supervisor mode).
**Pseudocode**: x[rd] = x[rs1] + x[rs2]
**Invalid values**: NONE
**Exception raised**: Illegal instruction exception is raised if the privilege mode isn't Supervisor mode, or rs_valid != 2'b11 && rs_valid != 3'b111.
- **CUS_U_ADD**: Custom User Add
**Format**: add rd, rs1, rs2 -> |0000010|rs2|rs1|000|rd|111_1011|
**Description**: add register rs1 to rs2, and store the result in register rd (works only in User mode).
**Pseudocode**: x[rd] = x[rs1] + x[rs2]
**Invalid values**: NONE
**Exception raised**: Illegal instruction exception is raised if the privilege mode isn't User mode, or rs_valid != 2'b11 && rs_valid != 3'b111.
- **CUS_ADD_MULTI**: Custom Multicycle Add
**Format**: addi rd, rs1, rs2 -> |0001000|rs2|rs1|000|rd|111_1011|
**Description**: add register rs1 to rs2, and store the result in rd (works for all privilege mode).
**Pseudocode**: x[rd] = x[rs1] + x[rs2]
**Invalid values**: NONE
**Exception raised**: Illegal instruction exception is raised if rs_valid != 2'b11 && rs_valid != 3'b111.
- **CUS_EXC**: Custom Exception
**Format**: cus_exc imm[5:0] -> |1100000|000000000001|imm|111_1011|
**Description**: raise an exception.
**Pseudocode**: mcause[5:0] = imm[5:0]
**Invalid values**: NONE
**Exception raised**: raise an exception based on the value on the immediate field.
When a CV-X-IF exception is raised, mcause[5:0] of the corresponding CORE-V hart is assumed set to exccode[5:0] of CV-X-IF.

View file

@ -1,4 +1,4 @@
..
..
Copyright (c) 2023 OpenHW Group
Copyright (c) 2023 Thales DIS design services SAS
@ -451,11 +451,11 @@ Control Transfer Instructions
**Format**: beq rs1, rs2, imm[12:1]
**Description**: takes the branch (pc is calculated using signed arithmetic) if registers rs1 and rs2 are equal.
**Pseudocode**: if (x[rs1] == x[rs2]) pc += sext({imm[12:1], 1b0}) else pc += 4
**Invalid values**: NONE
**Pseudocode**: if (x[rs1] == x[rs2]) pc += sext({imm[12:1], 1b0}) else pc += 4
**Exception raised**: no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions.
- **BNE**: Branch Not Equal
@ -464,9 +464,9 @@ Control Transfer Instructions
**Description**: takes the branch (pc is calculated using signed arithmetic) if registers rs1 and rs2 are not equal.
**Invalid values**: NONE
**Pseudocode**: if (x[rs1] != x[rs2]) pc += sext({imm[12:1], 1b0}) else pc += 4
**Invalid values**: NONE
**Exception raised**: no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions.
@ -476,10 +476,10 @@ Control Transfer Instructions
**Description**: takes the branch (pc is calculated using signed arithmetic) if registers rs1 less than rs2 (using signed comparison).
**Invalid values**: NONE
**Pseudocode**: if (x[rs1] < x[rs2]) pc += sext({imm[12:1], 1b0}) else pc += 4
**Invalid values**: NONE
**Exception raised**: no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions.
- **BLTU**: Branch Less Than Unsigned
@ -488,10 +488,10 @@ Control Transfer Instructions
**Description**: takes the branch (pc is calculated using signed arithmetic) if registers rs1 less than rs2 (using unsigned comparison).
**Invalid values**: NONE
**Pseudocode**: if (x[rs1] <u x[rs2]) pc += sext({imm[12:1], 1b0}) else pc += 4
**Invalid values**: NONE
**Exception raised**: no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions.
- **BGE**: Branch Greater or Equal
@ -512,9 +512,9 @@ Control Transfer Instructions
**Description**: takes the branch (pc is calculated using signed arithmetic) if registers rs1 is greater than or equal rs2 (using unsigned comparison).
**Invalid values**: NONE
**Pseudocode**: if (x[rs1] >=u x[rs2]) pc += sext({imm[12:1], 1b0}) else pc += 4
**Invalid values**: NONE
**Exception raised**: no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions.
@ -551,10 +551,10 @@ Load and Store Instructions
**Description**: loads a 32-bit value from memory, then storing in rd (rd is calculated using signed arithmetic). The effective address is obtained by adding register rs1 to the sign-extended 12-bit offset.
**Invalid values**: NONE
**Pseudocode**: x[rd] = sext(M[x[rs1] + sext(imm[11:0])][31:0])
**Invalid values**: NONE
**Exception raised**: loads with a destination of x0 must still raise any exceptions and action any other side effects even though the load value is discarded, also an exception is raised if the memory address isn't aligned (4-byte boundary).
- **LBU**: Load Byte Unsigned
@ -983,7 +983,7 @@ Integer Computational Instructions
- **C.ADDI4SPN**: Addition Immediate Scaled by 4, to Stack Pointer
**Format**: c.addi4spn nzimm[9:2]
**Format**: c.addi4spn rd', nzimm[9:2]
**Description**: adds a zero-extended non-zero immediate, scaled by 4, to the stack pointer, x2, and writes the result to rd'. This instruction is used to generate pointers to stack-allocated variables.

View file

@ -0,0 +1,583 @@
!Feature
next_elt_id: 16
name: sv32
id: 0
display_order: 0
subfeatures: !!omap
- 000_PMP permissions on Physical Address: !Subfeature
name: 000_PMP permissions on Physical Address
tag: VP_MMU_SV32_F000_S000
next_elt_id: 2
display_order: 0
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_MMU_SV32_F000_S000_I000
description: "If PTE has valid and non-reserved RWX permissions, but the translated\
\ Physical address (pte.ppn of leaf PTE + offset) does not have (r,w,x)\
\ PMP permissions, then accessing the translated Physical address would\
\ raise access fault exception.\nWhen satp.mode=sv32, and PTE has valid\
\ and non-reserved RWX permissions then test the following in supervisor\
\ and user privilege mode for level1 and level0 PTE.\n\n- Remove read PMP\
\ permission of translated Physical Address in pmpcfg and test the read\
\ acces.\n- Remvoe write PMP permission of translated Physical Address in\
\ pmpcfg and test the write access.\n- Remove execute PMP permission of\
\ translated Physical Address in pmpcfg and test the execute access."
reqt_doc: 'ISA Volume II: Privilege Architecture Version 20211203, Chapter
3.7, 5.3.2'
ref_mode: ''
ref_page: ''
ref_section: ''
ref_viewer: ''
verif_goals: "Access fault exception should be raised according to {x,r,w}\
\ access type. Check that:\n- m/scause must contain the exception number\
\ of:\n - instruction access fault for execute access.\n \
\ - load page access for read access.\n - store/AMO access fault\
\ for write access.\n- m/sepc must contain the virtual address of the instruction\
\ at which the trap occurs."
pfc: 3
test_type: 0
cov_method: 0
cores: 8
coverage_loc: ''
comments: ''
- 001_PMP permissions on PTE: !Subfeature
name: 001_PMP permissions on PTE
tag: VP_MMU_SV32_F000_S001
next_elt_id: 1
display_order: 1
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_MMU_SV32_F000_S001_I000
description: "If PTE does not have (r,w,x) PMP permissions, then accessing\
\ it would raise access fault exception of the corresponding access type.\
\ \nWhen satp.mode=sv32, then test the following in supervisor and user\
\ privilege mode for level0 and level1 PTE.\n- Remove read PMP permission\
\ of PTE address in pmpcfg and test the read acces.\n- Remvoe write PMP\
\ permission of PTE address in pmpcfg and test the write access.\n- Remove\
\ execute PMP permission of PTE address in pmpcfg and test the execute access."
reqt_doc: 'ISA Volume II: Privilege Architecture Version 20211203, Chapter
3.7, 5.3.2'
ref_mode: ''
ref_page: ''
ref_section: ''
ref_viewer: ''
verif_goals: "Access fault exception should be raised according to {x,r,w}\
\ access type. Check that:\n- m/scause must contain the exception number\
\ of:\n - instruction access fault for execute access.\n \
\ - load page access for read access.\n - store/AMO access fault\
\ for write access.\n- m/sepc must contain the virtual address of the instruction\
\ at which the trap occurs."
pfc: -1
test_type: -1
cov_method: -1
cores: 8
coverage_loc: ''
comments: ''
- 002_In-Valid Permission of PTE: !Subfeature
name: 002_In-Valid Permission of PTE
tag: VP_MMU_SV32_F000_S002
next_elt_id: 1
display_order: 2
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_MMU_SV32_F000_S002_I000
description: "If PTE does not have Valid (pte.V=0) permission, then accessing\
\ it would raise page fault exception of the corresponding access type.\
\ \nWhen satp.mode=sv32 and PTE has (r,w,x) PMP permissions, then test the\
\ following in supervisor and user privilege mode for level0 and level1\
\ PTE.\n- Set PTE.V = 0 and test the read acces.\n- Set PTE.V = 0 and test\
\ the write access.\n- Set PTE.V = 0 and test the execute access.\n\n* For\
\ testing at level0, set all the pte perimssions at level1 to 0 except pte.v,\
\ so that level1 points to level0.\n* Set pte.U=0 when test in Supervisor\
\ mode and Set pte.U=1 when testing in user mode"
reqt_doc: 'ISA Volume II: Privilege Architecture Version 20211203, Chpter
5.3.2'
ref_mode: ''
ref_page: ''
ref_section: ''
ref_viewer: ''
verif_goals: "Page fault exception should be raised according to {x,r,w} access\
\ type. Check that:\n- m/scause must contain the exception number of:\n\
\ - instruction page fault for execute access.\n - load\
\ page fault for read access.\n - store/AMO page fault for write\
\ access.\n- m/sepc must contain the virtual address of the instruction\
\ at which the trap occurs."
pfc: 3
test_type: 0
cov_method: 0
cores: 8
coverage_loc: ''
comments: ''
- 003_Reserved RWX permission encodings of PTE: !Subfeature
name: 003_Reserved RWX permission encodings of PTE
tag: VP_MMU_SV32_F000_S003
next_elt_id: 1
display_order: 3
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_MMU_SV32_F000_S003_I000
description: "If PTE has reserved RWX encodings (pte.w=1 & pte.r=0), then\
\ accessing it would raise page fault exception of the corresponding access\
\ type. \nWhen satp.mode=sv32, PTE has (r,w,x) PMP permissions, and pte.v=1,\
\ then test the following in supervisor and user privilege mode for level0\
\ and level1 PTE.\n- Set pte.w=1 & pte.r=0 and test the read acces.\n- Set\
\ pte.w=1 & pte.r=0 and test the write access.\n- Set pte.w=1 & pte.r=0\
\ and test the execute access.\n\n* For testing at level0, set all the pte\
\ perimssions at level1 to 0 except pte.v, so that level1 points to level0.\n\
* Set pte.U=0 when test in Supervisor mode and Set pte.U=1 when testing\
\ in user mode"
reqt_doc: 'ISA Volume II: Privilege Architecture Version 20211203, Chapter
3.7, 5.3.1'
ref_mode: ''
ref_page: ''
ref_section: ''
ref_viewer: ''
verif_goals: "Page fault exception should be raised according to {x,r,w} access\
\ type. Check that:\n- m/scause must contain the exception number of:\n\
\ - instruction page fault for execute access.\n - load\
\ page fault for read access.\n - store/AMO page fault for write\
\ access.\n- m/sepc must contain the virtual address of the instruction\
\ at which the trap occurs."
pfc: 3
test_type: 0
cov_method: 0
cores: 8
coverage_loc: ''
comments: ''
- 004_Non-leaf PTE permission at level 0: !Subfeature
name: 004_Non-leaf PTE permission at level 0
tag: VP_MMU_SV32_F000_S004
next_elt_id: 1
display_order: 4
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_MMU_SV32_F000_S004_I000
description: "If PTE at level0 has non-leaf RWX permissions (pte.x=0 & pte.r=0),\
\ then accessing it would raise page fault exception of the corresponding\
\ access type. \nWhen satp.mode=sv32, PTE has (r,w,x) PMP permissions, and\
\ pte.v=1, then test the following in supervisor and user privilege mode\
\ for level0 PTE.\n- Set pte.x=0 & pte.r=0 & pte.w=0 and test the read acces.\n\
- Set pte.x=0 & pte.r=0 & pte.w=0 and test the write access.\n- Set pte.x=0\
\ & pte.r=0 & pte.w=0 and test the execute access.\n\n* For testing at level0,\
\ set all the pte perimssions at level1 to 0 except pte.v, so that level1\
\ points to level0.\n* Set pte.U=0 when test in Supervisor mode and Set\
\ pte.U=1 when testing in user mode"
reqt_doc: 'ISA Volume II: Privilege Architecture Version 20211203, Chapter
5.3.2'
ref_mode: ''
ref_page: ''
ref_section: ''
ref_viewer: ''
verif_goals: "Page fault exception should be raised according to {x,r,w} access\
\ type. Check that:\n- m/scause must contain the exception number of:\n\
\ - instruction page fault for execute access.\n - load\
\ page fault for read access.\n - store/AMO page fault for write\
\ access.\n- m/sepc must contain the virtual address of the instruction\
\ at which the trap occurs."
pfc: 3
test_type: 0
cov_method: 0
cores: 8
coverage_loc: ''
comments: ''
- 005_RWX access on S-mode pages in S-mode: !Subfeature
name: 005_RWX access on S-mode pages in S-mode
tag: VP_MMU_SV32_F000_S005
next_elt_id: 1
display_order: 5
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_MMU_SV32_F000_S005_I000
description: "If PTE belongs to supervisor mode i.e. its U permission bit\
\ is clear (pte.u = 0), then accessing that PTE in supervisor mode should\
\ be successful if the corresponding (r,w,x) permission of PTE is granted.\
\ Otherwise raise page fault exception of the corresponding access type.\n\
When satp.mode=sv32, PTE has (r,w,x) PMP permissions, PTE has non-reserved\
\ RWX encoding, pte.u=0 and pte.v=1, then test the following in supervisor\
\ privilege mode for level 0 and level 1 PTE.\n- Test the read access for\
\ both pte.r=1 and for pte.r=0\n- Test the write access for both pte.w=1\
\ and for pte.w=0\n- Test the execute access for both pte.x=1 and for pte.x=0\n\
\n* For testing at level0, set all the pte perimssions at level1 to 0 except\
\ pte.v, so that level1 points to level0."
reqt_doc: 'ISA Volume II: Privilege Architecture Version 20211203, Chapter
5.3.1'
ref_mode: ''
ref_page: ''
ref_section: ''
ref_viewer: ''
verif_goals: "RWX access should be successful if the corresponding permissions\
\ are granted in the PTE. Check that load, store and execute works without\
\ any page fault.\nPage fault exception should be raised according to (x,r,w)\
\ access type if the corresponding (r,w,x) permissions are not granted in\
\ the PTE. Check that:\n- m/scause must contain the exception number of:\n\
\ - instruction page fault for execute.\n - load page fault\
\ for read access.\n - store/AMO page fault for write access.\n\
- m/sepc must contain the virtual address of the instruction at which the\
\ trap occurs."
pfc: 3
test_type: 0
cov_method: 0
cores: 8
coverage_loc: ''
comments: ''
- 006_RWX access on S-mode pages in U-mode: !Subfeature
name: 006_RWX access on S-mode pages in U-mode
tag: VP_MMU_SV32_F000_S006
next_elt_id: 1
display_order: 6
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_MMU_SV32_F000_S006_I000
description: "If PTE belongs to supervisor mode i.e. its U permission bit\
\ is clear (pte.u = 0), then accessing that PTE in user mode would raise\
\ page fault exception of the corresponding access type. \nWhen satp.mode=sv32,\
\ PTE has (r,w,x) PMP permissions, PTE has non-reserved RWX encoding, and\
\ pte.v=1, then test the following user privilege mode for level0 and level1\
\ PTE.\n- Set pte.u=0 and test the read acces.\n- Set pte.u=0 and test the\
\ write access.\n- Set pte.u=0 and test the execute access.\n\n* For testing\
\ at level0, set all the pte perimssions at level1 to 0 except pte.v, so\
\ that level1 points to level0."
reqt_doc: 'ISA Volume II: Privilege Architecture Version 20211203, Chapter
5.3.2'
ref_mode: ''
ref_page: ''
ref_section: ''
ref_viewer: ''
verif_goals: "Page fault exception should be raised according to {x,r,w} access\
\ type. Check that:\n- m/scause must contain the exception number of instruction,\
\ load, and store/AMO page fault for execute, read and write access type,\
\ respectively.\n- m/sepc must contain the virtual address of the instruction\
\ at which the trap occurs."
pfc: 3
test_type: 0
cov_method: 0
cores: 8
coverage_loc: ''
comments: ''
- 007_RWX access on U-mode pages in S-mode with mstatus.SUM unset: !Subfeature
name: 007_RWX access on U-mode pages in S-mode with mstatus.SUM unset
tag: VP_MMU_SV32_F000_S007
next_elt_id: 1
display_order: 7
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_MMU_SV32_F000_S007_I000
description: "If PTE belongs to user mode i.e. its U permission bit is set\
\ (pte.u = 1) and m/sstatus.SUM = 0, then accessing that PTE in supervisor\
\ mode would raise page fault exception of the corresponding access type.\
\ \nWhen satp.mode=sv32, PTE has (r,w,x) PMP permissions, PTE has non-reserved\
\ RWX encoding, and pte.v=1, then test the following in supervisor mode\
\ for level 0 and level 1 PTE.\n- Set pte.u=1 & s/mstatus.SUM = 0 and test\
\ the read acces.\n- Set pte.u=1 & s/mstatus.SUM = 0 and test the write\
\ access.\n- Set pte.u=1 & s/mstatus.SUM = 0 and test the execute access.\n\
\n* For testing at level0, set all the pte perimssions at level1 to 0 except\
\ pte.v, so that level1 points to level0."
reqt_doc: 'ISA Volume II: Privilege Architecture Version 20211203, Chapter
3.1.6.3, 5.3.2'
ref_mode: ''
ref_page: ''
ref_section: ''
ref_viewer: ''
verif_goals: "Page fault exception should be raised according to {x,r,w} access\
\ type. Check that:\n- m/scause must contain the exception number of:\n\
\ - instruction page fault for execute access.\n - load\
\ page fault for read access.\n - store/AMO page fault for write\
\ access.\n- m/sepc must contain the virtual address of the instruction\
\ at which the trap occurs."
pfc: 3
test_type: 0
cov_method: 0
cores: 8
coverage_loc: ''
comments: ''
- 008_RWX access on U-mode pages in S-mode with mstatus.SUM set: !Subfeature
name: 008_RWX access on U-mode pages in S-mode with mstatus.SUM set
tag: VP_MMU_SV32_F000_S008
next_elt_id: 1
display_order: 8
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_MMU_SV32_F000_S008_I000
description: "If PTE belongs to user mode i.e. its U permission bit is set\
\ (pte.u = 1) and m/sstatus.SUM = 1, then RW access to that PTE in supervisor\
\ mode would be successful but eXecute access would raise instruction page\
\ fault exception in s-mode.\nWhen satp.mode=sv32, PTE has (r,w,x) PMP permissions,\
\ PTE has non-reserved RWX encoding, and pte.v=1, then test the following\
\ in supervisor mode for level0 and level1 PTE.\n- Set pte.r=1 & pte.u=1\
\ & s/mstatus.SUM = 1 and test the read acces.\n- Set pte.w=1 & pte.u=1\
\ & s/mstatus.SUM = 1 and test the write access.\n- Set pte.x=1 & pte.u=1\
\ & s/mstatus.SUM = 1 and test the execute access.\n\n* For testing at level0,\
\ set all the pte perimssions at level1 to 0 except pte.v, so that level1\
\ points to level0."
reqt_doc: 'ISA Volume II: Privilege Architecture Version 20211203, Chapter
3.1.6.3, 5.3.2'
ref_mode: ''
ref_page: ''
ref_section: ''
ref_viewer: ''
verif_goals: "Read and Write access to the PTE should be successful. So, check\
\ that the load and store works without page fault and expected data is\
\ stored to and loaded from the memory, repectively.\n\nExecute access should\
\ raise instruction page fault. Check that:\n- m/scause must contain the\
\ exception number of instruction instruction access fault. \n- m/sepc must\
\ contain the virtual address of the instruction at which the trap occurs."
pfc: 3
test_type: 0
cov_method: 0
cores: 8
coverage_loc: ''
comments: ''
- 009_RWX access on U-mode pages in U-mode: !Subfeature
name: 009_RWX access on U-mode pages in U-mode
tag: VP_MMU_SV32_F000_S009
next_elt_id: 1
display_order: 9
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_MMU_SV32_F000_S009_I000
description: "If PTE belongs to user mode i.e. its U permission bit is set\
\ (pte.u = 1), then accessing that PTE in user mode should be successful\
\ if the corresponding (r,w,x) permission of PTE is granted. Otherwise raise\
\ page fault exception of the corresponding access type.\nWhen satp.mode=sv32,\
\ PTE has (r,w,x) PMP permissions, PTE has non-reserved RWX encoding, pte.u=1\
\ and pte.v=1, then test the following in user privilege mode for level0\
\ and level1 PTE.\n- Test the read access for both pte.r=1 and for pte.r=0\n\
- Test the write access for both pte.w=1 and for pte.w=0\n- Test the execute\
\ access for both pte.x=1 and for pte.x=0\n\n* For testing at level0, set\
\ all the pte perimssions at level1 to 0 except pte.v, so that level1 points\
\ to level0."
reqt_doc: 'ISA Volume II: Privilege Architecture Version 20211203, Chapter
5.3.2'
ref_mode: ''
ref_page: ''
ref_section: ''
ref_viewer: ''
verif_goals: "RWX access should be successful if the corresponding permissions\
\ are granted in the PTE. Check that load, store and execute works without\
\ any page fault.\n\nPage fault exception should be raised if the corresponding\
\ rwx PTE permissions are not granted. Check that:\n- m/scause must contain\
\ the exception number of:\n - instruction page fault for execute\
\ access.\n - load page fault for read access.\n - store/AMO\
\ page fault for write access.\n- m/sepc must contain the virtual address\
\ of the instruction at which the trap occurs."
pfc: 3
test_type: 0
cov_method: 0
cores: 8
coverage_loc: ''
comments: ''
- 010_Make Executable Page Readable with s/mstatus.MXR unset: !Subfeature
name: 010_Make Executable Page Readable with s/mstatus.MXR unset
tag: VP_MMU_SV32_F000_S010
next_elt_id: 1
display_order: 10
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_MMU_SV32_F000_S010_I000
description: "If PTE has only execute permission (pte.x = 1) and s/mstatus.MXR=0,\
\ then read access on that PTE should raise load page fault exception.\n\
When satp.mode=sv32, PTE has (r,w,x) PMP permissions, and pte.v=1, then\
\ test the following in supervisor and user privilege mode for level0 and\
\ level1 PTE.\n- Set pte.r=0 & pte.w=0 & pte.x=1 & s/mstatus.MXR=0 and test\
\ the read acces.\n\n* For testing at level0, set all the pte perimssions\
\ at level1 to 0 except pte.v, so that level1 points to level0.\n* Set pte.U=0\
\ when test in Supervisor mode and Set pte.U=1 when testing in user mode"
reqt_doc: 'ISA Volume II: Privilege Architecture Version 20211203, Chapter
3.1.6.3, 5.3.2'
ref_mode: ''
ref_page: ''
ref_section: ''
ref_viewer: ''
verif_goals: "Load Page fault exception should be raised. Check that:\n- m/scause\
\ must contain the exception number of load page fault for read access.\n\
- m/sepc must contain the virtual address of the instruction at which the\
\ trap occurs."
pfc: 2
test_type: 0
cov_method: 0
cores: 8
coverage_loc: ''
comments: ''
- 011_Make Executable Page Readable with s/mstatus.MXR set: !Subfeature
name: 011_Make Executable Page Readable with s/mstatus.MXR set
tag: VP_MMU_SV32_F000_S011
next_elt_id: 1
display_order: 11
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_MMU_SV32_F000_S011_I000
description: "If PTE has only execute permission (pte.x = 1) and s/mstatus.MXR=1,\
\ then read access on that PTE should be successful without having explicit\
\ read permission (pte.r=0).\nWhen satp.mode=sv32, PTE has (r,w,x) PMP permissions,\
\ and pte.v=1, then test the following in supervisor and user privilege\
\ mode for level0 and level1 PTE.\n- Set pte.r=0 & pte.w=0 & pte.x=1 & s/mstatus.MXR=1\
\ and test the read acces.\n\n* For testing at level0, set all the pte perimssions\
\ at level1 to 0 except pte.v, so that level1 points to level0.\n* Set pte.U=0\
\ when test in Supervisor mode and Set pte.U=1 when testing in user mode"
reqt_doc: 'ISA Volume II: Privilege Architecture Version 20211203, Chapter
3.1.6.3 ,5.3.2'
ref_mode: ''
ref_page: ''
ref_section: ''
ref_viewer: ''
verif_goals: Read access to the PTE should be successful. Check that load
instructions works without any load page fault exception and expected data
is loaded from the memory.
pfc: 3
test_type: 0
cov_method: 0
cores: 8
coverage_loc: ''
comments: ''
- '012_Global mapping ': !Subfeature
name: '012_Global mapping '
tag: VP_MMU_SV32_F000_S012
next_elt_id: 1
display_order: 12
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_MMU_SV32_F000_S012_I000
description: For two different processes having same Virtual address and different
satp.ASID, maps to same Physical address, and the pte.G is set; then one
process will go through the address translation and update the TLB while
the 2nd process will not go through the translation if pte.G is set and
Physical address exist in TLB.
reqt_doc: 'ISA Volume II: Privilege Architecture Version 20211203, Chapter
5.3.1'
ref_mode: ''
ref_page: ''
ref_section: ''
ref_viewer: ''
verif_goals: Show that two different processes having same VA to PA mapping
can access the translated PA from TLB (if exist) and not go through complete
translation.
pfc: 3
test_type: 0
cov_method: 0
cores: 8
coverage_loc: ''
comments: ''
- 013_Access bit implementation: !Subfeature
name: 013_Access bit implementation
tag: VP_MMU_SV32_F000_S013
next_elt_id: 1
display_order: 13
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_MMU_SV32_F000_S013_I000
description: "If implementation does not sets the pte.A on accessing the PTE,\
\ and PTE has pte.A=0, then accessing it would raise page fault exception\
\ of the corresponding access type. \nWhen satp.mode=sv32, PTE has (r,w,x)\
\ PMP permissions, and pte.v=1, then test the following in supervisor and\
\ user privilege mode for level0 and level1 PTE. Execute sfence.vma before\
\ accessign the PTE.\n- Set pte.r=1 & pte.a=0 and test the read acces. \n\
- Set pte.w=1 & pte.a=0 and test the write access.\n- Set pte.x=1 & pte.a=0\
\ and test the execute access.\n\n* For testing at level0, set all the pte\
\ perimssions at level1 to 0 except pte.v, so that level1 points to level0.\n\
* Set pte.U=0 when test in Supervisor mode and Set pte.U=1 when testing\
\ in user mode."
reqt_doc: 'ISA Volume II: Privilege Architecture Version 20211203, Chapter
5.3.1, 5.3.2'
ref_mode: ''
ref_page: ''
ref_section: ''
ref_viewer: ''
verif_goals: "Page fault exception should be raised according to {x,r,w} access\
\ type. Check that:\n- m/scause must contain the exception number of:\n\
\ - instruction page fault for execute access.\n - load\
\ page fault for read access.\n - store/AMO page fault for write\
\ access.\n- m/sepc must contain the virtual address of the instruction\
\ at which the trap occurs."
pfc: 3
test_type: 0
cov_method: 0
cores: 8
coverage_loc: ''
comments: ''
- 014_Dirty bit Implementation: !Subfeature
name: 014_Dirty bit Implementation
tag: VP_MMU_SV32_F000_S014
next_elt_id: 1
display_order: 14
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_MMU_SV32_F000_S014_I000
description: "If implementation does not sets the pte.D when PTE is written,\
\ and PTE has pte.D=0, then attempting to store on that PTE would raise\
\ Store/AMO page fault exception.\nWhen satp.mode=sv32, PTE has (r,w,x)\
\ PMP permissions, pte.a=1 and pte.v=1, then test the following in supervisor\
\ and user privilege mode for level0 and level1 PTE. Execute sfence.vma\
\ before accessign the PTE.\n- Set pte.w=1 & pte.d=0 and test the write\
\ access.\n\n* For testing at level0, set all the pte perimssions at level1\
\ to 0 except pte.v, so that level1 points to level0.\n* Set pte.U=0 when\
\ test in Supervisor mode and Set pte.U=1 when testing in user mode."
reqt_doc: 'ISA Volume II: Privilege Architecture Version 20211203, Chapter
5.3.1, 5.3.2'
ref_mode: ''
ref_page: ''
ref_section: ''
ref_viewer: ''
verif_goals: "Store/AMO page fault exception should be raised. Check that:\n\
- m/scause must contain the exception number of store/AMO page fault for\
\ write access.\n- m/sepc must contain the virtual address of the instruction\
\ at which the trap occurs."
pfc: 3
test_type: 0
cov_method: 0
cores: 8
coverage_loc: ''
comments: ''
- 015_Misaligned Superpage: !Subfeature
name: 015_Misaligned Superpage
tag: VP_MMU_SV32_F000_S015
next_elt_id: 1
display_order: 15
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_MMU_SV32_F000_S015_I000
description: "If PTE at level1 is leaf PTE (superpage) and its pte.ppn[0]=0,\
\ then it is a misaligned superpage and accessing that PTE would raise page\
\ fault exception of the corresponding access type.\nWhen satp.mode=sv32,\
\ PTE has (r,w,x) PMP permissions, PTE has non-reserved RWX encodings, (pte.r\
\ | pte.x)=1, and pte.v=1, then test the following in supervisor and user\
\ privilege mode for level1 PTE.\n-set pte.ppn[0]=0 and test for read, write\
\ and execute access.\n\n* Set pte.U=0 when test in Supervisor mode and\
\ Set pte.U=1 when testing in user mode."
reqt_doc: 'ISA Volume II: Privilege Architecture Version 20211203, Chapter
5.3.1, 5.3.2'
ref_mode: ''
ref_page: ''
ref_section: ''
ref_viewer: ''
verif_goals: "Page fault exception should be raised according to {x,r,w} access\
\ type. Check that:\n- m/scause must contain the exception number of:\n\
\ - instruction page fault for execute access.\n - load\
\ page fault for read access.\n - store/AMO page fault for write\
\ access.\n- m/sepc must contain the virtual address of the instruction\
\ at which the trap occurs."
pfc: 3
test_type: 0
cov_method: 0
cores: 8
coverage_loc: ''
comments: ''
vptool_gitrev: '$Id: b0efb3ae3f9057b71a577d43c2b77f1cfb2ef82f $'
io_fmt_gitrev: '$Id: 7ee5d68801f5498a957bcbe23fcad87817a364c5 $'
config_gitrev: '$Id: 0422e19126dae20ffc4d5a84e4ce3de0b6eb4eb5 $'
ymlcfg_gitrev: '$Id: 286c689bd48b7a58f9a37754267895cffef1270c $'

View file

@ -0,0 +1,36 @@
!Feature
next_elt_id: 1
name: mstatus.TVM
id: 1
display_order: 1
subfeatures: !!omap
- 000_Accessing satp and sfence.vma CSRs: !Subfeature
name: 000_Accessing satp and sfence.vma CSRs
tag: VP_MMU_SV32_F001_S000
next_elt_id: 1
display_order: 0
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_MMU_SV32_F001_S000_I000
description: If mstatus.TVM=1, read and write access to the satp and sfence.vma
will raise illegal instruction exception in S-mode.
reqt_doc: 'ISA Volume II: Privilege Architecture Version 20211203, Chapter
3.1.6.5'
ref_mode: ''
ref_page: ''
ref_section: ''
ref_viewer: ''
verif_goals: "Show that:\n- s/mcause contains the exception number of illegal\
\ instruction exception.\n- m/sepc must contain the virtual address of the\
\ instruction at which the trap occurs."
pfc: 3
test_type: 0
cov_method: 0
cores: 8
coverage_loc: ''
comments: ''
vptool_gitrev: '$Id: b0efb3ae3f9057b71a577d43c2b77f1cfb2ef82f $'
io_fmt_gitrev: '$Id: 7ee5d68801f5498a957bcbe23fcad87817a364c5 $'
config_gitrev: '$Id: 0422e19126dae20ffc4d5a84e4ce3de0b6eb4eb5 $'
ymlcfg_gitrev: '$Id: 286c689bd48b7a58f9a37754267895cffef1270c $'

View file

@ -0,0 +1,110 @@
!Feature
next_elt_id: 4
name: satp
id: 2
display_order: 2
subfeatures: !!omap
- 000_access permission: !Subfeature
name: 000_access permission
tag: VP_MMU_SV32_F002_S000
next_elt_id: 1
display_order: 0
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_MMU_SV32_F002_S000_I000
description: Access satp in M, S, and U mode using csrrw, csrrc, csrrs
reqt_doc: 'ISA Volume II: Privilege Architecture Version 20211203, Chapter
5.1.11'
ref_mode: ''
ref_page: ''
ref_section: ''
ref_viewer: ''
verif_goals: Show that satp is only accessible in M and S mode and illegal
instruction exception is generated when accessed in lower privilege mode
pfc: 3
test_type: 0
cov_method: 0
cores: 8
coverage_loc: ''
comments: ''
- 001_MODE field: !Subfeature
name: 001_MODE field
tag: VP_MMU_SV32_F002_S001
next_elt_id: 2
display_order: 1
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_MMU_SV32_F002_S001_I000
description: Allows to select different schemes of address translation. Writes
to satp are ignored when unsupported mode is selected.
reqt_doc: 'ISA Volume II: Privilege Architecture Version 20211203, Chapter
5.1.11'
ref_mode: ''
ref_page: ''
ref_section: ''
ref_viewer: ''
verif_goals: Show that supported address translation scheme i.e sv32 is selected
by writing satp.mode=sv32 and reading back the satp
pfc: 3
test_type: 0
cov_method: 0
cores: 8
coverage_loc: ''
comments: ''
- 002_MODE=Bare: !Subfeature
name: 002_MODE=Bare
tag: VP_MMU_SV32_F002_S002
next_elt_id: 1
display_order: 2
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_MMU_SV32_F002_S002_I000
description: Selecting MODE=Bare the remaining feild should be zero. Other
encoding for remaining feild in satp is reserved
reqt_doc: 'ISA Volume II: Privilege Architecture Version 20211203, Chapter
5.1.11'
ref_mode: ''
ref_page: ''
ref_section: ''
ref_viewer: ''
verif_goals: Show wirting {zero, non-zero} value to satp when mode=bare the
behaviour follows the design implemention
pfc: 3
test_type: 0
cov_method: 0
cores: 8
coverage_loc: ''
comments: ''
- 003_ASIDLEN: !Subfeature
name: 003_ASIDLEN
tag: VP_MMU_SV32_F002_S003
next_elt_id: 1
display_order: 3
items: !!omap
- '000': !VerifItem
name: '000'
tag: VP_MMU_SV32_F002_S003_I000
description: ASIDLEN is the number of ASID bits implemented. MAXASID bits
for sv32 is 9
reqt_doc: 'ISA Volume II: Privilege Architecture Version 20211203, Chapter
5.1.11'
ref_mode: ''
ref_page: ''
ref_section: ''
ref_viewer: ''
verif_goals: Determine by writing one to every bit position in the ASID field,
then reading back the value in satp to see which bit positions in the ASID
field hold a one. Show that ASIDLEN is equal to the expected ASIDLEN
pfc: 3
test_type: 0
cov_method: 0
cores: 8
coverage_loc: ''
comments: ''
vptool_gitrev: '$Id: b0efb3ae3f9057b71a577d43c2b77f1cfb2ef82f $'
io_fmt_gitrev: '$Id: 7ee5d68801f5498a957bcbe23fcad87817a364c5 $'
config_gitrev: '$Id: 0422e19126dae20ffc4d5a84e4ce3de0b6eb4eb5 $'
ymlcfg_gitrev: '$Id: 286c689bd48b7a58f9a37754267895cffef1270c $'

View file

@ -0,0 +1,34 @@
#############################################################################
# Copyright (C) 2022 Thales DIS France SAS
#
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0.
#
# Original Author: Zbigniew Chamski (zbigniew.chamski@thalesgroup.com)
#############################################################################
#!/bin/sh
# Location of project-specific directories
ROOTDIR=`readlink -f $(dirname "${BASH_SOURCE[0]}")`
# Set up platform location. It can be anywhere but should contain
# a valid `vp_config.py` file in `vptool` directory.
# Here we use the verification tree from the example directory.
export PLATFORM_TOP_DIR="$ROOTDIR"
# Set the printable name for the project that will be used
# in the human-readable documentation.
export PROJECT_NAME="MMU_SV32"
# Set the alphanumerical identifier of the project that
# will be used to construct file names etc.
export PROJECT_IDENT="MMU_SV32"
# Set the destination directory of Markdown files for this project.
# Since it will be used by VPTOOL, it shall NOT be a relative path.
export MARKDOWN_OUTPUT_DIR=`readlink -f "$ROOTDIR/../source"`
# Run VPTOOL overriding the default theme from Yaml config with 'winxpblue'.
# FIXME: Introduce a suitably named shell variable that points to the root
# directory of the tool set (TOOL_TOP etc.)
# FORNOW use a hardcoded relative path.
python3 $ROOTDIR/../../../../tools/vptool/vptool/vp.py $*

View file

@ -6,7 +6,7 @@
#### Item: 000
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
The “instr” and “mode” signals remain stable during an Issue request transaction.
@ -27,7 +27,7 @@
#### Item: 000
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
When issue transaction starts, instruction and current CPU mode are provided
@ -46,7 +46,7 @@
#### Item: 001
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
Check “mode” signal values.
@ -68,7 +68,7 @@
#### Item: 000
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
During a transaction, each bit of “rs_valid” can transition from 0 to 1 but are not allowed to transition back to 0.
@ -89,7 +89,7 @@
#### Item: 000
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
If XLEN = X_RFR_WIDTH, then rs[X_NUM_RS-1:0] correspond to rs1 and rs2 CPU registers (and rs3 if X_NUM_RS = 3).
@ -108,7 +108,7 @@
#### Item: 001
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
rs signals are only required to be stable during the part of a transaction in which these signals are considered to be valid.
@ -127,13 +127,15 @@
#### Item: 002
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
If XLEN != X_RFR_WIDTH , then rs[X_NUM_RS-1:0] correspond to even/odd register pair with rs1, rs2, (rs3) are even register and even register is provided in the 32 lower bits of rs signal.
* **Verification Goals**
For every issue transaction check that rs signal correspond to the concatenation of rs1/rs1+1,rs2/rs2+1, (rs3/rs3+1) value in CPU register file and even register is in the 32 lower bits of rs.
For every issue transaction check that rs signal correspond to the concatenation of rs1/rs1+1,rs2/rs2+1, (rs3/rs3+1) value in CPU register file and even register is in the 32 lower bits of rs.
Can't be check XLEN == X_RFR_WIDTH
* **Pass/Fail Criteria:** NDY (Not Defined Yet)
* **Test Type:** NDY (Not Defined Yet)
* **Coverage Method:** NDY (Not Defined Yet)
@ -148,7 +150,7 @@
#### Item: 000
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
If accept == 0 :
@ -170,7 +172,7 @@
#### Item: 000
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
The CPU shall cause an illegal instruction if:
@ -194,7 +196,7 @@
#### Item: 000
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
Check for issue id validity.
@ -215,11 +217,11 @@
#### Item: 000
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
Accept = 1 if:
- coprocessor can handle the instruction based on decoding “instr”and "mode".
- coprocessor can handle the instruction based on decoding “instr” and "mode".
- “issue_valid” == 1 and required bit(s) of “rs_valid” are 1.
* **Verification Goals**
@ -238,7 +240,7 @@
#### Item: 000
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
“issue_resp” signals and “issue_req” signals are accepted when “issue_valid” == “issue_ready” == 1
@ -264,7 +266,7 @@
#### Item: 000
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
The “commit_valid” == 1 exactly one clk cycle for every offloaded Instruction by the coprocessor (whether accepted or not).
@ -285,7 +287,7 @@
#### Item: 000
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
There is a unique commit transaction for every issue transaction (unique until an instruction has "fully completed" = its result has been submitted).
@ -306,7 +308,7 @@
#### Item: 000
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
- The CPU shall perform a commit transaction for every issue transaction, independent of the accept value of the issue transaction.
@ -328,7 +330,7 @@
#### Item: 000
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
The signals in commit are valid when commit_valid is 1.
@ -352,7 +354,7 @@
#### Item: 000
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
A coprocessor is not allowed to perform speculative result transactions.
@ -373,7 +375,7 @@
#### Item: 000
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
A coprocessor is allowed to provide results to the core in an out of order fashion.
@ -394,7 +396,7 @@
#### Item: 000
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
Each accepted offloaded (committed and not killed) instruction shall have exactly one result group transaction (even if no data needs to be written back to the CPUs register file).
@ -415,7 +417,7 @@
#### Item: 000
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
The signals in result shall remain stable during a result transaction (except data ...)
@ -436,7 +438,7 @@
#### Item: 000
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
Data is only required to remain stable during result transactions in which "we" is not 0.
@ -457,7 +459,7 @@
#### Item: 000
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
The exc is used to signal synchronous exceptions. A synchronous exception will lead to a trap in CPU unless the corresponding instruction is killed.
@ -476,7 +478,7 @@
#### Item: 001
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
exccode provides the least significant bits of the exception code bitfield of the mcause CSR.
@ -495,10 +497,10 @@
#### Item: 002
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
 "we" shall be driven to 0 by the coprocessor for synchronous exceptions.
"we" shall be driven to 0 by the coprocessor for synchronous exceptions.
* **Verification Goals**
Check that "we" signal == 0 when exc == 1.
@ -516,13 +518,15 @@
#### Item: 000
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
we is 2 bits wide when XLEN` = 32 and X_RFW_WIDTH = 64, and 1 bit wide otherwise. If "we" is 2 bits wide, then we[1] is only allowed to be 1 if we[0] is 1 as well (i.e. for dual writeback).
we is 2 bits wide when XLEN = 32 and X_RFW_WIDTH = 64, and 1 bit wide otherwise. If "we" is 2 bits wide, then we[1] is only allowed to be 1 if we[0] is 1 as well (i.e. for dual writeback).
* **Verification Goals**
For dualwrite instruction, check that we[1]==1 is only allowed if we[0] == 1.
For dualwrite instruction, check that we[1]==1 is only allowed if we[0] == 1.
Dualwrite not supported (for now)
* **Pass/Fail Criteria:** Assertion
* **Test Type:** Constrained Random
* **Coverage Method:** Assertion Coverage
@ -537,7 +541,7 @@
#### Item: 000
* **Requirement location:**
* **Requirement location:** https://github.com/openhwgroup/core-v-xif/blob/43dc03563e0c79cc55922f653406a9f122f61e80/docs/source/x_ext.rst
* **Feature Description**
Result transaction starts in the cycle that result_valid = 1 and ends in the cycle that both result_valid == result_ready == 1.
@ -554,3 +558,517 @@
*(none)*
## Feature: Custom Instructions
### Sub-feature: 000_CUS_ADD
#### Item: 000
* **Requirement location:** ./custom_instruction.rst
* **Feature Description**
cus_add rd, rs1, rs2
rd = rs1 + rs2
cus_add works in all privilege modes
* **Verification Goals**
Register operands:
All possible rs1 registers are used.
All possible rs2 registers are used.
All possible rd registers are used.
All possible register combinations where rs1 == rd are used
All possible register combinations where rs2 == rd are used
* **Pass/Fail Criteria:** Check RM
* **Test Type:** Constrained Random
* **Coverage Method:** Functional Coverage
* **Applicable Cores:** CV32A6_v0.1.0, CV32A6-step2, CV64A6-step3
* **Unique verification tag:** VP_CVXIF_F003_S000_I000
* **Link to Coverage:**
* **Comments**
*(none)*
#### Item: 001
* **Requirement location:** ./custom_instruction.rst
* **Feature Description**
cus_add rd, rs1, rs2
rd = rs1 + rs2
cus_add works in all privilege modes
* **Verification Goals**
Input operands:
rs1 value is +ve, -ve and zero
rs2 value is +ve, -ve and zero
All combinations of rs1 and rs2 +ve, -ve, and zero values are used
All bits of rs1 are toggled
All bits of rs2 are toggled
* **Pass/Fail Criteria:** NDY (Not Defined Yet)
* **Test Type:** NDY (Not Defined Yet)
* **Coverage Method:** NDY (Not Defined Yet)
* **Applicable Cores:** CV32A6_v0.1.0, CV32A6-step2, CV64A6-step3
* **Unique verification tag:** VP_CVXIF_F003_S000_I001
* **Link to Coverage:**
* **Comments**
*(none)*
#### Item: 002
* **Requirement location:** ./custom_instruction.rst
* **Feature Description**
cus_add rd, rs1, rs2
rd = rs1 + rs2
cus_add works in all privilege modes
* **Verification Goals**
Output result:
rd value is +ve, -ve and zero
All bits of rd are toggled
* **Pass/Fail Criteria:** NDY (Not Defined Yet)
* **Test Type:** NDY (Not Defined Yet)
* **Coverage Method:** NDY (Not Defined Yet)
* **Applicable Cores:** CV32A6_v0.1.0, CV32A6-step2, CV64A6-step3
* **Unique verification tag:** VP_CVXIF_F003_S000_I002
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 001_CUS_NOP
#### Item: 000
* **Requirement location:** ./custom_instruction.rst
* **Feature Description**
No operation Instruction
* **Verification Goals**
Instruction executed
* **Pass/Fail Criteria:** Check RM
* **Test Type:** Constrained Random
* **Coverage Method:** Functional Coverage
* **Applicable Cores:** CV32A6_v0.1.0, CV32A6-step2, CV64A6-step3
* **Unique verification tag:** VP_CVXIF_F003_S001_I000
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 003_CUS_S_ADD
#### Item: 000
* **Requirement location:** ./custom_instruction.rst
* **Feature Description**
cus_s_add rd, rs1, rs2
rd = rs1 + rs2
cus_s_add works in supervisor privilege mode
* **Verification Goals**
Register operands:
if (mode == s)
All possible rs1 registers are used.
All possible rs2 registers are used.
All possible rd registers are used.
All possible register combinations where rs1 == rd are used
All possible register combinations where rs2 == rd are used
else if (mode != s)
illegal exception raised on hte CPU
* **Pass/Fail Criteria:** Check RM
* **Test Type:** Constrained Random
* **Coverage Method:** Functional Coverage
* **Applicable Cores:** CV32A6_v0.1.0, CV32A6-step2, CV64A6-step3
* **Unique verification tag:** VP_CVXIF_F003_S003_I000
* **Link to Coverage:**
* **Comments**
*(none)*
#### Item: 001
* **Requirement location:** ./custom_instruction.rst
* **Feature Description**
cus_s_add rd, rs1, rs2
rd = rs1 + rs2
cus_s_add works in supervisor privilege mode
* **Verification Goals**
Input operands:
if (mode == s)
rs1 value is +ve, -ve and zero
rs2 value is +ve, -ve and zero
All combinations of rs1 and rs2 +ve, -ve, and zero values are used
All bits of rs1 are toggled
All bits of rs2 are toggled
else if (mode != s)
illegal exception raised on the CPU
* **Pass/Fail Criteria:** NDY (Not Defined Yet)
* **Test Type:** NDY (Not Defined Yet)
* **Coverage Method:** NDY (Not Defined Yet)
* **Applicable Cores:** CV32A6_v0.1.0, CV32A6-step2, CV64A6-step3
* **Unique verification tag:** VP_CVXIF_F003_S003_I001
* **Link to Coverage:**
* **Comments**
*(none)*
#### Item: 002
* **Requirement location:** ./custom_instruction.rst
* **Feature Description**
cus_s_add rd, rs1, rs2
rd = rs1 + rs2
cus_s_add works in supervisor privilege mode
* **Verification Goals**
Output operands:
if (mode == s)
rd value is +ve, -ve and zero
All bits of rd are toggled
else if (mode != s)
illegal exception raised on the CPU
* **Pass/Fail Criteria:** NDY (Not Defined Yet)
* **Test Type:** NDY (Not Defined Yet)
* **Coverage Method:** NDY (Not Defined Yet)
* **Applicable Cores:** CV32A6_v0.1.0, CV32A6-step2, CV64A6-step3
* **Unique verification tag:** VP_CVXIF_F003_S003_I002
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 004_CUS_U_ADD
#### Item: 000
* **Requirement location:** ./custom_instruction.rst
* **Feature Description**
cus_u_add rd, rs1, rs2
rd = rs1 + rs2
cus_u_add works in User privilege mode
* **Verification Goals**
Register operands:
if (mode == u)
All possible rs1 registers are used.
All possible rs2 registers are used.
All possible rd registers are used.
All possible register combinations where rs1 == rd are used
All possible register combinations where rs2 == rd are used
else if (mode != u)
illegal exception raised on hte CPU
* **Pass/Fail Criteria:** Check RM
* **Test Type:** Constrained Random
* **Coverage Method:** Functional Coverage
* **Applicable Cores:** CV32A6_v0.1.0, CV32A6-step2, CV64A6-step3
* **Unique verification tag:** VP_CVXIF_F003_S004_I000
* **Link to Coverage:**
* **Comments**
*(none)*
#### Item: 001
* **Requirement location:** ./custom_instruction.rst
* **Feature Description**
cus_u_add rd, rs1, rs2
rd = rs1 + rs2
cus_u_add works in User privilege mode
* **Verification Goals**
Input operands:
if (mode == u)
rs1 value is +ve, -ve and zero
rs2 value is +ve, -ve and zero
All combinations of rs1 and rs2 +ve, -ve, and zero values are used
All bits of rs1 are toggled
All bits of rs2 are toggled
else if (mode != u)
illegal exception raised on the CPU
* **Pass/Fail Criteria:** NDY (Not Defined Yet)
* **Test Type:** NDY (Not Defined Yet)
* **Coverage Method:** NDY (Not Defined Yet)
* **Applicable Cores:** CV32A6_v0.1.0, CV32A6-step2, CV64A6-step3
* **Unique verification tag:** VP_CVXIF_F003_S004_I001
* **Link to Coverage:**
* **Comments**
*(none)*
#### Item: 002
* **Requirement location:** ./custom_instruction.rst
* **Feature Description**
cus_u_add rd, rs1, rs2
rd = rs1 + rs2
cus_u_add works in User privilege mode
* **Verification Goals**
Output operands:
if (mode == u)
rd value is +ve, -ve and zero
All bits of rd are toggled
else if (mode != u)
illegal exception raised on the CPU
* **Pass/Fail Criteria:** NDY (Not Defined Yet)
* **Test Type:** NDY (Not Defined Yet)
* **Coverage Method:** NDY (Not Defined Yet)
* **Applicable Cores:** CV32A6_v0.1.0, CV32A6-step2, CV64A6-step3
* **Unique verification tag:** VP_CVXIF_F003_S004_I002
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 005_CUS_ADD_MULTI
#### Item: 000
* **Requirement location:** ./custom_instruction.rst
* **Feature Description**
cus_add_multi rd, rs1, rs2
rd = rs1 + rs2
cus_add_multi works in all privilege modes
* **Verification Goals**
Register operands:
All possible rs1 registers are used.
All possible rs2 registers are used.
All possible rd registers are used.
All possible register combinations where rs1 == rd are used
All possible register combinations where rs2 == rd are used
* **Pass/Fail Criteria:** Check RM
* **Test Type:** Constrained Random
* **Coverage Method:** Functional Coverage
* **Applicable Cores:** CV32A6_v0.1.0, CV32A6-step2, CV64A6-step3
* **Unique verification tag:** VP_CVXIF_F003_S005_I000
* **Link to Coverage:**
* **Comments**
*(none)*
#### Item: 001
* **Requirement location:** ./custom_instruction.rst
* **Feature Description**
cus_add_multi rd, rs1, rs2
rd = rs1 + rs2
cus_add_multi works in all privilege modes
* **Verification Goals**
Input operands:
rs1 value is +ve, -ve and zero
rs2 value is +ve, -ve and zero
All combinations of rs1 and rs2 +ve, -ve, and zero values are used
All bits of rs1 are toggled
All bits of rs2 are toggled
* **Pass/Fail Criteria:** NDY (Not Defined Yet)
* **Test Type:** NDY (Not Defined Yet)
* **Coverage Method:** NDY (Not Defined Yet)
* **Applicable Cores:** CV32A6_v0.1.0, CV32A6-step2, CV64A6-step3
* **Unique verification tag:** VP_CVXIF_F003_S005_I001
* **Link to Coverage:**
* **Comments**
*(none)*
#### Item: 002
* **Requirement location:** ./custom_instruction.rst
* **Feature Description**
cus_add_multi rd, rs1, rs2
rd = rs1 + rs2
cus_add_multi works in all privilege modes
* **Verification Goals**
Output result:
rd value is +ve, -ve and zero
All bits of rd are toggled
* **Pass/Fail Criteria:** NDY (Not Defined Yet)
* **Test Type:** NDY (Not Defined Yet)
* **Coverage Method:** NDY (Not Defined Yet)
* **Applicable Cores:** CV32A6_v0.1.0, CV32A6-step2, CV64A6-step3
* **Unique verification tag:** VP_CVXIF_F003_S005_I002
* **Link to Coverage:**
* **Comments**
*(none)*
#### Item: 003
* **Requirement location:** ./custom_instruction.rst
* **Feature Description**
cus_add_multi rd, rs1, rs2
rd = rs1 + rs2
cus_add_multi works in all privilege modes
* **Verification Goals**
Check all delays from min to max
* **Pass/Fail Criteria:** Check RM
* **Test Type:** Constrained Random
* **Coverage Method:** Functional Coverage
* **Applicable Cores:** CV32A6_v0.1.0, CV32A6-step2, CV64A6-step3
* **Unique verification tag:** VP_CVXIF_F003_S005_I003
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 006_CUS_EXC
#### Item: 000
* **Requirement location:** ./custom_instruction.rst
* **Feature Description**
cus_exc imm[5:0]
mcause[5:0] = imm[5:0]
cus_exc raise an exception on the CPU base on the imm value
* **Verification Goals**
Check all possible imm value
* **Pass/Fail Criteria:** NDY (Not Defined Yet)
* **Test Type:** NDY (Not Defined Yet)
* **Coverage Method:** NDY (Not Defined Yet)
* **Applicable Cores:** CV32A6_v0.1.0, CV32A6-step2, CV64A6-step3
* **Unique verification tag:** VP_CVXIF_F003_S006_I000
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 007_CUS_ADD_RS3
#### Item: 000
* **Requirement location:** ./custom_instruction.rst
* **Feature Description**
cus_add_rs3 rd, rs1, rs2, rs3
rd = rs1 + rs2 + rs3
cus_add_rs3 works in all privilege modes
X_NUM_RS == 3
* **Verification Goals**
Register operands:
if (X_NUM_RS == 3)
All possible rs1 registers are used.
All possible rs2 registers are used.
All possible rs3 registers are used.
All possible rd registers are used.
All possible register combinations where rs1 == rd are used
All possible register combinations where rs2 == rd are used
All possible register combinations where rs3 == rd are used
else if (X_NUM_RS != 3)
illegal exception raised on the CPU
* **Pass/Fail Criteria:** Check RM
* **Test Type:** Constrained Random
* **Coverage Method:** Functional Coverage
* **Applicable Cores:** CV32A6_v0.1.0, CV32A6-step2, CV64A6-step3
* **Unique verification tag:** VP_CVXIF_F003_S007_I000
* **Link to Coverage:**
* **Comments**
*(none)*
#### Item: 001
* **Requirement location:** ./custom_instruction.rst
* **Feature Description**
cus_add_rs3 rd, rs1, rs2, rs3
rd = rs1 + rs2 + rs3
cus_add_rs3 works in all privilege modes
X_NUM_RS == 3
* **Verification Goals**
Input operands:
if (X_NUS_RS == 3)
rs1 value is +ve, -ve and zero
rs2 value is +ve, -ve and zero
rs3 value is +ve, -ve and zero
All combinations of rs1, rs2 and rs3 +ve, -ve, and zero values are used
All bits of rs1 are toggled
All bits of rs2 are toggled
All bits of rs3 are toggled
else if (X_NUM_RS != 3)
illegal exception raised on the CPU
* **Pass/Fail Criteria:** NDY (Not Defined Yet)
* **Test Type:** NDY (Not Defined Yet)
* **Coverage Method:** NDY (Not Defined Yet)
* **Applicable Cores:** CV32E40P, CV32E40S, CV32E40X, CV32A6_v0.1.0, CV32A6-step2, CV64A6-step3
* **Unique verification tag:** VP_CVXIF_F003_S007_I001
* **Link to Coverage:**
* **Comments**
*(none)*
#### Item: 002
* **Requirement location:** ./custom_instruction.rst
* **Feature Description**
cus_add_rs3 rd, rs1, rs2, rs3
rd = rs1 + rs2 + rs3
cus_add_rs3 works in all privilege modes
X_NUM_RS == 3
* **Verification Goals**
Output operands:
if (X_NUM_RS == 3)
rd value is +ve, -ve and zero
All bits of rd are toggled
else if (X_NUM_RS != 3)
illegal exception raised on the CPU
* **Pass/Fail Criteria:** NDY (Not Defined Yet)
* **Test Type:** NDY (Not Defined Yet)
* **Coverage Method:** NDY (Not Defined Yet)
* **Applicable Cores:** CV32A6_v0.1.0, CV32A6-step2, CV64A6-step3
* **Unique verification tag:** VP_CVXIF_F003_S007_I002
* **Link to Coverage:**
* **Comments**
*(none)*

View file

@ -0,0 +1,600 @@
# Module: MMU_SV32
## Feature: sv32
### Sub-feature: 000_PMP permissions on Physical Address
#### Item: 000
* **Requirement location:** ISA Volume II: Privilege Architecture Version 20211203, Chapter 3.7, 5.3.2
* **Feature Description**
If PTE has valid and non-reserved RWX permissions, but the translated Physical address (pte.ppn of leaf PTE + offset) does not have (r,w,x) PMP permissions, then accessing the translated Physical address would raise access fault exception.
When satp.mode=sv32, and PTE has valid and non-reserved RWX permissions then test the following in supervisor and user privilege mode for level1 and level0 PTE.
- Remove read PMP permission of translated Physical Address in pmpcfg and test the read acces.
- Remvoe write PMP permission of translated Physical Address in pmpcfg and test the write access.
- Remove execute PMP permission of translated Physical Address in pmpcfg and test the execute access.
* **Verification Goals**
Access fault exception should be raised according to {x,r,w} access type. Check that:
- m/scause must contain the exception number of:
- instruction access fault for execute access.
- load page access for read access.
- store/AMO access fault for write access.
- m/sepc must contain the virtual address of the instruction at which the trap occurs.
* **Pass/Fail Criteria:** Check RM
* **Test Type:** RISC-V Arch-test
* **Coverage Method:** Testcase
* **Applicable Cores:** CV32A6_v0.1.0
* **Unique verification tag:** VP_MMU_SV32_F000_S000_I000
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 001_PMP permissions on PTE
#### Item: 000
* **Requirement location:** ISA Volume II: Privilege Architecture Version 20211203, Chapter 3.7, 5.3.2
* **Feature Description**
If PTE does not have (r,w,x) PMP permissions, then accessing it would raise access fault exception of the corresponding access type.
When satp.mode=sv32, then test the following in supervisor and user privilege mode for level0 and level1 PTE.
- Remove read PMP permission of PTE address in pmpcfg and test the read acces.
- Remvoe write PMP permission of PTE address in pmpcfg and test the write access.
- Remove execute PMP permission of PTE address in pmpcfg and test the execute access.
* **Verification Goals**
Access fault exception should be raised according to {x,r,w} access type. Check that:
- m/scause must contain the exception number of:
- instruction access fault for execute access.
- load page access for read access.
- store/AMO access fault for write access.
- m/sepc must contain the virtual address of the instruction at which the trap occurs.
* **Pass/Fail Criteria:** NDY (Not Defined Yet)
* **Test Type:** NDY (Not Defined Yet)
* **Coverage Method:** NDY (Not Defined Yet)
* **Applicable Cores:** CV32A6_v0.1.0
* **Unique verification tag:** VP_MMU_SV32_F000_S001_I000
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 002_In-Valid Permission of PTE
#### Item: 000
* **Requirement location:** ISA Volume II: Privilege Architecture Version 20211203, Chpter 5.3.2
* **Feature Description**
If PTE does not have Valid (pte.V=0) permission, then accessing it would raise page fault exception of the corresponding access type.
When satp.mode=sv32 and PTE has (r,w,x) PMP permissions, then test the following in supervisor and user privilege mode for level0 and level1 PTE.
- Set PTE.V = 0 and test the read acces.
- Set PTE.V = 0 and test the write access.
- Set PTE.V = 0 and test the execute access.
* For testing at level0, set all the pte perimssions at level1 to 0 except pte.v, so that level1 points to level0.
* Set pte.U=0 when test in Supervisor mode and Set pte.U=1 when testing in user mode
* **Verification Goals**
Page fault exception should be raised according to {x,r,w} access type. Check that:
- m/scause must contain the exception number of:
- instruction page fault for execute access.
- load page fault for read access.
- store/AMO page fault for write access.
- m/sepc must contain the virtual address of the instruction at which the trap occurs.
* **Pass/Fail Criteria:** Check RM
* **Test Type:** RISC-V Arch-test
* **Coverage Method:** Testcase
* **Applicable Cores:** CV32A6_v0.1.0
* **Unique verification tag:** VP_MMU_SV32_F000_S002_I000
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 003_Reserved RWX permission encodings of PTE
#### Item: 000
* **Requirement location:** ISA Volume II: Privilege Architecture Version 20211203, Chapter 3.7, 5.3.1
* **Feature Description**
If PTE has reserved RWX encodings (pte.w=1 & pte.r=0), then accessing it would raise page fault exception of the corresponding access type.
When satp.mode=sv32, PTE has (r,w,x) PMP permissions, and pte.v=1, then test the following in supervisor and user privilege mode for level0 and level1 PTE.
- Set pte.w=1 & pte.r=0 and test the read acces.
- Set pte.w=1 & pte.r=0 and test the write access.
- Set pte.w=1 & pte.r=0 and test the execute access.
* For testing at level0, set all the pte perimssions at level1 to 0 except pte.v, so that level1 points to level0.
* Set pte.U=0 when test in Supervisor mode and Set pte.U=1 when testing in user mode
* **Verification Goals**
Page fault exception should be raised according to {x,r,w} access type. Check that:
- m/scause must contain the exception number of:
- instruction page fault for execute access.
- load page fault for read access.
- store/AMO page fault for write access.
- m/sepc must contain the virtual address of the instruction at which the trap occurs.
* **Pass/Fail Criteria:** Check RM
* **Test Type:** RISC-V Arch-test
* **Coverage Method:** Testcase
* **Applicable Cores:** CV32A6_v0.1.0
* **Unique verification tag:** VP_MMU_SV32_F000_S003_I000
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 004_Non-leaf PTE permission at level 0
#### Item: 000
* **Requirement location:** ISA Volume II: Privilege Architecture Version 20211203, Chapter 5.3.2
* **Feature Description**
If PTE at level0 has non-leaf RWX permissions (pte.x=0 & pte.r=0), then accessing it would raise page fault exception of the corresponding access type.
When satp.mode=sv32, PTE has (r,w,x) PMP permissions, and pte.v=1, then test the following in supervisor and user privilege mode for level0 PTE.
- Set pte.x=0 & pte.r=0 & pte.w=0 and test the read acces.
- Set pte.x=0 & pte.r=0 & pte.w=0 and test the write access.
- Set pte.x=0 & pte.r=0 & pte.w=0 and test the execute access.
* For testing at level0, set all the pte perimssions at level1 to 0 except pte.v, so that level1 points to level0.
* Set pte.U=0 when test in Supervisor mode and Set pte.U=1 when testing in user mode
* **Verification Goals**
Page fault exception should be raised according to {x,r,w} access type. Check that:
- m/scause must contain the exception number of:
- instruction page fault for execute access.
- load page fault for read access.
- store/AMO page fault for write access.
- m/sepc must contain the virtual address of the instruction at which the trap occurs.
* **Pass/Fail Criteria:** Check RM
* **Test Type:** RISC-V Arch-test
* **Coverage Method:** Testcase
* **Applicable Cores:** CV32A6_v0.1.0
* **Unique verification tag:** VP_MMU_SV32_F000_S004_I000
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 005_RWX access on S-mode pages in S-mode
#### Item: 000
* **Requirement location:** ISA Volume II: Privilege Architecture Version 20211203, Chapter 5.3.1
* **Feature Description**
If PTE belongs to supervisor mode i.e. its U permission bit is clear (pte.u = 0), then accessing that PTE in supervisor mode should be successful if the corresponding (r,w,x) permission of PTE is granted. Otherwise raise page fault exception of the corresponding access type.
When satp.mode=sv32, PTE has (r,w,x) PMP permissions, PTE has non-reserved RWX encoding, pte.u=0 and pte.v=1, then test the following in supervisor privilege mode for level 0 and level 1 PTE.
- Test the read access for both pte.r=1 and for pte.r=0
- Test the write access for both pte.w=1 and for pte.w=0
- Test the execute access for both pte.x=1 and for pte.x=0
* For testing at level0, set all the pte perimssions at level1 to 0 except pte.v, so that level1 points to level0.
* **Verification Goals**
RWX access should be successful if the corresponding permissions are granted in the PTE. Check that load, store and execute works without any page fault.
Page fault exception should be raised according to (x,r,w) access type if the corresponding (r,w,x) permissions are not granted in the PTE. Check that:
- m/scause must contain the exception number of:
- instruction page fault for execute.
- load page fault for read access.
- store/AMO page fault for write access.
- m/sepc must contain the virtual address of the instruction at which the trap occurs.
* **Pass/Fail Criteria:** Check RM
* **Test Type:** RISC-V Arch-test
* **Coverage Method:** Testcase
* **Applicable Cores:** CV32A6_v0.1.0
* **Unique verification tag:** VP_MMU_SV32_F000_S005_I000
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 006_RWX access on S-mode pages in U-mode
#### Item: 000
* **Requirement location:** ISA Volume II: Privilege Architecture Version 20211203, Chapter 5.3.2
* **Feature Description**
If PTE belongs to supervisor mode i.e. its U permission bit is clear (pte.u = 0), then accessing that PTE in user mode would raise page fault exception of the corresponding access type.
When satp.mode=sv32, PTE has (r,w,x) PMP permissions, PTE has non-reserved RWX encoding, and pte.v=1, then test the following user privilege mode for level0 and level1 PTE.
- Set pte.u=0 and test the read acces.
- Set pte.u=0 and test the write access.
- Set pte.u=0 and test the execute access.
* For testing at level0, set all the pte perimssions at level1 to 0 except pte.v, so that level1 points to level0.
* **Verification Goals**
Page fault exception should be raised according to {x,r,w} access type. Check that:
- m/scause must contain the exception number of instruction, load, and store/AMO page fault for execute, read and write access type, respectively.
- m/sepc must contain the virtual address of the instruction at which the trap occurs.
* **Pass/Fail Criteria:** Check RM
* **Test Type:** RISC-V Arch-test
* **Coverage Method:** Testcase
* **Applicable Cores:** CV32A6_v0.1.0
* **Unique verification tag:** VP_MMU_SV32_F000_S006_I000
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 007_RWX access on U-mode pages in S-mode with mstatus.SUM unset
#### Item: 000
* **Requirement location:** ISA Volume II: Privilege Architecture Version 20211203, Chapter 3.1.6.3, 5.3.2
* **Feature Description**
If PTE belongs to user mode i.e. its U permission bit is set (pte.u = 1) and m/sstatus.SUM = 0, then accessing that PTE in supervisor mode would raise page fault exception of the corresponding access type.
When satp.mode=sv32, PTE has (r,w,x) PMP permissions, PTE has non-reserved RWX encoding, and pte.v=1, then test the following in supervisor mode for level 0 and level 1 PTE.
- Set pte.u=1 & s/mstatus.SUM = 0 and test the read acces.
- Set pte.u=1 & s/mstatus.SUM = 0 and test the write access.
- Set pte.u=1 & s/mstatus.SUM = 0 and test the execute access.
* For testing at level0, set all the pte perimssions at level1 to 0 except pte.v, so that level1 points to level0.
* **Verification Goals**
Page fault exception should be raised according to {x,r,w} access type. Check that:
- m/scause must contain the exception number of:
- instruction page fault for execute access.
- load page fault for read access.
- store/AMO page fault for write access.
- m/sepc must contain the virtual address of the instruction at which the trap occurs.
* **Pass/Fail Criteria:** Check RM
* **Test Type:** RISC-V Arch-test
* **Coverage Method:** Testcase
* **Applicable Cores:** CV32A6_v0.1.0
* **Unique verification tag:** VP_MMU_SV32_F000_S007_I000
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 008_RWX access on U-mode pages in S-mode with mstatus.SUM set
#### Item: 000
* **Requirement location:** ISA Volume II: Privilege Architecture Version 20211203, Chapter 3.1.6.3, 5.3.2
* **Feature Description**
If PTE belongs to user mode i.e. its U permission bit is set (pte.u = 1) and m/sstatus.SUM = 1, then RW access to that PTE in supervisor mode would be successful but eXecute access would raise instruction page fault exception in s-mode.
When satp.mode=sv32, PTE has (r,w,x) PMP permissions, PTE has non-reserved RWX encoding, and pte.v=1, then test the following in supervisor mode for level0 and level1 PTE.
- Set pte.r=1 & pte.u=1 & s/mstatus.SUM = 1 and test the read acces.
- Set pte.w=1 & pte.u=1 & s/mstatus.SUM = 1 and test the write access.
- Set pte.x=1 & pte.u=1 & s/mstatus.SUM = 1 and test the execute access.
* For testing at level0, set all the pte perimssions at level1 to 0 except pte.v, so that level1 points to level0.
* **Verification Goals**
Read and Write access to the PTE should be successful. So, check that the load and store works without page fault and expected data is stored to and loaded from the memory, repectively.
Execute access should raise instruction page fault. Check that:
- m/scause must contain the exception number of instruction instruction access fault.
- m/sepc must contain the virtual address of the instruction at which the trap occurs.
* **Pass/Fail Criteria:** Check RM
* **Test Type:** RISC-V Arch-test
* **Coverage Method:** Testcase
* **Applicable Cores:** CV32A6_v0.1.0
* **Unique verification tag:** VP_MMU_SV32_F000_S008_I000
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 009_RWX access on U-mode pages in U-mode
#### Item: 000
* **Requirement location:** ISA Volume II: Privilege Architecture Version 20211203, Chapter 5.3.2
* **Feature Description**
If PTE belongs to user mode i.e. its U permission bit is set (pte.u = 1), then accessing that PTE in user mode should be successful if the corresponding (r,w,x) permission of PTE is granted. Otherwise raise page fault exception of the corresponding access type.
When satp.mode=sv32, PTE has (r,w,x) PMP permissions, PTE has non-reserved RWX encoding, pte.u=1 and pte.v=1, then test the following in user privilege mode for level0 and level1 PTE.
- Test the read access for both pte.r=1 and for pte.r=0
- Test the write access for both pte.w=1 and for pte.w=0
- Test the execute access for both pte.x=1 and for pte.x=0
* For testing at level0, set all the pte perimssions at level1 to 0 except pte.v, so that level1 points to level0.
* **Verification Goals**
RWX access should be successful if the corresponding permissions are granted in the PTE. Check that load, store and execute works without any page fault.
Page fault exception should be raised if the corresponding rwx PTE permissions are not granted. Check that:
- m/scause must contain the exception number of:
- instruction page fault for execute access.
- load page fault for read access.
- store/AMO page fault for write access.
- m/sepc must contain the virtual address of the instruction at which the trap occurs.
* **Pass/Fail Criteria:** Check RM
* **Test Type:** RISC-V Arch-test
* **Coverage Method:** Testcase
* **Applicable Cores:** CV32A6_v0.1.0
* **Unique verification tag:** VP_MMU_SV32_F000_S009_I000
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 010_Make Executable Page Readable with s/mstatus.MXR unset
#### Item: 000
* **Requirement location:** ISA Volume II: Privilege Architecture Version 20211203, Chapter 3.1.6.3, 5.3.2
* **Feature Description**
If PTE has only execute permission (pte.x = 1) and s/mstatus.MXR=0, then read access on that PTE should raise load page fault exception.
When satp.mode=sv32, PTE has (r,w,x) PMP permissions, and pte.v=1, then test the following in supervisor and user privilege mode for level0 and level1 PTE.
- Set pte.r=0 & pte.w=0 & pte.x=1 & s/mstatus.MXR=0 and test the read acces.
* For testing at level0, set all the pte perimssions at level1 to 0 except pte.v, so that level1 points to level0.
* Set pte.U=0 when test in Supervisor mode and Set pte.U=1 when testing in user mode
* **Verification Goals**
Load Page fault exception should be raised. Check that:
- m/scause must contain the exception number of load page fault for read access.
- m/sepc must contain the virtual address of the instruction at which the trap occurs.
* **Pass/Fail Criteria:** Signature
* **Test Type:** RISC-V Arch-test
* **Coverage Method:** Testcase
* **Applicable Cores:** CV32A6_v0.1.0
* **Unique verification tag:** VP_MMU_SV32_F000_S010_I000
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 011_Make Executable Page Readable with s/mstatus.MXR set
#### Item: 000
* **Requirement location:** ISA Volume II: Privilege Architecture Version 20211203, Chapter 3.1.6.3 ,5.3.2
* **Feature Description**
If PTE has only execute permission (pte.x = 1) and s/mstatus.MXR=1, then read access on that PTE should be successful without having explicit read permission (pte.r=0).
When satp.mode=sv32, PTE has (r,w,x) PMP permissions, and pte.v=1, then test the following in supervisor and user privilege mode for level0 and level1 PTE.
- Set pte.r=0 & pte.w=0 & pte.x=1 & s/mstatus.MXR=1 and test the read acces.
* For testing at level0, set all the pte perimssions at level1 to 0 except pte.v, so that level1 points to level0.
* Set pte.U=0 when test in Supervisor mode and Set pte.U=1 when testing in user mode
* **Verification Goals**
Read access to the PTE should be successful. Check that load instructions works without any load page fault exception and expected data is loaded from the memory.
* **Pass/Fail Criteria:** Check RM
* **Test Type:** RISC-V Arch-test
* **Coverage Method:** Testcase
* **Applicable Cores:** CV32A6_v0.1.0
* **Unique verification tag:** VP_MMU_SV32_F000_S011_I000
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 012_Global mapping
#### Item: 000
* **Requirement location:** ISA Volume II: Privilege Architecture Version 20211203, Chapter 5.3.1
* **Feature Description**
For two different processes having same Virtual address and different satp.ASID, maps to same Physical address, and the pte.G is set; then one process will go through the address translation and update the TLB while the 2nd process will not go through the translation if pte.G is set and Physical address exist in TLB.
* **Verification Goals**
Show that two different processes having same VA to PA mapping can access the translated PA from TLB (if exist) and not go through complete translation.
* **Pass/Fail Criteria:** Check RM
* **Test Type:** RISC-V Arch-test
* **Coverage Method:** Testcase
* **Applicable Cores:** CV32A6_v0.1.0
* **Unique verification tag:** VP_MMU_SV32_F000_S012_I000
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 013_Access bit implementation
#### Item: 000
* **Requirement location:** ISA Volume II: Privilege Architecture Version 20211203, Chapter 5.3.1, 5.3.2
* **Feature Description**
If implementation does not sets the pte.A on accessing the PTE, and PTE has pte.A=0, then accessing it would raise page fault exception of the corresponding access type.
When satp.mode=sv32, PTE has (r,w,x) PMP permissions, and pte.v=1, then test the following in supervisor and user privilege mode for level0 and level1 PTE. Execute sfence.vma before accessign the PTE.
- Set pte.r=1 & pte.a=0 and test the read acces.
- Set pte.w=1 & pte.a=0 and test the write access.
- Set pte.x=1 & pte.a=0 and test the execute access.
* For testing at level0, set all the pte perimssions at level1 to 0 except pte.v, so that level1 points to level0.
* Set pte.U=0 when test in Supervisor mode and Set pte.U=1 when testing in user mode.
* **Verification Goals**
Page fault exception should be raised according to {x,r,w} access type. Check that:
- m/scause must contain the exception number of:
- instruction page fault for execute access.
- load page fault for read access.
- store/AMO page fault for write access.
- m/sepc must contain the virtual address of the instruction at which the trap occurs.
* **Pass/Fail Criteria:** Check RM
* **Test Type:** RISC-V Arch-test
* **Coverage Method:** Testcase
* **Applicable Cores:** CV32A6_v0.1.0
* **Unique verification tag:** VP_MMU_SV32_F000_S013_I000
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 014_Dirty bit Implementation
#### Item: 000
* **Requirement location:** ISA Volume II: Privilege Architecture Version 20211203, Chapter 5.3.1, 5.3.2
* **Feature Description**
If implementation does not sets the pte.D when PTE is written, and PTE has pte.D=0, then attempting to store on that PTE would raise Store/AMO page fault exception.
When satp.mode=sv32, PTE has (r,w,x) PMP permissions, pte.a=1 and pte.v=1, then test the following in supervisor and user privilege mode for level0 and level1 PTE. Execute sfence.vma before accessign the PTE.
- Set pte.w=1 & pte.d=0 and test the write access.
* For testing at level0, set all the pte perimssions at level1 to 0 except pte.v, so that level1 points to level0.
* Set pte.U=0 when test in Supervisor mode and Set pte.U=1 when testing in user mode.
* **Verification Goals**
Store/AMO page fault exception should be raised. Check that:
- m/scause must contain the exception number of store/AMO page fault for write access.
- m/sepc must contain the virtual address of the instruction at which the trap occurs.
* **Pass/Fail Criteria:** Check RM
* **Test Type:** RISC-V Arch-test
* **Coverage Method:** Testcase
* **Applicable Cores:** CV32A6_v0.1.0
* **Unique verification tag:** VP_MMU_SV32_F000_S014_I000
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 015_Misaligned Superpage
#### Item: 000
* **Requirement location:** ISA Volume II: Privilege Architecture Version 20211203, Chapter 5.3.1, 5.3.2
* **Feature Description**
If PTE at level1 is leaf PTE (superpage) and its pte.ppn[0]=0, then it is a misaligned superpage and accessing that PTE would raise page fault exception of the corresponding access type.
When satp.mode=sv32, PTE has (r,w,x) PMP permissions, PTE has non-reserved RWX encodings, (pte.r | pte.x)=1, and pte.v=1, then test the following in supervisor and user privilege mode for level1 PTE.
-set pte.ppn[0]=0 and test for read, write and execute access.
* Set pte.U=0 when test in Supervisor mode and Set pte.U=1 when testing in user mode.
* **Verification Goals**
Page fault exception should be raised according to {x,r,w} access type. Check that:
- m/scause must contain the exception number of:
- instruction page fault for execute access.
- load page fault for read access.
- store/AMO page fault for write access.
- m/sepc must contain the virtual address of the instruction at which the trap occurs.
* **Pass/Fail Criteria:** Check RM
* **Test Type:** RISC-V Arch-test
* **Coverage Method:** Testcase
* **Applicable Cores:** CV32A6_v0.1.0
* **Unique verification tag:** VP_MMU_SV32_F000_S015_I000
* **Link to Coverage:**
* **Comments**
*(none)*
## Feature: mstatus.TVM
### Sub-feature: 000_Accessing satp and sfence.vma CSRs
#### Item: 000
* **Requirement location:** ISA Volume II: Privilege Architecture Version 20211203, Chapter 3.1.6.5
* **Feature Description**
If mstatus.TVM=1, read and write access to the satp and sfence.vma will raise illegal instruction exception in S-mode.
* **Verification Goals**
Show that:
- s/mcause contains the exception number of illegal instruction exception.
- m/sepc must contain the virtual address of the instruction at which the trap occurs.
* **Pass/Fail Criteria:** Check RM
* **Test Type:** RISC-V Arch-test
* **Coverage Method:** Testcase
* **Applicable Cores:** CV32A6_v0.1.0
* **Unique verification tag:** VP_MMU_SV32_F001_S000_I000
* **Link to Coverage:**
* **Comments**
*(none)*
## Feature: satp
### Sub-feature: 000_access permission
#### Item: 000
* **Requirement location:** ISA Volume II: Privilege Architecture Version 20211203, Chapter 5.1.11
* **Feature Description**
Access satp in M, S, and U mode using csrrw, csrrc, csrrs
* **Verification Goals**
Show that satp is only accessible in M and S mode and illegal instruction exception is generated when accessed in lower privilege mode
* **Pass/Fail Criteria:** Check RM
* **Test Type:** RISC-V Arch-test
* **Coverage Method:** Testcase
* **Applicable Cores:** CV32A6_v0.1.0
* **Unique verification tag:** VP_MMU_SV32_F002_S000_I000
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 001_MODE field
#### Item: 000
* **Requirement location:** ISA Volume II: Privilege Architecture Version 20211203, Chapter 5.1.11
* **Feature Description**
Allows to select different schemes of address translation. Writes to satp are ignored when unsupported mode is selected.
* **Verification Goals**
Show that supported address translation scheme i.e sv32 is selected by writing satp.mode=sv32 and reading back the satp
* **Pass/Fail Criteria:** Check RM
* **Test Type:** RISC-V Arch-test
* **Coverage Method:** Testcase
* **Applicable Cores:** CV32A6_v0.1.0
* **Unique verification tag:** VP_MMU_SV32_F002_S001_I000
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 002_MODE=Bare
#### Item: 000
* **Requirement location:** ISA Volume II: Privilege Architecture Version 20211203, Chapter 5.1.11
* **Feature Description**
Selecting MODE=Bare the remaining feild should be zero. Other encoding for remaining feild in satp is reserved
* **Verification Goals**
Show wirting {zero, non-zero} value to satp when mode=bare the behaviour follows the design implemention
* **Pass/Fail Criteria:** Check RM
* **Test Type:** RISC-V Arch-test
* **Coverage Method:** Testcase
* **Applicable Cores:** CV32A6_v0.1.0
* **Unique verification tag:** VP_MMU_SV32_F002_S002_I000
* **Link to Coverage:**
* **Comments**
*(none)*
### Sub-feature: 003_ASIDLEN
#### Item: 000
* **Requirement location:** ISA Volume II: Privilege Architecture Version 20211203, Chapter 5.1.11
* **Feature Description**
ASIDLEN is the number of ASID bits implemented. MAXASID bits for sv32 is 9
* **Verification Goals**
Determine by writing one to every bit position in the ASID field, then reading back the value in satp to see which bit positions in the ASID field hold a one. Show that ASIDLEN is equal to the expected ASIDLEN
* **Pass/Fail Criteria:** Check RM
* **Test Type:** RISC-V Arch-test
* **Coverage Method:** Testcase
* **Applicable Cores:** CV32A6_v0.1.0
* **Unique verification tag:** VP_MMU_SV32_F002_S003_I000
* **Link to Coverage:**
* **Comments**
*(none)*

View file

@ -0,0 +1,192 @@
**ISACOV MISSING COVERAGE**
===============================
The table blow resume whats missing in ISACOV agent fucntionnal coverage :
+----------------------+------------------------------------+----------------------------------------+
| **Cover group - | **Missing bins/cover point** | **Why ?** |
| Instance** | | |
+======================+====================================+========================================+
| cg_executed_type | - rv32c_ebreak_cg.cp_executed | - RVFI limitation\* |
| | | |
| - rv32c_ebreak_cg | - rv32i_dret_cg.cp_executed | |
| | | |
| - rv32i_dret_cg | - rv32i_ebreak_cg.cp_executed | |
| | | |
| - rv32i_ebreak_cg | - rv32i_ecall_cg.cp_executed | |
| | | |
| - rv32i_ecall_cg | - rv32i_wfi_cg.cp_executed | |
| | | |
| - rv32i_wfi_cg | | |
+----------------------+------------------------------------+----------------------------------------+
| cg_sequential | - cp_instr, cp_instr_prev_x2 | - RVFI limitation\* |
| | | |
| | - cp_group, cp_group_pipe_x2 | - RVFI limitation\* |
| | | |
| | - cp_csr | - RVFI limitation\* |
| | | |
| | - cross_seq_instr_x2 | - RVFI limitation\* |
| | | |
| | - cross_seq_group_x2 | - RVFI limitation\* |
| | | |
| | - cross_seq_gpr_raw_hazard | - RVFI limitation\* |
| | | |
| | - cross_seq_csr_hazard_x2 | - RVFI limitation\* |
| | | |
+----------------------+------------------------------------+----------------------------------------+
| cg_csritype | - \*.cp_csr | - Need CSR tests*\* |
| | | |
| - | | |
| rv32zicsr_csrrwi_cg | | |
| | | |
| - | | |
| rv32zicsr_csrrsi_cg | | |
| | | |
| - | | |
| rv32zicsr_csrrci_cg | | |
+----------------------+------------------------------------+----------------------------------------+
| cg_cr_j | - rv32c_jalr_cg.cp_rs1_value | - boot_addr != 0x0 |
| | | |
| - rv32c_jalr_cg | - rv32c_jr_cg.cp_rs1_value | - boot_addr != 0x0 |
| | | |
| - rv32c_jr_cg | - rv32c_jalr_cg.cp_rs1_toggle | - Tests needed**\* |
| | | |
| | - rv32c_jr_cg.cp_rs1_toggle | - Tests needed**\* |
| | | |
+----------------------+------------------------------------+----------------------------------------+
| cg_csritype | - \*.cp_csr | - Need CSR tests*\* |
| | | |
| - | | |
| rv32zicsr_csrrw_cg | | |
| | | |
| - | | |
| rv32zicsr_csrrs_cg | | |
| | | |
| - | | |
| rv32zicsr_csrrc_cg | | |
+----------------------+------------------------------------+----------------------------------------+
| cg_cb_shift | - \*.cp_rs1 | - UVM_BUG #1425 |
| | | |
| - rv32c_srli_cg | | |
| | | |
| - rv32c_srai_cg | | |
+----------------------+------------------------------------+----------------------------------------+
| cg_cj | - \*.cp_imm_value | - imm = 0x0 (infinite loop) |
| | | |
| - rv32c_j_cg | | |
| | | |
| - rv32c_jal_cg | | |
+----------------------+------------------------------------+----------------------------------------+
| cg_itype_load | - rv32i_lbu_cg.cp_rd_toggle | - LBU,LHU limitation |
| | | |
| - rv32i_lbu_cg | - rv32i_lhu_cg.cp_rd_toggle | |
| | | |
| - rv32i_lhu_cg | | |
+----------------------+------------------------------------+----------------------------------------+
| cg_jtype | - cp_immj_value | - immj = 0x0 (infinite loop) |
| | | |
| - rv32i_jal_cg | - cp_rd_toggle | - Tests needed***\* |
+----------------------+------------------------------------+----------------------------------------+
| cg_cb_andi | - cp_rs1 | - UVM_BUG #1425 |
| | | |
| - rv32c_andi_cg | | |
+----------------------+------------------------------------+----------------------------------------+
| cg_cr | - cp_rs1_toggle | - c.mv should not have rs1 (UVM_BUG) |
| | | |
| - rv32c_mv_cg | | |
+----------------------+------------------------------------+----------------------------------------+
| cg_utype | - rv32i_lui_cg.cp_immu_value | - Test needed**\* |
| | | |
| - rv32i_auipc_cg | | |
+----------------------+------------------------------------+----------------------------------------+
| cg_rtype_slt | - \*.cross_rd_rs1_rs2 | - Test needed***\* |
| | | |
| - rv32i_sltu_cg | | |
| | | |
| - rv32i_slt_cg | | |
+----------------------+------------------------------------+----------------------------------------+
| cg_rtype_shift | - \*.cross_rd_rs1_rs2 | - Test needed***\* |
| | | |
| - rv32i_sra_cg | | |
| | | |
| - rv32i_srl_cg | | |
| | | |
| - rv32i_sll_cg | | |
+----------------------+------------------------------------+----------------------------------------+
| cg_rtype | - \*.cross_rd_rs1_rs2 | - Test needed***\* |
| | | |
| - rv32i_add_cg | | |
| | | |
| - rv32i_sub_cg | | |
| | | |
| - rv32i_xor_cg | | |
| | | |
| - rv32i_and_cg | | |
| | | |
| - rv32i_or_cg | | |
| | | |
| - rv32m_mul_cg | | |
| | | |
| - rv32m_mulh_cg | | |
| | | |
| - rv32m_mulhu_cg | | |
| | | |
| - rv32m_mulhsu_cg | | |
| | | |
| - rv32m_rem_cg | | |
| | | |
| - rv32m_remu_cg | | |
| | | |
| - rv32m_div_cg | | |
| | | |
| - rv32m_divu_cg | | |
+----------------------+------------------------------------+----------------------------------------+
| cg_itype | - rv32i_jalr_cg.cp_rs1 | - Test needed**\* |
| | | |
| - rv32i_jalr_cg | - rv32i_jalr_cg.cp_rd | - rd = 0x0 its a c.jalr (UVM_BUG) |
| | | |
| - rv32i_andi_cg | - rv32i_jalr_cg.cp_rd_rs1_hazard | - imm = 0x0 for jalr infinite loop |
| | | |
| - rv32i_ori_cg | - rv32i_jalr_cg.cp_rs1_value | - infinite loop |
| | | |
| - rv32i_xori_cg | - rv32i_jalr_cg.cp_rd_value | |
| | | |
| | - rv32i_jalr_cg.cp_rd_toggle | |
+----------------------+------------------------------------+----------------------------------------+
| cg_btype | - \*.cross_rs1_rs2 | - Test needed***\* |
| | | |
| - rv32i_bge_cg | | |
| | | |
| - rv32i_bltu_cg | | |
| | | |
| - rv32i_beq_cg | | |
| | | |
| - rv32i_bne_cg | | |
| | | |
| - rv32i_blt_cg | | |
| | | |
| - rv32i_bgeu_cg | | |
+----------------------+------------------------------------+----------------------------------------+
| cg_itype_slt | - cross_rs1_immi_value | - Test needed**\* |
| | | |
| - rv32i_slti_cg | | |
+----------------------+------------------------------------+----------------------------------------+
| cg_itype_shift | - rv32i_slli_cg.cp_rd_rs1_hazard | - Test needed**\* |
| | | |
| - rv32i_slli_cg | - rv32i_srli_cg.cp_rd_rs1_hazard | |
| | | |
| - rv32i_srli_cg | - rv32i_slli_cg.cross_rd_rs1 | |
| | | |
| - rv32i_srai_cg | - rv32i_srli_cg. cross_rd_rs1 | |
+----------------------+------------------------------------+----------------------------------------+
**Conventions and Terminology :**
*RVFI limitation\** : the RVFI in the CVA6 get it's information from the commit stage, that means the ISACOV agent can get only information of valid instruction (committed instruction), so any instruction raising an exception or cant be cover.
*Need CSR tests*\** : we can get what has been done in CSR verification task.
*Test needed*\*** : the test is feasible.
*Test needed*\**** : the test isnt feasible, because its going to take a
lot of time to write (a lot of combination to cover).

View file

@ -17,8 +17,6 @@
*/
class cvxif_custom_instr extends riscv_custom_instr;
rand riscv_reg_t rs1;
rand riscv_reg_t rs2;
rand riscv_reg_t rs3;
`uvm_object_utils(cvxif_custom_instr)
@ -29,6 +27,13 @@ class cvxif_custom_instr extends riscv_custom_instr;
return get_instr_name;
endfunction : get_instr_name
constraint cus_rx {
if (instr_name inside {CUS_EXC}) {
rs1 dist { [0:9] := 10, 10 := 2, [11:13] := 10, 14 := 2, 15 := 10, [16:23] := 2, [25:31] := 2 };
}
}
// Convert the instruction to assembly code
virtual function string convert2asm(string prefix = "");
string asm_str;
@ -38,12 +43,9 @@ class cvxif_custom_instr extends riscv_custom_instr;
CUS_ADD_MULTI: asm_str = $sformatf("%0s %0s, %0s, %0s", asm_str, rd.name(), rs1.name(), rs2.name());
CUS_ADD_RS3: asm_str = $sformatf("%0s %0s, %0s, %0s, %0s", asm_str, rd.name(), rs1.name(), rs2.name(), rs3.name());
CUS_NOP: asm_str = "cus_nop";
/* following instructions are not yet supported by cva6 */
//CUS_EXC: asm_str = $sformatf("%0s %0s, %0s, %0s", asm_str, rd.name(), rs1.name(), rs2.name());
//CUS_M_ADD: asm_str = $sformatf("%0s %0s, %0s, %0s", asm_str, rd.name(), rs1.name(), rs2.name());
//CUS_S_ADD: asm_str = $sformatf("%0s %0s, %0s, %0s", asm_str, rd.name(), rs1.name(), rs2.name());
//CUS_NOP_EXC: asm_str = "cus_nop_exc";
//CUS_ISS_EXC: asm_str = $sformatf("%0s %0s, %0s, %0s", asm_str, rd.name(), rs1.name(), rs2.name());
CUS_S_ADD: asm_str = $sformatf("%0s %0s, %0s, %0s", asm_str, rd.name(), rs1.name(), rs2.name());
CUS_U_ADD: asm_str = $sformatf("%0s %0s, %0s, %0s", asm_str, rd.name(), rs1.name(), rs2.name());
CUS_EXC: asm_str = $sformatf("%0s %0s", asm_str, rs1.name());
endcase
comment = {get_instr_name(), " ", comment};
if (comment != "") begin
@ -53,21 +55,21 @@ class cvxif_custom_instr extends riscv_custom_instr;
endfunction : convert2asm
virtual function void set_imm_len();
imm_len = 7;
imm_len = 6;
endfunction : set_imm_len
function bit [6:0] get_opcode();
case (instr_name) inside
{CUS_ADD, CUS_ADD_MULTI, CUS_ADD_RS3, CUS_NOP} : get_opcode = 7'b1111011;
// {CUS_ADD, CUS_ADD_MULTI, CUS_ADD_RS3, CUS_NOP, CUS_EXC, , CUS_NOP_EXC, CUS_ISS_EXC, CUS_M_ADD, CUS_S_ADD} : get_opcode = 7'b1111011;
{CUS_ADD, CUS_ADD_MULTI, CUS_ADD_RS3, CUS_NOP, CUS_U_ADD, CUS_S_ADD, CUS_EXC} : get_opcode = 7'b1111011;
default : `uvm_fatal(`gfn, $sformatf("Unsupported instruction %0s", instr_name.name()))
endcase
endfunction
virtual function bit [2:0] get_func3();
case (instr_name) inside
{CUS_ADD, CUS_ADD_MULTI, CUS_ADD_RS3, CUS_NOP} : get_func3 = 3'b000;
// {CUS_ADD, CUS_ADD_MULTI, CUS_ADD_RS3, CUS_NOP, CUS_EXC, CUS_NOP_EXC, CUS_ISS_EXC, CUS_M_ADD, CUS_S_ADD} : get_func3 = 3'b000;
CUS_ADD_MULTI, CUS_ADD_RS3, CUS_U_ADD, CUS_S_ADD : get_func3 = 3'b000;
CUS_ADD : get_func3 = 3'b001;
CUS_EXC : get_func3 = 3'b010;
endcase
endfunction
@ -76,46 +78,42 @@ class cvxif_custom_instr extends riscv_custom_instr;
CUS_ADD : get_func7 = 7'b0000000;
CUS_NOP : get_func7 = 7'b0000000;
CUS_ADD_MULTI : get_func7 = 7'b0001000;
// CUS_EXC : get_func7 = 7'b1000000;
// CUS_M_ADD : get_func7 = 7'b0000010;
// CUS_S_ADD : get_func7 = 7'b0000110;
// CUS_NOP_EXC : get_func7 = 7'b0100000;
// CUS_ISS_EXC : get_func7 = 7'b1100000;
CUS_U_ADD : get_func7 = 7'b0000010;
CUS_S_ADD : get_func7 = 7'b0000110;
CUS_EXC : get_func7 = 7'b1100000;
endcase
endfunction
virtual function bit [6:0] get_func2();
virtual function bit [1:0] get_func2();
case (instr_name)
CUS_ADD_RS3 : get_func2 = 2'b01;
endcase
endfunction
virtual function void set_rand_mode();
/*case (instr_name) inside
"CUS_EXC", "CUS_ISS_EXC": begin
has_rd= 1'b0;
has_rs2= 1'b0;
case (instr_name) inside
"CUS_NOP": begin
has_rd = 1'b0;
has_rs1 = 1'b0;
has_rs2 = 1'b0;
has_imm = 1'b0;
end
endcase*/
"CUS_EXC": begin
has_rd = 1'b0;
has_rs1 = 1'b1;
has_rs2 = 1'b0;
has_imm = 1'b0;
end
endcase
endfunction
function void pre_randomize();
rd.rand_mode(has_rd);
rs1.rand_mode(has_rs1);
rs2.rand_mode(has_rs2);
imm.rand_mode(has_imm);
endfunction
constraint rd_c {
// if (instr_name inside {CUS_ADD_MULTI, CUS_ADD, CUS_ADD_RS3, CUS_M_ADD, CUS_S_ADD}) {
if (instr_name inside {CUS_ADD_MULTI, CUS_ADD, CUS_ADD_RS3}) {
rd!=0;
}
/* if (instr_name inside { CUS_EXC, CUS_ISS_EXC} ) {
rd == 0;
rs1 inside {[4:7], 13, 15};
rs2 == 0;
}*/
}
endclass
`endif // __CVXIF_CUSTOM_INSTR_SV__

View file

@ -15,8 +15,6 @@ CUS_ADD,
CUS_ADD_MULTI,
CUS_NOP,
CUS_ADD_RS3,
// CUS_EXC,
// CUS_M_ADD,
// CUS_S_ADD,
// CUS_NOP_EXC,
// CUS_ISS_EXC,
CUS_EXC,
CUS_U_ADD,
CUS_S_ADD,

View file

@ -13,8 +13,6 @@
`DEFINE_CVXIF_CUSTOM_INSTR(CUS_ADD_MULTI, R_FORMAT, ARITHMETIC, RV32X)
`DEFINE_CVXIF_CUSTOM_INSTR(CUS_NOP, R_FORMAT, ARITHMETIC, RV32X)
`DEFINE_CVXIF_CUSTOM_INSTR(CUS_ADD_RS3, R4_FORMAT, ARITHMETIC, RV32X)
// `DEFINE_CVXIF_CUSTOM_INSTR(CUS_EXC, R_FORMAT, ARITHMETIC, RV32X)
// `DEFINE_CVXIF_CUSTOM_INSTR(CUS_M_ADD, R_FORMAT, ARITHMETIC, RV32X)
// `DEFINE_CVXIF_CUSTOM_INSTR(CUS_S_ADD, R_FORMAT, ARITHMETIC, RV32X)
// `DEFINE_CVXIF_CUSTOM_INSTR(CUS_NOP_EXC, R_FORMAT, ARITHMETIC, RV32X)
// `DEFINE_CVXIF_CUSTOM_INSTR(CUS_ISS_EXC, R_FORMAT, ARITHMETIC, RV32X)
`DEFINE_CVXIF_CUSTOM_INSTR(CUS_EXC, R_FORMAT, ARITHMETIC, RV32X)
`DEFINE_CVXIF_CUSTOM_INSTR(CUS_U_ADD, R_FORMAT, ARITHMETIC, RV32X)
`DEFINE_CVXIF_CUSTOM_INSTR(CUS_S_ADD, R_FORMAT, ARITHMETIC, RV32X)

View file

@ -15,6 +15,6 @@
+incdir+${CVA6_DV_ROOT}/user_extension
// SOURCES
${CVA6_DV_ROOT}/cva6_instr_pkg.sv
${CVA6_DV_ROOT}/cva6_signature_pkg.sv
${CVA6_DV_ROOT}/cva6_instr_test_pkg.sv

View file

@ -60,6 +60,375 @@ class cva6_asm_program_gen_c extends riscv_asm_program_gen;
end
endfunction
// Generate the interrupt and trap handler for different privileged mode.
// The trap handler checks the xCAUSE to determine the type of the exception and jumps to
// corresponding exeception handling routine.
virtual function void gen_trap_handler_section(int hart,
string mode,
privileged_reg_t cause, privileged_reg_t tvec,
privileged_reg_t tval, privileged_reg_t epc,
privileged_reg_t scratch, privileged_reg_t status,
privileged_reg_t ie, privileged_reg_t ip);
bit is_interrupt = 'b1;
string tvec_name;
string instr[$];
if (cfg.mtvec_mode == VECTORED) begin
gen_interrupt_vector_table(hart, mode, status, cause, ie, ip, scratch, instr);
end else begin
// Push user mode GPR to kernel stack before executing exception handling, this is to avoid
// exception handling routine modify user program state unexpectedly
push_gpr_to_kernel_stack(status, scratch, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr);
// Checking xStatus can be optional if ISS (like spike) has different implementation of
// certain fields compared with the RTL processor.
if (cfg.check_xstatus) begin
instr = {instr, $sformatf("csrr x%0d, 0x%0x # %0s", cfg.gpr[0], status, status.name())};
end
instr = {instr,
// Use scratch CSR to save a GPR value
// Check if the exception is caused by an interrupt, if yes, jump to interrupt
// handler Interrupt is indicated by xCause[XLEN-1]
$sformatf("csrr x%0d, 0x%0x # %0s", cfg.gpr[0], cause, cause.name()),
$sformatf("srli x%0d, x%0d, %0d", cfg.gpr[0], cfg.gpr[0], XLEN-1),
$sformatf("bne x%0d, x0, %0s%0smode_intr_handler",
cfg.gpr[0], hart_prefix(hart), mode)};
end
// The trap handler will occupy one 4KB page, it will be allocated one entry in the page table
// with a specific privileged mode.
if (SATP_MODE != BARE) begin
instr_stream.push_back(".align 12");
end else begin
instr_stream.push_back($sformatf(".align %d", cfg.tvec_alignment));
end
tvec_name = tvec.name();
gen_section(get_label($sformatf("%0s_handler", tvec_name.tolower()), hart), instr);
// Exception handler
instr = {};
if (cfg.mtvec_mode == VECTORED) begin
push_gpr_to_kernel_stack(status, scratch, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr);
end
gen_signature_handshake(instr, CORE_STATUS, HANDLING_EXCEPTION);
instr = {instr,
// The trap is caused by an exception, read back xCAUSE, xEPC to see if these
// CSR values are set properly. The checking is done by comparing against the log
// generated by ISA simulator (spike).
$sformatf("csrr x%0d, 0x%0x # %0s", cfg.gpr[0], epc, epc.name()),
$sformatf("csrr x%0d, 0x%0x # %0s", cfg.gpr[0], cause, cause.name()),
// Breakpoint
$sformatf("li x%0d, 0x%0x # BREAKPOINT", cfg.gpr[1], BREAKPOINT),
$sformatf("beq x%0d, x%0d, %0sebreak_handler",
cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)),
// Check if it's an ECALL exception. Jump to ECALL exception handler
$sformatf("li x%0d, 0x%0x # ECALL_UMODE", cfg.gpr[1], ECALL_UMODE),
$sformatf("beq x%0d, x%0d, %0secall_handler",
cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)),
$sformatf("li x%0d, 0x%0x # ECALL_SMODE", cfg.gpr[1], ECALL_SMODE),
$sformatf("beq x%0d, x%0d, %0secall_handler",
cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)),
$sformatf("li x%0d, 0x%0x # ECALL_MMODE", cfg.gpr[1], ECALL_MMODE),
$sformatf("beq x%0d, x%0d, %0secall_handler",
cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)),
// Page table fault or access fault conditions
$sformatf("li x%0d, 0x%0x", cfg.gpr[1], INSTRUCTION_ACCESS_FAULT),
$sformatf("beq x%0d, x%0d, %0sinstr_fault_handler",
cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)),
$sformatf("li x%0d, 0x%0x", cfg.gpr[1], LOAD_ACCESS_FAULT),
$sformatf("beq x%0d, x%0d, %0sload_fault_handler",
cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)),
$sformatf("li x%0d, 0x%0x", cfg.gpr[1], STORE_AMO_ACCESS_FAULT),
$sformatf("beq x%0d, x%0d, %0sstore_fault_handler",
cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)),
$sformatf("li x%0d, 0x%0x", cfg.gpr[1], INSTRUCTION_PAGE_FAULT),
$sformatf("beq x%0d, x%0d, %0spt_instr_fault_handler",
cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)),
$sformatf("li x%0d, 0x%0x", cfg.gpr[1], LOAD_PAGE_FAULT),
$sformatf("beq x%0d, x%0d, %0spt_load_fault_handler",
cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)),
$sformatf("li x%0d, 0x%0x", cfg.gpr[1], STORE_AMO_PAGE_FAULT),
$sformatf("beq x%0d, x%0d, %0spt_store_fault_handler",
cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)),
// Illegal instruction exception
$sformatf("li x%0d, 0x%0x # ILLEGAL_INSTRUCTION", cfg.gpr[1], ILLEGAL_INSTRUCTION),
$sformatf("beq x%0d, x%0d, %0sillegal_instr_handler",
cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)),
// Instruction Address misaligned exception
$sformatf("li x%0d, 0x%0x # INSTR ADDR MISALIGNED", cfg.gpr[1], INSTRUCTION_ADDRESS_MISALIGNED),
$sformatf("beq x%0d, x%0d, %0sinstr_misaligned_handler",
cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)),
// Load Address misaligned exception
$sformatf("li x%0d, 0x%0x # LOAD ADDR MISALIGNED", cfg.gpr[1], LOAD_ADDRESS_MISALIGNED),
$sformatf("beq x%0d, x%0d, %0sload_misaligned_handler",
cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)),
// Store Address misaligned exception
$sformatf("li x%0d, 0x%0x # STORE ADDR MISALIGNED", cfg.gpr[1], STORE_AMO_ADDRESS_MISALIGNED),
$sformatf("beq x%0d, x%0d, %0sstore_misaligned_handler",
cfg.gpr[0], cfg.gpr[1], hart_prefix(hart)),
// Skip checking tval for illegal instruction as it's implementation specific
$sformatf("csrr x%0d, 0x%0x # %0s", cfg.gpr[1], tval, tval.name()),
"1: jal x1, test_done "
};
gen_section(get_label($sformatf("%0smode_exception_handler", mode), hart), instr);
endfunction
// Trap handling routine
virtual function void gen_all_trap_handler(int hart);
string instr[$];
// If PMP isn't supported, generate the relevant trap handler sections as per usual
if (!support_pmp) begin
gen_trap_handlers(hart);
// Ecall handler
gen_ecall_handler(hart);
// Instruction fault handler
gen_instr_fault_handler(hart);
// Load fault handler
gen_load_fault_handler(hart);
// Store fault handler
gen_store_fault_handler(hart);
end
// Ebreak handler
gen_ebreak_handler(hart);
// Illegal instruction handler
gen_illegal_instr_handler(hart);
// Instruction page fault handler
gen_pt_instr_fault_handler(hart);
// Load page fault handler
gen_pt_load_fault_handler(hart);
// Store page fault handler
gen_pt_store_fault_handler(hart);
// Instruction Address Misaligned handler
gen_instr_misaligned_handler(hart);
// Load Address Misaligned handler
gen_load_misaligned_handler(hart);
// Store Address Misaligned handler
gen_store_misaligned_handler(hart);
// Generate page table fault handling routine
// Page table fault is always handled in machine mode, as virtual address translation may be
// broken when page fault happens.
gen_signature_handshake(instr, CORE_STATUS, HANDLING_EXCEPTION);
if(page_table_list != null) begin
page_table_list.gen_page_fault_handling_routine(instr);
end else begin
instr.push_back("nop");
end
gen_section(get_label("pt_fault_handler", hart), instr);
endfunction
// Helper function to generate the proper sequence of handshake instructions
// to signal the testbench (see riscv_signature_pkg.sv)
function void gen_signature_handshake(ref string instr[$],
input signature_type_t signature_type,
core_status_t core_status = INITIALIZED,
test_result_t test_result = TEST_FAIL,
privileged_reg_t csr = MSCRATCH,
string addr_label = "");
if (cfg.require_signature_addr) begin
string str[$];
str = {$sformatf("li x%0d, 0x%0h", cfg.gpr[1], cfg.signature_addr)};
instr = {instr, str};
case (signature_type)
// A single data word is written to the signature address.
// Bits [7:0] contain the signature_type of CORE_STATUS, and the upper
// XLEN-8 bits contain the core_status_t data.
CORE_STATUS: begin
str = {$sformatf("li x%0d, 0x%0h", cfg.gpr[0], core_status),
$sformatf("slli x%0d, x%0d, 8", cfg.gpr[0], cfg.gpr[0]),
$sformatf("addi x%0d, x%0d, 0x%0h", cfg.gpr[0],
cfg.gpr[0], signature_type),
$sformatf("sw x%0d, 0(x%0d)", cfg.gpr[0], cfg.gpr[1])};
instr = {instr, str};
end
// A single data word is written to the signature address.
// Bits [7:0] contain the signature_type of TEST_RESULT, and the upper
// XLEN-8 bits contain the test_result_t data.
TEST_RESULT: begin
str = {$sformatf("li x%0d, 0x%0h", cfg.gpr[0], test_result),
$sformatf("slli x%0d, x%0d, 8", cfg.gpr[0], cfg.gpr[0]),
$sformatf("addi x%0d, x%0d, 0x%0h", cfg.gpr[0],
cfg.gpr[0], signature_type),
$sformatf("sw x%0d, 0(x%0d)", cfg.gpr[0], cfg.gpr[1])};
instr = {instr, str};
end
// The first write to the signature address contains just the
// signature_type of WRITE_GPR.
// It is followed by 32 consecutive writes to the signature address,
// each writing the data contained in one GPR, starting from x0 as the
// first write, and ending with x31 as the 32nd write.
WRITE_GPR: begin
str = {$sformatf("li x%0d, 0x%0h", cfg.gpr[0], signature_type),
$sformatf("sw x%0d, 0(x%0d)", cfg.gpr[0], cfg.gpr[1])};
instr = {instr, str};
for(int i = 0; i < 32; i++) begin
str = {$sformatf("sw x%0x, 0(x%0d)", i, cfg.gpr[1])};
instr = {instr, str};
end
end
// The first write to the signature address contains the
// signature_type of WRITE_CSR in bits [7:0], and the CSR address in
// the upper XLEN-8 bits.
// It is followed by a second write to the signature address,
// containing the data stored in the specified CSR.
WRITE_CSR: begin
if (!(csr inside {implemented_csr})) begin
return;
end
str = {$sformatf("li x%0d, 0x%0h", cfg.gpr[0], csr),
$sformatf("slli x%0d, x%0d, 8", cfg.gpr[0], cfg.gpr[0]),
$sformatf("addi x%0d, x%0d, 0x%0h", cfg.gpr[0],
cfg.gpr[0], signature_type),
$sformatf("sw x%0d, 0(x%0d)", cfg.gpr[0], cfg.gpr[1]),
$sformatf("csrr x%0d, 0x%0h", cfg.gpr[0], csr),
$sformatf("sw x%0d, 0(x%0d)", cfg.gpr[0], cfg.gpr[1])};
instr = {instr, str};
end
default: begin
`uvm_fatal(`gfn, "signature_type is not defined")
end
endcase
end
endfunction
// ECALL trap handler
virtual function void gen_ecall_handler(int hart);
string instr[$];
gen_signature_handshake(instr, CORE_STATUS, ECALL_EXCEPTION);
gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(MCAUSE));
instr = {instr,
$sformatf("csrr x%0d, mepc", cfg.gpr[0]),
$sformatf("addi x%0d, x%0d, 4", cfg.gpr[0], cfg.gpr[0]),
$sformatf("csrw mepc, x%0d", cfg.gpr[0])
};
pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr);
instr.push_back("mret");
gen_section(get_label("ecall_handler", hart), instr);
endfunction
// TODO: handshake correct csr based on delegation
virtual function void gen_instr_fault_handler(int hart);
string instr[$];
gen_signature_handshake(instr, CORE_STATUS, INSTR_FAULT_EXCEPTION);
gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(MCAUSE));
instr = {instr,
$sformatf("csrr x%0d, mepc", cfg.gpr[0]),
$sformatf("addi x%0d, x%0d, 4", cfg.gpr[0], cfg.gpr[0]),
$sformatf("csrw mepc, x%0d", cfg.gpr[0])
};
pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr);
instr.push_back("mret");
gen_section(get_label("instr_fault_handler", hart), instr);
endfunction
// TODO: handshake correct csr based on delegation
virtual function void gen_load_fault_handler(int hart);
string instr[$];
gen_signature_handshake(instr, CORE_STATUS, LOAD_FAULT_EXCEPTION);
gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(MCAUSE));
instr = {instr,
$sformatf("csrr x%0d, mepc", cfg.gpr[0]),
$sformatf("addi x%0d, x%0d, 4", cfg.gpr[0], cfg.gpr[0]),
$sformatf("csrw mepc, x%0d", cfg.gpr[0])
};
pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr);
instr.push_back("mret");
gen_section(get_label("load_fault_handler", hart), instr);
endfunction
// TODO: handshake correct csr based on delegation
virtual function void gen_store_fault_handler(int hart);
string instr[$];
gen_signature_handshake(instr, CORE_STATUS, STORE_FAULT_EXCEPTION);
gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(MCAUSE));
instr = {instr,
$sformatf("csrr x%0d, mepc", cfg.gpr[0]),
$sformatf("addi x%0d, x%0d, 4", cfg.gpr[0], cfg.gpr[0]),
$sformatf("csrw mepc, x%0d", cfg.gpr[0])
};
pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr);
instr.push_back("mret");
gen_section(get_label("store_fault_handler", hart), instr);
endfunction
virtual function void gen_pt_instr_fault_handler(int hart);
string instr[$];
gen_signature_handshake(instr, CORE_STATUS, INSTR_PAGE_FAULT_EXCEPTION);
gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(MCAUSE));
instr = {instr,
$sformatf("csrr x%0d, mepc", cfg.gpr[0]),
$sformatf("addi x%0d, x%0d, 4", cfg.gpr[0], cfg.gpr[0]),
$sformatf("csrw mepc, x%0d", cfg.gpr[0])
};
pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr);
instr.push_back("mret");
gen_section(get_label("pt_instr_fault_handler", hart), instr);
endfunction
virtual function void gen_pt_load_fault_handler(int hart);
string instr[$];
gen_signature_handshake(instr, CORE_STATUS, LOAD_PAGE_FAULT_EXCEPTION);
gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(MCAUSE));
instr = {instr,
$sformatf("csrr x%0d, mepc", cfg.gpr[0]),
$sformatf("addi x%0d, x%0d, 4", cfg.gpr[0], cfg.gpr[0]),
$sformatf("csrw mepc, x%0d", cfg.gpr[0])
};
pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr);
instr.push_back("mret");
gen_section(get_label("pt_load_fault_handler", hart), instr);
endfunction
virtual function void gen_pt_store_fault_handler(int hart);
string instr[$];
gen_signature_handshake(instr, CORE_STATUS, STORE_PAGE_FAULT_EXCEPTION);
gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(MCAUSE));
instr = {instr,
$sformatf("csrr x%0d, mepc", cfg.gpr[0]),
$sformatf("addi x%0d, x%0d, 4", cfg.gpr[0], cfg.gpr[0]),
$sformatf("csrw mepc, x%0d", cfg.gpr[0])
};
pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr);
instr.push_back("mret");
gen_section(get_label("pt_store_fault_handler", hart), instr);
endfunction
virtual function void gen_load_misaligned_handler(int hart);
string instr[$];
gen_signature_handshake(instr, CORE_STATUS, LD_MISALIGNED_EXCEPTION);
gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(MCAUSE));
instr = {instr,
$sformatf("csrr x%0d, mepc", cfg.gpr[0]),
$sformatf("addi x%0d, x%0d, 4", cfg.gpr[0], cfg.gpr[0]),
$sformatf("csrw mepc, x%0d", cfg.gpr[0])
};
pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr);
instr.push_back("mret");
gen_section(get_label("load_misaligned_handler", hart), instr);
endfunction
virtual function void gen_store_misaligned_handler(int hart);
string instr[$];
gen_signature_handshake(instr, CORE_STATUS, ST_MISALIGNED_EXCEPTION);
gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(MCAUSE));
instr = {instr,
$sformatf("csrr x%0d, mepc", cfg.gpr[0]),
$sformatf("addi x%0d, x%0d, 4", cfg.gpr[0], cfg.gpr[0]),
$sformatf("csrw mepc, x%0d", cfg.gpr[0])
};
pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr);
instr.push_back("mret");
gen_section(get_label("store_misaligned_handler", hart), instr);
endfunction
virtual function void gen_instr_misaligned_handler(int hart);
string instr[$];
gen_signature_handshake(instr, CORE_STATUS, INSTR_MISALIGNED_EXCEPTION);
gen_signature_handshake(.instr(instr), .signature_type(WRITE_CSR), .csr(MCAUSE));
instr = {instr,
$sformatf("csrr x%0d, mepc", cfg.gpr[0]),
$sformatf("addi x%0d, x%0d, 4", cfg.gpr[0], cfg.gpr[0]),
$sformatf("csrw mepc, x%0d", cfg.gpr[0])
};
pop_gpr_from_kernel_stack(MSTATUS, MSCRATCH, cfg.mstatus_mprv, cfg.sp, cfg.tp, instr);
instr.push_back("mret");
gen_section(get_label("instr_misaligned_handler", hart), instr);
endfunction
virtual function void gen_test_done();
string str = format_string("test_done:", LABEL_STR_LEN);

View file

@ -26,15 +26,31 @@ class cva6_instr_gen_config_c extends riscv_instr_gen_config;
//-----------------------------------------------------------------------------
// cvxif extension support
bit enable_x_extension ;
bit enable_x_extension;
bit enable_rdrs1_hazard;
bit enable_rdrs2_hazard;
bit enable_same_reg;
constraint hazard_reg_c {
if (enable_same_reg) {
enable_rdrs1_hazard == 1'b0;
enable_rdrs2_hazard == 1'b0;
}
}
`uvm_object_utils_begin(cva6_instr_gen_config_c)
`uvm_field_int(enable_x_extension, UVM_DEFAULT)
`uvm_field_int(enable_rdrs1_hazard, UVM_DEFAULT)
`uvm_field_int(enable_rdrs2_hazard, UVM_DEFAULT)
`uvm_field_int(enable_same_reg, UVM_DEFAULT)
`uvm_object_utils_end
function new (string name = "");
super.new(name);
get_bool_arg_value("+enable_x_extension=", enable_x_extension);
get_bool_arg_value("+enable_rdrs1_hazard=", enable_rdrs1_hazard);
get_bool_arg_value("+enable_rdrs2_hazard=", enable_rdrs2_hazard);
get_bool_arg_value("+enable_same_reg=", enable_same_reg);
endfunction
endclass : cva6_instr_gen_config_c

View file

@ -0,0 +1,61 @@
/*
* Copyright 2018 Google LLC
* Copyright 2020 OpenHW Group
* Copyright 2023 Thales
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//------------------------------------------------------------------------------
// CORE-V instruction generator base test:
// - extension of the RISC-V instruction generator base test.
//
//------------------------------------------------------------------------------
class cva6_instr_hazard_test_c extends riscv_instr_base_test;
`uvm_component_utils(cva6_instr_hazard_test_c)
function new(string name="", uvm_component parent=null);
super.new(name, parent);
endfunction
virtual function void build_phase(uvm_phase phase);
override_asm_program_gen();
override_gen_config();
override_rand_stream();
super.build_phase(phase);
endfunction
virtual function void override_asm_program_gen();
`uvm_info("CVA6_DV", $sformatf("Overriding ..."), UVM_LOW)
uvm_factory::get().set_type_override_by_type(riscv_asm_program_gen::get_type(),
cva6_asm_program_gen_c::get_type());
`uvm_info("CVA6_DV", $sformatf("Overrid done "), UVM_LOW)
endfunction
virtual function void override_gen_config();
`uvm_info("CVA6_DV", $sformatf("Overriding ..."), UVM_LOW)
uvm_factory::get().set_type_override_by_type(riscv_instr_gen_config::get_type(),
cva6_instr_gen_config_c::get_type());
`uvm_info("CVA6_DV", $sformatf("Overrid done "), UVM_LOW)
endfunction
virtual function void override_rand_stream();
`uvm_info("CVA6_DV", $sformatf("Overriding ..."), UVM_LOW)
uvm_factory::get().set_type_override_by_type(riscv_rand_instr_stream::get_type(),
cva6_reg_hazard_stream_c::get_type());
`uvm_info("CVA6_DV", $sformatf("Overrid done "), UVM_LOW)
endfunction
endclass : cva6_instr_hazard_test_c

View file

@ -1,23 +0,0 @@
// Copyright 2022 Thales DIS design services SAS
// Copyright 2022 OpenHW Group
//
// Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
// You may obtain a copy of the License at https://solderpad.org/licenses/
//
// Original Author: Zineb EL KACIMI (zineb.el-kacimi@external.thalesgroup.com)
// ------------------------------------------------------------------------------ //
package cva6_instr_pkg;
import uvm_pkg::*;
`include "cva6_defines.svh"
import riscv_instr_pkg::*;
`include "cva6_instr_gen_config.sv"
`include "cva6_asm_program_gen.sv"
`include "cvxif_custom_instr.sv"
`include "rv32x_instr.sv"
`include "riscv_core_setting.sv"
endpackage

View file

@ -12,11 +12,17 @@
package cva6_instr_test_pkg;
import uvm_pkg::*;
`include "cva6_defines.svh"
import riscv_instr_pkg::*;
import riscv_instr_test_pkg::*;
import cva6_instr_pkg::*;
import cva6_signature_pkg::*;
`include "cva6_instr_gen_config.sv"
`include "cva6_reg_hazard_stream.sv"
`include "cva6_asm_program_gen.sv"
`include "cva6_instr_base_test.sv"
`include "cva6_instr_hazard_test.sv"
`include "cvxif_custom_instr.sv"
`include "rv32x_instr.sv"
endpackage : cva6_instr_test_pkg;

View file

@ -0,0 +1,62 @@
// class for hazard instruction stream (RAW)
// that means destination register of previous instruction is the same source register of the current instruction
class cva6_reg_hazard_stream_c extends riscv_rand_instr_stream;
`uvm_object_utils(cva6_reg_hazard_stream_c)
string label;
function new(string name = "");
super.new(name);
endfunction
virtual function void gen_instr(bit no_branch = 1'b0, bit no_load_store = 1'b1,
bit is_debug_program = 1'b0);
riscv_reg_t prev_reg;
cva6_instr_gen_config_c cfg_cva6;
`DV_CHECK_FATAL($cast(cfg_cva6, cfg), "Could not cast cfg into cfg_cva6")
setup_allowed_instr(no_branch, no_load_store);
foreach(instr_list[i]) begin
if (i == 0) begin
randomize_instr(instr_list[i], is_debug_program);
prev_reg = instr_list[i].rd;
end
else if (i >= 1) begin
randomize_instr(instr_list[i], is_debug_program);
if (!instr_list[i].is_compressed) begin
`DV_CHECK_RANDOMIZE_WITH_FATAL(instr_list[i],
if (has_rs1 && cfg_cva6.enable_rdrs1_hazard) {
instr_list[i].rs1 == prev_reg;
}
if (has_rs2 && cfg_cva6.enable_rdrs2_hazard) {
instr_list[i].rs2 == prev_reg;
}
if (cfg_cva6.enable_same_reg) {
instr_list[i].rd == instr_list[i].rs1;
instr_list[i].rs1 == instr_list[i].rs2;
})
prev_reg = instr_list[i].rd;
end
else begin
`DV_CHECK_RANDOMIZE_WITH_FATAL(instr_list[i],
if (instr_list[i-1].rd inside {[S0:A5]}) {
if (has_rs1 && cfg_cva6.enable_rdrs1_hazard) {
instr_list[i].rs1 == prev_reg;
}
if (has_rs2 && cfg_cva6.enable_rdrs2_hazard) {
instr_list[i].rs2 == prev_reg;
}})
prev_reg = instr_list[i].rd;
end
end
end
// Do not allow branch instruction as the last instruction because there's no
// forward branch target
while (instr_list[$].category == BRANCH) begin
void'(instr_list.pop_back());
if (instr_list.size() == 0) break;
end
endfunction
endclass

66
cva6/env/corev-dv/cva6_signature_pkg.sv vendored Normal file
View file

@ -0,0 +1,66 @@
/*
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cva6_signature_pkg;
// Will be the lowest 8 bits of the data word
typedef enum bit[7:0] {
// Information sent to the core relating its current status.
// Bits [12:8] of the data word will be the core_status_t value
// corresponding to the current core status.
CORE_STATUS,
// Information sent to the core conveying the uvm simulation result.
// Bit [8] of the data word will be the test_result_t value.
TEST_RESULT,
// Sent to the core to indicate a dump of GPRs to testbench.
// Will be followed by 32 writes of registers x0-x32.
WRITE_GPR,
// Sent to the core to indicate a write of a CSR's data.
// Bits [19:8] of the data word will be the CSR address.
// Will be followed by a second write of the actual data from the CSR.
WRITE_CSR
} signature_type_t;
typedef enum bit[4:0] {
INITIALIZED,
IN_DEBUG_MODE,
IN_MACHINE_MODE,
IN_HYPERVISOR_MODE,
IN_SUPERVISOR_MODE,
IN_USER_MODE,
HANDLING_IRQ,
FINISHED_IRQ,
HANDLING_EXCEPTION,
INSTR_FAULT_EXCEPTION,
ILLEGAL_INSTR_EXCEPTION,
LOAD_FAULT_EXCEPTION,
STORE_FAULT_EXCEPTION,
EBREAK_EXCEPTION,
ECALL_EXCEPTION,
INSTR_MISALIGNED_EXCEPTION,
LD_MISALIGNED_EXCEPTION,
ST_MISALIGNED_EXCEPTION,
INSTR_PAGE_FAULT_EXCEPTION,
LOAD_PAGE_FAULT_EXCEPTION,
STORE_PAGE_FAULT_EXCEPTION
} core_status_t;
typedef enum bit {
TEST_PASS,
TEST_FAIL
} test_result_t;
endpackage

View file

@ -0,0 +1,118 @@
/*
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//-----------------------------------------------------------------------------
// Processor feature configuration
//-----------------------------------------------------------------------------
// XLEN
parameter int XLEN = 32;
// Parameter for SATP mode, set to BARE if address translation is not supported
parameter satp_mode_t SATP_MODE = BARE;
// Supported Privileged mode
privileged_mode_t supported_privileged_mode[] = {MACHINE_MODE};
// Unsupported instructions
riscv_instr_name_t unsupported_instr[];
// ISA supported by the processor
riscv_instr_group_t supported_isa[$] = {RV32I, RV32M, RV32C, RV32A};
// Interrupt mode support
mtvec_mode_t supported_interrupt_mode[$] = {DIRECT, VECTORED};
// The number of interrupt vectors to be generated, only used if VECTORED interrupt mode is
// supported
int max_interrupt_vector_num = 16;
// Physical memory protection support
bit support_pmp = 0;
// Debug mode support
bit support_debug_mode = 0;
// Support delegate trap to user mode
bit support_umode_trap = 0;
// Support sfence.vma instruction
bit support_sfence = 0;
// Support unaligned load/store
bit support_unaligned_load_store = 1'b1;
// Parameter for vector extension
parameter int VECTOR_EXTENSION_ENABLE = 0;
parameter int VLEN = 512;
parameter int ELEN = 64;
parameter int SLEN = 64;
// Number of harts
parameter int NUM_HARTS = 1;
// ----------------------------------------------------------------------------
// Previleged CSR implementation
// ----------------------------------------------------------------------------
// Implemented previlieged CSR list
`ifdef DSIM
privileged_reg_t implemented_csr[] = {
`else
const privileged_reg_t implemented_csr[] = {
`endif
// Machine mode mode CSR
MVENDORID, // Vendor ID
MARCHID, // Architecture ID
MIMPID, // Implementation ID
MHARTID, // Hardware thread ID
MSTATUS, // Machine status
MISA, // ISA and extensions
MIE, // Machine interrupt-enable register
MTVEC, // Machine trap-handler base address
MCOUNTEREN, // Machine counter enable
MSCRATCH, // Scratch register for machine trap handlers
MEPC, // Machine exception program counter
MCAUSE, // Machine trap cause
MTVAL, // Machine bad address or instruction
MIP // Machine interrupt pending
};
// ----------------------------------------------------------------------------
// Supported interrupt/exception setting, used for functional coverage
// ----------------------------------------------------------------------------
`ifdef DSIM
interrupt_cause_t implemented_interrupt[] = {
`else
const interrupt_cause_t implemented_interrupt[] = {
`endif
M_SOFTWARE_INTR,
M_TIMER_INTR,
M_EXTERNAL_INTR
};
`ifdef DSIM
exception_cause_t implemented_exception[] = {
`else
const exception_cause_t implemented_exception[] = {
`endif
INSTRUCTION_ACCESS_FAULT,
ILLEGAL_INSTRUCTION,
BREAKPOINT,
LOAD_ADDRESS_MISALIGNED,
LOAD_ACCESS_FAULT,
ECALL_MMODE
};

View file

@ -99,8 +99,14 @@ interrupt_cause_t implemented_interrupt[] = {
`else
const interrupt_cause_t implemented_interrupt[] = {
`endif
U_SOFTWARE_INTR,
S_SOFTWARE_INTR,
M_SOFTWARE_INTR,
U_TIMER_INTR,
S_TIMER_INTR,
M_TIMER_INTR,
U_EXTERNAL_INTR,
S_EXTERNAL_INTR,
M_EXTERNAL_INTR
};
@ -109,10 +115,18 @@ exception_cause_t implemented_exception[] = {
`else
const exception_cause_t implemented_exception[] = {
`endif
INSTRUCTION_ADDRESS_MISALIGNED,
INSTRUCTION_ACCESS_FAULT,
ILLEGAL_INSTRUCTION,
BREAKPOINT,
LOAD_ADDRESS_MISALIGNED,
LOAD_ACCESS_FAULT,
ECALL_MMODE
STORE_AMO_ADDRESS_MISALIGNED,
STORE_AMO_ACCESS_FAULT,
ECALL_UMODE,
ECALL_SMODE,
ECALL_MMODE,
INSTRUCTION_PAGE_FAULT,
LOAD_PAGE_FAULT,
STORE_AMO_PAGE_FAULT
};

View file

@ -12,9 +12,9 @@
# Mappings of custom_* mnemonics to .insn pseudo-op of GAS
# CUS_ADD rd, rs1, rs2 -> .insn r CUSTOM_3, 0x0, 0x0, rd, rs1, rs2
# CUS_ADD rd, rs1, rs2 -> .insn r CUSTOM_3, 0x1, 0x0, rd, rs1, rs2
.macro cus_add rd, rs1, rs2
.insn r CUSTOM_3, 0x0, 0x0, \rd, \rs1, \rs2
.insn r CUSTOM_3, 0x1, 0x0, \rd, \rs1, \rs2
.endm
# CUS_NOP -> .insn r CUSTOM_3, 0x0, 0x0, x0, x0, x0
@ -22,24 +22,19 @@
.insn r CUSTOM_3, 0x0, 0x0, x0, x0, x0
.endm
# CUS_NOP_EXC -> .insn r CUSTOM_3, 0x0, 0x20, x0, x0, x0
.macro cus_nop_exc
.insn r CUSTOM_3, 0x0, 0x20, x0, x0, x0
.endm
# CUS_ADD_RS3 rd, rs1, rs2, rs3 -> .insn r CUSTOM_3, 0x0, 0x1, rd, rs1, rs2, rs3
.macro cus_add_rs3 rd, rs1, rs2, rs3
.insn r CUSTOM_3, 0x0, 0x1, \rd, \rs1, \rs2, \rs3
.endm
# CUS_M_ADD rd, rs1, rs2 -> .insn r CUSTOM_3, 0x0, 0x6, rd, rs1, rs2
.macro cus_m_add rd, rs1, rs2
.insn r CUSTOM_3, 0x0, 0x6, \rd, \rs1, \rs2
# CUS_U_ADD rd, rs1, rs2 -> .insn r CUSTOM_3, 0x0, 0x2, rd, rs1, rs2
.macro cus_u_add rd, rs1, rs2
.insn r CUSTOM_3, 0x0, 0x2, \rd, \rs1, \rs2
.endm
# CUS_S_ADD rd, rs1, rs2 -> .insn r CUSTOM_3, 0x0, 0x2, rd, rs1, rs2
# CUS_S_ADD rd, rs1, rs2 -> .insn r CUSTOM_3, 0x0, 0x6, rd, rs1, rs2
.macro cus_s_add rd, rs1, rs2
.insn r CUSTOM_3, 0x0, 0x2, \rd, \rs1, \rs2
.insn r CUSTOM_3, 0x0, 0x6, \rd, \rs1, \rs2
.endm
# CUS_ADD_MULTI rd, rs1, rs2 -> .insn r CUSTOM_3, 0x0, 0x8, rd, rs1, rs2
@ -47,22 +42,8 @@
.insn r CUSTOM_3, 0x0, 0x8, \rd, \rs1, \rs2
.endm
# CUS_EXC rd, rs1, rs2 -> .insn r CUSTOM_3, 0x0, 0x40, rd, rs1, rs2
.macro cus_exc rd, rs1, rs2
.insn r CUSTOM_3, 0x0, 0x40, \rd, \rs1, \rs2
# CUS_EXC rs1 -> .insn r CUSTOM_3, 0x2, 0x60, x0, rs1, x0
.macro cus_exc rs1
.insn r CUSTOM_3, 0x2, 0x60, x0, \rs1, x0
.endm
# CUS_ISS_EXC rd, rs1, rs2 -> .insn r CUSTOM_3, 0x0, 0x60, rd, rs1, rs2
.macro cus_iss_exc rd, rs1, rs2
.insn r CUSTOM_3, 0x0, 0x60, \rd, \rs1, \rs2
.endm
# CUS_LD rd, rs1, simm12 -> .insn i CUSTOM_3, 0x1, rd, rs1, simm12
.macro cus_ld rd, rs1, simm12
.insn i CUSTOM_3, 0x1, \rd, \rs1, \simm12
.endm
# CUS_SD rs2, simm12(rs1) -> .insn s CUSTOM_3, 0x2, rs2, simm12(rs1)
.macro cus_sd rs2, addr
.insn s CUSTOM_3, 0x2, \rs2, \addr
.endm

View file

@ -88,6 +88,7 @@ function void uvme_cva6_cov_model_c::build_phase(uvm_phase phase);
end
cvxif_covg = uvme_cvxif_covg_c::type_id::create("cvxif_covg", this);
uvm_config_db#(uvme_cva6_cfg_c)::set(this, "cvxif_covg", "cfg", cfg);
uvm_config_db#(uvme_cva6_cntxt_c)::set(this, "cvxif_covg", "cntxt", cntxt);
endfunction : build_phase

View file

@ -16,71 +16,278 @@
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
covergroup cg_executed(
string name,
bit seq_cus_instr_x2_enabled
) with function
sample(uvma_cvxif_req_item_c req_item,
uvma_cvxif_req_item_c prev_req_item);
option.per_instance = 1;
option.name = name;
cp_instr : coverpoint req_item.issue_req.instr {
wildcard bins CUS_ADD = {32'b0000000??????????001?????1111011};
wildcard bins CUS_ADD_RS3 = {32'b?????01??????????000?????1111011};
wildcard bins CUS_ADD_MULTI = {32'b0001000??????????000?????1111011};
wildcard bins CUS_U_ADD = {32'b0000010??????????000?????1111011};
wildcard bins CUS_S_ADD = {32'b0000110??????????000?????1111011};
wildcard bins CUS_NOP = {32'b00000000000000000000000001111011};
wildcard bins CUS_EXC = {32'b110000000000?????010000001111011};
}
cp_prev_instr : coverpoint prev_req_item.issue_req.instr iff (prev_req_item != null) {
ignore_bins IGN_X2_OFF = {[0:$]} iff (!seq_cus_instr_x2_enabled);
wildcard bins CUS_ADD = {32'b0000000??????????001?????1111011};
wildcard bins CUS_ADD_RS3 = {32'b?????01??????????000?????1111011};
wildcard bins CUS_ADD_MULTI = {32'b0001000??????????000?????1111011};
wildcard bins CUS_U_ADD = {32'b0000010??????????000?????1111011};
wildcard bins CUS_S_ADD = {32'b0000110??????????000?????1111011};
wildcard bins CUS_NOP = {32'b00000000000000000000000001111011};
wildcard bins CUS_EXC = {32'b110000000000?????010000001111011};
}
cross_seq_cus_instr_x2 : cross cp_instr, cp_prev_instr;
endgroup: cg_executed
covergroup cg_cus_add_instr(
string name,
bit reg_cus_crosses_enabled,
bit rs3_valid
) with function sample(uvma_cvxif_req_item_c req_item);
option.per_instance = 1;
option.name = name;
cp_rd : coverpoint req_item.issue_req.instr[11:7] {
bins RD[] = {[0:31]};
}
cp_rs1 : coverpoint req_item.issue_req.instr[19:15] {
bins RS1[] = {[0:31]};
}
cp_rs2 : coverpoint req_item.issue_req.instr[24:20] {
bins RS2[] = {[0:31]};
}
cp_rs3 : coverpoint req_item.issue_req.instr[31:27] {
ignore_bins IGN_RS3[] = {[0:31]} iff (!rs3_valid);
bins RS3[] = {[0:31]};
}
cross_rd_rs1 : cross cp_rd, cp_rs1 {
ignore_bins IGN_OFF = cross_rd_rs1 iff (!reg_cus_crosses_enabled);
}
cross_rd_rs2 : cross cp_rd, cp_rs2 {
ignore_bins IGN_OFF = cross_rd_rs2 iff (!reg_cus_crosses_enabled);
}
cross_rd_rs3 : cross cp_rd, cp_rs3 {
ignore_bins IGN_OFF = cross_rd_rs3 iff (!reg_cus_crosses_enabled || !rs3_valid);
}
`CVXIF_CP_BITWISE(cp_rs1_toggle, req_item.issue_req.rs[0], 1)
`CVXIF_CP_BITWISE(cp_rs2_toggle, req_item.issue_req.rs[1], 1)
`CVXIF_CP_BITWISE(cp_rs3_toggle, req_item.issue_req.rs[2], rs3_valid) //TODO : fix need more filtring
endgroup: cg_cus_add_instr
covergroup cg_cus_instr(
string name
) with function sample(uvma_cvxif_req_item_c req_item);
option.per_instance = 1;
option.name = name;
cp_rs1 : coverpoint req_item.issue_req.instr[19:15] {
bins RS1[] = {[0:31]};
}
endgroup: cg_cus_instr
class uvme_cvxif_covg_c extends uvm_component;
/*
* Class members
*/
uvma_cvxif_req_item_c req_item ;
// Objects
uvme_cva6_cfg_c cfg ;
uvme_cva6_cntxt_c cntxt ;
uvma_cvxif_req_item_c req_item;
uvma_cvxif_req_item_c prev_req_item;
// TLM
uvm_tlm_analysis_fifo#(uvma_cvxif_req_item_c ) req_item_fifo;
`uvm_component_utils_begin(uvme_cvxif_covg_c)
`uvm_field_object(cfg , UVM_DEFAULT)
`uvm_field_object(cntxt, UVM_DEFAULT)
`uvm_component_utils_end
`uvm_component_utils(uvme_cvxif_covg_c);
// Covergroups
//ADD INSTRUCTIONS
cg_cus_add_instr cus_add_cg;
cg_cus_add_instr cus_add_rs3_cg;
cg_cus_add_instr cus_add_multi_cg;
cg_cus_add_instr cus_add_u_cg;
cg_cus_add_instr cus_add_s_cg;
cg_cus_instr cus_exc_cg;
//Sequential instruction
cg_executed cus_seq_cg;
extern function new(string name = "cvxif_covg", uvm_component parent = null);
extern function void build_phase(uvm_phase phase);
extern task run_phase(uvm_phase phase);
extern task sample_cvxif_req_i(uvma_cvxif_req_item_c req_item);
/*
* Covergroups
*/
covergroup mode_cg(string name)
with function sample(uvma_cvxif_req_item_c req_item);
mode_cp: coverpoint (req_item.issue_req.mode)
{
bins u_mode = {2'b00};
bins s_mode = {2'b01};
bins r_mode = {2'b10};
bins m_mode = {2'b11};
}
endgroup : mode_cg
extern task sample_cvxif_req(uvma_cvxif_req_item_c req_item);
endclass : uvme_cvxif_covg_c
function uvme_cvxif_covg_c::new(string name = "cvxif_covg", uvm_component parent = null);
super.new(name, parent);
mode_cg = new("mode_cg");
super.new(name, parent);
endfunction : new
function void uvme_cvxif_covg_c::build_phase(uvm_phase phase);
super.build_phase(phase);
void'(uvm_config_db#(uvme_cva6_cfg_c)::get(this, "", "cfg", cfg));
if (!cfg) begin
`uvm_fatal("CFG", "Configuration handle is null")
end
void'(uvm_config_db#(uvme_cva6_cntxt_c)::get(this, "", "cntxt", cntxt));
if (!cntxt) begin
`uvm_fatal("CNTXT", "Context handle is null")
end
cus_add_cg = new("cus_add_cg",
.reg_cus_crosses_enabled(cfg.cvxif_cfg.reg_cus_crosses_enabled),
.rs3_valid(0));
cus_add_rs3_cg = new("cus_add_rs3_cg",
.reg_cus_crosses_enabled(cfg.cvxif_cfg.reg_cus_crosses_enabled),
.rs3_valid(1));
cus_add_multi_cg = new("cus_add_multi_cg",
.reg_cus_crosses_enabled(cfg.cvxif_cfg.reg_cus_crosses_enabled),
.rs3_valid(0));
cus_add_u_cg = new("cus_add_u_cg",
.reg_cus_crosses_enabled(cfg.cvxif_cfg.reg_cus_crosses_enabled),
.rs3_valid(0));
cus_add_s_cg = new("cus_add_s_cg",
.reg_cus_crosses_enabled(cfg.cvxif_cfg.reg_cus_crosses_enabled),
.rs3_valid(0));
cus_exc_cg = new("cus_exc_cg");
cus_seq_cg = new("cus_seq_cg",
.seq_cus_instr_x2_enabled(cfg.cvxif_cfg.seq_cus_instr_x2_enabled));
req_item_fifo = new("req_item_fifo" , this);
endfunction : build_phase
task uvme_cvxif_covg_c::run_phase(uvm_phase phase);
super.run_phase(phase);
`uvm_info("CVXIFCOVG", "The CVXIF coverage model is running", UVM_LOW);
forever begin
req_item_fifo.get(req_item);
sample_cvxif_req_i(req_item);
sample_cvxif_req(req_item);
end
endtask : run_phase
task uvme_cvxif_covg_c::sample_cvxif_req_i(uvma_cvxif_req_item_c req_item);
task uvme_cvxif_covg_c::sample_cvxif_req(uvma_cvxif_req_item_c req_item);
mode_cg.sample(req_item);
logic have_sample = 0;
bit [6:0] opcode = req_item.issue_req.instr [6:0];
bit [6:0] custom3 = 7'b1111011;
bit [6:0] func7 = req_item.issue_req.instr [31:25];
bit [1:0] func2 = req_item.issue_req.instr [26:25];
bit [2:0] func3 = req_item.issue_req.instr [14:12];
bit [4:0] rd = req_item.issue_req.instr [11:7];
bit [4:0] rs1 = req_item.issue_req.instr [19:15];
bit [4:0] rs2 = req_item.issue_req.instr [24:20];
endtask : sample_cvxif_req_i
if (opcode == custom3) begin
if (func3 == 3'b000) begin
if (func7 == 7'b0000000 && rd != 0) begin
cus_add_cg.sample(req_item);
cus_seq_cg.sample(req_item,
prev_req_item);
// Move instructions down the pipeline
prev_req_item = req_item;
have_sample = 1;
end
if (func7 == 7'b0001000) begin
cus_add_multi_cg.sample(req_item);
cus_seq_cg.sample(req_item,
prev_req_item);
// Move instructions down the pipeline
prev_req_item = req_item;
have_sample = 1;
end
if (func2 == 2'b01) begin
cus_add_rs3_cg.sample(req_item);
cus_seq_cg.sample(req_item,
prev_req_item);
// Move instructions down the pipeline
prev_req_item = req_item;
have_sample = 1;
end
if (func7 == 7'b0000010) begin
cus_add_u_cg.sample(req_item);
cus_seq_cg.sample(req_item,
prev_req_item);
// Move instructions down the pipeline
prev_req_item = req_item;
have_sample = 1;
end
if (func7 == 7'b0000110) begin
cus_add_s_cg.sample(req_item);
cus_seq_cg.sample(req_item,
prev_req_item);
// Move instructions down the pipeline
prev_req_item = req_item;
have_sample = 1;
end
if (func7 == 7'b0000000 && rd == 0 && rs1 == 0 && rs2 == 0) begin
cus_seq_cg.sample(req_item,
prev_req_item);
// Move instructions down the pipeline
prev_req_item = req_item;
have_sample = 1;
end
end
if (func3 == 3'b001) begin
if (func7 == 7'b0000000) begin
cus_add_cg.sample(req_item);
cus_seq_cg.sample(req_item,
prev_req_item);
// Move instructions down the pipeline
prev_req_item = req_item;
have_sample = 1;
end
end
if (func3 == 3'b010 && rd == 0 && rs2 == 0) begin
if (func7 == 7'b1100000) begin
cus_exc_cg.sample(req_item);
cus_seq_cg.sample(req_item,
prev_req_item);
// Move instructions down the pipeline
prev_req_item = req_item;
have_sample = 1;
end
end
end
if (!have_sample) `uvm_warning("CVXIF", $sformatf("Could not sample instruction: %b", req_item.issue_req.instr));
endtask : sample_cvxif_req

View file

@ -0,0 +1,100 @@
..
Copyright (c) 2023 OpenHW Group
Copyright (c) 2023 Thales DIS design services SAS
SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
..
Custom Instruction to challenge CV-X-IF protocol
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This section describes some custom instruction, for stress or challenge the CV-X-IF protocol for the 3 implemented interfaces, it's just to interact with the cvxif agent.
All instructions use opcode `CUSTOM_3`(0x7b, 0b111_1011).
- **CUS_ADD**: Custom Add
**Format**: cus_add rd, rs1, rs2 -> |0000000|rs2|rs1|001|rd|111_1011|
**Description**: add register rs1 to rs2, and store the result in rd (works for all privilege modes).
**Pseudocode**: x[rd] = x[rs1] + x[rs2]
**Invalid values**: NONE
**Exception raised**: Illegal instruction exception is raised if rs_valid != 2'b11 && rs_valid != 3'b111.
- **CUS_NOP**: Custom No Operation
**Format**: cus_nop -> |0000000000000000000000000|111_1011|
**Description**: do nothing, it's just a hint instruction.
**Pseudocode**: cus_nop
**Invalid values**: NONE
**Exception raised**: NONE
- **CUS_ADD_RS3**: Custom Add
**Format**: cus_add_rs3 rd, rs1, rs2, rs3 -> |rs3|01|rs2|rs1|000|rd|111_1011|
**Description**: add register rs1 to rs2 then the result to rs3, and store the result in register rd (works for all privilege modes).
**Pseudocode**: x[rd] = x[rs1] + x[rs2] + x[rs3]
**Invalid values**: NONE
**Exception raised**: Illegal instruction exception is raised if rs_valid != 3'b111.
- **CUS_S_ADD**: Custom Supervisor Add
**Format**: add rd, rs1, rs2 -> |0000110|rs2|rs1|000|rd|111_1011|
**Description**: add register rs1 to rs2, and store the result in register rd (works only in Supervisor mode).
**Pseudocode**: x[rd] = x[rs1] + x[rs2]
**Invalid values**: NONE
**Exception raised**: Illegal instruction exception is raised if the privilege mode isn't Supervisor mode, or rs_valid != 2'b11 && rs_valid != 3'b111.
- **CUS_U_ADD**: Custom User Add
**Format**: add rd, rs1, rs2 -> |0000010|rs2|rs1|000|rd|111_1011|
**Description**: add register rs1 to rs2, and store the result in register rd (works only in User mode).
**Pseudocode**: x[rd] = x[rs1] + x[rs2]
**Invalid values**: NONE
**Exception raised**: Illegal instruction exception is raised if the privilege mode isn't User mode, or rs_valid != 2'b11 && rs_valid != 3'b111.
- **CUS_ADD_MULTI**: Custom Multicycle Add
**Format**: addi rd, rs1, rs2 -> |0001000|rs2|rs1|000|rd|111_1011|
**Description**: add register rs1 to rs2, and store the result in rd (works for all privilege mode).
**Pseudocode**: x[rd] = x[rs1] + x[rs2]
**Invalid values**: NONE
**Exception raised**: Illegal instruction exception is raised if rs_valid != 2'b11 && rs_valid != 3'b111.
- **CUS_EXC**: Custom Exception
**Format**: cus_exc rs1 -> |1100000|00000|rs1|010|00000|111_1011|
**Description**: raise an exception.
**Pseudocode**: mcause[5:0] = rs1
**Invalid values**: NONE
**Exception raised**: raise an exception based on the rs1 register address.
When a CV-X-IF exception is raised, mcause[5:0] of the corresponding CORE-V hart is assumed set to exccode[5:0] of CV-X-IF.

View file

@ -53,32 +53,36 @@ function string uvme_cvxif_base_vseq_c::decode(input logic [31:0] instr);
bit [6:0] custom3 = 7'b1111011;
bit [6:0] func7 = instr [31:25];
bit [1:0] func2 = instr [26:25];
bit [1:0] func3 = instr [14:12];
bit [2:0] func3 = instr [14:12];
bit [4:0] rd = instr [11:7];
bit [4:0] rs1 = instr [19:15];
bit [4:0] rs2 = instr [24:20];
if (opcode == custom3) begin
if (func3 == 0) begin
if (func7 == 7'b0000000 && rd != 0) begin
return ("CUS_ADD");
end
if (func7 == 7'b0001000 && rd != 0) begin
if (func3 == 3'b000) begin
if (func7 == 7'b0001000) begin
return ("CUS_ADD_MULTI");
end
if (func2 == 2'b01 && rd != 0) begin
if (func2 == 2'b01) begin
return ("CUS_ADD_RS3");
end
if (func7 == 7'b0000010 && rd != 0) begin
return ("CUS_M_ADD");
if (func7 == 7'b0000010) begin
return ("CUS_U_ADD");
end
if (func7 == 7'b0000110 && rd != 0) begin
if (func7 == 7'b0000110) begin
return ("CUS_S_ADD");
end
if (func7 == 7'b0000000 && rd == 0 && rs1 == 0 && rs2 == 0) begin
return ("CUS_NOP");
end
if (func7 == 7'b1000000 && rd == 0 && rs2[4:1] == 0) begin
end
if (func3 == 3'b001) begin
if (func7 == 7'b0000000) begin
return ("CUS_ADD");
end
end
if (func3 == 3'b010 && rd == 0 && rs2 == 0) begin
if (func7 == 7'b1100000) begin
return ("CUS_EXC");
end
end

View file

@ -68,7 +68,7 @@ task uvme_cvxif_vseq_c::body();
instr = decode(req_item.issue_req.instr);
// generate response based on observed request, e.g:
if (instr == "ILLEGAL" || instr == "") begin
if (instr == "") begin
do_default();
end
else begin
@ -117,15 +117,10 @@ task uvme_cvxif_vseq_c::do_issue_resp();
resp_item.issue_resp.exc = 0;
case (instr) inside
"CUS_ADD", "CUS_ADD_MULTI" : begin
if (req_item.issue_req.rs_valid == 2'b11) begin
if (req_item.issue_req.rs_valid == 2'b11 || req_item.issue_req.rs_valid == 3'b111) begin
resp_item.issue_resp.writeback = 1;
resp_item.issue_resp.accept = 1;
end
else begin
resp_item.issue_resp.writeback = 0;
resp_item.issue_resp.accept = 1;
resp_item.issue_resp.exc = 1;
end
end
"CUS_ADD_RS3" : begin
if (req_item.issue_req.rs_valid == 3'b111) begin
@ -147,8 +142,8 @@ task uvme_cvxif_vseq_c::do_issue_resp();
resp_item.issue_resp.accept = 1;
resp_item.issue_resp.exc = 1;
end
"CUS_M_ADD" : begin
if (req_item.issue_req.mode == 2'b11) begin
"CUS_U_ADD" : begin
if (req_item.issue_req.mode == PRIV_LVL_U && req_item.issue_req.rs_valid == 2'b11 || req_item.issue_req.rs_valid == 3'b111) begin
resp_item.issue_resp.writeback = 1;
resp_item.issue_resp.accept = 1;
end
@ -159,7 +154,7 @@ task uvme_cvxif_vseq_c::do_issue_resp();
end
end
"CUS_S_ADD" : begin
if (req_item.issue_req.mode == 2'b01) begin
if (req_item.issue_req.mode == PRIV_LVL_S && req_item.issue_req.rs_valid == 2'b11 || req_item.issue_req.rs_valid == 3'b111) begin
resp_item.issue_resp.writeback = 1;
resp_item.issue_resp.accept = 1;
end
@ -169,6 +164,11 @@ task uvme_cvxif_vseq_c::do_issue_resp();
resp_item.issue_resp.exc = 1;
end
end
"ILLEGAL" : begin
resp_item.issue_resp.writeback = 0;
resp_item.issue_resp.accept = 1;
resp_item.issue_resp.exc = 1;
end
endcase
`uvm_info(info_tag, $sformatf("instr = %s", instr), UVM_LOW);
`uvm_info(info_tag, $sformatf("Response : accept = %h writeback = %h dualwrite = %h dualread = %h exc = %h",
@ -216,7 +216,7 @@ task uvme_cvxif_vseq_c::do_instr_result();
cfg.instr_delayed = 0;
case (instr)
"CUS_ADD": begin
if (req_item.issue_req.rs_valid == 2'b11)
if (req_item.issue_req.rs_valid == 2'b11 || req_item.issue_req.rs_valid == 3'b111)
resp_item.result.data = req_item.issue_req.rs[0] + req_item.issue_req.rs[1];
else begin
resp_item.result.exc = 1;
@ -225,7 +225,7 @@ task uvme_cvxif_vseq_c::do_instr_result();
end
end
"CUS_ADD_MULTI": begin
if (req_item.issue_req.rs_valid == 2'b11) begin
if (req_item.issue_req.rs_valid == 2'b11 || req_item.issue_req.rs_valid == 3'b111) begin
resp_item.result.data = req_item.issue_req.rs[0] + req_item.issue_req.rs[1];
cfg.instr_delayed = 1;
end
@ -238,7 +238,7 @@ task uvme_cvxif_vseq_c::do_instr_result();
"CUS_EXC": begin
resp_item.result.exc = 1;
resp_item.result.exccode[4:0] = req_item.issue_req.instr[19:15];
resp_item.result.exccode[5] = req_item.issue_req.instr[20];
resp_item.result.exccode[5] = 1'b0;
`uvm_info(info_tag, $sformatf("EXCCODE: %d", resp_item.result.exccode), UVM_LOW);
end
"CUS_ADD_RS3": begin
@ -250,8 +250,8 @@ task uvme_cvxif_vseq_c::do_instr_result();
`uvm_info(info_tag, $sformatf("Exception Illegal instruction -> EXCCODE: %d", resp_item.result.exccode), UVM_LOW);
end
end
"CUS_M_ADD": begin
if (req_item.issue_req.mode == 2'b11 && req_item.issue_req.rs_valid == 2'b11)
"CUS_U_ADD": begin
if (req_item.issue_req.mode == PRIV_LVL_U && req_item.issue_req.rs_valid == 2'b11 || req_item.issue_req.rs_valid == 3'b111)
resp_item.result.data = req_item.issue_req.rs[0] + req_item.issue_req.rs[1];
else begin
resp_item.result.exc = 1;
@ -260,7 +260,7 @@ task uvme_cvxif_vseq_c::do_instr_result();
end
end
"CUS_S_ADD": begin
if (req_item.issue_req.mode == 2'b01 && req_item.issue_req.rs_valid == 2'b11)
if (req_item.issue_req.mode == PRIV_LVL_S && req_item.issue_req.rs_valid == 2'b11 || req_item.issue_req.rs_valid == 3'b111)
resp_item.result.data = req_item.issue_req.rs[0] + req_item.issue_req.rs[1];
else begin
resp_item.result.exc = 1;
@ -268,6 +268,11 @@ task uvme_cvxif_vseq_c::do_instr_result();
`uvm_info(info_tag, $sformatf("Exception Illegal instruction -> EXCCODE: %d", resp_item.result.exccode), UVM_LOW);
end
end
"ILLEGAL": begin
resp_item.result.exc = 1;
resp_item.result.exccode[5:0] = 6'b000010; //Exception Illegal instruction
`uvm_info(info_tag, $sformatf("Exception Illegal instruction -> EXCCODE: %d", resp_item.result.exccode), UVM_LOW);
end
endcase
endtask

View file

@ -73,9 +73,11 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
soft sys_clk_period == uvme_cva6_sys_default_clk_period; // see uvme_cva6_constants.sv
}
constraint cvxif_feature { //CVA6 do not support dual read & write also the memory interface
soft cvxif_cfg.dual_read_write_support_x == 0;
soft cvxif_cfg.load_store_support_x == 0;
constraint cvxif_feature { //CV32A60X do not support dual read & write also the memory interface
cvxif_cfg.dual_read_write_support_x == 0;
cvxif_cfg.load_store_support_x == 0;
cvxif_cfg.seq_cus_instr_x2_enabled == 1;
cvxif_cfg.reg_cus_crosses_enabled == 0;
}
constraint cva6_riscv_cons {
xlen == uvma_core_cntrl_pkg::MXL_32;
@ -106,7 +108,7 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
mode_u_supported == 0;
pmp_supported == 0;
debug_supported == 1;
debug_supported == 0;
unaligned_access_supported == 0;
unaligned_access_amo_supported == 0;
@ -143,7 +145,7 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
isacov_cfg.seq_instr_group_x3_enabled == 0;
isacov_cfg.seq_instr_group_x4_enabled == 0;
isacov_cfg.seq_instr_x2_enabled == 1;
isacov_cfg.reg_crosses_enabled == 1;
isacov_cfg.reg_crosses_enabled == 0;
isacov_cfg.reg_hazards_enabled == 1;
rvfi_cfg.nret == RVFI_NRET;
@ -177,6 +179,11 @@ class uvme_cva6_cfg_c extends uvma_core_cntrl_cfg_c;
*/
extern virtual function void sample_parameters(uvma_core_cntrl_cntxt_c cntxt);
/**
* Set unsupported_csr_mask based on extensions/modes supported
*/
extern virtual function void set_unsupported_csr_mask();
endclass : uvme_cva6_cfg_c
@ -225,4 +232,13 @@ function void uvme_cva6_cfg_c::sample_parameters(uvma_core_cntrl_cntxt_c cntxt);
endfunction : sample_parameters
function void uvme_cva6_cfg_c::set_unsupported_csr_mask();
super.set_unsupported_csr_mask();
// Remove unsupported CSRs for STEP1 configuration
unsupported_csr_mask[uvma_core_cntrl_pkg::MCOUNTINHIBIT] = 1;
endfunction : set_unsupported_csr_mask
`endif // __UVME_CVA6_CFG_SV__

View file

@ -8,8 +8,8 @@
# Original Author: Guillaume Chauvon (guillaume.chauvon@thalesgroup.com)
# where are the tools
if ! [ -n "$RISCV_PREFIX" ]; then
echo "Error: RISCV_PREFIX variable undefined"
if [ -z "$RISCV" ]; then
echo "Error: RISCV variable undefined"
return
fi
@ -17,46 +17,52 @@ fi
source ./cva6/regress/install-cva6.sh
source ./cva6/regress/install-riscv-dv.sh
if ! [ -n "$DV_SIMULATORS" ]; then
if [ -z "$DV_SIMULATORS" ]; then
DV_SIMULATORS=veri-testharness,spike
fi
cd cva6/tests/riscv-tests/benchmarks
if ! [ -n "$DV_TARGET" ]; then
if [ -z "$DV_TARGET" ]; then
DV_TARGET=cv64a6_imafdc_sv39
fi
make clean
make
for f in *.riscv; do
mv -- "$f" "${f%.riscv}.o"
done
cd -
cd cva6/sim/
python3 cva6.py --target $DV_TARGET --iss=$DV_SIMULATORS --iss_yaml cva6.yaml --elf_tests ../tests/riscv-tests/benchmarks/dhrystone.o
python3 cva6.py --target $DV_TARGET --iss=$DV_SIMULATORS --iss_yaml cva6.yaml --elf_tests ../tests/riscv-tests/benchmarks/median.o
python3 cva6.py --target $DV_TARGET --iss=$DV_SIMULATORS --iss_yaml cva6.yaml --elf_tests ../tests/riscv-tests/benchmarks/mm.o
python3 cva6.py --target $DV_TARGET --iss=$DV_SIMULATORS --iss_yaml cva6.yaml --elf_tests ../tests/riscv-tests/benchmarks/mt-matmul.o
python3 cva6.py --target $DV_TARGET --iss=$DV_SIMULATORS --iss_yaml cva6.yaml --elf_tests ../tests/riscv-tests/benchmarks/mt-vvadd.o
python3 cva6.py --target $DV_TARGET --iss=$DV_SIMULATORS --iss_yaml cva6.yaml --elf_tests ../tests/riscv-tests/benchmarks/multiply.o
python3 cva6.py --target $DV_TARGET --iss=$DV_SIMULATORS --iss_yaml cva6.yaml --elf_tests ../tests/riscv-tests/benchmarks/pmp.o
python3 cva6.py --target $DV_TARGET --iss=$DV_SIMULATORS --iss_yaml cva6.yaml --elf_tests ../tests/riscv-tests/benchmarks/qsort.o
python3 cva6.py --target $DV_TARGET --iss=$DV_SIMULATORS --iss_yaml cva6.yaml --elf_tests ../tests/riscv-tests/benchmarks/rsort.o
python3 cva6.py --target $DV_TARGET --iss=$DV_SIMULATORS --iss_yaml cva6.yaml --elf_tests ../tests/riscv-tests/benchmarks/spmv.o
python3 cva6.py --target $DV_TARGET --iss=$DV_SIMULATORS --iss_yaml cva6.yaml --elf_tests ../tests/riscv-tests/benchmarks/towers.o
python3 cva6.py --target $DV_TARGET --iss=$DV_SIMULATORS --iss_yaml cva6.yaml --elf_tests ../tests/riscv-tests/benchmarks/vvadd.o
BDIR=../tests/riscv-tests/benchmarks/
CVA6_FLAGS="--target $DV_TARGET --iss=$DV_SIMULATORS --iss_yaml cva6.yaml --linker ../tests/custom/common/test.ld"
GCC_COMMON_SRC=(
../tests/riscv-tests/benchmarks/common/syscalls.c
../tests/riscv-tests/benchmarks/common/crt.S
)
GCC_CFLAGS=(
-fno-tree-loop-distribute-patterns
-nostdlib
-nostartfiles
-lgcc
-O3 --no-inline
-I../tests/custom/env
-I../tests/custom/common
-DNOPRINT
)
GCC_OPTS="${GCC_CFLAGS[*]} ${GCC_COMMON_SRC[*]}"
python3 cva6.py $CVA6_FLAGS --c_tests $BDIR/dhrystone/dhrystone.c --gcc_opts "$GCC_OPTS -I$BDIR/dhrystone/ $BDIR/dhrystone/dhrystone_main.c"
python3 cva6.py $CVA6_FLAGS --c_tests $BDIR/median/median.c --gcc_opts "$GCC_OPTS -I$BDIR/median/ $BDIR/median/median_main.c"
python3 cva6.py $CVA6_FLAGS --c_tests $BDIR/mm/mm.c --gcc_opts "$GCC_OPTS -I$BDIR/mm/ $BDIR/mm/mm_main.c"
python3 cva6.py $CVA6_FLAGS --c_tests $BDIR/mt-matmul/mt-matmul.c --gcc_opts "$GCC_OPTS -I$BDIR/mt-matmul/ $BDIR/mt-matmul/matmul.c"
python3 cva6.py $CVA6_FLAGS --c_tests $BDIR/mt-vvadd/mt-vvadd.c --gcc_opts "$GCC_OPTS -I$BDIR/mt-vvadd/ $BDIR/mt-vvadd/vvadd.c"
python3 cva6.py $CVA6_FLAGS --c_tests $BDIR/multiply/multiply.c --gcc_opts "$GCC_OPTS -I$BDIR/multiply/ $BDIR/multiply/multiply_main.c"
python3 cva6.py $CVA6_FLAGS --c_tests $BDIR/pmp/pmp.c --gcc_opts "$GCC_OPTS -I$BDIR/pmp/"
python3 cva6.py $CVA6_FLAGS --c_tests $BDIR/qsort/qsort_main.c --gcc_opts "$GCC_OPTS -I$BDIR/qsort/"
python3 cva6.py $CVA6_FLAGS --c_tests $BDIR/rsort/rsort.c --gcc_opts "$GCC_OPTS -I$BDIR/rsort/"
python3 cva6.py $CVA6_FLAGS --c_tests $BDIR/spmv/spmv_main.c --gcc_opts "$GCC_OPTS -I$BDIR/spmv/"
python3 cva6.py $CVA6_FLAGS --c_tests $BDIR/towers/towers_main.c --gcc_opts "$GCC_OPTS -I$BDIR/towers/"
python3 cva6.py $CVA6_FLAGS --c_tests $BDIR/vvadd/vvadd.c --gcc_opts "$GCC_OPTS -I$BDIR/vvadd/ $BDIR/vvadd/vvadd_main.c"
make -C ../../core-v-cores/cva6 clean
make clean_all
cd -
cd cva6/tests/riscv-tests/benchmarks
for f in *.o; do
mv -- "$f" "${f%.o}.riscv"
done
cd -

View file

@ -15,9 +15,10 @@ fi
# install the required tools
source ./cva6/regress/install-cva6.sh
source ./cva6/regress/install-riscv-dv.sh
source ./cva6/regress/install-spike.sh
if ! [ -n "$DV_TARGET" ]; then
DV_TARGET=cv64a6_imafdc_sv39
DV_TARGET=cv32a60x
fi
if ! [ -n "$DV_SIMULATORS" ]; then
@ -34,46 +35,68 @@ cd cva6/sim/
dd=$(date '+%Y-%m-%d')
key_word="Mismatch[1]:"
#Read from the iss_regr.log to detect the failed tests
logfile=out_$dd/iss_regr.log
logfile=out_$dd/iss_regr.log
TESTLIST_FILE=cva6_base_testlist.yaml
DIRECTED_TESTLIST=../tests/testlist_isacov.yaml
j=0;
rm -rf out_$dd
if [[ "$list_num" = 0 ]];then
TEST_NAME=(
"riscv_arithmetic_basic_test"
"riscv_unaligned_load_store_test"
);
I=(50 10);
#this list re-use tests from the base_testlist in the riscv-dv
#Just the tests in the riscv-dv YAML file
TESTLIST_FILE=dv/yaml/base_testlist.yaml
elif [[ "$list_num" = 1 ]];then
if [[ "$list_num" = 1 ]];then
TEST_NAME=(
"riscv_arithmetic_basic_test_no_comp"
"riscv_arithmetic_basic_illegal_test"
"riscv_arithmetic_basic_test_bcomp"
"riscv_arithmetic_basic_illegal"
"riscv_arithmetic_basic_test_comp"
"riscv_arithmetic_basic_illegal_hint_test"
"riscv_arithmetic_basic_dret"
"riscv_arithmetic_basic_loop_test"
);
I=(50 10 10 20);
TESTLIST_FILE=cva6_base_testlist.yaml
elif [[ "$list_num" = 2 ]];then
TEST_NAME=(
"riscv_arithmetic_basic_csr_test"
"riscv_arithmetic_basic_hint_csr_test"
"riscv_arithmetic_basic_rand_prvl"
I=(100 100 20 100 20 20);
elif [[ "$list_num" = 2 ]];then
TEST_NAME=(
"riscv_arithmetic_basic_same_reg_test"
"riscv_arithmetic_basic_hazard_rdrs1_test"
"riscv_arithmetic_basic_hazard_rdrs2_test"
);
I=(100 100 100);
elif [[ "$list_num" = 3 ]];then
TEST_NAME=(
"riscv_arithmetic_basic_csr_dummy"
"riscv_arithmetic_basic_Randcsr_test"
"riscv_arithmetic_basic_ebreak_dret_test"
"riscv_arithmetic_basic_illegal_csr"
);
I=(100 100 40 20);
TESTLIST_FILE=cva6_base_testlist.yaml
I=(20 20 20 20);
elif [[ "$list_num" = 4 ]];then
TEST_NAME=(
"riscv_mmu_stress_hint_test"
"riscv_mmu_stress_test"
);
I=(100 100);
elif [[ "$list_num" = 5 ]];then
TEST_NAME=(
"riscv_load_store_test"
"riscv_load_store_cmp_test"
"riscv_load_store_hazard_test"
"riscv_unaligned_load_store_test"
);
I=(50 50 50 50);
elif [[ "$list_num" = 6 ]];then
TEST_NAME=(
"riscv_rand_jump_hint_comp_test"
"riscv_rand_jump_no_cmp_test"
"riscv_rand_jump_illegal_test"
"riscv_arithmetic_basic_sub_prog_test"
);
I=(75 75 50 20);
fi
if [[ "$list_num" != 0 ]];then
if [[ ${#TEST_NAME[@]} != ${#I[@]} ]];then
echo "***********ERROR***************"
echo "The length of TEST_NAME and I should be equal !!!!"
echo "The length of TEST_NAME and Iteration should be equal !!!!"
echo "Fix the length of one of the arrays"
exit
fi
printf "+====================================================================================+"
header="\n %-50s %-20s %s\n"
format=" %-50s %-20d %d\n"
@ -87,20 +110,20 @@ while [[ $j -lt ${#TEST_NAME[@]} ]];do
done
printf "+====================================================================================+\n"
j=0
while [[ $j -lt ${#TEST_NAME[@]} ]];do
python3 cva6.py --testlist=$TESTLIST_FILE --test ${TEST_NAME[j]} --iss_yaml cva6.yaml --target $DV_TARGET --iss=vcs-uvm,spike -i ${I[j]} -bz 1 --iss_timeout 300
cp ../env/corev-dv/custom/riscv_custom_instr_enum.sv ./dv/src/isa/custom/
python3 cva6.py --testlist=$TESTLIST_FILE --test ${TEST_NAME[j]} --iss_yaml cva6.yaml --target $DV_TARGET -cs ../env/corev-dv/target/rv32imac/ --mabi ilp32 --isa rv32imac --simulator_yaml ../env/corev-dv/simulator.yaml --iss=vcs-uvm,spike -i ${I[j]} -bz 1 --iss_timeout 300
n=0
echo "Generate the test : ${TEST_NAME[j]}"
echo "Generate the test: ${TEST_NAME[j]}"
#this while loop detects the failed tests from the log file and remove them
echo "Deleting failed tests : "
echo "Deleting failed tests: "
while read line;do
if [[ "$line" = "" ]];then
n=$((n+1))
fi
for word in $line;do
if [[ "$word" = "$key_word" ]];then
echo -e ""${TEST_NAME[j]}"_"$n" : Failed"
echo -e ""${TEST_NAME[j]}"_"$n": Failed"
rm -rf vcs_results/default/vcs.d/simv.vdb/snps/coverage/db/testdata/"${TEST_NAME[j]}"_"$n"/
fi
done
@ -108,4 +131,10 @@ while [[ $j -lt ${#TEST_NAME[@]} ]];do
rm -rf out_$dd
j=$((j+1))
done
#Execute directed tests to improve functional coverage of ISA
j=0
elif [[ "$list_num" = 0 ]];then
printf "==== Execute Directed tests to improve functional coverage of isa, by hitting corners !!! ====\n\n"
python3 cva6.py --testlist=$DIRECTED_TESTLIST --iss_yaml cva6.yaml --target $DV_TARGET --iss=vcs-uvm,spike
fi
cd -

View file

@ -0,0 +1,102 @@
# Copyright 2023 Thales DIS SAS
#
# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
# You may obtain a copy of the License at https://solderpad.org/licenses/
#
# Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
if ! [ -n "$RISCV" ]; then
echo "Error: RISCV variable undefined"
return
fi
# install the required tools
source ./cva6/regress/install-cva6.sh
source ./cva6/regress/install-riscv-dv.sh
source ./cva6/regress/install-spike.sh
if ! [ -n "$DV_TARGET" ]; then
DV_TARGET=cv32a60x
fi
if ! [ -n "$DV_SIMULATORS" ]; then
DV_SIMULATORS=vcs-uvm,spike
fi
if ! [ -n "$list_num" ]; then
list_num=1 #default test list
fi
export cov=1 #enable the Code Coverage
export cvxif=1 #enable cvxif extension for Spike
cd cva6/sim/
dd=$(date '+%Y-%m-%d')
key_word="Mismatch[1]:"
#Read from the iss_regr.log to detect the failed tests
logfile=out_$dd/iss_regr.log
TESTLIST_FILE=cva6_base_testlist.yaml
DIRECTED_TESTLIST=../tests/testlist_cvxif.yaml
j=0;
rm -rf out_$dd
if [[ "$list_num" = 1 ]];then
TEST_NAME=(
"riscv_arithmetic_basic_xif_test"
"riscv_arithmetic_basic_xif_illegal_test"
"riscv_load_store_xif_test"
"riscv_rand_jump_xif_test"
);
I=(100 100 100 100);
fi
if [[ "$list_num" != 0 ]];then
if [[ ${#TEST_NAME[@]} != ${#I[@]} ]];then
echo "***********ERROR***************"
echo "The length of TEST_NAME and Iteration should be equal !!!!"
echo "Fix the length of one of the arrays"
exit
fi
printf "+====================================================================================+"
header="\n %-50s %-20s %s\n"
format=" %-50s %-20d %d\n"
printf "$header" "TEST NAME" "ITERATION" "BATCH SIZE"
printf "+====================================================================================+\n"
while [[ $j -lt ${#TEST_NAME[@]} ]];do
printf "$format" \
${TEST_NAME[j]} ${I[j]} ${BZ[j]}
j=$((j+1))
done
printf "+====================================================================================+\n"
j=0
while [[ $j -lt ${#TEST_NAME[@]} ]];do
cp ../env/corev-dv/custom/riscv_custom_instr_enum.sv ./dv/src/isa/custom/
python3 cva6.py --testlist=$TESTLIST_FILE --test ${TEST_NAME[j]} --iss_yaml cva6.yaml --target $DV_TARGET -cs ../env/corev-dv/target/rv32imc/ --mabi ilp32 --isa rv32imc --simulator_yaml ../env/corev-dv/simulator.yaml --iss=vcs-uvm,spike -i ${I[j]} -bz 1 --iss_timeout 300
n=0
echo "Generate the test: ${TEST_NAME[j]}"
#this while loop detects the failed tests from the log file and remove them
echo "Deleting failed tests: "
while read line;do
if [[ "$line" = "" ]];then
n=$((n+1))
fi
for word in $line;do
if [[ "$word" = "$key_word" ]];then
echo -e ""${TEST_NAME[j]}"_"$n": Failed"
rm -rf vcs_results/default/vcs.d/simv.vdb/snps/coverage/db/testdata/"${TEST_NAME[j]}"_"$n"/
fi
done
done < $logfile
rm -rf out_$dd
j=$((j+1))
done
#Execute directed tests to improve functional coverage of ISA
j=0
elif [[ "$list_num" = 0 ]];then
printf "==== Execute Directed tests to improve functional coverage of isa, by hitting corners !!! ====\n\n"
python3 cva6.py --testlist=$DIRECTED_TESTLIST --iss_yaml cva6.yaml --target $DV_TARGET --iss=vcs-uvm,spike
fi
cd -

View file

@ -8,15 +8,27 @@
# Original Author: Jean-Roch COULON - Thales
# Customise this to a fast local disk
export ROOT_PROJECT=$(cd "$(dirname "${BASH_SOURCE[0]}")/../../" && pwd)
export ROOT_PROJECT=$(readlink -f $(dirname "${BASH_SOURCE[0]}")/../../)
export TOP="$ROOT_PROJECT/tools"
# where to install the tools
if ! [ -n "$RISCV" ]; then
if [ -z "$RISCV" ]; then
echo "Error: RISCV variable undefined."
return
fi
if [ -z "$CV_SW_PREFIX" ]; then
export CV_SW_PREFIX="$(ls -1 -r $RISCV/bin/riscv*-gcc | head -n 1| grep gcc | rev | cut -d '/' -f 1 | cut -d '-' -f 2- | rev)-"
fi
if [ -z "$RISCV_GCC" ]; then
export RISCV_GCC=$RISCV/bin/${CV_SW_PREFIX}gcc
fi
if [ -z "$RISCV_OBJCOPY" ]; then
export RISCV_OBJCOPY=$RISCV/bin/${CV_SW_PREFIX}objcopy
fi
# Set up tool-related variables.
export PATH="$RISCV/bin:$PATH"
export LIBRARY_PATH="$RISCV/lib"
@ -28,7 +40,7 @@ export CPLUS_INCLUDE_PATH="$RISCV/include"
# Set VERILATOR_INSTALL_DIR to 'NO' to skip installation and checks
# of Verilator (useful for CI jobs not depending on Verilator in any way).
if [ "$VERILATOR_INSTALL_DIR" != "NO" ]; then
cva6/regress/install-verilator.sh
source cva6/regress/install-verilator.sh
# Complain if the installation directory of Verilator still is not set
# after running the installer.
@ -42,8 +54,6 @@ if [ "$VERILATOR_INSTALL_DIR" != "NO" ]; then
export C_INCLUDE_PATH="$VERILATOR_INSTALL_DIR/share/verilator/include:$C_INCLUDE_PATH"
export CPLUS_INCLUDE_PATH="$VERILATOR_INSTALL_DIR/share/verilator/include:$CPLUS_INCLUDE_PATH"
# Check proper Verilator installation given current $PATH.
echo PATH=\"$PATH\"
echo "Verilator version:"
verilator --version || { echo "Error: Verilator not in \$PATH." ; return ; }
else
@ -54,10 +64,10 @@ fi
export NUM_JOBS=24
# install the required tools for cva6
if ! [ -n "$CVA6_REPO" ]; then
if [ -z "$CVA6_REPO" ]; then
CVA6_REPO="https://github.com/openhwgroup/cva6.git"
CVA6_BRANCH="master"
CVA6_HASH="4f06aa620f75bcae369f05d0652283d45ef76a24"
CVA6_HASH="853fb4bee5ca6e36e39dc3c272a97f49d95c3c1d"
CVA6_PATCH=
fi
echo $CVA6_REPO
@ -67,16 +77,17 @@ echo $CVA6_PATCH
if ! [ -d core-v-cores/cva6 ]; then
git clone --recursive $CVA6_REPO -b $CVA6_BRANCH core-v-cores/cva6
cd core-v-cores/cva6; git checkout $CVA6_HASH;
pushd core-v-cores/cva6
git checkout $CVA6_HASH
echo -n "Using CVA6 commit "; git describe --always HEAD
if [ -f ../$CVA6_PATCH ]; then
git apply ../$CVA6_PATCH
if [[ -n "$CVA6_PATCH" && -f "$CVA6_PATCH" ]]; then
git apply "$CVA6_PATCH"
fi
cd -
popd
fi
# install Spike
if ! [ -n "$SPIKE_ROOT" ]; then
if [ -z "$SPIKE_ROOT" ]; then
export SPIKE_ROOT=$TOP/spike/
fi
cva6/regress/install-spike.sh
source cva6/regress/install-spike.sh

View file

@ -17,7 +17,7 @@ fi
if ! [ -n "$ARCH_TEST_REPO" ]; then
ARCH_TEST_REPO=https://github.com/riscv-non-isa/riscv-arch-test
ARCH_TEST_BRANCH=main
ARCH_TEST_HASH=ad04e119a5d846a1c11159786ad3382cf5ad3649
ARCH_TEST_HASH="46cf99d0e020887e398508fc776928a1adad7c23"
fi
echo "Repo: " $ARCH_TEST_REPO
echo "Branch:" $ARCH_TEST_BRANCH
@ -29,7 +29,7 @@ if ! [ -d cva6/tests/riscv-arch-test ]; then
git clone $ARCH_TEST_REPO -b $ARCH_TEST_BRANCH cva6/tests/riscv-arch-test
cd cva6/tests/riscv-arch-test; git checkout $ARCH_TEST_HASH;
# Copy Spike definitions to the corresponding riscv-target subdirectory.
cp -rpa $SPIKE_SRC_DIR/arch_test_target/spike riscv-target
cp -rpa $SPIKE_SRC_DIR/arch_test_target riscv-target
cd -
fi

View file

@ -22,9 +22,9 @@ mkdir -p cva6/tests
if ! [ -d cva6/tests/riscv-compliance ]; then
git clone $COMPLIANCE_REPO -b $COMPLIANCE_BRANCH cva6/tests/riscv-compliance
cd cva6/tests/riscv-compliance; git checkout $COMPLIANCE_HASH;
if [ -f "$COMPLIANCE_PATCH" ]; then
if [[ -n "$COMPLIANCE_PATCH" && -f "$COMPLIANCE_PATCH" ]]; then
echo "Applying patch $COMPLIANCE_PATCH in $PWD..."
git apply $COMPLIANCE_PATCH
git apply "$COMPLIANCE_PATCH"
fi
cd -
fi

View file

@ -9,10 +9,10 @@
# riscv-dv env variables
export RISCV_TOOLCHAIN=$RISCV
if ! [ -n "$RISCV_GCC" ]; then
if [ -z "$RISCV_GCC" ]; then
export RISCV_GCC="$RISCV_TOOLCHAIN/bin/riscv-none-elf-gcc"
fi
if ! [ -n "$RISCV_OBJCOPY" ]; then
if [ -z "$RISCV_OBJCOPY" ]; then
export RISCV_OBJCOPY="$RISCV_TOOLCHAIN/bin/riscv-none-elf-objcopy"
fi
export SPIKE_PATH=$SPIKE_ROOT/bin
@ -20,10 +20,10 @@ export RTL_PATH=$ROOT_PROJECT/core-v-cores/cva6
export TB_PATH=$ROOT_PROJECT/cva6/tb/core
export TESTS_PATH=$ROOT_PROJECT/cva6/tests
if ! [ -n "$DV_REPO" ]; then
if [ -z "$DV_REPO" ]; then
export DV_REPO="https://github.com/google/riscv-dv.git"
export DV_BRANCH=master
export DV_HASH=96c1ee6f371f2754c45b4831fcab95f6671689d9
export DV_BRANCH="master"
export DV_HASH="96c1ee6f371f2754c45b4831fcab95f6671689d9"
export DV_PATCH=
fi
echo "Repo: " $DV_REPO
@ -35,8 +35,8 @@ mkdir -p cva6/sim
if ! [ -d cva6/sim/dv ]; then
git clone $DV_REPO -b $DV_BRANCH cva6/sim/dv
cd cva6/sim/dv; git checkout $DV_HASH;
if [ -f "$DV_PATCH" ]; then
git apply $DV_PATCH
if [[ -n "$DV_PATCH" && -f "$DV_PATCH" ]]; then
git apply "$DV_PATCH"
fi
cd -
# install riscv-dv dependencies

View file

@ -7,7 +7,7 @@
#
# Original Author: Jean-Roch COULON - Thales
if [ -z ${NUM_JOBS} ]; then
if [ -z "$NUM_JOBS" ]; then
NUM_JOBS=1
fi
@ -39,7 +39,7 @@ fi
# Continuous Integration may need to override this particular variable
# to use a preinstalled build of Verilator.
if [ -z "$VERILATOR_INSTALL_DIR" ]; then
export VERILATOR_INSTALL_DIR=$(dirname ${VERILATOR_BUILD_DIR})
export VERILATOR_INSTALL_DIR="$(dirname $VERILATOR_BUILD_DIR)"
fi
# Build and install Verilator only if not already installed at the expected
@ -58,7 +58,7 @@ if [ ! -f "$VERILATOR_INSTALL_DIR/bin/verilator" ]; then
# to preserve user content - let git fail instead.
[ -d .git ] || git clone $VERILATOR_REPO -b $VERILATOR_BRANCH .
git checkout $VERILATOR_HASH
if [ ! -z "$VERILATOR_PATCH" ] ; then
if [[ -n "$VERILATOR_PATCH" && -f "$VERILATOR_PATCH" ]] ; then
git apply $VERILATOR_PATCH || true
fi
# Generate the config script and configure Verilator.

View file

@ -0,0 +1,36 @@
# Copyright 2023 Thales DIS
#
# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
# You may obtain a copy of the License at https://solderpad.org/licenses/
#
# Original Author: Ayoub JALALI - Thales
# where are the tools
if ! [ -n "$RISCV" ]; then
echo "Error: RISCV variable undefined"
return
fi
# install the required tools
source ./cva6/regress/install-cva6.sh
source ./cva6/regress/install-riscv-dv.sh
source ./cva6/regress/install-riscv-isa-sim.sh
if ! [ -n "$DV_TARGET" ]; then
DV_TARGET=cv32a60x
fi
if ! [ -n "$DV_SIMULATORS" ]; then
DV_SIMULATORS=vcs-uvm,spike
fi
cd cva6/sim/
cp ../env/corev-dv/custom/riscv_custom_instr_enum.sv ./dv/src/isa/custom/
python3 cva6.py --testlist=cva6_base_testlist.yaml --test riscv_arithmetic_basic_test_comp --iss_yaml cva6.yaml --target $DV_TARGET -cs ../env/corev-dv/target/rv32imac/ --mabi ilp32 --isa rv32imac --simulator_yaml ../env/corev-dv/simulator.yaml --iss=$DV_SIMULATORS $DV_OPTS -i 1 --iss_timeout 300
python3 cva6.py --testlist=cva6_base_testlist.yaml --test riscv_load_store_test --iss_yaml cva6.yaml --target $DV_TARGET -cs ../env/corev-dv/target/rv32imac/ --mabi ilp32 --isa rv32imac --simulator_yaml ../env/corev-dv/simulator.yaml --iss=$DV_SIMULATORS $DV_OPTS -i 1 --iss_timeout 300
python3 cva6.py --testlist=cva6_base_testlist.yaml --test riscv_unaligned_load_store_test --iss_yaml cva6.yaml --target $DV_TARGET -cs ../env/corev-dv/target/rv32imac/ --mabi ilp32 --isa rv32imac --simulator_yaml ../env/corev-dv/simulator.yaml --iss=$DV_SIMULATORS $DV_OPTS -i 1 --iss_timeout 300
make clean_all
cd -

View file

@ -20,6 +20,7 @@ source ./cva6/regress/install-riscv-compliance.sh
source ./cva6/regress/install-riscv-tests.sh
source ./cva6/regress/install-riscv-arch-test.sh
if ! [ -n "$DV_SIMULATORS" ]; then
DV_SIMULATORS=vcs-testharness,spike
fi
@ -37,8 +38,8 @@ make clean_all
python3 cva6.py --testlist=../tests/testlist_riscv-compliance-cv32a60x.yaml --test rv32i-I-ADD-01 --iss_yaml cva6.yaml --target cv32a60x --iss=$DV_SIMULATORS $DV_OPTS
python3 cva6.py --testlist=../tests/testlist_riscv-tests-cv32a60x-p.yaml --test rv32ui-p-add --iss_yaml cva6.yaml --target cv32a60x --iss=$DV_SIMULATORS $DV_OPTS
python3 cva6.py --testlist=../tests/testlist_riscv-arch-test-cv32a60x.yaml --test rv32im-cadd-01 --iss_yaml cva6.yaml --target cv32a60x --iss=$DV_SIMULATORS $DV_OPTS --linker=../tests/riscv-arch-test/riscv-target/spike/link.ld
python3 cva6.py --target cv32a60x --iss=$DV_SIMULATORS --iss_yaml=cva6.yaml --c_tests ../tests/custom/hello_world/hello_world.c\
--gcc_opts "-g ../tests/custom/common/syscalls.c ../tests/custom/common/crt.S -lgcc -I../tests/custom/env -I../tests/custom/common -T ../tests/custom/common/test.ld"
python3 cva6.py --target cv32a60x --iss=$DV_SIMULATORS --iss_yaml=cva6.yaml --c_tests ../tests/custom/hello_world/hello_world.c --linker=../tests/custom/common/test.ld\
--gcc_opts "-g ../tests/custom/common/syscalls.c ../tests/custom/common/crt.S -lgcc -I../tests/custom/env -I../tests/custom/common"
make -C ../../core-v-cores/cva6 clean
make clean_all

View file

@ -38,6 +38,10 @@ issrun_opts ?=
isspostrun_opts ?=
log ?=
variant ?=
# Set Spike step count limit if the caller provided a step count value in variable 'steps'.
ifneq ($(steps),)
spike_stepout = --steps=$(steps)
endif
# TRACE_FAST, TRACE_COMPACT and VERDI are mutually exclusive and imply non-empty DEBUG.
ifneq ($(TRACE_FAST),)
@ -97,11 +101,16 @@ else
cov-run-opt =
endif
ifdef cvxif
spike_extension = --extension=cvxif
endif
###############################################################################
# Spike specific commands, variables
###############################################################################
spike:
$(tool_path)/spike --log-commits --isa=$(variant) -l $(elf)
LD_LIBRARY_PATH="$$(realpath ../../tools/spike/lib):$$LD_LIBRARY_PATH" \
$(tool_path)/spike $(spike_stepout) $(spike_extension) --log-commits --isa=$(variant) -l $(elf)
cp $(log).iss $(log)
###############################################################################
@ -110,7 +119,7 @@ spike:
vcs-testharness:
make -C $(path_var) vcs_build target=$(target) defines=$(subst +define+,,$(isscomp_opts))
$(path_var)/work-vcs/simv $(if $(VERDI), -verdi -do $(path_var)/init_testharness.do,) +permissive -sv_lib $(path_var)/work-dpi/ariane_dpi \
+tohost_addr=$(shell $$RISCV/bin/riscv-none-elf-nm -B $(elf) | grep -w tohost | cut -d' ' -f1) \
+tohost_addr=$(shell $$RISCV/bin/${CV_SW_PREFIX}nm -B $(elf) | grep -w tohost | cut -d' ' -f1) \
+PRELOAD=$(elf) +permissive-off ++$(elf) $(issrun_opts)
$(tool_path)/spike-dasm --isa=$(variant) < ./trace_rvfi_hart_00.dasm > $(log)
grep $(isspostrun_opts) ./trace_rvfi_hart_00.dasm
@ -118,13 +127,19 @@ vcs-testharness:
veri-testharness:
make -C $(path_var) verilate verilator="verilator --no-timing" target=$(target) defines=$(subst +define+,,$(isscomp_opts))
$(path_var)/work-ver/Variane_testharness $(if $(TRACE_COMPACT), -f verilator.fst) $(if $(TRACE_FAST), -v verilator.vcd) $(elf) $(issrun_opts) +PRELOAD=$(elf) \
+tohost_addr=$(shell $$RISCV/bin/riscv-none-elf-nm -B $(elf) | grep -w tohost | cut -d' ' -f1)
+tohost_addr=$(shell $$RISCV/bin/${CV_SW_PREFIX}nm -B $(elf) | grep -w tohost | cut -d' ' -f1)
$(tool_path)/spike-dasm --isa=$(variant) < ./trace_rvfi_hart_00.dasm > $(log)
# If present, move default trace files to per-test directory.
[ ! -f verilator.fst ] || mv verilator.fst `dirname $(log)`/`basename $(log) .log`.$(target).fst
[ ! -f verilator.vcd ] || mv verilator.vcd `dirname $(log)`/`basename $(log) .log`.$(target).vcd
grep $(isspostrun_opts) ./trace_rvfi_hart_00.dasm
questa-testharness:
mkdir -p $(path_var)/tmp
make -C $(path_var) sim target=$(target) defines=$(subst +define+,,$(isscomp_opts)) batch-mode=1 elf-bin=$(elf) $(issrun_opts)
$(tool_path)/spike-dasm --isa=$(variant) < $(path_var)/trace_rvfi_hart_00.dasm > $(log)
grep $(isspostrun_opts) $(path_var)/trace_rvfi_hart_00.dasm
###############################################################################
# UVM specific commands, variables
###############################################################################
@ -171,7 +186,7 @@ ALL_UVM_FLAGS = -lca -sverilog +incdir+$(VCS_HOME)/etc/uvm/src \
+incdir+$(CORE_V_VERIF)/$(CV_CORE_LC)/env/uvme +incdir+$(CORE_V_VERIF)/$(CV_CORE_LC)/tb/uvmt \
$(if $(DEBUG), -debug_access+all $(if $(VERDI), -kdb) $(if $(TRACE_COMPACT),+vcs+fsdbon))
ALL_SIMV_UVM_FLAGS = -licwait 20 +ntb_random_seed=1 \
ALL_SIMV_UVM_FLAGS = -licwait 20 $(issrun_opts) \
-sv_lib $(CORE_V_VERIF)/lib/dpi_dasm/lib/Linux64/libdpi_dasm +signature=I-ADD-01.signature_output \
+UVM_TESTNAME=uvmt_cva6_firmware_test_c
@ -196,7 +211,7 @@ endif
dpi-library = $(VCS_WORK_DIR)/work-dpi
dpi_build:
mkdir -p $(dpi-library)
g++ -shared -fPIC -std=c++0x -Bsymbolic -std=c++11 -I../corev_apu/tb/dpi -O3 -I$(SPIKE_ROOT)/include \
g++ -shared -fPIC -std=c++17 -Bsymbolic -I../corev_apu/tb/dpi -O3 -I$(SPIKE_ROOT)/include \
-I$(VCS_HOME)/include -I$(RISCV)/include -c $(CVA6_REPO_DIR)/corev_apu/tb/dpi/elfloader.cc \
-o $(dpi-library)/elfloader.o
g++ -shared -m64 -o $(dpi-library)/ariane_dpi.so $(dpi-library)/elfloader.o -L$(RISCV)/lib -Wl,-rpath,$(RISCV)/lib
@ -233,7 +248,7 @@ vcs-uvm:
for i in `ls *.$(SIMV_TRACE_EXTN)` ; do mv $$i `dirname $(log)`/`basename $(log) .log`.$(target).$$i ; done || true
generate_cov_dash:
urg -dir $(VCS_WORK_DIR)/simv.vdb
urg -dir $(VCS_WORK_DIR)/simv.vdb -group instcov_for_score
vcs_clean_all:
@echo "[VCS] Cleanup (entire vcs_work dir)"

View file

@ -100,7 +100,7 @@ def parse_iss_yaml(iss, iss_yaml, isa, target, setting_dir, debug_cmd):
for entry in yaml_data:
if entry['iss'] == iss:
logging.info("Found matching ISS: %s" % entry['iss'])
m = re.search(r"rv(?P<xlen>[0-9]+?)(?P<variant>[a-z]+?)$", isa)
m = re.search(r"rv(?P<xlen>[0-9]+?)(?P<variant>[a-z]+(_[szx]\w+)*)$", isa)
if m: logging.info("ISA %0s" % isa)
else: logging.error("Illegal ISA %0s" % isa)
@ -349,7 +349,9 @@ def gcc_compile(test_list, output_dir, isa, mabi, opts, debug_cmd, linker):
asm = prefix + ".S"
elf = prefix + ".o"
binary = prefix + ".bin"
test_isa = isa
test_isa=re.match("[a-z0-9A-Z]+", isa)
test_isa=test_isa.group()
isa_ext=isa
if not os.path.isfile(asm) and not debug_cmd:
logging.error("Cannot find assembly test: %s\n", asm)
sys.exit(RET_FAIL)
@ -366,13 +368,18 @@ def gcc_compile(test_list, output_dir, isa, mabi, opts, debug_cmd, linker):
# Disable compressed instruction
if re.search('disable_compressed_instr=1', test['gen_opts']):
test_isa = re.sub("c", "", test_isa)
#add z,s,x extensions to the isa if there are some
if isa_extension_list !=['none']:
for i in isa_extension_list:
test_isa += (f"_{i}")
isa_ext=test_isa
# If march/mabi is not defined in the test gcc_opts, use the default
# setting from the command line.
if not re.search('march', cmd):
cmd += (" -march=%s" % test_isa)
cmd += (" -march=%s" % isa_ext)
if not re.search('mabi', cmd):
cmd += (" -mabi=%s" % mabi)
logging.info("Compiling %s" % asm)
logging.info("Compiling test : %s" % asm)
run_cmd_output(cmd.split(), debug_cmd = debug_cmd)
elf2bin(elf, binary, debug_cmd)
@ -414,7 +421,7 @@ def run_assembly(asm_test, iss_yaml, isa, target, mabi, gcc_opts, iss_opts, outp
cmd = ("%s -static -mcmodel=medany \
-fvisibility=hidden -nostdlib \
-nostartfiles %s \
-I%s/dv/user_extension \
-I%s/../env/corev-dv/user_extension \
-T%s %s -o %s " % \
(get_env_var("RISCV_GCC", debug_cmd = debug_cmd), asm_test, cwd, linker,
gcc_opts, elf))
@ -426,7 +433,10 @@ def run_assembly(asm_test, iss_yaml, isa, target, mabi, gcc_opts, iss_opts, outp
# ISS simulation
for iss in iss_list:
run_cmd("mkdir -p %s/%s_sim" % (output_dir, iss))
log = ("%s/%s_sim/%s.log" % (output_dir, iss, asm))
if log_format == 1:
log = ("%s/%s_sim/%s_%d.log" % (output_dir, iss, asm, test_iteration))
else:
log = ("%s/%s_sim/%s.log" % (output_dir, iss, asm))
log_list.append(log)
base_cmd = parse_iss_yaml(iss, iss_yaml, isa, target, setting_dir, debug_cmd)
cmd = get_iss_cmd(base_cmd, elf, target, log)
@ -539,7 +549,7 @@ def run_c(c_test, iss_yaml, isa, target, mabi, gcc_opts, iss_opts, output_dir,
report = ("%s/iss_regr.log" % output_dir).rstrip()
c = re.sub(r"^.*\/", "", c_test)
c = re.sub(r"\.c$", "", c)
prefix = ("%s/directed_c_tests/%s" % (output_dir, c))
prefix = (f"{output_dir}/directed_c_tests/{c}")
elf = prefix + ".o"
binary = prefix + ".bin"
iss_list = iss_opts.split(",")
@ -550,9 +560,9 @@ def run_c(c_test, iss_yaml, isa, target, mabi, gcc_opts, iss_opts, output_dir,
cmd = ("%s -mcmodel=medany -nostdlib \
-nostartfiles %s \
-I%s/dv/user_extension \
-T%s %s -o %s " % \
(get_env_var("RISCV_GCC", debug_cmd = debug_cmd), c_test, cwd,
linker, gcc_opts, elf))
-T%s %s -o %s " % \
(get_env_var("RISCV_GCC", debug_cmd = debug_cmd), c_test, cwd,
linker, gcc_opts, elf))
cmd += (" -march=%s" % isa)
cmd += (" -mabi=%s" % mabi)
run_cmd(cmd, debug_cmd = debug_cmd)
@ -561,7 +571,10 @@ def run_c(c_test, iss_yaml, isa, target, mabi, gcc_opts, iss_opts, output_dir,
# ISS simulation
for iss in iss_list:
run_cmd("mkdir -p %s/%s_sim" % (output_dir, iss))
log = ("%s/%s_sim/%s.log" % (output_dir, iss, c))
if log_format == 1:
log = ("%s/%s_sim/%s_%d.log" % (output_dir, iss, c, test_iteration))
else:
log = ("%s/%s_sim/%s.log" % (output_dir, iss, c))
log_list.append(log)
base_cmd = parse_iss_yaml(iss, iss_yaml, isa, target, setting_dir, debug_cmd)
cmd = get_iss_cmd(base_cmd, elf, target, log)
@ -675,6 +688,7 @@ def iss_cmp(test_list, iss, output_dir, stop_on_first_error, exp, debug_cmd):
def compare_iss_log(iss_list, log_list, report, stop_on_first_error=0, exp=False):
if (len(iss_list) != 2 or len(log_list) != 2) :
logging.error("Only support comparing two ISS logs")
logging.info("len(iss_list) = %s len(log_list) = %s" % (len(iss_list), len(log_list)))
else:
csv_list = []
for i in range(2):
@ -684,7 +698,7 @@ def compare_iss_log(iss_list, log_list, report, stop_on_first_error=0, exp=False
csv_list.append(csv)
if iss == "spike":
process_spike_sim_log(log, csv)
elif "veri" in iss or "vsim" in iss or "vcs" in iss:
elif "veri" in iss or "vsim" in iss or "vcs" in iss or "questa" in iss:
process_verilator_sim_log(log, csv)
elif iss == "ovpsim":
process_ovpsim_sim_log(log, csv, stop_on_first_error)
@ -818,6 +832,12 @@ def setup_parser():
help="Path for the link.ld")
parser.add_argument("--axi_active", type=str, default="",
help="switch AXI agent mode: yes for Active, no for Passive")
parser.add_argument("--gen_sv_seed", type=int, default=0,
help="Run test N times with random seed")
parser.add_argument("--sv_seed", type=str, default="1",
help="Run test with a specific seed")
parser.add_argument("--isa_extension", type=str, default="",
help="Choose additional z, s, x extensions")
return parser
@ -829,6 +849,12 @@ def load_config(args, cwd):
Returns:
Loaded configuration dictionary.
"""
global isa_extension_list
isa_extension_list = args.isa_extension.split(",")
isa_extension_list.append("zicsr")
isa_extension_list.append("zifencei")
if args.debug:
args.debug = open(args.debug, "w")
if not args.csr_yaml:
@ -857,12 +883,12 @@ def load_config(args, cwd):
if args.target == "cv64a6_imafdc_sv39":
args.mabi = "lp64d"
args.isa = "rv64gc"
elif args.target == "cv32a60x":
elif args.target == "cv32a60x": # step1 configuration
args.mabi = "ilp32"
args.isa = "rv32imc" # Step1 configuration has no A extension.
args.isa = "rv32imac"
elif args.target == "cv32a6_embedded":
args.mabi = "ilp32"
args.isa = "rv32imc" # Step1 configuration has no A extension.
args.isa = "rv32imc"
elif args.target == "cv32a6_imac_sv0":
args.mabi = "ilp32"
args.isa = "rv32imac"
@ -933,10 +959,26 @@ def main():
parser = setup_parser()
args = parser.parse_args()
global issrun_opts
global test_iteration
global log_format
if args.axi_active == "yes":
args.issrun_opts = args.issrun_opts + " +uvm_set_config_int=*uvm_test_top,force_axi_mode,1"
elif args.axi_active == "no":
args.issrun_opts = args.issrun_opts + " +uvm_set_config_int=uvm_test_top,force_axi_mode,0"
if args.gen_sv_seed > 0 and args.sv_seed != "1":
logging.error('You cannot use gen_sv_seed and sv_seed options at the same time')
if args.gen_sv_seed > 0:
args.issrun_opts = args.issrun_opts + " +ntb_random_seed_automatic"
log_format = 1
elif args.gen_sv_seed == 0:
args.issrun_opts = args.issrun_opts + " +ntb_random_seed=" + args.sv_seed
args.gen_sv_seed = 1
log_format = 0
else:
logging.error('gen_sv_seed can not take a negative value')
issrun_opts = "\""+args.issrun_opts+"\""
global isspostrun_opts
@ -948,7 +990,22 @@ def main():
os.environ["CVA6_DV_ROOT"] = cwd + "/../env/corev-dv"
setup_logging(args.verbose)
logg = logging.getLogger()
# create file handler which logs even debug messages
#Check gcc version
gcc_path=get_env_var("RISCV_GCC")
version=run_cmd("%s --version" % gcc_path)
gcc_version=re.match(".*\s(\d+\.\d+\.\d+).*", version)
gcc_version=gcc_version.group(1)
version_number=gcc_version.split('.')
if int(version_number[0])<11 :
logging.error('Your are currently using version %s of gcc, please update your version to version 11.1.0 or more to use all features of this script' % gcc_version)
sys.exit(RET_FAIL)
#print environment softwares
logging.info("GCC Version : %s" % (gcc_version))
spike_version=get_env_var("SPIKE_ROOT")
logging.info("Spike Version : %s" % (spike_version))
verilator_version=run_cmd("verilator --version")
logging.info("Verilator Version : %s" % (verilator_version))
# create file handler which logs even debug messages13.1.1
fh = logging.FileHandler('logfile.log')
fh.setLevel(logging.DEBUG)
# create formatter and add it to the handlers
@ -960,188 +1017,201 @@ def main():
cfg = load_config(args, cwd)
# Create output directory
output_dir = create_output(args.o, args.noclean, cwd+"/out_")
#add z,s,x extensions to the isa if there are some
if isa_extension_list !=['']:
for i in isa_extension_list:
if i!= "":
args.isa += (f"_{i}")
if args.verilog_style_check:
logging.debug("Run style check")
style_err = run_cmd("verilog_style/run.sh")
if style_err: logging.info("Found style error: \nERROR: " + style_err)
# Run any handcoded/directed assembly tests specified by args.asm_tests
if args.asm_tests != "":
asm_test = args.asm_tests.split(',')
for path_asm_test in asm_test:
full_path = os.path.expanduser(path_asm_test)
# path_asm_test is a directory
if os.path.isdir(full_path):
run_assembly_from_dir(full_path, args.iss_yaml, args.isa, args.mabi,
args.gcc_opts, args.iss, output_dir,
args.core_setting_dir, args.debug)
# path_asm_test is an assembly file
elif os.path.isfile(full_path) or args.debug:
run_assembly(full_path, args.iss_yaml, args.isa, args.target, args.mabi, args.gcc_opts,
args.iss, output_dir, args.core_setting_dir, args.debug, args.linker)
else:
logging.error('%s does not exist' % full_path)
sys.exit(RET_FAIL)
return
for i in range(args.gen_sv_seed):
test_executed = 0
test_iteration = i
print("")
logging.info("Execution numero : %s" % (i+1))
# Run any handcoded/directed assembly tests specified by args.asm_tests
if args.asm_tests != "":
asm_test = args.asm_tests.split(',')
for path_asm_test in asm_test:
full_path = os.path.expanduser(path_asm_test)
# path_asm_test is a directory
if os.path.isdir(full_path):
run_assembly_from_dir(full_path, args.iss_yaml, args.isa, args.mabi,
args.gcc_opts, args.iss, output_dir,
args.core_setting_dir, args.debug)
# path_asm_test is an assembly file
elif os.path.isfile(full_path) or args.debug:
run_assembly(full_path, args.iss_yaml, args.isa, args.target, args.mabi, args.gcc_opts,
args.iss, output_dir, args.core_setting_dir, args.debug, args.linker)
else:
logging.error('%s does not exist' % full_path)
sys.exit(RET_FAIL)
test_executed = 1
# Run any handcoded/directed c tests specified by args.c_tests
if args.c_tests != "":
c_test = args.c_tests.split(',')
for path_c_test in c_test:
full_path = os.path.expanduser(path_c_test)
# path_c_test is a directory
if os.path.isdir(full_path):
run_c_from_dir(full_path, args.iss_yaml, args.isa, args.mabi,
args.gcc_opts, args.iss, output_dir,
args.core_setting_dir, args.debug)
# path_c_test is a c file
elif os.path.isfile(full_path) or args.debug:
run_c(full_path, args.iss_yaml, args.isa, args.target, args.mabi, args.gcc_opts,
args.iss, output_dir, args.core_setting_dir, args.debug, args.linker)
else:
logging.error('%s does not exist' % full_path)
sys.exit(RET_FAIL)
return
# Run any handcoded/directed c tests specified by args.c_tests
if args.c_tests != "":
c_test = args.c_tests.split(',')
for path_c_test in c_test:
full_path = os.path.expanduser(path_c_test)
# path_c_test is a directory
if os.path.isdir(full_path):
run_c_from_dir(full_path, args.iss_yaml, args.isa, args.mabi,
args.gcc_opts, args.iss, output_dir,
args.core_setting_dir, args.debug)
# path_c_test is a c file
elif os.path.isfile(full_path) or args.debug:
run_c(full_path, args.iss_yaml, args.isa, args.target, args.mabi, args.gcc_opts,
args.iss, output_dir, args.core_setting_dir, args.debug, args.linker)
else:
logging.error('%s does not exist' % full_path)
sys.exit(RET_FAIL)
test_executed = 1
# Run any handcoded/directed elf tests specified by args.elf_tests
if args.elf_tests != "":
elf_test = args.elf_tests.split(',')
for path_elf_test in elf_test:
full_path = os.path.expanduser(path_elf_test)
# path_elf_test is an elf file
if os.path.isfile(full_path) or args.debug:
run_elf(full_path, args.iss_yaml, args.isa, args.target, args.mabi, args.gcc_opts,
args.iss, output_dir, args.core_setting_dir, args.debug)
else:
logging.error('%s does not exist' % full_path)
sys.exit(RET_FAIL)
return
# Run any handcoded/directed elf tests specified by args.elf_tests
if args.elf_tests != "":
elf_test = args.elf_tests.split(',')
for path_elf_test in elf_test:
full_path = os.path.expanduser(path_elf_test)
# path_elf_test is an elf file
if os.path.isfile(full_path) or args.debug:
run_elf(full_path, args.iss_yaml, args.isa, args.target, args.mabi, args.gcc_opts,
args.iss, output_dir, args.core_setting_dir, args.debug)
else:
logging.error('%s does not exist' % full_path)
sys.exit(RET_FAIL)
test_executed = 1
run_cmd_output(["mkdir", "-p", ("%s/asm_tests" % output_dir)])
# Process regression test list
matched_list = []
# Any tests in the YAML test list that specify a directed assembly test
asm_directed_list = []
# Any tests in the YAML test list that specify a directed c test
c_directed_list = []
run_cmd_output(["mkdir", "-p", ("%s/asm_tests" % output_dir)])
# Process regression test list
matched_list = []
# Any tests in the YAML test list that specify a directed assembly test
asm_directed_list = []
# Any tests in the YAML test list that specify a directed c test
c_directed_list = []
if not args.co:
process_regression_list(args.testlist, args.test, args.iterations, matched_list, cwd)
logging.info('CVA6 Configuration is %s'% cfg["hwconfig_opts"])
for entry in list(matched_list):
yaml_needs = entry["needs"] if "needs" in entry else []
if yaml_needs:
needs = dict()
for i in range(len(yaml_needs)):
needs.update(yaml_needs[i])
for keys in needs.keys():
if cfg["hwconfig_opts"][keys] != needs[keys]:
logging.info('Removing test %s CVA6 configuration can not run it' % entry['test'])
matched_list.remove(entry)
break
for t in list(matched_list):
try:
t['gcc_opts'] = re.sub("\<path_var\>", get_env_var(t['path_var']), t['gcc_opts'])
except KeyError:
continue
if test_executed ==0:
if not args.co:
process_regression_list(args.testlist, args.test, args.iterations, matched_list, cwd)
logging.info('CVA6 Configuration is %s'% cfg["hwconfig_opts"])
for entry in list(matched_list):
yaml_needs = entry["needs"] if "needs" in entry else []
if yaml_needs:
needs = dict()
for i in range(len(yaml_needs)):
needs.update(yaml_needs[i])
for keys in needs.keys():
if cfg["hwconfig_opts"][keys] != needs[keys]:
logging.info('Removing test %s CVA6 configuration can not run it' % entry['test'])
matched_list.remove(entry)
break
for t in list(matched_list):
try:
t['gcc_opts'] = re.sub("\<path_var\>", get_env_var(t['path_var']), t['gcc_opts'])
except KeyError:
continue
# Check mutual exclusive between gen_test, asm_tests, and c_tests
if 'asm_tests' in t:
if 'gen_test' in t or 'c_tests' in t:
logging.error('asm_tests must not be defined in the testlist '
'together with the gen_test or c_tests field')
sys.exit(RET_FATAL)
t['asm_tests'] = re.sub("\<path_var\>", get_env_var(t['path_var']), t['asm_tests'])
asm_directed_list.append(t)
matched_list.remove(t)
# Check mutual exclusive between gen_test, asm_tests, and c_tests
if 'asm_tests' in t:
if 'gen_test' in t or 'c_tests' in t:
logging.error('asm_tests must not be defined in the testlist '
'together with the gen_test or c_tests field')
sys.exit(RET_FATAL)
t['asm_tests'] = re.sub("\<path_var\>", get_env_var(t['path_var']), t['asm_tests'])
asm_directed_list.append(t)
matched_list.remove(t)
if 'c_tests' in t:
if 'gen_test' in t or 'asm_tests' in t:
logging.error('c_tests must not be defined in the testlist '
'together with the gen_test or asm_tests field')
sys.exit(RET_FATAL)
t['c_tests'] = re.sub("\<path_var\>", get_env_var(t['path_var']), t['c_tests'])
c_directed_list.append(t)
matched_list.remove(t)
if 'c_tests' in t:
if 'gen_test' in t or 'asm_tests' in t:
logging.error('c_tests must not be defined in the testlist '
'together with the gen_test or asm_tests field')
sys.exit(RET_FATAL)
t['c_tests'] = re.sub("\<path_var\>", get_env_var(t['path_var']), t['c_tests'])
c_directed_list.append(t)
matched_list.remove(t)
if len(matched_list) == 0 and len(asm_directed_list) == 0 and len(c_directed_list) == 0:
sys.exit("Cannot find %s in %s" % (args.test, args.testlist))
if len(matched_list) == 0 and len(asm_directed_list) == 0 and len(c_directed_list) == 0:
sys.exit("Cannot find %s in %s" % (args.test, args.testlist))
for t in c_directed_list:
copy = re.sub(r'(.*)\/(.*).c$', r'cp \1/\2.c \1/', t['c_tests'])+t['test']+'.c'
run_cmd("%s" % copy)
t['c_tests'] = re.sub(r'(.*)\/(.*).c$', r'\1/', t['c_tests'])+t['test']+'.c'
# Run instruction generator
if args.steps == "all" or re.match(".*gen.*", args.steps):
# Run any handcoded/directed assembly tests specified in YAML format
if len(asm_directed_list) != 0:
for test_entry in asm_directed_list:
gcc_opts = args.gcc_opts
gcc_opts += test_entry.get('gcc_opts', '')
path_asm_test = os.path.expanduser(test_entry.get('asm_tests'))
if path_asm_test:
# path_asm_test is a directory
if os.path.isdir(path_asm_test):
run_assembly_from_dir(path_asm_test, args.iss_yaml, args.isa, args.mabi,
gcc_opts, args.iss, output_dir,
args.core_setting_dir, args.debug)
# path_asm_test is an assembly file
elif os.path.isfile(path_asm_test):
run_assembly(path_asm_test, args.iss_yaml, args.isa, args.target, args.mabi, gcc_opts,
args.iss, output_dir, args.core_setting_dir, args.debug, args.linker)
else:
if not args.debug:
logging.error('%s does not exist' % path_asm_test)
sys.exit(RET_FAIL)
for t in c_directed_list:
copy = re.sub(r'(.*)\/(.*).c$', r'cp \1/\2.c \1/', t['c_tests'])+t['test']+'.c'
run_cmd("%s" % copy)
t['c_tests'] = re.sub(r'(.*)\/(.*).c$', r'\1/', t['c_tests'])+t['test']+'.c'
# Run any handcoded/directed C tests specified in YAML format
if len(c_directed_list) != 0:
for test_entry in c_directed_list:
gcc_opts = args.gcc_opts
gcc_opts += test_entry.get('gcc_opts', '')
# Run instruction generator
if args.steps == "all" or re.match(".*gen.*", args.steps):
# Run any handcoded/directed assembly tests specified in YAML format
if len(asm_directed_list) != 0:
for test_entry in asm_directed_list:
gcc_opts = args.gcc_opts
gcc_opts += test_entry.get('gcc_opts', '')
path_asm_test = os.path.expanduser(test_entry.get('asm_tests'))
if path_asm_test:
# path_asm_test is a directory
if os.path.isdir(path_asm_test):
run_assembly_from_dir(path_asm_test, args.iss_yaml, args.isa, args.mabi,
gcc_opts, args.iss, output_dir,
args.core_setting_dir, args.debug)
# path_asm_test is an assembly file
elif os.path.isfile(path_asm_test):
run_assembly(path_asm_test, args.iss_yaml, args.isa, args.target, args.mabi, gcc_opts,
args.iss, output_dir, args.core_setting_dir, args.debug, args.linker)
else:
if not args.debug:
logging.error('%s does not exist' % path_asm_test)
sys.exit(RET_FAIL)
if 'sim_do' in test_entry:
sim_do = test_entry['sim_do'].split(';')
with open("sim.do", "w") as fd:
for cmd in sim_do:
fd.write(cmd + "\n")
logging.info('sim.do: %s' % sim_do)
# Run any handcoded/directed C tests specified in YAML format
if len(c_directed_list) != 0:
for test_entry in c_directed_list:
gcc_opts = args.gcc_opts
gcc_opts += test_entry.get('gcc_opts', '')
path_c_test = os.path.expanduser(test_entry.get('c_tests'))
if path_c_test:
# path_c_test is a directory
if os.path.isdir(path_c_test):
run_c_from_dir(path_c_test, args.iss_yaml, args.isa, args.mabi,
gcc_opts, args.iss, output_dir,
args.core_setting_dir, args.debug)
# path_c_test is a C file
elif os.path.isfile(path_c_test):
run_c(path_c_test, args.iss_yaml, args.isa, args.target, args.mabi, gcc_opts,
args.iss, output_dir, args.core_setting_dir, args.debug, args.linker)
else:
if not args.debug:
logging.error('%s does not exist' % path_c_test)
sys.exit(RET_FAIL)
if 'sim_do' in test_entry:
sim_do = test_entry['sim_do'].split(';')
with open("sim.do", "w") as fd:
for cmd in sim_do:
fd.write(cmd + "\n")
logging.info('sim.do: %s' % sim_do)
# Run remaining tests using the instruction generator
gen(matched_list, cfg, output_dir, cwd)
path_c_test = os.path.expanduser(test_entry.get('c_tests'))
if path_c_test:
# path_c_test is a directory
if os.path.isdir(path_c_test):
run_c_from_dir(path_c_test, args.iss_yaml, args.isa, args.mabi,
gcc_opts, args.iss, output_dir,
args.core_setting_dir, args.debug)
# path_c_test is a C file
elif os.path.isfile(path_c_test):
run_c(path_c_test, args.iss_yaml, args.isa, args.target, args.mabi, gcc_opts,
args.iss, output_dir, args.core_setting_dir, args.debug, args.linker)
else:
if not args.debug:
logging.error('%s does not exist' % path_c_test)
sys.exit(RET_FAIL)
if not args.co:
# Compile the assembly program to ELF, convert to plain binary
if args.steps == "all" or re.match(".*gcc_compile.*", args.steps):
gcc_compile(matched_list, output_dir, args.isa, args.mabi,
args.gcc_opts, args.debug, args.linker)
# Run remaining tests using the instruction generator
gen(matched_list, cfg, output_dir, cwd)
# Run ISS simulation
if args.steps == "all" or re.match(".*iss_sim.*", args.steps):
iss_sim(matched_list, output_dir, args.iss, args.iss_yaml, args.iss_opts,
args.isa, args.target, args.core_setting_dir, args.iss_timeout, args.debug)
if not args.co:
# Compile the assembly program to ELF, convert to plain binary
if args.steps == "all" or re.match(".*gcc_compile.*", args.steps):
gcc_compile(matched_list, output_dir, args.isa, args.mabi,
args.gcc_opts, args.debug, args.linker)
# Compare ISS simulation result
if args.steps == "all" or re.match(".*iss_cmp.*", args.steps):
iss_cmp(matched_list, args.iss, output_dir, args.stop_on_first_error,
args.exp, args.debug)
# Run ISS simulation
if args.steps == "all" or re.match(".*iss_sim.*", args.steps):
iss_sim(matched_list, output_dir, args.iss, args.iss_yaml, args.iss_opts,
args.isa, args.target, args.core_setting_dir, args.iss_timeout, args.debug)
# Compare ISS simulation result
if args.steps == "all" or re.match(".*iss_cmp.*", args.steps):
iss_cmp(matched_list, args.iss, output_dir, args.stop_on_first_error,
args.exp, args.debug)
sys.exit(RET_SUCCESS)
except KeyboardInterrupt:
@ -1149,6 +1219,7 @@ def main():
sys.exit(130)
if __name__ == "__main__":
sys.path.append(os.getcwd()+"/../../core-v-cores/cva6")
sys.path.append(os.getcwd()+"/../../core-v-cores/cva6/util")
from config_pkg_generator import *
main()

View file

@ -14,8 +14,11 @@
path_var: RTL_PATH
tool_path: SPIKE_PATH
tb_path: TB_PATH
# Set a limit of 2M steps for Spike to match the RVFI 2M cycles RTL timeout.
# Always keep this value in sync with the settings of RTL simulators (cf.
# <issrun_opts> values below).
cmd: >
make spike variant=<variant> elf=<elf> tool_path=<tool_path> log=<log>
make spike steps=2000000 variant=<variant> elf=<elf> tool_path=<tool_path> log=<log>
###############################################################################
# Verilator
@ -50,3 +53,13 @@
tb_path: TB_PATH
cmd: >
make vcs-uvm target=<target> cov=${cov} variant=<variant> elf=<elf> tool_path=<tool_path> isscomp_opts=<isscomp_opts> issrun_opts=<issrun_opts> isspostrun_opts=<isspostrun_opts> log=<log>
###############################################################################
# Questasim specific commands, variables
###############################################################################
- iss: questa-testharness
path_var: RTL_PATH
tool_path: SPIKE_PATH
tb_path: TB_PATH
cmd: >
make questa-testharness target=<target> variant=<variant> elf=<elf> path_var=<path_var> tool_path=<tool_path> isscomp_opts=<isscomp_opts> issrun_opts=<issrun_opts> isspostrun_opts=<isspostrun_opts> log=<log>

View file

@ -28,6 +28,187 @@
# gcc_opts : gcc compile options
# --------------------------------------------------------------------------------
- test: riscv_mmu_stress_test
description: >
Test with different patterns of load/store instructions, stress test MMU
operations.
gen_opts: >
+instr_cnt=500
+num_of_sub_program=5
+directed_instr_0=riscv_load_store_rand_instr_stream,10
+directed_instr_1=riscv_load_store_hazard_instr_stream,10
+directed_instr_2=riscv_multi_page_load_store_instr_stream,10
+directed_instr_3=riscv_mem_region_stress_test,10
+disable_compressed_instr=0
iterations: 2
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_mmu_stress_hint_test
description: >
Test with different patterns of load/store instructions, stress test MMU
operations.
gen_opts: >
+instr_cnt=500
+num_of_sub_program=5
+directed_instr_0=riscv_load_store_rand_instr_stream,10
+directed_instr_1=riscv_load_store_hazard_instr_stream,10
+directed_instr_2=riscv_multi_page_load_store_instr_stream,10
+directed_instr_3=riscv_mem_region_stress_test,10
+hint_instr_ratio=500
iterations: 2
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_rand_jump_illegal_test
description: >
Jump among large number of sub-programs, stress testing iTLB operations.
gen_opts: >
+instr_cnt=300
+num_of_sub_program=0
+directed_instr_0=riscv_load_store_rand_instr_stream,10
+directed_instr_1=riscv_jal_instr,20
+illegal_instr_ratio=100
+tvec_alignment=8
iterations: 2
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_rand_jump_hint_comp_test
description: >
Jump among large number of sub-programs, stress testing iTLB operations.
gen_opts: >
+instr_cnt=500
+num_of_sub_program=0
+directed_instr_1=riscv_jal_instr,70
+hint_instr_ratio=500
iterations: 2
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_rand_jump_no_cmp_test
description: >
Jump among large number of sub-programs, stress testing iTLB operations.
gen_opts: >
+instr_cnt=500
+num_of_sub_program=0
+directed_instr_0=riscv_jal_instr,70
+disable_compressed_instr=1
iterations: 2
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_load_store_test
description: >
Unaligned load/store test
gen_opts: >
+instr_cnt=500
+num_of_sub_program=0
+no_load_store=0
+no_branch_jump=0
+directed_instr_0=riscv_load_store_rand_instr_stream,70
+directed_instr_1=riscv_load_store_hazard_instr_stream,50
+disable_compressed_instr=0
iterations: 2
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_load_store_cmp_test
description: >
Unaligned load/store test
gen_opts: >
+instr_cnt=500
+num_of_sub_program=0
+no_load_store=0
+no_branch_jump=0
+directed_instr_0=riscv_load_store_rand_instr_stream,20
+directed_instr_1=riscv_load_store_hazard_instr_stream,50
+disable_compressed_instr=1
iterations: 2
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_load_store_hazard_test
description: >
Arithmetic instruction test, no load/store/branch instructions no compressed
gen_opts: >
+instr_cnt=500
+num_of_sub_program=0
+no_fence=1
+directed_instr_1=riscv_multi_page_load_store_instr_stream,20
+no_data_page=0
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=1
+disable_compressed_instr=0
iterations: 2
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_arithmetic_basic_xif_test
description: >
Arithmetic instruction test, no load/store/branch instructions no compressed
gen_opts: >
+instr_cnt=500
+num_of_sub_program=0
+no_fence=1
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=1
+enable_x_extension=1
+disable_compressed_instr=1
+tvec_alignment=8
iterations: 2
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_arithmetic_basic_xif_illegal_test
description: >
Arithmetic instruction test, no load/store/branch instructions
gen_opts: >
+instr_cnt=500
+num_of_sub_program=0
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=1
+enable_x_extension=1
+illegal_instr_ratio=100
+tvec_alignment=8
iterations: 2
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_load_store_xif_test
description: >
Unaligned load/store test
gen_opts: >
+instr_cnt=500
+num_of_sub_program=0
+no_load_store=0
+no_branch_jump=1
+directed_instr_0=riscv_load_store_rand_instr_stream,20
+directed_instr_1=riscv_load_store_hazard_instr_stream,50
+tvec_alignment=8
+enable_x_extension=1
iterations: 2
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_rand_jump_xif_test
description: >
Jump among large number of sub-programs, stress testing iTLB operations.
gen_opts: >
+instr_cnt=500
+num_of_sub_program=0
+directed_instr_1=riscv_jal_instr,70
+enable_x_extension=1
+tvec_alignment=8
iterations: 2
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_arithmetic_basic_test_no_comp
description: >
Arithmetic instruction test, no load/store/branch instructions no compressed
@ -42,58 +223,90 @@
+no_csr_instr=1
+disable_compressed_instr=1
iterations: 2
gen_test: riscv_instr_base_test
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_arithmetic_basic_csr_test
- test: riscv_arithmetic_basic_test_comp
description: >
Arithmetic instruction test, with CSR instructions
Arithmetic instruction test, no load/store/branch instructions no compressed
gen_opts: >
+instr_cnt=300
+instr_cnt=500
+num_of_sub_program=0
+directed_instr_0=riscv_int_numeric_corner_stream,5
+directed_instr_0=riscv_int_numeric_corner_stream,4
+no_fence=1
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=1
iterations: 2
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_arithmetic_basic_test_bcomp
description: >
Arithmetic instruction test, no load/store/branch instructions no compressed
gen_opts: >
+instr_cnt=500
+num_of_sub_program=0
+directed_instr_0=riscv_int_numeric_corner_stream,4
+no_fence=1
+no_data_page=1
+no_branch_jump=0
+boot_mode=m
+no_csr_instr=1
iterations: 2
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_arithmetic_basic_sub_prog_test
description: >
Arithmetic instruction test, no load/store/branch instructions no compressed
gen_opts: >
+instr_cnt=500
+num_of_sub_program=20
+no_fence=1
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=1
iterations: 2
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_arithmetic_basic_illegal
description: >
Arithmetic instruction test, no load/store/branch instructions
gen_opts: >
+instr_cnt=500
+num_of_sub_program=0
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=1
+illegal_instr_ratio=100
+tvec_alignment=8
iterations: 2
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_unaligned_load_store_test
description: >
Unaligned load/store test
gcc_opts: >
-mno-strict-align
gen_opts: >
+instr_cnt=100
+num_of_sub_program=0
+no_branch_jump=1
+no_data_page=0
+use_push_data_section=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=0
+enable_illegal_csr_instruction=1
+directed_instr_0=riscv_load_store_rand_instr_stream,20
+directed_instr_1=riscv_load_store_hazard_instr_stream,20
+enable_unaligned_load_store=1
+tvec_alignment=8
+disable_compressed_instr=1
+enable_x_extension=1
iterations: 2
gen_test: riscv_instr_base_test
rtl_test: core_base_test
- test: riscv_arithmetic_basic_rand_prvl
description: >
Arithmetic instruction test, no load/store/branch instructions
gen_opts: >
+instr_cnt=500
+num_of_sub_program=5
+directed_instr_0=riscv_int_numeric_corner_stream,4
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+enable_dummy_csr_write=1
+enable_access_invalid_csr_level=1
iterations: 2
gen_test: riscv_instr_base_test
rtl_test: core_base_test
- test: riscv_arithmetic_basic_hint_csr_test
description: >
Arithmetic instruction test, no load/store/branch instructions
gen_opts: >
+instr_cnt=500
+num_of_sub_program=5
+directed_instr_0=riscv_int_numeric_corner_stream,4
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=0
+enable_illegal_csr_instruction=1
+hint_instr_ratio=500
iterations: 2
gen_test: riscv_instr_base_test
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_arithmetic_basic_illegal_csr
@ -107,27 +320,11 @@
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=0
+enable_illegal_csr_instruction=1
+illegal_instr_ratio=100
iterations: 2
gen_test: riscv_instr_base_test
rtl_test: core_base_test
- test: riscv_arithmetic_basic_comp_csr
description: >
Arithmetic instruction test, no load/store/branch instructions
gen_opts: >
+instr_cnt=500
+num_of_sub_program=5
+directed_instr_0=riscv_int_numeric_corner_stream,4
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=0
+enable_illegal_csr_instruction=1
+enable_access_invalid_csr_level=1
+disable_compressed_instr=1
+tvec_alignment=8
iterations: 2
gen_test: riscv_instr_base_test
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_arithmetic_basic_csr_dummy
@ -143,24 +340,7 @@
+enable_dummy_csr_write=1
+no_csr_instr=0
iterations: 2
gen_test: riscv_instr_base_test
rtl_test: core_base_test
- test: riscv_arithmetic_basic_dret
description: >
Arithmetic instruction test, no load/store/branch instructions
gen_opts: >
+instr_cnt=500
+num_of_sub_program=10
+directed_instr_0=riscv_int_numeric_corner_stream,4
+no_fence=1
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=1
+no_dret=0
iterations: 2
gen_test: riscv_instr_base_test
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_arithmetic_basic_Randcsr_test
@ -177,118 +357,10 @@
+no_csr_instr=0
+randomize_csr=1
+enable_acess_invalid_csr_level=1
+tvec_alignment=8
iterations: 2
gen_test: riscv_instr_base_test
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_arithmetic_basic_illegal_test
description: >
Arithmetic instruction test, no load/store/branch instructions
gen_opts: >
+instr_cnt=300
+num_of_sub_program=0
+directed_instr_0=riscv_int_numeric_corner_stream,4
+no_fence=1
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=1
+illegal_instr_ratio=100
iterations: 2
gen_test: riscv_instr_base_test
rtl_test: core_base_test
- test: riscv_arithmetic_basic_illegal_fP
description: >
Arithmetic instruction test, no load/store/branch instructions
gen_opts: >
+instr_cnt=200
+num_of_sub_program=2
+directed_instr_0=riscv_int_numeric_corner_stream,5
+no_fence=1
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=1
+enable_floating_point=1
+illegal_instr_ratio=50
iterations: 2
gen_test: riscv_instr_base_test
rtl_test: core_base_test
- test: riscv_arithmetic_basic_floating_test
description: >
Arithmetic instruction test, no load/store/branch instructions
gen_opts: >
+instr_cnt=500
+num_of_sub_program=0
+directed_instr_0=riscv_int_numeric_corner_stream,5
+no_fence=0
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=1
+enable_floating_point=1
iterations: 2
gen_test: riscv_instr_base_test
rtl_test: core_base_test
- test: riscv_arithmetic_basic_csr_exp_fp
description: >
Arithmetic instruction test, no load/store/branch instructions
gen_opts: >
+instr_cnt=500
+num_of_sub_program=0
+directed_instr_0=riscv_int_numeric_corner_stream,5
+no_fence=0
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=0
+enable_illegal_csr_instruction=1
+enable_page_table_exception=1
+enable_floating_point=1
iterations: 2
gen_test: riscv_instr_base_test
rtl_test: core_base_test
- test: riscv_arithmetic_basic_hint_exp_fp
description: >
Arithmetic instruction test, no load/store/branch instructions
gen_opts: >
+instr_cnt=500
+num_of_sub_program=0
+directed_instr_0=riscv_int_numeric_corner_stream,5
+no_fence=0
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=0
+enable_illegal_csr_instruction=1
+enable_page_table_exception=1
+enable_floating_point=1
+hint_instr_ratio=500
iterations: 2
gen_test: riscv_instr_base_test
rtl_test: core_base_test
- test: riscv_arithmetic_basic_exp_csr
description: >
Arithmetic instruction test, no load/store/branch instructions
gen_opts: >
+instr_cnt=500
+num_of_sub_program=0
+directed_instr_0=riscv_int_numeric_corner_stream,5
+no_fence=0
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=0
+enable_illegal_csr_instruction=1
+enable_page_table_exception=1
iterations: 2
gen_test: riscv_instr_base_test
rtl_test: core_base_test
- test: riscv_arithmetic_basic_hint_illegal_csr
description: >
@ -303,10 +375,10 @@
+boot_mode=m
+no_csr_instr=0
+enable_illegal_csr_instruction=1
+illegal_instr_ratio=50
+hint_instr_ratio=150
+tvec_alignment=8
iterations: 2
gen_test: riscv_instr_base_test
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_arithmetic_basic_illegal_hint_test
@ -324,8 +396,9 @@
+no_csr_instr=1
+illegal_instr_ratio=200
+hint_instr_ratio=500
+tvec_alignment=8
iterations: 2
gen_test: riscv_instr_base_test
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_arithmetic_basic_hint_test
@ -340,72 +413,94 @@
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=1
+enable_interrupt=1
+enable_timer_irq=1
+hint_instr_ratio=500
iterations: 2
gen_test: riscv_instr_base_test
rtl_test: core_base_test
- test: riscv_arithmetic_basic_illegal_hint_floating_test
description: >
Arithmetic instruction test, no load/store/branch instructions
gen_opts: >
+instr_cnt=300
+num_of_sub_program=10
+directed_instr_0=riscv_int_numeric_corner_stream,4
+no_fence=1
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=1
+enable_floating_point=1
+illegal_instr_ratio=100
+hint_instr_ratio=200
iterations: 2
gen_test: riscv_instr_base_test
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_arithmetic_basic_illegal_no_comp_test
- test: riscv_arithmetic_basic_loop_test
description: >
Arithmetic instruction test, no load/store/branch instructions
gen_opts: >
+instr_cnt=500
+num_of_sub_program=10
+directed_instr_0=riscv_int_numeric_corner_stream,4
+directed_instr_1=riscv_loop_instr,2
+no_fence=1
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=1
+hint_instr_ratio=200
+illegal_instr_ratio=50
+disable_compressed_instr=1
iterations: 2
gen_test: riscv_instr_base_test
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_rand_data_obi_err
- test: riscv_arithmetic_basic_ebreak_dret_test
description: >
RISCV-DV generated random debug tests
Arithmetic instruction test, no load/store/branch instructions
gen_opts: >
+instr_cnt=200
+num_of_sub_program=5
+directed_instr_0=riscv_load_store_rand_instr_stream,4
+directed_instr_1=riscv_loop_instr,4
+directed_instr_2=riscv_hazard_instr_stream,4
+directed_instr_3=riscv_load_store_hazard_instr_stream,4
+directed_instr_4=riscv_multi_page_load_store_instr_stream,4
+directed_instr_5=riscv_mem_region_stress_test,4
+directed_instr_6=riscv_jal_instr,4
+hint_instr_ratio=20
+randomize_csr=1
+instr_cnt=500
+num_of_sub_program=0
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=0
+enable_interrupt=1
+enable_fast_interrupt_handler=1
+no_wfi=0
+enable_ebreak_in_debug_rom=0
+set_dcsr_ebreak=0
+enable_debug_single_step=1
iterations: 1
gen_test: riscv_instr_base_test
+no_csr_instr=1
+no_ebreak=0
+no_dret=0
+no_fence=0
+tvec_alignment=8
iterations: 2
gen_test: cva6_instr_base_test_c
rtl_test: core_base_test
- test: riscv_arithmetic_basic_same_reg_test
description: >
Arithmetic instruction test, no load/store/branch instructions no compressed
gen_opts: >
+instr_cnt=1000
+num_of_sub_program=0
+no_fence=1
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=1
+enable_same_reg=1
+disable_compressed_instr=1
iterations: 2
gen_test: cva6_instr_hazard_test_c
rtl_test: core_base_test
- test: riscv_arithmetic_basic_hazard_rdrs1_test
description: >
Arithmetic instruction test, no load/store/branch instructions no compressed
gen_opts: >
+instr_cnt=1000
+num_of_sub_program=0
+no_fence=1
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=1
+enable_rdrs1_hazard=1
+disable_compressed_instr=1
iterations: 2
gen_test: cva6_instr_hazard_test_c
rtl_test: core_base_test
- test: riscv_arithmetic_basic_hazard_rdrs2_test
description: >
Arithmetic instruction test, no load/store/branch instructions no compressed
gen_opts: >
+instr_cnt=1000
+num_of_sub_program=0
+no_fence=1
+no_data_page=1
+no_branch_jump=1
+boot_mode=m
+no_csr_instr=1
+enable_rdrs2_hazard=1
+disable_compressed_instr=1
iterations: 2
gen_test: cva6_instr_hazard_test_c
rtl_test: core_base_test

View file

@ -29,6 +29,8 @@
${CVA6_REPO_DIR}/corev_apu/riscv-dbg/src/dm_pkg.sv
${CVA6_REPO_DIR}/corev_apu/axi_mem_if/src/axi2mem.sv
${CVA6_REPO_DIR}/corev_apu/tb/ariane_soc_pkg.sv
${CVA6_REPO_DIR}/corev_apu/tb/axi_intf.sv
${CVA6_REPO_DIR}/corev_apu/tb/ariane_axi_pkg.sv
// RVFI tracer
${CVA6_REPO_DIR}/corev_apu/tb/rvfi_tracer.sv

View file

@ -34,20 +34,19 @@ import "DPI-C" function read_elf(input string filename);
import "DPI-C" function byte get_section(output longint address, output longint len);
import "DPI-C" context function void read_section(input longint address, inout byte buffer[]);
module cva6_tb_wrapper
import uvmt_cva6_pkg::*;
#(
parameter int unsigned AXI_USER_WIDTH = 1,
module cva6_tb_wrapper import uvmt_cva6_pkg::*; #(
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
parameter bit IsRVFI = 1'b0,
parameter type rvfi_instr_t = logic,
//
parameter int unsigned AXI_USER_EN = 0,
parameter int unsigned AXI_ADDRESS_WIDTH = 64,
parameter int unsigned AXI_DATA_WIDTH = 64,
parameter int unsigned NUM_WORDS = 2**25
) (
input logic clk_i,
input logic rst_ni,
input logic [XLEN-1:0] boot_addr_i,
output logic [31:0] tb_exit_o,
output ariane_pkg::rvfi_port_t rvfi_o,
output rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_o,
input cvxif_pkg::cvxif_resp_t cvxif_resp,
output cvxif_pkg::cvxif_req_t cvxif_req,
uvma_axi_intf axi_slave,
@ -60,10 +59,13 @@ module cva6_tb_wrapper
static uvm_cmdline_processor uvcl = uvm_cmdline_processor::get_inst();
string binary = "";
ariane_pkg::rvfi_port_t rvfi;
rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi;
assign rvfi_o = rvfi;
cva6 #(
.CVA6Cfg ( CVA6Cfg ),
.IsRVFI ( IsRVFI ),
//
.ArianeCfg ( ariane_soc::ArianeSocCfg )
) i_cva6 (
.clk_i ( clk_i ),
@ -77,8 +79,8 @@ module cva6_tb_wrapper
.rvfi_o ( rvfi ),
.cvxif_req_o ( cvxif_req ),
.cvxif_resp_i ( cvxif_resp ),
.axi_req_o ( axi_ariane_req ),
.axi_resp_i ( axi_ariane_resp )
.noc_req_o ( axi_ariane_req ),
.noc_resp_i ( axi_ariane_resp )
);
//----------------------------------------------------------------------------
@ -86,10 +88,12 @@ module cva6_tb_wrapper
//----------------------------------------------------------------------------
rvfi_tracer #(
.CVA6Cfg(CVA6Cfg),
.rvfi_instr_t(rvfi_instr_t),
//
.HART_ID(8'h0),
.DEBUG_START(0),
.DEBUG_STOP(0),
.NR_COMMIT_PORTS(ariane_pkg::NR_COMMIT_PORTS)
.DEBUG_STOP(0)
) rvfi_tracer_i (
.clk_i(clk_i),
.rst_ni(rst_ni),
@ -103,12 +107,12 @@ module cva6_tb_wrapper
logic req;
logic we;
logic [AXI_ADDRESS_WIDTH-1:0] addr;
logic [AXI_DATA_WIDTH/8-1:0] be;
logic [AXI_DATA_WIDTH-1:0] wdata;
logic [AXI_USER_WIDTH-1:0] wuser;
logic [AXI_DATA_WIDTH-1:0] rdata;
logic [AXI_USER_WIDTH-1:0] ruser;
logic [CVA6Cfg.AxiAddrWidth-1:0] addr;
logic [CVA6Cfg.AxiDataWidth/8-1:0] be;
logic [CVA6Cfg.AxiDataWidth-1:0] wdata;
logic [CVA6Cfg.AxiUserWidth-1:0] wuser;
logic [CVA6Cfg.AxiDataWidth-1:0] rdata;
logic [CVA6Cfg.AxiUserWidth-1:0] ruser;
//Response structs
assign axi_ariane_resp.aw_ready = (axi_switch_vif.active) ? axi_slave.aw_ready : cva6_axi_bus.aw_ready;
@ -181,10 +185,10 @@ module cva6_tb_wrapper
AXI_BUS #(
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
.AXI_ADDR_WIDTH ( CVA6Cfg.AxiAddrWidth ),
.AXI_DATA_WIDTH ( CVA6Cfg.AxiDataWidth ),
.AXI_ID_WIDTH ( ariane_soc::IdWidthSlave ),
.AXI_USER_WIDTH ( AXI_USER_WIDTH )
.AXI_USER_WIDTH ( CVA6Cfg.AxiUserWidth )
) cva6_axi_bus();
axi_master_connect #(
@ -196,9 +200,9 @@ module cva6_tb_wrapper
axi2mem #(
.AXI_ID_WIDTH ( ariane_soc::IdWidthSlave ),
.AXI_ADDR_WIDTH ( AXI_ADDRESS_WIDTH ),
.AXI_DATA_WIDTH ( AXI_DATA_WIDTH ),
.AXI_USER_WIDTH ( AXI_USER_WIDTH )
.AXI_ADDR_WIDTH ( CVA6Cfg.AxiAddrWidth ),
.AXI_DATA_WIDTH ( CVA6Cfg.AxiDataWidth ),
.AXI_USER_WIDTH ( CVA6Cfg.AxiUserWidth )
) i_cva6_axi2mem (
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
@ -214,8 +218,8 @@ module cva6_tb_wrapper
);
sram #(
.USER_WIDTH ( AXI_USER_WIDTH ),
.DATA_WIDTH ( AXI_DATA_WIDTH ),
.USER_WIDTH ( CVA6Cfg.AxiUserWidth ),
.DATA_WIDTH ( CVA6Cfg.AxiDataWidth ),
.USER_EN ( AXI_USER_EN ),
.SIM_INIT ( "zeros" ),
.NUM_WORDS ( NUM_WORDS )
@ -224,7 +228,7 @@ module cva6_tb_wrapper
.rst_ni ( rst_ni ),
.req_i ( req ),
.we_i ( we ),
.addr_i ( addr[$clog2(NUM_WORDS)-1+$clog2(AXI_DATA_WIDTH/8):$clog2(AXI_DATA_WIDTH/8)] ),
.addr_i ( addr[$clog2(NUM_WORDS)-1+$clog2(CVA6Cfg.AxiDataWidth/8):$clog2(CVA6Cfg.AxiDataWidth/8)] ),
.wuser_i ( wuser ),
.wdata_i ( wdata ),
.be_i ( be ),

View file

@ -84,14 +84,14 @@ module uvmt_cva6_axi_assert (uvma_axi_intf axi_assert, input bit clk, input rst
@(posedge clk) disable iff (!rst_n) axi_assert.ar_valid |-> axi_assert.ar_burst == 1;
endproperty
//Check if all write transaction performed by CVA6 are equal to 0 or 1
//Check if all write transaction performed by CVA6 are equal to 0
property AXI4_CVA6_AWLEN;
@(posedge clk) disable iff (!rst_n) axi_assert.aw_valid |-> axi_assert.aw_len == 0;
endproperty
//Check if all Read transaction performed by CVA6 are equal to 0 or 1
property AXI4_CVA6_ARLEN;
@(posedge clk) disable iff (!rst_n) axi_assert.ar_valid |-> axi_assert.ar_len == 1;
@(posedge clk) disable iff (!rst_n) axi_assert.ar_valid |-> axi_assert.ar_len == 0 || axi_assert.ar_len == 1;
endproperty
/********************************************** Assert Property ******************************************************/

View file

@ -14,10 +14,12 @@
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
module uvmt_cva6_dut_wrap # ( parameter int unsigned AXI_USER_WIDTH = 1,
module uvmt_cva6_dut_wrap # (
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
parameter bit IsRVFI = 1'b0,
parameter type rvfi_instr_t = logic,
//
parameter int unsigned AXI_USER_EN = 0,
parameter int unsigned AXI_ADDRESS_WIDTH = 64,
parameter int unsigned AXI_DATA_WIDTH = 64,
parameter int unsigned NUM_WORDS = 2**25
)
@ -28,16 +30,17 @@ module uvmt_cva6_dut_wrap # ( parameter int unsigned AXI_USER_WIDTH = 1,
uvmt_axi_switch_intf axi_switch_vif,
uvme_cva6_core_cntrl_if core_cntrl_if,
output logic[31:0] tb_exit_o,
output ariane_pkg::rvfi_port_t rvfi_o
output rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_o
);
cva6_tb_wrapper #(
.AXI_USER_WIDTH (AXI_USER_WIDTH),
.CVA6Cfg ( CVA6Cfg ),
.IsRVFI ( IsRVFI ),
.rvfi_instr_t ( rvfi_instr_t ),
//
.AXI_USER_EN (AXI_USER_EN),
.AXI_ADDRESS_WIDTH (AXI_ADDRESS_WIDTH),
.AXI_DATA_WIDTH (AXI_DATA_WIDTH),
.NUM_WORDS (NUM_WORDS)
)
cva6_tb_wrapper_i (

View file

@ -30,10 +30,36 @@ module uvmt_cva6_tb;
import uvmt_cva6_pkg::*;
import uvme_cva6_pkg::*;
localparam AXI_USER_WIDTH = ariane_pkg::AXI_USER_WIDTH;
// CVA6 config
localparam config_pkg::cva6_cfg_t CVA6Cfg = cva6_config_pkg::cva6_cfg;
localparam bit IsRVFI = bit'(cva6_config_pkg::CVA6ConfigRvfiTrace);
localparam type rvfi_instr_t = struct packed {
logic [config_pkg::NRET-1:0] valid;
logic [config_pkg::NRET*64-1:0] order;
logic [config_pkg::NRET*config_pkg::ILEN-1:0] insn;
logic [config_pkg::NRET-1:0] trap;
logic [config_pkg::NRET*riscv::XLEN-1:0] cause;
logic [config_pkg::NRET-1:0] halt;
logic [config_pkg::NRET-1:0] intr;
logic [config_pkg::NRET*2-1:0] mode;
logic [config_pkg::NRET*2-1:0] ixl;
logic [config_pkg::NRET*5-1:0] rs1_addr;
logic [config_pkg::NRET*5-1:0] rs2_addr;
logic [config_pkg::NRET*riscv::XLEN-1:0] rs1_rdata;
logic [config_pkg::NRET*riscv::XLEN-1:0] rs2_rdata;
logic [config_pkg::NRET*5-1:0] rd_addr;
logic [config_pkg::NRET*riscv::XLEN-1:0] rd_wdata;
logic [config_pkg::NRET*riscv::XLEN-1:0] pc_rdata;
logic [config_pkg::NRET*riscv::XLEN-1:0] pc_wdata;
logic [config_pkg::NRET*riscv::VLEN-1:0] mem_addr;
logic [config_pkg::NRET*riscv::PLEN-1:0] mem_paddr;
logic [config_pkg::NRET*(riscv::XLEN/8)-1:0] mem_rmask;
logic [config_pkg::NRET*(riscv::XLEN/8)-1:0] mem_wmask;
logic [config_pkg::NRET*riscv::XLEN-1:0] mem_rdata;
logic [config_pkg::NRET*riscv::XLEN-1:0] mem_wdata;
};
localparam AXI_USER_EN = ariane_pkg::AXI_USER_EN;
localparam AXI_ADDRESS_WIDTH = 64;
localparam AXI_DATA_WIDTH = 64;
localparam NUM_WORDS = 2**24;
// ENV (testbench) parameters
@ -53,8 +79,10 @@ module uvmt_cva6_tb;
);
uvmt_axi_switch_intf axi_switch_vif();
uvme_cva6_core_cntrl_if core_cntrl_if();
uvma_rvfi_instr_if#(uvme_cva6_pkg::ILEN,uvme_cva6_pkg::XLEN)
rvfi_instr_if [uvme_cva6_pkg::RVFI_NRET-1:0]();
uvma_rvfi_instr_if #(
uvme_cva6_pkg::ILEN,
uvme_cva6_pkg::XLEN
) rvfi_instr_if [uvme_cva6_pkg::RVFI_NRET-1:0] ();
uvma_rvfi_csr_if#(uvme_cva6_pkg::XLEN) rvfi_csr_if [uvme_cva6_pkg::RVFI_NRET-1:0]();
@ -71,7 +99,11 @@ module uvmt_cva6_tb;
.rst_n(clknrst_if.reset_n)
);
// DUT Wrapper Interfaces
uvmt_rvfi_if rvfi_if(
uvmt_rvfi_if #(
// RVFI
.rvfi_instr_t ( rvfi_instr_t ),
.CVA6Cfg ( CVA6Cfg )
) rvfi_if(
.rvfi_o(),
.tb_exit_o()
); // Status information generated by the Virtual Peripherals in the DUT WRAPPER memory.
@ -81,10 +113,11 @@ module uvmt_cva6_tb;
*/
uvmt_cva6_dut_wrap #(
.AXI_USER_WIDTH (AXI_USER_WIDTH),
.CVA6Cfg ( CVA6Cfg ),
.IsRVFI ( IsRVFI ),
.rvfi_instr_t ( rvfi_instr_t ),
//
.AXI_USER_EN (AXI_USER_EN),
.AXI_ADDRESS_WIDTH (AXI_ADDRESS_WIDTH),
.AXI_DATA_WIDTH (AXI_DATA_WIDTH),
.NUM_WORDS (NUM_WORDS)
) cva6_dut_wrap (
.clknrst_if(clknrst_if),

View file

@ -21,8 +21,11 @@
`define __UVMT_CVA6_TB_IFS_SV__
interface uvmt_rvfi_if (
output ariane_pkg::rvfi_port_t rvfi_o,
interface uvmt_rvfi_if #(
parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty,
parameter type rvfi_instr_t = logic
) (
output rvfi_instr_t [CVA6Cfg.NrCommitPorts-1:0] rvfi_o,
output logic[31:0] tb_exit_o
);

View file

@ -10,12 +10,10 @@
#define LOAD_RS(rs,value) li rs, value
#define COMP_RS(rs1,rs2,rd) xor rd, rs1, rs2
#define CUS_ADD(rs1,rs2,rs3,rd) .word 0b##0000000##rs2####rs1##000##rd##1111011
#define CUS_NOP(rs1,rs2,rs3,rd) .word 0b##0000000##00000####00000##000##00000##1111011
#define CUS_NOP_EXC(rs1,rs2,rs3,rd) .word 0b##0100000##00000####00000##000##00000##1111011
#define CUS_ISS_EXC(rs1,rs2,rs3,rd) .word 0b##1100000##00000####00000##000##00000##1111011
#define CUS_ADD(rs1,rs2,rd) .word 0b##0000000##rs2####rs1##001##rd##1111011
#define CUS_NOP(rs1,rs2,rd) .word 0b##0000000##00000####00000##000##00000##1111011
#define CUS_ADD_RS3(rs1,rs2,rs3,rd) .word 0b##rs3##01##rs2####rs1##000##rd##1111011
#define CUS_ADD_MULTI(rs1,rs2,rs3,rd) .word 0b##0001000##rs2####rs1##000##rd##1111011
#define CUS_EXC(rs1,rs2,rs3,rd) .word 0b####1000000##00000####rs1##000##00000##1111011
#define CUS_M_ADD(rs1,rs2,rs3,rd) .word 0b####0000010##rs2####rs1##011##rd##1111011
#define CUS_S_ADD(rs1,rs2,rs3,rd) .word 0b####0000110##rs2####rs1##001##rd##1111011
#define CUS_ADD_MULTI(rs1,rs2,rd) .word 0b##0001000##rs2####rs1##000##rd##1111011
#define CUS_EXC(rs1,rs2,rs3,rd) .word 0b####1100000##rs2####rs1##010##rd##1111011
#define CUS_U_ADD(rs1,rs2,rd) .word 0b####0000010##rs2####rs1##000##rd##1111011
#define CUS_S_ADD(rs1,rs2,rd) .word 0b####0000110##rs2####rs1##000##rd##1111011

View file

@ -0,0 +1,73 @@
# Copyright 2023 Thales DIS
#
# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
# You may obtain a copy of the License at https://solderpad.org/licenses/
#
# Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
#include "cvxif_macros.h"
#*****************************************************************************
# cvxif_s_mode.S
#-----------------------------------------------------------------------------
#
.globl main
main:
## set start address range t0 x7
la x7, supervisor_code
li x28, 0x10000
add x7, x7, x28
# Enable R,W,X,TOR IN PMPCFG CSR t0 x8
li x8, 0x0F
#set PMPADDR0 CSR with x7
csrw 0x3B0, x7
# set PMPCFG0 CSR with x8
csrw 0x3A0, x8
# Set the MPP field to supervisor mode (1)
li x29, 0b01
slli x29, x29, 11
or x28, x28, x29
# Write the modified MSTATUS value back to the CSR
csrw 0x300, x28
# Load address of supervisor code
la x28, supervisor_code
#set MEPC register to address of supervisor code
csrw 0x341, x28
csrr x31, 0x300
mret
supervisor_code:
CUS_S_ADD(01010,01010,01011);
CUS_S_ADD(01010,11111,11010);
CUS_ADD_MULTI(01010,01010,01011);
CUS_ADD(11010,11001,11011);
CUS_ADD(01010,01010,01011);
CUS_S_ADD(10000,00010,00000);
CUS_S_ADD(11111,11110,11111);
CUS_S_ADD(00000,01010,01011);
CUS_S_ADD(01010,01010,01011);
CUS_ADD_MULTI(01010,00000,01011);
CUS_S_ADD(11111,11111,01011);
# (example of) final self-check test
li a0, 0xCAFE;
li a1, 0xCAFE;
xor a2, a0, a1;
beqz a2, pass;
fail:
# Failure post-processing (messages, ecall setup etc.)
li a0, 0x0;
jal exit;
pass:
# Success post-processing (messages, ecall setup etc.)
li a0, 0x0;
jal exit;

View file

@ -0,0 +1,73 @@
# Copyright 2023 Thales DIS
#
# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
# You may obtain a copy of the License at https://solderpad.org/licenses/
#
# Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
#include "cvxif_macros.h"
#*****************************************************************************
# cvxif_s_mode.S
#-----------------------------------------------------------------------------
#
.globl main
main:
## set start address range t0 x7
la x7, user_code
li x28, 0x10000
add x7, x7, x28
# Enable R,W,X,TOR IN PMPCFG CSR t0 x8
li x8, 0x0F
#set PMPADDR0 CSR with x7
csrw 0x3B0, x7
# set PMPCFG0 CSR with x8
csrw 0x3A0, x8
# Set the MPP field to user mode (0)
li x29, 0b00
slli x29, x29, 11
or x28, x28, x29
# Write the modified MSTATUS value back to the CSR
csrw 0x300, x28
# Load address of user code
la x28, user_code
#set MEPC register to address of user code
csrw 0x341, x28
csrr x31, 0x300
mret
user_code:
CUS_U_ADD(01010,01010,01011);
CUS_U_ADD(01010,11111,11010);
CUS_ADD_MULTI(01010,01010,01011);
CUS_ADD(11010,11001,11011);
CUS_ADD(01010,01010,01011);
CUS_U_ADD(10000,00010,00000);
CUS_U_ADD(11111,11110,11111);
CUS_U_ADD(00000,01010,01011);
CUS_U_ADD(01010,01010,01011);
CUS_ADD_MULTI(01010,00000,01011);
CUS_U_ADD(11111,11111,01011);
# (example of) final self-check test
li a0, 0xCAFE;
li a1, 0xCAFE;
xor a2, a0, a1;
beqz a2, pass;
fail:
# Failure post-processing (messages, ecall setup etc.)
li a0, 0x0;
jal exit;
pass:
# Success post-processing (messages, ecall setup etc.)
li a0, 0x0;
jal exit;

View file

@ -0,0 +1,66 @@
# Copyright 2023 Thales DIS design services SAS
#
# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
# You may obtain a copy of the License at https://solderpad.org/licenses/
#
# Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
#*****************************************************************************
# branch.S
#-----------------------------------------------------------------------------
#
.globl main
main:
# core of the test
blt zero, t3, main # BRANCH TO ZERO
csrrs s8, 0x340, a5
li a1, 0x1
li t0, 0x0
beq a1, t0, main
bne t0, t0, main
blt t0, t0, main
bltu a1, a1, main
add t5, a1 ,s6
bge zero, t5, main
bgeu zero, t5, main
c.beqz s0, main
add s1, zero ,zero
c.bnez s1, main
add s1, zero ,zero
branch:
c.bnez s1, branch
branch1:
c.beqz s0, branch1
branch2:
bge zero, t5, branch2
branch3:
bltu a1, a1, branch3
branch4:
beq zero, a1, branch4
branch5:
bne t5, t5, branch5
addi a0, a0, 22
srl a4, a5, a0
csrrsi t4, 0x340, 0
sltiu t4, s9, 236
remu t4, tp, a1
c.andi a5, -1
lui zero, 0
# (example of) final self-check test
li a0, 0xCAFE;
li a1, 0xCAFE;
xor a2, a0, a1;
beqz a2, pass;
fail:
# Failure post-processing (messages, ecall setup etc.)
li a0, 0x0;
jal exit;
pass:
# Success post-processing (messages, ecall setup etc.)
li a0, 0x0;
jal exit;

View file

@ -0,0 +1,73 @@
# Copyright 2023 Thales DIS France SAS
#
# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
# You may obtain a copy of the License at https://solderpad.org/licenses/
#
#include "csrrw_test.S"
#include "csrrwi_test.S"
#include "csrcs_test.S"
#include "csrcsi_test.S"
.globl main
main:
#Start CSR tests: all tests
#Handle exceptions
la x6, exception_handler
csrw mtvec, x6 ## Load the address of the exception handler into MTVEC
csrw 0x341, x0 ## Writing Zero to MEPC CSR
csrw 0x342, x0 ## Writing Zero to MCAUSE CSR
#End Handle exceptions
call csrrw
call csrrwi
call csrcs
call csrcsi
#End of csr test
j csr_pass
csr_pass:
li x1, 0xBEEFBEEF
li x1, 0
slli x1, x1, 1
addi x1, x1, 1
sw x1, tohost, x30
self_loop: j self_loop
csr_fail:
li x1, 0xBADBAD
li x1, 1
slli x1, x1, 1
addi x1, x1, 1
sw x1, tohost, x30
self_loop_2: j self_loop_2
exception_handler:
#addi x10, x10, 1 ##Increment number of exceptions
li x1, 0xABCDEF
csrr x3, 0x300
srli x3, x3, 11
andi x3, x3, 0b11
li x8, 3
li x9, 1
beq x3, x8, machine_exception_handler
#beqz x3, user_exception_handler
#beq x3, x9, supervisor_exception_handler
j csr_fail
machine_exception_handler:
csrr x6, 0x300
csrr x30, 0x341 ## Reading MEPC CSR which holds exception origin Address
csrr x31, 0x342 ## Reading MCAUSE CSR which holds the cause of exception
li x2 ,2 ## MCAUSE == Illegal instruction
beq x31, x2, goto_next_instr ## Checking if exception is illegal instruction
j csr_fail
goto_next_instr:
csrw 0x342, 0 ## Reseting MCAUSE value to 0 before handling new exception
beq x30, x0, csr_fail
addi x7, x30, 4
jr x7 ## Jump to latest instruction: MEPC + 4 Address location
j csr_fail

View file

@ -0,0 +1,684 @@
# Copyright 2023 Thales DIS France SAS
#
# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
# You may obtain a copy of the License at https://solderpad.org/licenses/
#
csrcs:
#Start CSR tests: Write/Read all registers using Clear/Set instructions
#User ignored registers: MHPMEVENT3 ,MHPMEVENT4 ,MHPMEVENT5 ,MHPMEVENT6 ,MHPMEVENT7 ,MHPMEVENT8 ,MHPMEVENT9 ,MHPMEVENT10 ,MHPMEVENT11 ,MHPMEVENT12 ,MHPMEVENT13 ,MHPMEVENT14 ,MHPMEVENT15 ,MHPMEVENT16 ,MHPMEVENT17 ,MHPMEVENT18 ,MHPMEVENT19 ,MHPMEVENT20 ,MHPMEVENT21 ,MHPMEVENT22 ,MHPMEVENT23 ,MHPMEVENT24 ,MHPMEVENT25 ,MHPMEVENT26 ,MHPMEVENT27 ,MHPMEVENT28 ,MHPMEVENT29 ,MHPMEVENT30 ,MHPMEVENT31 ,PMPCFG0 ,PMPCFG1 ,PMPCFG2 ,PMPCFG3 ,PMPADDR0 ,PMPADDR1 ,PMPADDR2 ,PMPADDR3 ,PMPADDR4 ,PMPADDR5 ,PMPADDR6 ,PMPADDR7 ,PMPADDR8 ,PMPADDR9 ,PMPADDR10 ,PMPADDR11 ,PMPADDR12 ,PMPADDR13 ,PMPADDR14 ,PMPADDR15 ,ICACHE ,MHPMCOUNTER3 ,MHPMCOUNTER4 ,MHPMCOUNTER5 ,MHPMCOUNTER6 ,MHPMCOUNTER7 ,MHPMCOUNTER8 ,MHPMCOUNTER9 ,MHPMCOUNTER10 ,MHPMCOUNTER11 ,MHPMCOUNTER12 ,MHPMCOUNTER13 ,MHPMCOUNTER14 ,MHPMCOUNTER15 ,MHPMCOUNTER16 ,MHPMCOUNTER17 ,MHPMCOUNTER18 ,MHPMCOUNTER19 ,MHPMCOUNTER20 ,MHPMCOUNTER21 ,MHPMCOUNTER22 ,MHPMCOUNTER23 ,MHPMCOUNTER24 ,MHPMCOUNTER25 ,MHPMCOUNTER26 ,MHPMCOUNTER27 ,MHPMCOUNTER28 ,MHPMCOUNTER29 ,MHPMCOUNTER30 ,MHPMCOUNTER31 ,MHPMCOUNTERH3 ,MHPMCOUNTERH4 ,MHPMCOUNTERH5 ,MHPMCOUNTERH6 ,MHPMCOUNTERH7 ,MHPMCOUNTERH8 ,MHPMCOUNTERH9 ,MHPMCOUNTERH10 ,MHPMCOUNTERH11 ,MHPMCOUNTERH12 ,MHPMCOUNTERH13 ,MHPMCOUNTERH14 ,MHPMCOUNTERH15 ,MHPMCOUNTERH16 ,MHPMCOUNTERH17 ,MHPMCOUNTERH18 ,MHPMCOUNTERH19 ,MHPMCOUNTERH20 ,MHPMCOUNTERH21 ,MHPMCOUNTERH22 ,MHPMCOUNTERH23 ,MHPMCOUNTERH24 ,MHPMCOUNTERH25 ,MHPMCOUNTERH26 ,MHPMCOUNTERH27 ,MHPMCOUNTERH28 ,MHPMCOUNTERH29 ,MHPMCOUNTERH30 ,MHPMCOUNTERH31 ,
##########################
#MSTATUS testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h18}
##########################
#MSTATUS Write clear/set value 0x1f
li x3, 0x7ffe19e0
csrrc x14, 0x300, x3
li x3, 0x1f
csrrs x14, 0x300, x3
#MSTATUS read value, expected 0xa
csrr x14, 0x300
#MSTATUS Write clear/set value 0x0
li x3, 0x7ffe19ff
csrrc x14, 0x300, x3
li x3, 0x0
csrrs x14, 0x300, x3
#MSTATUS read value, expected 0x0
csrr x14, 0x300
#MSTATUS Write clear/set value 0x15
li x3, 0x7ffe19ea
csrrc x14, 0x300, x3
li x3, 0x15
csrrs x14, 0x300, x3
#MSTATUS read value, expected 0x0
csrr x14, 0x300
#MSTATUS Write clear/set value 0xa
li x3, 0x7ffe19f5
csrrc x14, 0x300, x3
li x3, 0xa
csrrs x14, 0x300, x3
#MSTATUS read value, expected 0xa
csrr x14, 0x300
#MSTATUS Write clear/set value 0x18
li x3, 0x7ffe19e7
csrrc x14, 0x300, x3
li x3, 0x18
csrrs x14, 0x300, x3
#MSTATUS read value, expected 0x8
csrr x14, 0x300
##########################
#MTVEC testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h4}
##########################
#MTVEC Write clear/set value 0x1f
li x3, 0xffffffe0
csrrc x14, 0x305, x3
li x3, 0x1f
csrrs x14, 0x305, x3
#MTVEC read value, expected 0x1f
csrr x14, 0x305
#MTVEC Write clear/set value 0x0
li x3, 0xffffffff
csrrc x14, 0x305, x3
li x3, 0x0
csrrs x14, 0x305, x3
#MTVEC read value, expected 0x0
csrr x14, 0x305
#MTVEC Write clear/set value 0x15
li x3, 0xffffffea
csrrc x14, 0x305, x3
li x3, 0x15
csrrs x14, 0x305, x3
#MTVEC read value, expected 0x15
csrr x14, 0x305
#MTVEC Write clear/set value 0xa
li x3, 0xfffffff5
csrrc x14, 0x305, x3
li x3, 0xa
csrrs x14, 0x305, x3
#MTVEC read value, expected 0xa
csrr x14, 0x305
#MTVEC Write clear/set value 0x4
li x3, 0xfffffffb
csrrc x14, 0x305, x3
li x3, 0x4
csrrs x14, 0x305, x3
#MTVEC read value, expected 0x4
csrr x14, 0x305
##########################
#MSTATUSH testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h1}
##########################
#MSTATUSH Write clear/set value 0x1f
li x3, 0xffffffe0
csrrc x14, 0x310, x3
li x3, 0x1f
csrrs x14, 0x310, x3
#MSTATUSH read value, expected 0x10
csrr x14, 0x310
#MSTATUSH Write clear/set value 0x0
li x3, 0xffffffff
csrrc x14, 0x310, x3
li x3, 0x0
csrrs x14, 0x310, x3
#MSTATUSH read value, expected 0x0
csrr x14, 0x310
#MSTATUSH Write clear/set value 0x15
li x3, 0xffffffea
csrrc x14, 0x310, x3
li x3, 0x15
csrrs x14, 0x310, x3
#MSTATUSH read value, expected 0x10
csrr x14, 0x310
#MSTATUSH Write clear/set value 0xa
li x3, 0xfffffff5
csrrc x14, 0x310, x3
li x3, 0xa
csrrs x14, 0x310, x3
#MSTATUSH read value, expected 0x0
csrr x14, 0x310
#MSTATUSH Write clear/set value 0x1
li x3, 0xfffffffe
csrrc x14, 0x310, x3
li x3, 0x1
csrrs x14, 0x310, x3
#MSTATUSH read value, expected 0x0
csrr x14, 0x310
##########################
#MCYCLEH testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h2}
##########################
#MCYCLEH Write clear/set value 0x1f
li x3, 0xffffffe0
csrrc x14, 0xb80, x3
li x3, 0x1f
csrrs x14, 0xb80, x3
#MCYCLEH read value, expected 0x1f
csrr x14, 0xb80
#MCYCLEH Write clear/set value 0x0
li x3, 0xffffffff
csrrc x14, 0xb80, x3
li x3, 0x0
csrrs x14, 0xb80, x3
#MCYCLEH read value, expected 0x0
csrr x14, 0xb80
#MCYCLEH Write clear/set value 0x15
li x3, 0xffffffea
csrrc x14, 0xb80, x3
li x3, 0x15
csrrs x14, 0xb80, x3
#MCYCLEH read value, expected 0x15
csrr x14, 0xb80
#MCYCLEH Write clear/set value 0xa
li x3, 0xfffffff5
csrrc x14, 0xb80, x3
li x3, 0xa
csrrs x14, 0xb80, x3
#MCYCLEH read value, expected 0xa
csrr x14, 0xb80
#MCYCLEH Write clear/set value 0x2
li x3, 0xfffffffd
csrrc x14, 0xb80, x3
li x3, 0x2
csrrs x14, 0xb80, x3
#MCYCLEH read value, expected 0x2
csrr x14, 0xb80
##########################
#MSCRATCH testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'hd}
##########################
#MSCRATCH Write clear/set value 0x1f
li x3, 0xffffffe0
csrrc x14, 0x340, x3
li x3, 0x1f
csrrs x14, 0x340, x3
#MSCRATCH read value, expected 0x1f
csrr x14, 0x340
#MSCRATCH Write clear/set value 0x0
li x3, 0xffffffff
csrrc x14, 0x340, x3
li x3, 0x0
csrrs x14, 0x340, x3
#MSCRATCH read value, expected 0x0
csrr x14, 0x340
#MSCRATCH Write clear/set value 0x15
li x3, 0xffffffea
csrrc x14, 0x340, x3
li x3, 0x15
csrrs x14, 0x340, x3
#MSCRATCH read value, expected 0x15
csrr x14, 0x340
#MSCRATCH Write clear/set value 0xa
li x3, 0xfffffff5
csrrc x14, 0x340, x3
li x3, 0xa
csrrs x14, 0x340, x3
#MSCRATCH read value, expected 0xa
csrr x14, 0x340
#MSCRATCH Write clear/set value 0xd
li x3, 0xfffffff2
csrrc x14, 0x340, x3
li x3, 0xd
csrrs x14, 0x340, x3
#MSCRATCH read value, expected 0xd
csrr x14, 0x340
##########################
#MINSTRET testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h15}
##########################
#MINSTRET Write clear/set value 0x1f
li x3, 0xffffffe0
csrrc x14, 0xb02, x3
li x3, 0x1f
csrrs x14, 0xb02, x3
#MINSTRET read value, expected 0x1f
csrr x14, 0xb02
#MINSTRET Write clear/set value 0x0
li x3, 0xffffffff
csrrc x14, 0xb02, x3
li x3, 0x0
csrrs x14, 0xb02, x3
#MINSTRET read value, expected 0x0
csrr x14, 0xb02
#MINSTRET Write clear/set value 0x15
li x3, 0xffffffea
csrrc x14, 0xb02, x3
li x3, 0x15
csrrs x14, 0xb02, x3
#MINSTRET read value, expected 0x15
csrr x14, 0xb02
#MINSTRET Write clear/set value 0xa
li x3, 0xfffffff5
csrrc x14, 0xb02, x3
li x3, 0xa
csrrs x14, 0xb02, x3
#MINSTRET read value, expected 0xa
csrr x14, 0xb02
#MINSTRET Write clear/set value 0x15
li x3, 0xffffffea
csrrc x14, 0xb02, x3
li x3, 0x15
csrrs x14, 0xb02, x3
#MINSTRET read value, expected 0x15
csrr x14, 0xb02
##########################
#MIP testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h4}
##########################
#MIP Write clear/set value 0x1f
li x3, 0xfffff760
csrrc x14, 0x344, x3
li x3, 0x1f
csrrs x14, 0x344, x3
#MIP read value, expected 0x1b
csrr x14, 0x344
#MIP Write clear/set value 0x0
li x3, 0xfffff777
csrrc x14, 0x344, x3
li x3, 0x0
csrrs x14, 0x344, x3
#MIP read value, expected 0x0
csrr x14, 0x344
#MIP Write clear/set value 0x15
li x3, 0xfffff762
csrrc x14, 0x344, x3
li x3, 0x15
csrrs x14, 0x344, x3
#MIP read value, expected 0x11
csrr x14, 0x344
#MIP Write clear/set value 0xa
li x3, 0xfffff775
csrrc x14, 0x344, x3
li x3, 0xa
csrrs x14, 0x344, x3
#MIP read value, expected 0xa
csrr x14, 0x344
#MIP Write clear/set value 0x4
li x3, 0xfffff773
csrrc x14, 0x344, x3
li x3, 0x4
csrrs x14, 0x344, x3
#MIP read value, expected 0x0
csrr x14, 0x344
##########################
#MEPC testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h1b}
##########################
#MEPC Write clear/set value 0x1f
li x3, 0xffffffe0
csrrc x14, 0x341, x3
li x3, 0x1f
csrrs x14, 0x341, x3
#MEPC read value, expected 0x1f
csrr x14, 0x341
#MEPC Write clear/set value 0x0
li x3, 0xffffffff
csrrc x14, 0x341, x3
li x3, 0x0
csrrs x14, 0x341, x3
#MEPC read value, expected 0x0
csrr x14, 0x341
#MEPC Write clear/set value 0x15
li x3, 0xffffffea
csrrc x14, 0x341, x3
li x3, 0x15
csrrs x14, 0x341, x3
#MEPC read value, expected 0x15
csrr x14, 0x341
#MEPC Write clear/set value 0xa
li x3, 0xfffffff5
csrrc x14, 0x341, x3
li x3, 0xa
csrrs x14, 0x341, x3
#MEPC read value, expected 0xa
csrr x14, 0x341
#MEPC Write clear/set value 0x1b
li x3, 0xffffffe4
csrrc x14, 0x341, x3
li x3, 0x1b
csrrs x14, 0x341, x3
#MEPC read value, expected 0x1b
csrr x14, 0x341
##########################
#MCYCLE testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h1d}
##########################
#MCYCLE Write clear/set value 0x1f
li x3, 0xffffffe0
csrrc x14, 0xb00, x3
li x3, 0x1f
csrrs x14, 0xb00, x3
#MCYCLE read value, expected 0x1f
csrr x14, 0xb00
#MCYCLE Write clear/set value 0x0
li x3, 0xffffffff
csrrc x14, 0xb00, x3
li x3, 0x0
csrrs x14, 0xb00, x3
#MCYCLE read value, expected 0x0
csrr x14, 0xb00
#MCYCLE Write clear/set value 0x15
li x3, 0xffffffea
csrrc x14, 0xb00, x3
li x3, 0x15
csrrs x14, 0xb00, x3
#MCYCLE read value, expected 0x15
csrr x14, 0xb00
#MCYCLE Write clear/set value 0xa
li x3, 0xfffffff5
csrrc x14, 0xb00, x3
li x3, 0xa
csrrs x14, 0xb00, x3
#MCYCLE read value, expected 0xa
csrr x14, 0xb00
#MCYCLE Write clear/set value 0x1d
li x3, 0xffffffe2
csrrc x14, 0xb00, x3
li x3, 0x1d
csrrs x14, 0xb00, x3
#MCYCLE read value, expected 0x1d
csrr x14, 0xb00
##########################
#MINSTRETH testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h1a}
##########################
#MINSTRETH Write clear/set value 0x1f
li x3, 0xffffffe0
csrrc x14, 0xb82, x3
li x3, 0x1f
csrrs x14, 0xb82, x3
#MINSTRETH read value, expected 0x1f
csrr x14, 0xb82
#MINSTRETH Write clear/set value 0x0
li x3, 0xffffffff
csrrc x14, 0xb82, x3
li x3, 0x0
csrrs x14, 0xb82, x3
#MINSTRETH read value, expected 0x0
csrr x14, 0xb82
#MINSTRETH Write clear/set value 0x15
li x3, 0xffffffea
csrrc x14, 0xb82, x3
li x3, 0x15
csrrs x14, 0xb82, x3
#MINSTRETH read value, expected 0x15
csrr x14, 0xb82
#MINSTRETH Write clear/set value 0xa
li x3, 0xfffffff5
csrrc x14, 0xb82, x3
li x3, 0xa
csrrs x14, 0xb82, x3
#MINSTRETH read value, expected 0xa
csrr x14, 0xb82
#MINSTRETH Write clear/set value 0x1a
li x3, 0xffffffe5
csrrc x14, 0xb82, x3
li x3, 0x1a
csrrs x14, 0xb82, x3
#MINSTRETH read value, expected 0x1a
csrr x14, 0xb82
##########################
#MCAUSE testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h16}
##########################
#MCAUSE Write clear/set value 0x1f
li x3, 0xffffffe0
csrrc x14, 0x342, x3
li x3, 0x1f
csrrs x14, 0x342, x3
#MCAUSE read value, expected 0x1f
csrr x14, 0x342
#MCAUSE Write clear/set value 0x0
li x3, 0xffffffff
csrrc x14, 0x342, x3
li x3, 0x0
csrrs x14, 0x342, x3
#MCAUSE read value, expected 0x0
csrr x14, 0x342
#MCAUSE Write clear/set value 0x15
li x3, 0xffffffea
csrrc x14, 0x342, x3
li x3, 0x15
csrrs x14, 0x342, x3
#MCAUSE read value, expected 0x15
csrr x14, 0x342
#MCAUSE Write clear/set value 0xa
li x3, 0xfffffff5
csrrc x14, 0x342, x3
li x3, 0xa
csrrs x14, 0x342, x3
#MCAUSE read value, expected 0xa
csrr x14, 0x342
#MCAUSE Write clear/set value 0x16
li x3, 0xffffffe9
csrrc x14, 0x342, x3
li x3, 0x16
csrrs x14, 0x342, x3
#MCAUSE read value, expected 0x16
csrr x14, 0x342
##########################
#MISA testing W/R values '{'h1b, 'h4, 'h15, 'ha, 'h8}
##########################
#MISA Write clear/set value 0x1b
li x3, 0xffffffe4
csrrc x14, 0x301, x3
li x3, 0x1b
csrrs x14, 0x301, x3
#MISA read value, expected 0x1b
csrr x14, 0x301
#MISA Write clear/set value 0x4
li x3, 0xfffffffb
csrrc x14, 0x301, x3
li x3, 0x4
csrrs x14, 0x301, x3
#MISA read value, expected 0x4
csrr x14, 0x301
#MISA Write clear/set value 0x15
li x3, 0xffffffea
csrrc x14, 0x301, x3
li x3, 0x15
csrrs x14, 0x301, x3
#MISA read value, expected 0x15
csrr x14, 0x301
#MISA Write clear/set value 0xa
li x3, 0xfffffff5
csrrc x14, 0x301, x3
li x3, 0xa
csrrs x14, 0x301, x3
#MISA read value, expected 0xa
csrr x14, 0x301
#MISA Write clear/set value 0x8
li x3, 0xfffffff7
csrrc x14, 0x301, x3
li x3, 0x8
csrrs x14, 0x301, x3
#MISA read value, expected 0x8
csrr x14, 0x301
##########################
#MTVAL testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h1e}
##########################
#MTVAL Write clear/set value 0x1f
li x3, 0xffffffe0
csrrc x14, 0x343, x3
li x3, 0x1f
csrrs x14, 0x343, x3
#MTVAL read value, expected 0x1f
csrr x14, 0x343
#MTVAL Write clear/set value 0x0
li x3, 0xffffffff
csrrc x14, 0x343, x3
li x3, 0x0
csrrs x14, 0x343, x3
#MTVAL read value, expected 0x0
csrr x14, 0x343
#MTVAL Write clear/set value 0x15
li x3, 0xffffffea
csrrc x14, 0x343, x3
li x3, 0x15
csrrs x14, 0x343, x3
#MTVAL read value, expected 0x15
csrr x14, 0x343
#MTVAL Write clear/set value 0xa
li x3, 0xfffffff5
csrrc x14, 0x343, x3
li x3, 0xa
csrrs x14, 0x343, x3
#MTVAL read value, expected 0xa
csrr x14, 0x343
#MTVAL Write clear/set value 0x1e
li x3, 0xffffffe1
csrrc x14, 0x343, x3
li x3, 0x1e
csrrs x14, 0x343, x3
#MTVAL read value, expected 0x1e
csrr x14, 0x343
##########################
#MIE testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h1a}
##########################
#MIE Write clear/set value 0x1f
li x3, 0xffffffe0
csrrc x14, 0x304, x3
li x3, 0x1f
csrrs x14, 0x304, x3
#MIE read value, expected 0x1b
csrr x14, 0x304
#MIE Write clear/set value 0x0
li x3, 0xffffffff
csrrc x14, 0x304, x3
li x3, 0x0
csrrs x14, 0x304, x3
#MIE read value, expected 0x0
csrr x14, 0x304
#MIE Write clear/set value 0x15
li x3, 0xffffffea
csrrc x14, 0x304, x3
li x3, 0x15
csrrs x14, 0x304, x3
#MIE read value, expected 0x11
csrr x14, 0x304
#MIE Write clear/set value 0xa
li x3, 0xfffffff5
csrrc x14, 0x304, x3
li x3, 0xa
csrrs x14, 0x304, x3
#MIE read value, expected 0xa
csrr x14, 0x304
#MIE Write clear/set value 0x1a
li x3, 0xffffffe5
csrrc x14, 0x304, x3
li x3, 0x1a
csrrs x14, 0x304, x3
#MIE read value, expected 0x1a
csrr x14, 0x304
ret

View file

@ -0,0 +1,544 @@
# Copyright 2023 Thales DIS France SAS
#
# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
# You may obtain a copy of the License at https://solderpad.org/licenses/
#
csrcsi:
#Start CSR tests: Write/Read all registers using Clear/Set immediate instructions
#User ignored registers: MHPMEVENT3 ,MHPMEVENT4 ,MHPMEVENT5 ,MHPMEVENT6 ,MHPMEVENT7 ,MHPMEVENT8 ,MHPMEVENT9 ,MHPMEVENT10 ,MHPMEVENT11 ,MHPMEVENT12 ,MHPMEVENT13 ,MHPMEVENT14 ,MHPMEVENT15 ,MHPMEVENT16 ,MHPMEVENT17 ,MHPMEVENT18 ,MHPMEVENT19 ,MHPMEVENT20 ,MHPMEVENT21 ,MHPMEVENT22 ,MHPMEVENT23 ,MHPMEVENT24 ,MHPMEVENT25 ,MHPMEVENT26 ,MHPMEVENT27 ,MHPMEVENT28 ,MHPMEVENT29 ,MHPMEVENT30 ,MHPMEVENT31 ,PMPCFG0 ,PMPCFG1 ,PMPCFG2 ,PMPCFG3 ,PMPADDR0 ,PMPADDR1 ,PMPADDR2 ,PMPADDR3 ,PMPADDR4 ,PMPADDR5 ,PMPADDR6 ,PMPADDR7 ,PMPADDR8 ,PMPADDR9 ,PMPADDR10 ,PMPADDR11 ,PMPADDR12 ,PMPADDR13 ,PMPADDR14 ,PMPADDR15 ,ICACHE ,MHPMCOUNTER3 ,MHPMCOUNTER4 ,MHPMCOUNTER5 ,MHPMCOUNTER6 ,MHPMCOUNTER7 ,MHPMCOUNTER8 ,MHPMCOUNTER9 ,MHPMCOUNTER10 ,MHPMCOUNTER11 ,MHPMCOUNTER12 ,MHPMCOUNTER13 ,MHPMCOUNTER14 ,MHPMCOUNTER15 ,MHPMCOUNTER16 ,MHPMCOUNTER17 ,MHPMCOUNTER18 ,MHPMCOUNTER19 ,MHPMCOUNTER20 ,MHPMCOUNTER21 ,MHPMCOUNTER22 ,MHPMCOUNTER23 ,MHPMCOUNTER24 ,MHPMCOUNTER25 ,MHPMCOUNTER26 ,MHPMCOUNTER27 ,MHPMCOUNTER28 ,MHPMCOUNTER29 ,MHPMCOUNTER30 ,MHPMCOUNTER31 ,MHPMCOUNTERH3 ,MHPMCOUNTERH4 ,MHPMCOUNTERH5 ,MHPMCOUNTERH6 ,MHPMCOUNTERH7 ,MHPMCOUNTERH8 ,MHPMCOUNTERH9 ,MHPMCOUNTERH10 ,MHPMCOUNTERH11 ,MHPMCOUNTERH12 ,MHPMCOUNTERH13 ,MHPMCOUNTERH14 ,MHPMCOUNTERH15 ,MHPMCOUNTERH16 ,MHPMCOUNTERH17 ,MHPMCOUNTERH18 ,MHPMCOUNTERH19 ,MHPMCOUNTERH20 ,MHPMCOUNTERH21 ,MHPMCOUNTERH22 ,MHPMCOUNTERH23 ,MHPMCOUNTERH24 ,MHPMCOUNTERH25 ,MHPMCOUNTERH26 ,MHPMCOUNTERH27 ,MHPMCOUNTERH28 ,MHPMCOUNTERH29 ,MHPMCOUNTERH30 ,MHPMCOUNTERH31 ,
##########################
#MSTATUS testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h16}
##########################
#MSTATUS Write clear/set value 0x1f
csrrci x14, 0x300, 0x0
csrrsi x14, 0x300, 0x1f
#MSTATUS read value, expected 0xa
csrr x14, 0x300
#MSTATUS Write clear/set value 0x0
csrrci x14, 0x300, 0x1f
csrrsi x14, 0x300, 0x0
#MSTATUS read value, expected 0x0
csrr x14, 0x300
#MSTATUS Write clear/set value 0x15
csrrci x14, 0x300, 0xa
csrrsi x14, 0x300, 0x15
#MSTATUS read value, expected 0x0
csrr x14, 0x300
#MSTATUS Write clear/set value 0xa
csrrci x14, 0x300, 0x15
csrrsi x14, 0x300, 0xa
#MSTATUS read value, expected 0xa
csrr x14, 0x300
#MSTATUS Write clear/set value 0x16
csrrci x14, 0x300, 0x9
csrrsi x14, 0x300, 0x16
#MSTATUS read value, expected 0x2
csrr x14, 0x300
##########################
#MTVAL testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h18}
##########################
#MTVAL Write clear/set value 0x1f
csrrci x14, 0x343, 0x0
csrrsi x14, 0x343, 0x1f
#MTVAL read value, expected 0x1f
csrr x14, 0x343
#MTVAL Write clear/set value 0x0
csrrci x14, 0x343, 0x1f
csrrsi x14, 0x343, 0x0
#MTVAL read value, expected 0x0
csrr x14, 0x343
#MTVAL Write clear/set value 0x15
csrrci x14, 0x343, 0xa
csrrsi x14, 0x343, 0x15
#MTVAL read value, expected 0x15
csrr x14, 0x343
#MTVAL Write clear/set value 0xa
csrrci x14, 0x343, 0x15
csrrsi x14, 0x343, 0xa
#MTVAL read value, expected 0xa
csrr x14, 0x343
#MTVAL Write clear/set value 0x18
csrrci x14, 0x343, 0x7
csrrsi x14, 0x343, 0x18
#MTVAL read value, expected 0x18
csrr x14, 0x343
##########################
#MSCRATCH testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h9}
##########################
#MSCRATCH Write clear/set value 0x1f
csrrci x14, 0x340, 0x0
csrrsi x14, 0x340, 0x1f
#MSCRATCH read value, expected 0x1f
csrr x14, 0x340
#MSCRATCH Write clear/set value 0x0
csrrci x14, 0x340, 0x1f
csrrsi x14, 0x340, 0x0
#MSCRATCH read value, expected 0x0
csrr x14, 0x340
#MSCRATCH Write clear/set value 0x15
csrrci x14, 0x340, 0xa
csrrsi x14, 0x340, 0x15
#MSCRATCH read value, expected 0x15
csrr x14, 0x340
#MSCRATCH Write clear/set value 0xa
csrrci x14, 0x340, 0x15
csrrsi x14, 0x340, 0xa
#MSCRATCH read value, expected 0xa
csrr x14, 0x340
#MSCRATCH Write clear/set value 0x9
csrrci x14, 0x340, 0x16
csrrsi x14, 0x340, 0x9
#MSCRATCH read value, expected 0x9
csrr x14, 0x340
##########################
#MCYCLE testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h2}
##########################
#MCYCLE Write clear/set value 0x1f
csrrci x14, 0xb00, 0x0
csrrsi x14, 0xb00, 0x1f
#MCYCLE read value, expected 0x1f
csrr x14, 0xb00
#MCYCLE Write clear/set value 0x0
csrrci x14, 0xb00, 0x1f
csrrsi x14, 0xb00, 0x0
#MCYCLE read value, expected 0x0
csrr x14, 0xb00
#MCYCLE Write clear/set value 0x15
csrrci x14, 0xb00, 0xa
csrrsi x14, 0xb00, 0x15
#MCYCLE read value, expected 0x15
csrr x14, 0xb00
#MCYCLE Write clear/set value 0xa
csrrci x14, 0xb00, 0x15
csrrsi x14, 0xb00, 0xa
#MCYCLE read value, expected 0xa
csrr x14, 0xb00
#MCYCLE Write clear/set value 0x2
csrrci x14, 0xb00, 0x1d
csrrsi x14, 0xb00, 0x2
#MCYCLE read value, expected 0x2
csrr x14, 0xb00
##########################
#MTVEC testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h7}
##########################
#MTVEC Write clear/set value 0x1f
csrrci x14, 0x305, 0x0
csrrsi x14, 0x305, 0x1f
#MTVEC read value, expected 0x1f
csrr x14, 0x305
#MTVEC Write clear/set value 0x0
csrrci x14, 0x305, 0x1f
csrrsi x14, 0x305, 0x0
#MTVEC read value, expected 0x0
csrr x14, 0x305
#MTVEC Write clear/set value 0x15
csrrci x14, 0x305, 0xa
csrrsi x14, 0x305, 0x15
#MTVEC read value, expected 0x15
csrr x14, 0x305
#MTVEC Write clear/set value 0xa
csrrci x14, 0x305, 0x15
csrrsi x14, 0x305, 0xa
#MTVEC read value, expected 0xa
csrr x14, 0x305
#MTVEC Write clear/set value 0x7
csrrci x14, 0x305, 0x18
csrrsi x14, 0x305, 0x7
#MTVEC read value, expected 0x7
csrr x14, 0x305
##########################
#MCAUSE testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h16}
##########################
#MCAUSE Write clear/set value 0x1f
csrrci x14, 0x342, 0x0
csrrsi x14, 0x342, 0x1f
#MCAUSE read value, expected 0x1f
csrr x14, 0x342
#MCAUSE Write clear/set value 0x0
csrrci x14, 0x342, 0x1f
csrrsi x14, 0x342, 0x0
#MCAUSE read value, expected 0x0
csrr x14, 0x342
#MCAUSE Write clear/set value 0x15
csrrci x14, 0x342, 0xa
csrrsi x14, 0x342, 0x15
#MCAUSE read value, expected 0x15
csrr x14, 0x342
#MCAUSE Write clear/set value 0xa
csrrci x14, 0x342, 0x15
csrrsi x14, 0x342, 0xa
#MCAUSE read value, expected 0xa
csrr x14, 0x342
#MCAUSE Write clear/set value 0x16
csrrci x14, 0x342, 0x9
csrrsi x14, 0x342, 0x16
#MCAUSE read value, expected 0x16
csrr x14, 0x342
##########################
#MINSTRETH testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h1f}
##########################
#MINSTRETH Write clear/set value 0x1f
csrrci x14, 0xb82, 0x0
csrrsi x14, 0xb82, 0x1f
#MINSTRETH read value, expected 0x1f
csrr x14, 0xb82
#MINSTRETH Write clear/set value 0x0
csrrci x14, 0xb82, 0x1f
csrrsi x14, 0xb82, 0x0
#MINSTRETH read value, expected 0x0
csrr x14, 0xb82
#MINSTRETH Write clear/set value 0x15
csrrci x14, 0xb82, 0xa
csrrsi x14, 0xb82, 0x15
#MINSTRETH read value, expected 0x15
csrr x14, 0xb82
#MINSTRETH Write clear/set value 0xa
csrrci x14, 0xb82, 0x15
csrrsi x14, 0xb82, 0xa
#MINSTRETH read value, expected 0xa
csrr x14, 0xb82
#MINSTRETH Write clear/set value 0x1f
csrrci x14, 0xb82, 0x0
csrrsi x14, 0xb82, 0x1f
#MINSTRETH read value, expected 0x1f
csrr x14, 0xb82
##########################
#MIP testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h10}
##########################
#MIP Write clear/set value 0x1f
csrrci x14, 0x344, 0x0
csrrsi x14, 0x344, 0x1f
#MIP read value, expected 0x1b
csrr x14, 0x344
#MIP Write clear/set value 0x0
csrrci x14, 0x344, 0x17
csrrsi x14, 0x344, 0x0
#MIP read value, expected 0x0
csrr x14, 0x344
#MIP Write clear/set value 0x15
csrrci x14, 0x344, 0x2
csrrsi x14, 0x344, 0x15
#MIP read value, expected 0x11
csrr x14, 0x344
#MIP Write clear/set value 0xa
csrrci x14, 0x344, 0x15
csrrsi x14, 0x344, 0xa
#MIP read value, expected 0xa
csrr x14, 0x344
#MIP Write clear/set value 0x10
csrrci x14, 0x344, 0x7
csrrsi x14, 0x344, 0x10
#MIP read value, expected 0x10
csrr x14, 0x344
##########################
#MISA testing W/R values '{'h1b, 'h4, 'h15, 'ha, 'h3}
##########################
#MISA Write clear/set value 0x1b
csrrci x14, 0x301, 0x4
csrrsi x14, 0x301, 0x1b
#MISA read value, expected 0x1b
csrr x14, 0x301
#MISA Write clear/set value 0x4
csrrci x14, 0x301, 0x1b
csrrsi x14, 0x301, 0x4
#MISA read value, expected 0x4
csrr x14, 0x301
#MISA Write clear/set value 0x15
csrrci x14, 0x301, 0xa
csrrsi x14, 0x301, 0x15
#MISA read value, expected 0x15
csrr x14, 0x301
#MISA Write clear/set value 0xa
csrrci x14, 0x301, 0x15
csrrsi x14, 0x301, 0xa
#MISA read value, expected 0xa
csrr x14, 0x301
#MISA Write clear/set value 0x3
csrrci x14, 0x301, 0x1c
csrrsi x14, 0x301, 0x3
#MISA read value, expected 0x3
csrr x14, 0x301
##########################
#MSTATUSH testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h2}
##########################
#MSTATUSH Write clear/set value 0x1f
csrrci x14, 0x310, 0x0
csrrsi x14, 0x310, 0x1f
#MSTATUSH read value, expected 0x10
csrr x14, 0x310
#MSTATUSH Write clear/set value 0x0
csrrci x14, 0x310, 0x1f
csrrsi x14, 0x310, 0x0
#MSTATUSH read value, expected 0x0
csrr x14, 0x310
#MSTATUSH Write clear/set value 0x15
csrrci x14, 0x310, 0xa
csrrsi x14, 0x310, 0x15
#MSTATUSH read value, expected 0x10
csrr x14, 0x310
#MSTATUSH Write clear/set value 0xa
csrrci x14, 0x310, 0x15
csrrsi x14, 0x310, 0xa
#MSTATUSH read value, expected 0x0
csrr x14, 0x310
#MSTATUSH Write clear/set value 0x2
csrrci x14, 0x310, 0x1d
csrrsi x14, 0x310, 0x2
#MSTATUSH read value, expected 0x0
csrr x14, 0x310
##########################
#MCYCLEH testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'hd}
##########################
#MCYCLEH Write clear/set value 0x1f
csrrci x14, 0xb80, 0x0
csrrsi x14, 0xb80, 0x1f
#MCYCLEH read value, expected 0x1f
csrr x14, 0xb80
#MCYCLEH Write clear/set value 0x0
csrrci x14, 0xb80, 0x1f
csrrsi x14, 0xb80, 0x0
#MCYCLEH read value, expected 0x0
csrr x14, 0xb80
#MCYCLEH Write clear/set value 0x15
csrrci x14, 0xb80, 0xa
csrrsi x14, 0xb80, 0x15
#MCYCLEH read value, expected 0x15
csrr x14, 0xb80
#MCYCLEH Write clear/set value 0xa
csrrci x14, 0xb80, 0x15
csrrsi x14, 0xb80, 0xa
#MCYCLEH read value, expected 0xa
csrr x14, 0xb80
#MCYCLEH Write clear/set value 0xd
csrrci x14, 0xb80, 0x12
csrrsi x14, 0xb80, 0xd
#MCYCLEH read value, expected 0xd
csrr x14, 0xb80
##########################
#MIE testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h6}
##########################
#MIE Write clear/set value 0x1f
csrrci x14, 0x304, 0x0
csrrsi x14, 0x304, 0x1f
#MIE read value, expected 0x1b
csrr x14, 0x304
#MIE Write clear/set value 0x0
csrrci x14, 0x304, 0x1f
csrrsi x14, 0x304, 0x0
#MIE read value, expected 0x0
csrr x14, 0x304
#MIE Write clear/set value 0x15
csrrci x14, 0x304, 0xa
csrrsi x14, 0x304, 0x15
#MIE read value, expected 0x11
csrr x14, 0x304
#MIE Write clear/set value 0xa
csrrci x14, 0x304, 0x15
csrrsi x14, 0x304, 0xa
#MIE read value, expected 0xa
csrr x14, 0x304
#MIE Write clear/set value 0x6
csrrci x14, 0x304, 0x19
csrrsi x14, 0x304, 0x6
#MIE read value, expected 0x2
csrr x14, 0x304
##########################
#MEPC testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h1c}
##########################
#MEPC Write clear/set value 0x1f
csrrci x14, 0x341, 0x0
csrrsi x14, 0x341, 0x1f
#MEPC read value, expected 0x1f
csrr x14, 0x341
#MEPC Write clear/set value 0x0
csrrci x14, 0x341, 0x1f
csrrsi x14, 0x341, 0x0
#MEPC read value, expected 0x0
csrr x14, 0x341
#MEPC Write clear/set value 0x15
csrrci x14, 0x341, 0xa
csrrsi x14, 0x341, 0x15
#MEPC read value, expected 0x15
csrr x14, 0x341
#MEPC Write clear/set value 0xa
csrrci x14, 0x341, 0x15
csrrsi x14, 0x341, 0xa
#MEPC read value, expected 0xa
csrr x14, 0x341
#MEPC Write clear/set value 0x1c
csrrci x14, 0x341, 0x3
csrrsi x14, 0x341, 0x1c
#MEPC read value, expected 0x1c
csrr x14, 0x341
##########################
#MINSTRET testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h1}
##########################
#MINSTRET Write clear/set value 0x1f
csrrci x14, 0xb02, 0x0
csrrsi x14, 0xb02, 0x1f
#MINSTRET read value, expected 0x1f
csrr x14, 0xb02
#MINSTRET Write clear/set value 0x0
csrrci x14, 0xb02, 0x1f
csrrsi x14, 0xb02, 0x0
#MINSTRET read value, expected 0x0
csrr x14, 0xb02
#MINSTRET Write clear/set value 0x15
csrrci x14, 0xb02, 0xa
csrrsi x14, 0xb02, 0x15
#MINSTRET read value, expected 0x15
csrr x14, 0xb02
#MINSTRET Write clear/set value 0xa
csrrci x14, 0xb02, 0x15
csrrsi x14, 0xb02, 0xa
#MINSTRET read value, expected 0xa
csrr x14, 0xb02
#MINSTRET Write clear/set value 0x1
csrrci x14, 0xb02, 0x1e
csrrsi x14, 0xb02, 0x1
#MINSTRET read value, expected 0x1
csrr x14, 0xb02
ret

View file

@ -0,0 +1,544 @@
# Copyright 2023 Thales DIS France SAS
#
# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
# You may obtain a copy of the License at https://solderpad.org/licenses/
#
csrrw:
#Start CSR tests: Write/Read all registers
#User ignored registers: MHPMEVENT3 ,MHPMEVENT4 ,MHPMEVENT5 ,MHPMEVENT6 ,MHPMEVENT7 ,MHPMEVENT8 ,MHPMEVENT9 ,MHPMEVENT10 ,MHPMEVENT11 ,MHPMEVENT12 ,MHPMEVENT13 ,MHPMEVENT14 ,MHPMEVENT15 ,MHPMEVENT16 ,MHPMEVENT17 ,MHPMEVENT18 ,MHPMEVENT19 ,MHPMEVENT20 ,MHPMEVENT21 ,MHPMEVENT22 ,MHPMEVENT23 ,MHPMEVENT24 ,MHPMEVENT25 ,MHPMEVENT26 ,MHPMEVENT27 ,MHPMEVENT28 ,MHPMEVENT29 ,MHPMEVENT30 ,MHPMEVENT31 ,PMPCFG0 ,PMPCFG1 ,PMPCFG2 ,PMPCFG3 ,PMPADDR0 ,PMPADDR1 ,PMPADDR2 ,PMPADDR3 ,PMPADDR4 ,PMPADDR5 ,PMPADDR6 ,PMPADDR7 ,PMPADDR8 ,PMPADDR9 ,PMPADDR10 ,PMPADDR11 ,PMPADDR12 ,PMPADDR13 ,PMPADDR14 ,PMPADDR15 ,ICACHE ,MHPMCOUNTER3 ,MHPMCOUNTER4 ,MHPMCOUNTER5 ,MHPMCOUNTER6 ,MHPMCOUNTER7 ,MHPMCOUNTER8 ,MHPMCOUNTER9 ,MHPMCOUNTER10 ,MHPMCOUNTER11 ,MHPMCOUNTER12 ,MHPMCOUNTER13 ,MHPMCOUNTER14 ,MHPMCOUNTER15 ,MHPMCOUNTER16 ,MHPMCOUNTER17 ,MHPMCOUNTER18 ,MHPMCOUNTER19 ,MHPMCOUNTER20 ,MHPMCOUNTER21 ,MHPMCOUNTER22 ,MHPMCOUNTER23 ,MHPMCOUNTER24 ,MHPMCOUNTER25 ,MHPMCOUNTER26 ,MHPMCOUNTER27 ,MHPMCOUNTER28 ,MHPMCOUNTER29 ,MHPMCOUNTER30 ,MHPMCOUNTER31 ,MHPMCOUNTERH3 ,MHPMCOUNTERH4 ,MHPMCOUNTERH5 ,MHPMCOUNTERH6 ,MHPMCOUNTERH7 ,MHPMCOUNTERH8 ,MHPMCOUNTERH9 ,MHPMCOUNTERH10 ,MHPMCOUNTERH11 ,MHPMCOUNTERH12 ,MHPMCOUNTERH13 ,MHPMCOUNTERH14 ,MHPMCOUNTERH15 ,MHPMCOUNTERH16 ,MHPMCOUNTERH17 ,MHPMCOUNTERH18 ,MHPMCOUNTERH19 ,MHPMCOUNTERH20 ,MHPMCOUNTERH21 ,MHPMCOUNTERH22 ,MHPMCOUNTERH23 ,MHPMCOUNTERH24 ,MHPMCOUNTERH25 ,MHPMCOUNTERH26 ,MHPMCOUNTERH27 ,MHPMCOUNTERH28 ,MHPMCOUNTERH29 ,MHPMCOUNTERH30 ,MHPMCOUNTERH31 ,
##########################
#MSTATUS testing W/R values '{'hffffffff, 'h0, 'h55555555, 'haaaaaaaa, 'hd13933c1}
##########################
#MSTATUS Write value 0xffffffff
li x3, 0xffffffff
csrw 0x300, x3
#MSTATUS read value, expected 0x807fffea
csrr x14, 0x300
#MSTATUS Write value 0x0
li x3, 0x0
csrw 0x300, x3
#MSTATUS read value, expected 0x0
csrr x14, 0x300
#MSTATUS Write value 0x55555555
li x3, 0x55555555
csrw 0x300, x3
#MSTATUS read value, expected 0x555540
csrr x14, 0x300
#MSTATUS Write value 0xaaaaaaaa
li x3, 0xaaaaaaaa
csrw 0x300, x3
#MSTATUS read value, expected 0x802aaaaa
csrr x14, 0x300
#MSTATUS Write value 0xd13933c1
li x3, 0xd13933c1
csrw 0x300, x3
#MSTATUS read value, expected 0x803933c0
csrr x14, 0x300
##########################
#MTVEC testing W/R values '{'hffffffff, 'h0, 'h55555555, 'haaaaaaaa, 'h30d053db}
##########################
#MTVEC Write value 0xffffffff
li x3, 0xffffffff
csrw 0x305, x3
#MTVEC read value, expected 0xffffffff
csrr x14, 0x305
#MTVEC Write value 0x0
li x3, 0x0
csrw 0x305, x3
#MTVEC read value, expected 0x0
csrr x14, 0x305
#MTVEC Write value 0x55555555
li x3, 0x55555555
csrw 0x305, x3
#MTVEC read value, expected 0x55555555
csrr x14, 0x305
#MTVEC Write value 0xaaaaaaaa
li x3, 0xaaaaaaaa
csrw 0x305, x3
#MTVEC read value, expected 0xaaaaaaaa
csrr x14, 0x305
#MTVEC Write value 0x30d053db
li x3, 0x30d053db
csrw 0x305, x3
#MTVEC read value, expected 0x30d053db
csrr x14, 0x305
##########################
#MINSTRET testing W/R values '{'hffffffff, 'h0, 'h55555555, 'haaaaaaaa, 'hb88086b0}
##########################
#MINSTRET Write value 0xffffffff
li x3, 0xffffffff
csrw 0xb02, x3
#MINSTRET read value, expected 0xffffffff
csrr x14, 0xb02
#MINSTRET Write value 0x0
li x3, 0x0
csrw 0xb02, x3
#MINSTRET read value, expected 0x0
csrr x14, 0xb02
#MINSTRET Write value 0x55555555
li x3, 0x55555555
csrw 0xb02, x3
#MINSTRET read value, expected 0x55555555
csrr x14, 0xb02
#MINSTRET Write value 0xaaaaaaaa
li x3, 0xaaaaaaaa
csrw 0xb02, x3
#MINSTRET read value, expected 0xaaaaaaaa
csrr x14, 0xb02
#MINSTRET Write value 0xb88086b0
li x3, 0xb88086b0
csrw 0xb02, x3
#MINSTRET read value, expected 0xb88086b0
csrr x14, 0xb02
##########################
#MIE testing W/R values '{'hffffffff, 'h0, 'h55555555, 'haaaaaaaa, 'hfef91206}
##########################
#MIE Write value 0xffffffff
li x3, 0xffffffff
csrw 0x304, x3
#MIE read value, expected 0xbbb
csrr x14, 0x304
#MIE Write value 0x0
li x3, 0x0
csrw 0x304, x3
#MIE read value, expected 0x0
csrr x14, 0x304
#MIE Write value 0x55555555
li x3, 0x55555555
csrw 0x304, x3
#MIE read value, expected 0x111
csrr x14, 0x304
#MIE Write value 0xaaaaaaaa
li x3, 0xaaaaaaaa
csrw 0x304, x3
#MIE read value, expected 0xaaa
csrr x14, 0x304
#MIE Write value 0xfef91206
li x3, 0xfef91206
csrw 0x304, x3
#MIE read value, expected 0x202
csrr x14, 0x304
##########################
#MIP testing W/R values '{'hffffffff, 'h0, 'h55555555, 'haaaaaaaa, 'hd3052355}
##########################
#MIP Write value 0xffffffff
li x3, 0xffffffff
csrw 0x344, x3
#MIP read value, expected 0xbbb
csrr x14, 0x344
#MIP Write value 0x0
li x3, 0x0
csrw 0x344, x3
#MIP read value, expected 0x0
csrr x14, 0x344
#MIP Write value 0x55555555
li x3, 0x55555555
csrw 0x344, x3
#MIP read value, expected 0x111
csrr x14, 0x344
#MIP Write value 0xaaaaaaaa
li x3, 0xaaaaaaaa
csrw 0x344, x3
#MIP read value, expected 0xaaa
csrr x14, 0x344
#MIP Write value 0xd3052355
li x3, 0xd3052355
csrw 0x344, x3
#MIP read value, expected 0x311
csrr x14, 0x344
##########################
#MEPC testing W/R values '{'hffffffff, 'h0, 'h55555555, 'haaaaaaaa, 'h7238da3e}
##########################
#MEPC Write value 0xffffffff
li x3, 0xffffffff
csrw 0x341, x3
#MEPC read value, expected 0xffffffff
csrr x14, 0x341
#MEPC Write value 0x0
li x3, 0x0
csrw 0x341, x3
#MEPC read value, expected 0x0
csrr x14, 0x341
#MEPC Write value 0x55555555
li x3, 0x55555555
csrw 0x341, x3
#MEPC read value, expected 0x55555555
csrr x14, 0x341
#MEPC Write value 0xaaaaaaaa
li x3, 0xaaaaaaaa
csrw 0x341, x3
#MEPC read value, expected 0xaaaaaaaa
csrr x14, 0x341
#MEPC Write value 0x7238da3e
li x3, 0x7238da3e
csrw 0x341, x3
#MEPC read value, expected 0x7238da3e
csrr x14, 0x341
##########################
#MCYCLEH testing W/R values '{'hffffffff, 'h0, 'h55555555, 'haaaaaaaa, 'h7572495f}
##########################
#MCYCLEH Write value 0xffffffff
li x3, 0xffffffff
csrw 0xb80, x3
#MCYCLEH read value, expected 0xffffffff
csrr x14, 0xb80
#MCYCLEH Write value 0x0
li x3, 0x0
csrw 0xb80, x3
#MCYCLEH read value, expected 0x0
csrr x14, 0xb80
#MCYCLEH Write value 0x55555555
li x3, 0x55555555
csrw 0xb80, x3
#MCYCLEH read value, expected 0x55555555
csrr x14, 0xb80
#MCYCLEH Write value 0xaaaaaaaa
li x3, 0xaaaaaaaa
csrw 0xb80, x3
#MCYCLEH read value, expected 0xaaaaaaaa
csrr x14, 0xb80
#MCYCLEH Write value 0x7572495f
li x3, 0x7572495f
csrw 0xb80, x3
#MCYCLEH read value, expected 0x7572495f
csrr x14, 0xb80
##########################
#MINSTRETH testing W/R values '{'hffffffff, 'h0, 'h55555555, 'haaaaaaaa, 'he0f0095e}
##########################
#MINSTRETH Write value 0xffffffff
li x3, 0xffffffff
csrw 0xb82, x3
#MINSTRETH read value, expected 0xffffffff
csrr x14, 0xb82
#MINSTRETH Write value 0x0
li x3, 0x0
csrw 0xb82, x3
#MINSTRETH read value, expected 0x0
csrr x14, 0xb82
#MINSTRETH Write value 0x55555555
li x3, 0x55555555
csrw 0xb82, x3
#MINSTRETH read value, expected 0x55555555
csrr x14, 0xb82
#MINSTRETH Write value 0xaaaaaaaa
li x3, 0xaaaaaaaa
csrw 0xb82, x3
#MINSTRETH read value, expected 0xaaaaaaaa
csrr x14, 0xb82
#MINSTRETH Write value 0xe0f0095e
li x3, 0xe0f0095e
csrw 0xb82, x3
#MINSTRETH read value, expected 0xe0f0095e
csrr x14, 0xb82
##########################
#MCAUSE testing W/R values '{'hffffffff, 'h0, 'h55555555, 'haaaaaaaa, 'hd43e7a20}
##########################
#MCAUSE Write value 0xffffffff
li x3, 0xffffffff
csrw 0x342, x3
#MCAUSE read value, expected 0xffffffff
csrr x14, 0x342
#MCAUSE Write value 0x0
li x3, 0x0
csrw 0x342, x3
#MCAUSE read value, expected 0x0
csrr x14, 0x342
#MCAUSE Write value 0x55555555
li x3, 0x55555555
csrw 0x342, x3
#MCAUSE read value, expected 0x55555555
csrr x14, 0x342
#MCAUSE Write value 0xaaaaaaaa
li x3, 0xaaaaaaaa
csrw 0x342, x3
#MCAUSE read value, expected 0xaaaaaaaa
csrr x14, 0x342
#MCAUSE Write value 0xd43e7a20
li x3, 0xd43e7a20
csrw 0x342, x3
#MCAUSE read value, expected 0xd43e7a20
csrr x14, 0x342
##########################
#MISA testing W/R values '{'hfdbf7bfb, 'h2408404, 'h55555555, 'haaaaaaaa, 'h2f0d4a6b}
##########################
#MISA Write value 0xfdbf7bfb
li x3, 0xfdbf7bfb
csrw 0x301, x3
#MISA read value, expected 0xc1bf7bfb
csrr x14, 0x301
#MISA Write value 0x2408404
li x3, 0x2408404
csrw 0x301, x3
#MISA read value, expected 0x2408404
csrr x14, 0x301
#MISA Write value 0x55555555
li x3, 0x55555555
csrw 0x301, x3
#MISA read value, expected 0x41555555
csrr x14, 0x301
#MISA Write value 0xaaaaaaaa
li x3, 0xaaaaaaaa
csrw 0x301, x3
#MISA read value, expected 0x82aaaaaa
csrr x14, 0x301
#MISA Write value 0x2f0d4a6b
li x3, 0x2f0d4a6b
csrw 0x301, x3
#MISA read value, expected 0x30d4a6b
csrr x14, 0x301
##########################
#MCYCLE testing W/R values '{'hffffffff, 'h0, 'h55555555, 'haaaaaaaa, 'hbfbcce35}
##########################
#MCYCLE Write value 0xffffffff
li x3, 0xffffffff
csrw 0xb00, x3
#MCYCLE read value, expected 0xffffffff
csrr x14, 0xb00
#MCYCLE Write value 0x0
li x3, 0x0
csrw 0xb00, x3
#MCYCLE read value, expected 0x0
csrr x14, 0xb00
#MCYCLE Write value 0x55555555
li x3, 0x55555555
csrw 0xb00, x3
#MCYCLE read value, expected 0x55555555
csrr x14, 0xb00
#MCYCLE Write value 0xaaaaaaaa
li x3, 0xaaaaaaaa
csrw 0xb00, x3
#MCYCLE read value, expected 0xaaaaaaaa
csrr x14, 0xb00
#MCYCLE Write value 0xbfbcce35
li x3, 0xbfbcce35
csrw 0xb00, x3
#MCYCLE read value, expected 0xbfbcce35
csrr x14, 0xb00
##########################
#MSCRATCH testing W/R values '{'hffffffff, 'h0, 'h55555555, 'haaaaaaaa, 'h5334c7f3}
##########################
#MSCRATCH Write value 0xffffffff
li x3, 0xffffffff
csrw 0x340, x3
#MSCRATCH read value, expected 0xffffffff
csrr x14, 0x340
#MSCRATCH Write value 0x0
li x3, 0x0
csrw 0x340, x3
#MSCRATCH read value, expected 0x0
csrr x14, 0x340
#MSCRATCH Write value 0x55555555
li x3, 0x55555555
csrw 0x340, x3
#MSCRATCH read value, expected 0x55555555
csrr x14, 0x340
#MSCRATCH Write value 0xaaaaaaaa
li x3, 0xaaaaaaaa
csrw 0x340, x3
#MSCRATCH read value, expected 0xaaaaaaaa
csrr x14, 0x340
#MSCRATCH Write value 0x5334c7f3
li x3, 0x5334c7f3
csrw 0x340, x3
#MSCRATCH read value, expected 0x5334c7f3
csrr x14, 0x340
##########################
#MSTATUSH testing W/R values '{'hffffffff, 'h0, 'h55555555, 'haaaaaaaa, 'h6391f8b7}
##########################
#MSTATUSH Write value 0xffffffff
li x3, 0xffffffff
csrw 0x310, x3
#MSTATUSH read value, expected 0x30
csrr x14, 0x310
#MSTATUSH Write value 0x0
li x3, 0x0
csrw 0x310, x3
#MSTATUSH read value, expected 0x0
csrr x14, 0x310
#MSTATUSH Write value 0x55555555
li x3, 0x55555555
csrw 0x310, x3
#MSTATUSH read value, expected 0x10
csrr x14, 0x310
#MSTATUSH Write value 0xaaaaaaaa
li x3, 0xaaaaaaaa
csrw 0x310, x3
#MSTATUSH read value, expected 0x20
csrr x14, 0x310
#MSTATUSH Write value 0x6391f8b7
li x3, 0x6391f8b7
csrw 0x310, x3
#MSTATUSH read value, expected 0x30
csrr x14, 0x310
##########################
#MTVAL testing W/R values '{'hffffffff, 'h0, 'h55555555, 'haaaaaaaa, 'h973a306b}
##########################
#MTVAL Write value 0xffffffff
li x3, 0xffffffff
csrw 0x343, x3
#MTVAL read value, expected 0xffffffff
csrr x14, 0x343
#MTVAL Write value 0x0
li x3, 0x0
csrw 0x343, x3
#MTVAL read value, expected 0x0
csrr x14, 0x343
#MTVAL Write value 0x55555555
li x3, 0x55555555
csrw 0x343, x3
#MTVAL read value, expected 0x55555555
csrr x14, 0x343
#MTVAL Write value 0xaaaaaaaa
li x3, 0xaaaaaaaa
csrw 0x343, x3
#MTVAL read value, expected 0xaaaaaaaa
csrr x14, 0x343
#MTVAL Write value 0x973a306b
li x3, 0x973a306b
csrw 0x343, x3
#MTVAL read value, expected 0x973a306b
csrr x14, 0x343
ret

View file

@ -0,0 +1,474 @@
# Copyright 2023 Thales DIS France SAS
#
# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
# You may obtain a copy of the License at https://solderpad.org/licenses/
#
csrrwi:
#Start CSR tests: Write/Read all registers using immediate instructions
#User ignored registers: MHPMEVENT3 ,MHPMEVENT4 ,MHPMEVENT5 ,MHPMEVENT6 ,MHPMEVENT7 ,MHPMEVENT8 ,MHPMEVENT9 ,MHPMEVENT10 ,MHPMEVENT11 ,MHPMEVENT12 ,MHPMEVENT13 ,MHPMEVENT14 ,MHPMEVENT15 ,MHPMEVENT16 ,MHPMEVENT17 ,MHPMEVENT18 ,MHPMEVENT19 ,MHPMEVENT20 ,MHPMEVENT21 ,MHPMEVENT22 ,MHPMEVENT23 ,MHPMEVENT24 ,MHPMEVENT25 ,MHPMEVENT26 ,MHPMEVENT27 ,MHPMEVENT28 ,MHPMEVENT29 ,MHPMEVENT30 ,MHPMEVENT31 ,PMPCFG0 ,PMPCFG1 ,PMPCFG2 ,PMPCFG3 ,PMPADDR0 ,PMPADDR1 ,PMPADDR2 ,PMPADDR3 ,PMPADDR4 ,PMPADDR5 ,PMPADDR6 ,PMPADDR7 ,PMPADDR8 ,PMPADDR9 ,PMPADDR10 ,PMPADDR11 ,PMPADDR12 ,PMPADDR13 ,PMPADDR14 ,PMPADDR15 ,ICACHE ,MHPMCOUNTER3 ,MHPMCOUNTER4 ,MHPMCOUNTER5 ,MHPMCOUNTER6 ,MHPMCOUNTER7 ,MHPMCOUNTER8 ,MHPMCOUNTER9 ,MHPMCOUNTER10 ,MHPMCOUNTER11 ,MHPMCOUNTER12 ,MHPMCOUNTER13 ,MHPMCOUNTER14 ,MHPMCOUNTER15 ,MHPMCOUNTER16 ,MHPMCOUNTER17 ,MHPMCOUNTER18 ,MHPMCOUNTER19 ,MHPMCOUNTER20 ,MHPMCOUNTER21 ,MHPMCOUNTER22 ,MHPMCOUNTER23 ,MHPMCOUNTER24 ,MHPMCOUNTER25 ,MHPMCOUNTER26 ,MHPMCOUNTER27 ,MHPMCOUNTER28 ,MHPMCOUNTER29 ,MHPMCOUNTER30 ,MHPMCOUNTER31 ,MHPMCOUNTERH3 ,MHPMCOUNTERH4 ,MHPMCOUNTERH5 ,MHPMCOUNTERH6 ,MHPMCOUNTERH7 ,MHPMCOUNTERH8 ,MHPMCOUNTERH9 ,MHPMCOUNTERH10 ,MHPMCOUNTERH11 ,MHPMCOUNTERH12 ,MHPMCOUNTERH13 ,MHPMCOUNTERH14 ,MHPMCOUNTERH15 ,MHPMCOUNTERH16 ,MHPMCOUNTERH17 ,MHPMCOUNTERH18 ,MHPMCOUNTERH19 ,MHPMCOUNTERH20 ,MHPMCOUNTERH21 ,MHPMCOUNTERH22 ,MHPMCOUNTERH23 ,MHPMCOUNTERH24 ,MHPMCOUNTERH25 ,MHPMCOUNTERH26 ,MHPMCOUNTERH27 ,MHPMCOUNTERH28 ,MHPMCOUNTERH29 ,MHPMCOUNTERH30 ,MHPMCOUNTERH31 ,
##########################
#MSTATUSH testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h1e}
##########################
#MSTATUSH Write immediate value 0x1f
csrrwi x14, 0x310, 0x1f
#MSTATUSH read value, expected 0x10
csrr x14, 0x310
#MSTATUSH Write immediate value 0x0
csrrwi x14, 0x310, 0x0
#MSTATUSH read value, expected 0x0
csrr x14, 0x310
#MSTATUSH Write immediate value 0x15
csrrwi x14, 0x310, 0x15
#MSTATUSH read value, expected 0x10
csrr x14, 0x310
#MSTATUSH Write immediate value 0xa
csrrwi x14, 0x310, 0xa
#MSTATUSH read value, expected 0x0
csrr x14, 0x310
#MSTATUSH Write immediate value 0x1e
csrrwi x14, 0x310, 0x1e
#MSTATUSH read value, expected 0x10
csrr x14, 0x310
##########################
#MIE testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h1c}
##########################
#MIE Write immediate value 0x1f
csrrwi x14, 0x304, 0x1f
#MIE read value, expected 0x1b
csrr x14, 0x304
#MIE Write immediate value 0x0
csrrwi x14, 0x304, 0x0
#MIE read value, expected 0x0
csrr x14, 0x304
#MIE Write immediate value 0x15
csrrwi x14, 0x304, 0x15
#MIE read value, expected 0x11
csrr x14, 0x304
#MIE Write immediate value 0xa
csrrwi x14, 0x304, 0xa
#MIE read value, expected 0xa
csrr x14, 0x304
#MIE Write immediate value 0x1c
csrrwi x14, 0x304, 0x1c
#MIE read value, expected 0x18
csrr x14, 0x304
##########################
#MCYCLEH testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'hc}
##########################
#MCYCLEH Write immediate value 0x1f
csrrwi x14, 0xb80, 0x1f
#MCYCLEH read value, expected 0x1f
csrr x14, 0xb80
#MCYCLEH Write immediate value 0x0
csrrwi x14, 0xb80, 0x0
#MCYCLEH read value, expected 0x0
csrr x14, 0xb80
#MCYCLEH Write immediate value 0x15
csrrwi x14, 0xb80, 0x15
#MCYCLEH read value, expected 0x15
csrr x14, 0xb80
#MCYCLEH Write immediate value 0xa
csrrwi x14, 0xb80, 0xa
#MCYCLEH read value, expected 0xa
csrr x14, 0xb80
#MCYCLEH Write immediate value 0xc
csrrwi x14, 0xb80, 0xc
#MCYCLEH read value, expected 0xc
csrr x14, 0xb80
##########################
#MSCRATCH testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h1c}
##########################
#MSCRATCH Write immediate value 0x1f
csrrwi x14, 0x340, 0x1f
#MSCRATCH read value, expected 0x1f
csrr x14, 0x340
#MSCRATCH Write immediate value 0x0
csrrwi x14, 0x340, 0x0
#MSCRATCH read value, expected 0x0
csrr x14, 0x340
#MSCRATCH Write immediate value 0x15
csrrwi x14, 0x340, 0x15
#MSCRATCH read value, expected 0x15
csrr x14, 0x340
#MSCRATCH Write immediate value 0xa
csrrwi x14, 0x340, 0xa
#MSCRATCH read value, expected 0xa
csrr x14, 0x340
#MSCRATCH Write immediate value 0x1c
csrrwi x14, 0x340, 0x1c
#MSCRATCH read value, expected 0x1c
csrr x14, 0x340
##########################
#MINSTRET testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h14}
##########################
#MINSTRET Write immediate value 0x1f
csrrwi x14, 0xb02, 0x1f
#MINSTRET read value, expected 0x1f
csrr x14, 0xb02
#MINSTRET Write immediate value 0x0
csrrwi x14, 0xb02, 0x0
#MINSTRET read value, expected 0x0
csrr x14, 0xb02
#MINSTRET Write immediate value 0x15
csrrwi x14, 0xb02, 0x15
#MINSTRET read value, expected 0x15
csrr x14, 0xb02
#MINSTRET Write immediate value 0xa
csrrwi x14, 0xb02, 0xa
#MINSTRET read value, expected 0xa
csrr x14, 0xb02
#MINSTRET Write immediate value 0x14
csrrwi x14, 0xb02, 0x14
#MINSTRET read value, expected 0x14
csrr x14, 0xb02
##########################
#MIP testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h2}
##########################
#MIP Write immediate value 0x1f
csrrwi x14, 0x344, 0x1f
#MIP read value, expected 0x1b
csrr x14, 0x344
#MIP Write immediate value 0x0
csrrwi x14, 0x344, 0x0
#MIP read value, expected 0x0
csrr x14, 0x344
#MIP Write immediate value 0x15
csrrwi x14, 0x344, 0x15
#MIP read value, expected 0x11
csrr x14, 0x344
#MIP Write immediate value 0xa
csrrwi x14, 0x344, 0xa
#MIP read value, expected 0xa
csrr x14, 0x344
#MIP Write immediate value 0x2
csrrwi x14, 0x344, 0x2
#MIP read value, expected 0x2
csrr x14, 0x344
##########################
#MTVEC testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h19}
##########################
#MTVEC Write immediate value 0x1f
csrrwi x14, 0x305, 0x1f
#MTVEC read value, expected 0x1f
csrr x14, 0x305
#MTVEC Write immediate value 0x0
csrrwi x14, 0x305, 0x0
#MTVEC read value, expected 0x0
csrr x14, 0x305
#MTVEC Write immediate value 0x15
csrrwi x14, 0x305, 0x15
#MTVEC read value, expected 0x15
csrr x14, 0x305
#MTVEC Write immediate value 0xa
csrrwi x14, 0x305, 0xa
#MTVEC read value, expected 0xa
csrr x14, 0x305
#MTVEC Write immediate value 0x19
csrrwi x14, 0x305, 0x19
#MTVEC read value, expected 0x19
csrr x14, 0x305
##########################
#MEPC testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h18}
##########################
#MEPC Write immediate value 0x1f
csrrwi x14, 0x341, 0x1f
#MEPC read value, expected 0x1f
csrr x14, 0x341
#MEPC Write immediate value 0x0
csrrwi x14, 0x341, 0x0
#MEPC read value, expected 0x0
csrr x14, 0x341
#MEPC Write immediate value 0x15
csrrwi x14, 0x341, 0x15
#MEPC read value, expected 0x15
csrr x14, 0x341
#MEPC Write immediate value 0xa
csrrwi x14, 0x341, 0xa
#MEPC read value, expected 0xa
csrr x14, 0x341
#MEPC Write immediate value 0x18
csrrwi x14, 0x341, 0x18
#MEPC read value, expected 0x18
csrr x14, 0x341
##########################
#MCYCLE testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h1}
##########################
#MCYCLE Write immediate value 0x1f
csrrwi x14, 0xb00, 0x1f
#MCYCLE read value, expected 0x1f
csrr x14, 0xb00
#MCYCLE Write immediate value 0x0
csrrwi x14, 0xb00, 0x0
#MCYCLE read value, expected 0x0
csrr x14, 0xb00
#MCYCLE Write immediate value 0x15
csrrwi x14, 0xb00, 0x15
#MCYCLE read value, expected 0x15
csrr x14, 0xb00
#MCYCLE Write immediate value 0xa
csrrwi x14, 0xb00, 0xa
#MCYCLE read value, expected 0xa
csrr x14, 0xb00
#MCYCLE Write immediate value 0x1
csrrwi x14, 0xb00, 0x1
#MCYCLE read value, expected 0x1
csrr x14, 0xb00
##########################
#MINSTRETH testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h6}
##########################
#MINSTRETH Write immediate value 0x1f
csrrwi x14, 0xb82, 0x1f
#MINSTRETH read value, expected 0x1f
csrr x14, 0xb82
#MINSTRETH Write immediate value 0x0
csrrwi x14, 0xb82, 0x0
#MINSTRETH read value, expected 0x0
csrr x14, 0xb82
#MINSTRETH Write immediate value 0x15
csrrwi x14, 0xb82, 0x15
#MINSTRETH read value, expected 0x15
csrr x14, 0xb82
#MINSTRETH Write immediate value 0xa
csrrwi x14, 0xb82, 0xa
#MINSTRETH read value, expected 0xa
csrr x14, 0xb82
#MINSTRETH Write immediate value 0x6
csrrwi x14, 0xb82, 0x6
#MINSTRETH read value, expected 0x6
csrr x14, 0xb82
##########################
#MCAUSE testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h7}
##########################
#MCAUSE Write immediate value 0x1f
csrrwi x14, 0x342, 0x1f
#MCAUSE read value, expected 0x1f
csrr x14, 0x342
#MCAUSE Write immediate value 0x0
csrrwi x14, 0x342, 0x0
#MCAUSE read value, expected 0x0
csrr x14, 0x342
#MCAUSE Write immediate value 0x15
csrrwi x14, 0x342, 0x15
#MCAUSE read value, expected 0x15
csrr x14, 0x342
#MCAUSE Write immediate value 0xa
csrrwi x14, 0x342, 0xa
#MCAUSE read value, expected 0xa
csrr x14, 0x342
#MCAUSE Write immediate value 0x7
csrrwi x14, 0x342, 0x7
#MCAUSE read value, expected 0x7
csrr x14, 0x342
##########################
#MISA testing W/R values '{'h1b, 'h4, 'h15, 'ha, 'h4}
##########################
#MISA Write immediate value 0x1b
csrrwi x14, 0x301, 0x1b
#MISA read value, expected 0x1b
csrr x14, 0x301
#MISA Write immediate value 0x4
csrrwi x14, 0x301, 0x4
#MISA read value, expected 0x4
csrr x14, 0x301
#MISA Write immediate value 0x15
csrrwi x14, 0x301, 0x15
#MISA read value, expected 0x15
csrr x14, 0x301
#MISA Write immediate value 0xa
csrrwi x14, 0x301, 0xa
#MISA read value, expected 0xa
csrr x14, 0x301
#MISA Write immediate value 0x4
csrrwi x14, 0x301, 0x4
#MISA read value, expected 0x4
csrr x14, 0x301
##########################
#MTVAL testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h3}
##########################
#MTVAL Write immediate value 0x1f
csrrwi x14, 0x343, 0x1f
#MTVAL read value, expected 0x1f
csrr x14, 0x343
#MTVAL Write immediate value 0x0
csrrwi x14, 0x343, 0x0
#MTVAL read value, expected 0x0
csrr x14, 0x343
#MTVAL Write immediate value 0x15
csrrwi x14, 0x343, 0x15
#MTVAL read value, expected 0x15
csrr x14, 0x343
#MTVAL Write immediate value 0xa
csrrwi x14, 0x343, 0xa
#MTVAL read value, expected 0xa
csrr x14, 0x343
#MTVAL Write immediate value 0x3
csrrwi x14, 0x343, 0x3
#MTVAL read value, expected 0x3
csrr x14, 0x343
##########################
#MSTATUS testing W/R values '{'h1f, 'h0, 'h15, 'ha, 'h18}
##########################
#MSTATUS Write immediate value 0x1f
csrrwi x14, 0x300, 0x1f
#MSTATUS read value, expected 0xa
csrr x14, 0x300
#MSTATUS Write immediate value 0x0
csrrwi x14, 0x300, 0x0
#MSTATUS read value, expected 0x0
csrr x14, 0x300
#MSTATUS Write immediate value 0x15
csrrwi x14, 0x300, 0x15
#MSTATUS read value, expected 0x0
csrr x14, 0x300
#MSTATUS Write immediate value 0xa
csrrwi x14, 0x300, 0xa
#MSTATUS read value, expected 0xa
csrr x14, 0x300
#MSTATUS Write immediate value 0x18
csrrwi x14, 0x300, 0x18
#MSTATUS read value, expected 0x8
csrr x14, 0x300
ret

View file

@ -0,0 +1,349 @@
# Copyright 2023 Thales DIS design services SAS
#
# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
# You may obtain a copy of the License at https://solderpad.org/licenses/
#
# Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
#*****************************************************************************
# load_reg_hazard.S
#-----------------------------------------------------------------------------
#
.globl main
main:
li ra, 0x80000000
li sp, 0x80000000
li gp, 0x80000000
li tp, 0x80000000
li t0, 0x80000000
li t1, 0x80000000
li t2, 0x80000000
li s0, 0x80000000
li s1, 0x80000000
li a0, 0x80000000
li a1, 0x80000000
li a2, 0x80000000
li a3, 0x80000000
li a4, 0x80000000
li a5, 0x80000000
li a6, 0x80000000
li a7, 0x80000000
li s2, 0x80000000
li s3, 0x80000000
li s4, 0x80000000
li s5, 0x80000000
li s6, 0x80000000
li s7, 0x80000000
li s8, 0x80000000
li s9, 0x80000000
li s10, 0x80000000
li s11, 0x80000000
li t3, 0x80000000
li t4, 0x80000000
li t5, 0x80000000
li t6, 0x80000000
lw zero, -16(zero)
lw sp, 1024(sp)
lw ra, 52(ra)
lw gp, 52(gp)
lw tp, 52(tp)
lw t0, 52(t0)
lw t1, 52(t1)
lw t2, 52(t2)
lw s0, 1024(s0)
lw s1, 1024(s1)
lw a0, 1024(a0)
lw a1, 1024(a1)
lw a2, 1024(a2)
lw a3, 1024(a3)
lw a4, 1024(a4)
lw a5, 1024(a5)
lw a6, 1024(a6)
lw a7, 1024(a7)
lw s2, 52(s2)
lw s3, 52(s3)
lw s4, 52(s4)
lw s5, 72(s5)
lw s6, 76(s6)
lw s7, 80(s7)
lw s8, 84(s8)
lw s9, 88(s9)
lw s10, 92(s10)
lw s11, 96(s11)
lw t3, 12(t3)
lw t4, 16(t4)
lw t5, 12(t5)
lw t6, 16(t6)
li ra, 0x80000000
li sp, 0x80000000
li gp, 0x80000000
li tp, 0x80000000
li t0, 0x80000000
li t1, 0x80000000
li t2, 0x80000000
li s0, 0x80000000
li s1, 0x80000000
li a0, 0x80000000
li a1, 0x80000000
li a2, 0x80000000
li a3, 0x80000000
li a4, 0x80000000
li a5, 0x80000000
li a6, 0x80000000
li a7, 0x80000000
li s2, 0x80000000
li s3, 0x80000000
li s4, 0x80000000
li s5, 0x80000000
li s6, 0x80000000
li s7, 0x80000000
li s8, 0x80000000
li s9, 0x80000000
li s10, 0x80000000
li s11, 0x80000000
li t3, 0x80000000
li t4, 0x80000000
li t5, 0x80000000
li t6, 0x80000000
lh zero, -16(zero)
lh sp, 1024(sp)
lh ra, 52(ra)
lh gp, 52(gp)
lh tp, 52(tp)
lh t0, 52(t0)
lh t1, 52(t1)
lh t2, 52(t2)
lh s0, 1024(s0)
lh s1, 1024(s1)
lh a0, 1024(a0)
lh a1, 1024(a1)
lh a2, 1024(a2)
lh a3, 1024(a3)
lh a4, 1024(a4)
lh a5, 1024(a5)
lh a6, 1024(a6)
lh a7, 1024(a7)
lh s2, 52(s2)
lh s3, 52(s3)
lh s4, 52(s4)
lh s5, 72(s5)
lh s6, 76(s6)
lh s7, 80(s7)
lh s8, 84(s8)
lh s9, 88(s9)
lh s10, 92(s10)
lh s11, 96(s11)
lh t3, 12(t3)
lh t4, 16(t4)
lh t5, 12(t5)
lh t6, 16(t6)
li ra, 0x80000000
li sp, 0x80000000
li gp, 0x80000000
li tp, 0x80000000
li t0, 0x80000000
li t1, 0x80000000
li t2, 0x80000000
li s0, 0x80000000
li s1, 0x80000000
li a0, 0x80000000
li a1, 0x80000000
li a2, 0x80000000
li a3, 0x80000000
li a4, 0x80000000
li a5, 0x80000000
li a6, 0x80000000
li a7, 0x80000000
li s2, 0x80000000
li s3, 0x80000000
li s4, 0x80000000
li s5, 0x80000000
li s6, 0x80000000
li s7, 0x80000000
li s8, 0x80000000
li s9, 0x80000000
li s10, 0x80000000
li s11, 0x80000000
li t3, 0x80000000
li t4, 0x80000000
li t5, 0x80000000
li t6, 0x80000000
lb zero, -16(zero)
lb sp, 1024(sp)
lb ra, 52(ra)
lb gp, 52(gp)
lb tp, 52(tp)
lb t0, 52(t0)
lb t1, 52(t1)
lb t2, 52(t2)
lb s0, 1024(s0)
lb s1, 1024(s1)
lb a0, 1024(a0)
lb a1, 1024(a1)
lb a2, 1024(a2)
lb a3, 1024(a3)
lb a4, 1024(a4)
lb a5, 1024(a5)
lb a6, 1024(a6)
lb a7, 1024(a7)
lb s2, 52(s2)
lb s3, 52(s3)
lb s4, 52(s4)
lb s5, 72(s5)
lb s6, 76(s6)
lb s7, 80(s7)
lb s8, 84(s8)
lb s9, 88(s9)
lb s10, 92(s10)
lb s11, 96(s11)
lb t3, 12(t3)
lb t4, 16(t4)
lb t5, 12(t5)
lb t6, 16(t6)
li ra, 0x80000000
li sp, 0x80000000
li gp, 0x80000000
li tp, 0x80000000
li t0, 0x80000000
li t1, 0x80000000
li t2, 0x80000000
li s0, 0x80000000
li s1, 0x80000000
li a0, 0x80000000
li a1, 0x80000000
li a2, 0x80000000
li a3, 0x80000000
li a4, 0x80000000
li a5, 0x80000000
li a6, 0x80000000
li a7, 0x80000000
li s2, 0x80000000
li s3, 0x80000000
li s4, 0x80000000
li s5, 0x80000000
li s6, 0x80000000
li s7, 0x80000000
li s8, 0x80000000
li s9, 0x80000000
li s10, 0x80000000
li s11, 0x80000000
li t3, 0x80000000
li t4, 0x80000000
li t5, 0x80000000
li t6, 0x80000000
lbu zero, -16(zero)
lbu sp, 1024(sp)
lbu ra, 52(ra)
lbu gp, 52(gp)
lbu tp, 52(tp)
lbu t0, 52(t0)
lbu t1, 52(t1)
lbu t2, 52(t2)
lbu s0, 1024(s0)
lbu s1, 1024(s1)
lbu a0, 1024(a0)
lbu a1, 1024(a1)
lbu a2, 1024(a2)
lbu a3, 1024(a3)
lbu a4, 1024(a4)
lbu a5, 1024(a5)
lbu a6, 1024(a6)
lbu a7, 1024(a7)
lbu s2, 52(s2)
lbu s3, 52(s3)
lbu s4, 52(s4)
lbu s5, 72(s5)
lbu s6, 76(s6)
lbu s7, 80(s7)
lbu s8, 84(s8)
lbu s9, 88(s9)
lbu s10, 92(s10)
lbu s11, 96(s11)
lbu t3, 12(t3)
lbu t4, 16(t4)
lbu t5, 12(t5)
lbu t6, 16(t6)
li ra, 0x80000000
li sp, 0x80000000
li gp, 0x80000000
li tp, 0x80000000
li t0, 0x80000000
li t1, 0x80000000
li t2, 0x80000000
li s0, 0x80000000
li s1, 0x80000000
li a0, 0x80000000
li a1, 0x80000000
li a2, 0x80000000
li a3, 0x80000000
li a4, 0x80000000
li a5, 0x80000000
li a6, 0x80000000
li a7, 0x80000000
li s2, 0x80000000
li s3, 0x80000000
li s4, 0x80000000
li s5, 0x80000000
li s6, 0x80000000
li s7, 0x80000000
li s8, 0x80000000
li s9, 0x80000000
li s10, 0x80000000
li s11, 0x80000000
li t3, 0x80000000
li t4, 0x80000000
li t5, 0x80000000
li t6, 0x80000000
lhu zero, -16(zero)
lhu sp, 1024(sp)
lhu ra, 52(ra)
lhu gp, 52(gp)
lhu tp, 52(tp)
lhu t0, 52(t0)
lhu t1, 52(t1)
lhu t2, 52(t2)
lhu s0, 1024(s0)
lhu s1, 1024(s1)
lhu a0, 1024(a0)
lhu a1, 1024(a1)
lhu a2, 1024(a2)
lhu a3, 1024(a3)
lhu a4, 1024(a4)
lhu a5, 1024(a5)
lhu a6, 1024(a6)
lhu a7, 1024(a7)
lhu s2, 52(s2)
lhu s3, 52(s3)
lhu s4, 52(s4)
lhu s5, 72(s5)
lhu s6, 76(s6)
lhu s7, 80(s7)
lhu s8, 84(s8)
lhu s9, 88(s9)
lhu s10, 92(s10)
lhu s11, 96(s11)
lhu t3, 12(t3)
lhu t4, 16(t4)
lhu t5, 12(t5)
lhu t6, 16(t6)
add t0, s8, t0
addi s8, t0, -420
lui s8, 902640
# (example of) final self-check test
li a0, 0xCAFE;
li a1, 0xCAFE;
xor a2, a0, a1;
beqz a2, pass;
fail:
# Failure post-processing (messages, ecall setup etc.)
li a0, 0x0;
jal exit;
pass:
# Success post-processing (messages, ecall setup etc.)
li a0, 0x0;
jal exit;

View file

@ -0,0 +1,71 @@
# Copyright 2023 Thales DIS design services SAS
#
# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
# You may obtain a copy of the License at https://solderpad.org/licenses/
#
# Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
#*****************************************************************************
# load_reg_hazard.S
#-----------------------------------------------------------------------------
#
.globl main
main:
mulhu s11, t3, s3
srl a3, s2, gp
c.mv sp, s5
addi a1, a1, -856
or s7, t0, a5
remu a3, s5, t5
c.nop
li s3, 0x0 #start riscv_int_numeric_corner_stream_0
li s1, 0xffffffff
li a5, 0x80000000
li sp, 0x80000000
li s10, 0x80000000
li t2, 0xffffffff
li t0, 0x0
li s6, 0x80000000
li tp, 0xffffffff
li ra, 0x0
addi s1, zero,0xffffff00
c.lwsp sp, 0(sp)
lb t0, 0(s1)
lh t0, 0(s1)
lw t0, 0(s1)
lbu t0, 0(s1)
lhu t0, 0(s1)
sb t0, 0(s1)
sh t0, 0(s1)
sw t0, 0(s1)
sb t0, -16(zero)
sh t0, -16(zero)
sw t0, -16(zero)
addi a0, zero,0xffffff00
c.sw a2, 124(a0)
c.lw a0, 124(s1)
c.sw a0, 124(s1)
c.sw a0, 124(a5)
mul a5, ra, s1
divu s6, ra, s6
auipc s10, 1013927
sub ra, ra, s10
div t0, t2, ra
# (example of) final self-check test
li a0, 0xCAFE;
li a1, 0xCAFE;
xor a2, a0, a1;
beqz a2, pass;
fail:
# Failure post-processing (messages, ecall setup etc.)
li a0, 0x0;
jal exit;
pass:
# Success post-processing (messages, ecall setup etc.)
li a0, 0x0;
jal exit;

View file

@ -26,43 +26,55 @@
# --------------------------------------------------------------------------------
- test: cvxif_add_nop
iterations: 1
iterations: 0
path_var: TESTS_PATH
gcc_opts: "-static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles ../tests/custom/common/syscalls.c ../tests/custom/common/crt.S -I../tests/custom/env -I../tests/custom/common -T ../tests/custom/common/test.ld"
asm_tests: <path_var>/custom/cv_xif/cvxif_add_nop.S
- test: cvxif_multi
iterations: 1
iterations: 0
path_var: TESTS_PATH
gcc_opts: "-static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles ../tests/custom/common/syscalls.c ../tests/custom/common/crt.S -I../tests/custom/env -I../tests/custom/common -T ../tests/custom/common/test.ld"
asm_tests: <path_var>/custom/cv_xif/cvxif_multi.S
- test: cvxif_rs3
iterations: 1
iterations: 0
path_var: TESTS_PATH
gcc_opts: "-static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles ../tests/custom/common/syscalls.c ../tests/custom/common/crt.S -I../tests/custom/env -I../tests/custom/common -T ../tests/custom/common/test.ld"
asm_tests: <path_var>/custom/cv_xif/cvxif_rs3.S
- test: cvxif_exc
iterations: 1
iterations: 0
path_var: TESTS_PATH
gcc_opts: "-static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles ../tests/custom/common/syscalls.c ../tests/custom/common/crt.S -I../tests/custom/env -I../tests/custom/common -T ../tests/custom/common/test.ld"
asm_tests: <path_var>/custom/cv_xif/cvxif_exc.S
- test: cvxif_illegal
iterations: 1
iterations: 0
path_var: TESTS_PATH
gcc_opts: "-static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles ../tests/custom/common/syscalls.c ../tests/custom/common/crt.S -I../tests/custom/env -I../tests/custom/common -T ../tests/custom/common/test.ld"
asm_tests: <path_var>/custom/cv_xif/cvxif_illegal.S
- test: cvxif_nopexc
iterations: 1
iterations: 0
path_var: TESTS_PATH
gcc_opts: "-static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles ../tests/custom/common/syscalls.c ../tests/custom/common/crt.S -I../tests/custom/env -I../tests/custom/common -T ../tests/custom/common/test.ld"
asm_tests: <path_var>/custom/cv_xif/cvxif_nopexc.S
- test: cvxif_issexc
iterations: 1
iterations: 0
path_var: TESTS_PATH
gcc_opts: "-static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles ../tests/custom/common/syscalls.c ../tests/custom/common/crt.S -I../tests/custom/env -I../tests/custom/common -T ../tests/custom/common/test.ld"
asm_tests: <path_var>/custom/cv_xif/cvxif_issexc.S
- test: cvxif_s_mode
iterations: 1
path_var: TESTS_PATH
gcc_opts: "-static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles ../tests/custom/common/syscalls.c ../tests/custom/common/crt.S -I../tests/custom/env -I../tests/custom/common -T ../tests/custom/common/test.ld -lgcc"
asm_tests: <path_var>/custom/cv_xif/cvxif_s_mode.S
- test: cvxif_u_mode
iterations: 1
path_var: TESTS_PATH
gcc_opts: "-static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles ../tests/custom/common/syscalls.c ../tests/custom/common/crt.S -I../tests/custom/env -I../tests/custom/common -T ../tests/custom/common/test.ld -lgcc"
asm_tests: <path_var>/custom/cv_xif/cvxif_u_mode.S

View file

@ -0,0 +1,50 @@
# Copyright 2023 Thales DIS design services SAS
#
# Licensed under the Solderpad Hardware Licence, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0
# You may obtain a copy of the License at https:#solderpad.org/licenses/
#
# Original Author: Ayoub JALALI (ayoub.jalali@external.thalesgroup.com)
# ================================================================================
# Regression test list format
# --------------------------------------------------------------------------------
# test : Assembly test name
# description : Description of this test
# gen_opts : Instruction generator options
# iterations : Number of iterations of this test
# no_iss : Enable/disable ISS simulator (Optional)
# gen_test : Test name used by the instruction generator
# asm_tests : Path to directed, hand-coded assembly test file or directory
# rtl_test : RTL simulation test name
# cmp_opts : Compile options passed to the instruction generator
# sim_opts : Simulation options passed to the instruction generator
# no_post_compare : Enable/disable comparison of trace log and ISS log (Optional)
# compare_opts : Options for the RTL & ISS trace comparison
# gcc_opts : gcc compile options
# --------------------------------------------------------------------------------
- test: branch_test
iterations: 1
path_var: TESTS_PATH
gcc_opts: "-static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles ../tests/custom/common/syscalls.c ../tests/custom/common/crt.S -I../tests/custom/env -I../tests/custom/common -T ../tests/custom/common/test.ld -lgcc"
asm_tests: <path_var>/custom/isacov/branch_to_zero.S
- test: load_reg_hazard
iterations: 1
path_var: TESTS_PATH
gcc_opts: "-static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles ../tests/custom/common/syscalls.c ../tests/custom/common/crt.S -I../tests/custom/env -I../tests/custom/common -T ../tests/custom/common/test.ld -lgcc"
asm_tests: <path_var>/custom/isacov/load_reg_hazard.S
- test: load_store_test
iterations: 1
path_var: TESTS_PATH
gcc_opts: "-static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles ../tests/custom/common/syscalls.c ../tests/custom/common/crt.S -I../tests/custom/env -I../tests/custom/common -T ../tests/custom/common/test.ld -lgcc"
asm_tests: <path_var>/custom/isacov/load_store_test.S
- test: csr_test
iterations: 1
path_var: TESTS_PATH
gcc_opts: "-static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles ../tests/custom/common/syscalls.c ../tests/custom/common/crt.S -I../tests/custom/env -I../tests/custom/common -T ../tests/custom/common/test.ld -lgcc"
asm_tests: <path_var>/custom/isacov/csr_test.S

View file

@ -141,7 +141,9 @@ function void uvma_cvxif_agent_c::create_components();
monitor = uvma_cvxif_mon_c ::type_id::create("monitor" , this);
vsequencer = uvma_cvxif_vsqr_c ::type_id::create("vsequencer", this);
driver = uvma_cvxif_drv_c ::type_id::create("driver" , this);
cov_model = uvma_cvxif_cov_model_c ::type_id::create("cov_model" , this);
if (cfg.cov_model_enabled) begin
cov_model = uvma_cvxif_cov_model_c ::type_id::create("cov_model" , this);
end
endfunction : create_components
@ -159,8 +161,10 @@ endfunction : connect_analysis_ports
function void uvma_cvxif_agent_c::connect_cov_model();
monitor.req_ap.connect(cov_model.req_item_fifo.analysis_export);
monitor.resp_ap.connect(cov_model.resp_item_fifo.analysis_export);
if (cfg.cov_model_enabled) begin
monitor.req_ap.connect(cov_model.req_item_fifo.analysis_export);
monitor.resp_ap.connect(cov_model.resp_item_fifo.analysis_export);
end
endfunction : connect_cov_model

View file

@ -18,56 +18,6 @@
*/
//covergroup instances
covergroup cg_executed(
string name
) with function sample(uvma_cvxif_req_item_c req_item);
option.per_instance = 1;
option.name = name;
cp_instr : coverpoint req_item.issue_req.instr {
wildcard bins CUS_ADD = {32'b0000000??????????000?????1111011};
wildcard bins CUS_ADD_RS3 = {32'b?????01??????????000?????1111011};
wildcard bins CUS_ADD_MULTI = {32'b0001000??????????000?????1111011};
wildcard bins CUS_M_ADD = {32'b0000100??????????000?????1111011};
wildcard bins CUS_S_ADD = {32'b0000110??????????000?????1111011};
wildcard bins CUS_NOP = {32'b00000000000000000000000001111011};
wildcard bins CUS_EXC = {32'b10000000000000000000000001111011};
}
endgroup: cg_executed
covergroup cg_cus_instr(
string name,
bit rs3_valid
) with function sample(uvma_cvxif_req_item_c req_item);
option.per_instance = 1;
option.name = name;
cp_rd : coverpoint req_item.issue_req.instr[11:7] {
bins RD[] = {[1:31]};
}
cp_rs1 : coverpoint req_item.issue_req.instr[19:15] {
bins RS1[] = {[0:31]};
}
cp_rs2 : coverpoint req_item.issue_req.instr[24:20] {
bins RS2[] = {[0:31]};
}
cp_rs3 : coverpoint req_item.issue_req.instr[31:27] {
ignore_bins IGN_RS3[] = {[0:31]} iff (!rs3_valid);
bins RS3[] = {[0:31]};
}
`CVXIF_CP_BITWISE(cp_rs1_toggle, req_item.issue_req.rs[0], 1)
`CVXIF_CP_BITWISE(cp_rs2_toggle, req_item.issue_req.rs[1], 1)
`CVXIF_CP_BITWISE(cp_rs3_toggle, req_item.issue_req.rs[2], rs3_valid) //TODO : fix need more filtring
endgroup: cg_cus_instr
covergroup cg_request(
string name
) with function sample(uvma_cvxif_req_item_c req_item);
@ -75,16 +25,6 @@ covergroup cg_request(
option.per_instance = 1;
option.name = name;
cp_instr : coverpoint req_item.issue_req.instr {
wildcard bins CUS_ADD = {32'b0000000??????????000?????1111011};
wildcard bins CUS_ADD_RS3 = {32'b?????01??????????000?????1111011};
wildcard bins CUS_ADD_MULTI = {32'b0001000??????????000?????1111011};
wildcard bins CUS_M_ADD = {32'b0000100??????????000?????1111011};
wildcard bins CUS_S_ADD = {32'b0000110??????????000?????1111011};
wildcard bins CUS_NOP = {32'b00000000000000000000000001111011};
wildcard bins CUS_EXC = {32'b10000000000000000000000001111011};
}
cp_valid : coverpoint req_item.issue_valid {
bins ISSUE_VALID [] = {[0:$]};
}
@ -117,9 +57,11 @@ covergroup cg_request(
bins COMMIT_VALID [] = {[0:$]};
}
cross_req : cross cp_instr, cp_id, cp_rs_valid, cp_mode;
cross_req : cross cp_id, cp_rs_valid, cp_mode;
cross_valid_ready : cross cp_valid, cp_ready;
cross_commit : cross cp_commit_valid, cp_commit_kill, cp_commit_id;
cross_commit : cross cp_commit_valid, cp_commit_kill, cp_commit_id {
ignore_bins IGN_BINS = binsof(cp_commit_valid) intersect{0}; //commit signals are valid when commmit_valid is assert
}
endgroup: cg_request
@ -220,20 +162,14 @@ covergroup cg_result(
}
cp_exccode : coverpoint resp_item.result.exccode {
bins EXCCODE [] = {[0:$]};
bins EXCCODE [] = {[0:9],[11:13],15,24}; //Supported Exception code
}
cp_result_valid : coverpoint resp_item.result_valid {
bins RESULT_VALID [] = {[0:$]};
cross_result : cross cp_id, cp_we, cp_exc, cp_exccode {
illegal_bins ILLEGAL_BINS = binsof(cp_we) intersect{1} &&
binsof(cp_exc) intersect{1};
ignore_bins IGN_BINS = binsof(cp_exc) intersect{0}; //if exc=0 that means no exception
}
cp_result_ready : coverpoint resp_item.result_ready {
bins RESULT_READY [] = {[0:$]};
}
cross_result : cross cp_id, cp_we, cp_exc, cp_exccode;
cross_valid_ready : cross cp_result_valid, cp_result_ready;
endgroup: cg_result
class uvma_cvxif_cov_model_c extends uvm_component;
@ -241,8 +177,6 @@ class uvma_cvxif_cov_model_c extends uvm_component;
// Objects
uvma_cvxif_cfg_c cfg ;
uvma_cvxif_cntxt_c cntxt ;
uvma_cvxif_req_item_c req_item ;
uvma_cvxif_resp_item_c resp_item;
// TLM
uvm_tlm_analysis_fifo#(uvma_cvxif_req_item_c ) req_item_fifo;
@ -253,16 +187,6 @@ class uvma_cvxif_cov_model_c extends uvm_component;
`uvm_field_object(cntxt, UVM_DEFAULT)
`uvm_component_utils_end
// Covergroups
//ADD INSTRUCTIONS
cg_cus_instr cus_add_cg;
cg_cus_instr cus_add_rs3_cg;
cg_cus_instr cus_add_multi_cg;
cg_cus_instr cus_add_m_cg;
cg_cus_instr cus_add_s_cg;
//Sequential instruction
cg_executed cus_seq_cg;
cg_request request_cg;
cg_response response_cg;
cg_result result_cg;
@ -325,18 +249,6 @@ function void uvma_cvxif_cov_model_c::build_phase(uvm_phase phase);
`uvm_fatal("CNTXT", "Context handle is null")
end
cus_add_cg = new("cus_add_cg",
.rs3_valid(0));
cus_add_rs3_cg = new("cus_add_rs3_cg",
.rs3_valid(1));
cus_add_multi_cg = new("cus_add_multi_cg",
.rs3_valid(0));
cus_add_m_cg = new("cus_add_m_cg",
.rs3_valid(0));
cus_add_s_cg = new("cus_add_s_cg",
.rs3_valid(0));
cus_seq_cg = new("cus_seq_cg");
request_cg = new("request_cg");
response_cg = new("response_cg",
.dual_read_write_support(cfg.dual_read_write_support_x),
@ -351,6 +263,10 @@ endfunction : build_phase
task uvma_cvxif_cov_model_c::run_phase(uvm_phase phase);
uvma_cvxif_req_item_c req_item ;
uvma_cvxif_resp_item_c resp_item;
super.run_phase(phase);
if (cfg.enabled && cfg.cov_model_enabled) begin
fork
@ -399,44 +315,6 @@ endfunction : sample_cntxt
function void uvma_cvxif_cov_model_c::sample_req_item(uvma_cvxif_req_item_c req_item);
// TODO Implement uvma_cvxif_cov_model_c::sample_req_item();
bit [6:0] opcode = req_item.issue_req.instr [6:0];
bit [6:0] custom3 = 7'b1111011;
bit [6:0] func7 = req_item.issue_req.instr [31:25];
bit [1:0] func2 = req_item.issue_req.instr [26:25];
bit [1:0] func3 = req_item.issue_req.instr [14:12];
bit [4:0] rd = req_item.issue_req.instr [11:7];
bit [4:0] rs1 = req_item.issue_req.instr [19:15];
bit [4:0] rs2 = req_item.issue_req.instr [24:20];
if (opcode != custom3 ) begin
`uvm_warning("CVXIF", $sformatf("Could not sample instruction: %b", req_item.issue_req.instr));
end
else begin
if (func3 == 0) begin
if (rd != 0) begin
if (func7 == 0) begin
cus_add_cg.sample(req_item);
end
if (func2 == 2'b01) begin
cus_add_rs3_cg.sample(req_item);
end
if (func7 == 7'b0001000) begin
cus_add_multi_cg.sample(req_item);
end
if (func7 == 7'b0000010) begin
cus_add_m_cg.sample(req_item);
end
if (func7 == 7'b0000110) begin
cus_add_s_cg.sample(req_item);
end
end
end
else begin
`uvm_warning("CVXIF", $sformatf("Could not sample instruction: %b", req_item.issue_req.instr));
end
end
cus_seq_cg.sample(req_item);
request_cg.sample(req_item);
endfunction : sample_req_item

View file

@ -28,6 +28,8 @@ class uvma_cvxif_cfg_c extends uvm_object;
rand bit dual_read_write_support_x;
rand bit load_store_support_x;
rand bit seq_cus_instr_x2_enabled;
rand bit reg_cus_crosses_enabled;
constraint reasonable_values {
soft uvma_cvxif_issue_ready inside {[4:10]};
@ -40,11 +42,6 @@ class uvma_cvxif_cfg_c extends uvm_object;
uvma_cvxif_issue_not_ready!=0 || uvma_cvxif_issue_ready != 0;
}
constraint support_feature { // The dual read & write also load store are enabled default
soft dual_read_write_support_x == 1;
soft load_store_support_x == 1;
}
constraint defaults_val {
soft ready_mode == UVMA_CVXIF_ISSUE_READY_FIX; // issue_ready is not randomized => the agent is always ready by default,
// you can randomize it by giving "UVMA_CVXIF_ISSUE_READY_RANDOMIZED" to "ready_mode"
@ -63,6 +60,10 @@ class uvma_cvxif_cfg_c extends uvm_object;
`uvm_field_int ( in_order, UVM_DEFAULT)
`uvm_field_int ( cov_model_enabled, UVM_DEFAULT)
`uvm_field_int ( enabled, UVM_DEFAULT)
`uvm_field_int ( dual_read_write_support_x, UVM_DEFAULT)
`uvm_field_int ( load_store_support_x, UVM_DEFAULT)
`uvm_field_int ( seq_cus_instr_x2_enabled, UVM_DEFAULT)
`uvm_field_int ( reg_cus_crosses_enabled, UVM_DEFAULT)
`uvm_object_utils_end
/**

View file

@ -87,4 +87,20 @@
wildcard bins BIT31_1 = {32'b1???????????????????????????????}; \
}
`define CVXIF_IMM_BITWISE(name, field, iff_exp) \
``name``: coverpoint(``field``) iff (``iff_exp``) { \
wildcard bins BIT0_0 = {6'b?????0}; \
wildcard bins BIT1_0 = {6'b????0?}; \
wildcard bins BIT2_0 = {6'b???0??}; \
wildcard bins BIT3_0 = {6'b??0???}; \
wildcard bins BIT4_0 = {6'b?0????}; \
wildcard bins BIT5_0 = {6'b0?????}; \
wildcard bins BIT0_1 = {6'b?????1}; \
wildcard bins BIT1_1 = {6'b????1?}; \
wildcard bins BIT2_1 = {6'b???1??}; \
wildcard bins BIT3_1 = {6'b??1???}; \
wildcard bins BIT4_1 = {6'b?1????}; \
wildcard bins BIT5_1 = {6'b1?????}; \
}
`endif // __UVMA_CVXIF_MACROS_SV__

View file

@ -36,10 +36,16 @@ typedef struct packed {
logic [5:0] exccode;
} result_t ;
typedef enum logic[1:0] {
PRIV_LVL_M = 2'b11,
PRIV_LVL_S = 2'b01,
PRIV_LVL_U = 2'b00
} priv_lvl_t;
typedef struct packed {
logic [31:0] instr;
logic [X_ID_WIDTH-1:0] id;
logic [1:0] mode;
priv_lvl_t mode;
logic [X_NUM_RS-1:0][X_RFR_WIDTH-1:0] rs;
logic [X_NUM_RS-1:0] rs_valid;
} x_issue_req;

View file

@ -550,9 +550,9 @@ covergroup cg_div_special_results(
}
cp_div_arithmetic_overflow : coverpoint instr.rs1_value {
//ignore_bins IGN_OVERFLOW = {[0:$]} with (!check_overflow);
`ifdef UNSUPPORTED_WITH
bins OFLOW = {32'h8000_0000} iff (check_overflow && instr.rs2_value == 32'hffff_ffff); //TODO
ignore_bins IGN_OVERFLOW = cp_div_arithmetic_overflow iff (!check_overflow);
bins OFLOW = {32'h8000_0000} iff (instr.rs2_value == 32'hffff_ffff); //TODO
`else
bins OFLOW = {32'h8000_0000} with (check_overflow) iff (instr.rs2_value == 32'hffff_ffff);
`endif
@ -1156,7 +1156,7 @@ covergroup cg_ciw(
option.per_instance = 1;
option.name = name;
cp_rd: coverpoint instr.c_rdp;
cp_c_rd: coverpoint instr.c_rd;
`ISACOV_CP_BITWISE(cp_rd_toggle, instr.rd_value, 1)
`ISACOV_CP_BITWISE_7_0(cp_imm_toggle, instr.get_field_imm(), 1)
@ -1187,15 +1187,14 @@ covergroup cg_cl(
ignore_bins NON_ZERO_OFF = {NON_ZERO} `WITH (imm_is_signed);
}
cp_rs1: coverpoint instr.c_rs1s;
cp_rd: coverpoint instr.c_rdp;
cp_c_rs1: coverpoint instr.c_rs1;
cp_c_rd: coverpoint instr.c_rd;
cp_rd_rs1_hazard: coverpoint instr.rd {
cp_c_rd_rs1_hazard: coverpoint instr.c_rd {
ignore_bins IGN_RS1_HAZARD_OFF = {[0:$]} `WITH (!reg_hazards_enabled);
bins RD[] = {[0:31]} iff (instr.rd == instr.rs1);
bins RD[] = {[0:7]} iff (instr.c_rd == instr.c_rs1);
}
`ISACOV_CP_BITWISE(cp_rs2_toggle, instr.rs2_value, 1)
`ISACOV_CP_BITWISE(cp_rs1_toggle, instr.rs1_value, 1)
`ISACOV_CP_BITWISE_4_0(cp_imm_toggle, instr.get_field_imm(), 1)
@ -1225,8 +1224,8 @@ covergroup cg_cs(
ignore_bins NON_ZERO_OFF = {NON_ZERO} `WITH (rs2_is_signed);
}
cp_rs1: coverpoint instr.c_rs1s;
cp_rs2: coverpoint instr.c_rs2s;
cp_c_rs1: coverpoint instr.c_rs1;
cp_c_rs2: coverpoint instr.c_rs2;
`ISACOV_CP_BITWISE(cp_rs2_toggle, instr.rs2_value, 1)
`ISACOV_CP_BITWISE(cp_rs1_toggle, instr.rs1_value, 1)
@ -1265,11 +1264,10 @@ covergroup cg_ca(
ignore_bins NON_ZERO_OFF = {NON_ZERO} `WITH (rd_is_signed);
}
cp_rs1: coverpoint instr.c_rs1s;
cp_rs2: coverpoint instr.c_rs2s;
cp_rd: coverpoint instr.c_rdp;
cp_c_rs2: coverpoint instr.c_rs2;
cp_c_rdrs1: coverpoint instr.c_rs1;
cross_rs1_rs2: cross cp_rs1, cp_rs2 {
cross_rs1_rs2: cross cp_c_rs2, cp_c_rdrs1 {
ignore_bins IGN_OFF = cross_rs1_rs2 `WITH (!reg_crosses_enabled);
}
@ -1301,7 +1299,7 @@ covergroup cg_cb(
ignore_bins NON_ZERO_OFF = {NON_ZERO} `WITH (imm_is_signed);
}
cp_rs1: coverpoint instr.c_rs1s;
cp_c_rs1: coverpoint instr.c_rs1;
`ISACOV_CP_BITWISE(cp_rs1_toggle, instr.rs1_value, 1)
`ISACOV_CP_BITWISE_7_0(cp_imm_toggle, instr.get_field_imm(), 1)
@ -1330,7 +1328,7 @@ covergroup cg_cb_andi(
ignore_bins NON_ZERO_OFF = {NON_ZERO} `WITH (imm_is_signed);
}
cp_rs1: coverpoint instr.rs1;
cp_c_rdrs1: coverpoint instr.c_rs1;
`ISACOV_CP_BITWISE(cp_rs1_toggle, instr.rs1_value, 1)
`ISACOV_CP_BITWISE_5_0(cp_imm_toggle, instr.get_field_imm(), 1)
@ -1357,7 +1355,7 @@ covergroup cg_cb_shift(
illegal_bins ILLEGAL_SHAMT[] = {[32:63]}; // MSB of the immediate value should be always zero
}
cp_rs1: coverpoint instr.rs1;
cp_c_rdrs1: coverpoint instr.c_rs1;
`ISACOV_CP_BITWISE(cp_rs1_toggle, instr.rs1_value, 1) // No need to toggle imm again because cp_shamt did the job
@ -1388,6 +1386,7 @@ covergroup cg_sequential(string name,
bit seq_instr_group_x4_enabled,
bit seq_instr_x2_enabled,
bit [CSR_MASK_WL-1:0] cfg_illegal_csr,
bit unaligned_access_supported,
bit ext_m_supported,
bit ext_c_supported,
bit ext_zba_supported,
@ -1417,24 +1416,28 @@ covergroup cg_sequential(string name,
cp_group: coverpoint (instr.group) {
illegal_bins ILL_EXT_M = {MUL_GROUP, MULTI_MUL_GROUP, DIV_GROUP} `WITH (!ext_m_supported);
illegal_bins ILL_EXT_A = {ALOAD_GROUP, ASTORE_GROUP, AMEM_GROUP} `WITH (!ext_a_supported);
illegal_bins ILL_MISALIGN = {MISALIGN_LOAD_GROUP, MISALIGN_STORE_GROUP} `WITH (!unaligned_access_supported);
}
cp_group_pipe_x2: coverpoint (instr_prev.group) iff (instr_prev != null) {
ignore_bins IGN_X2_OFF = {[0:$]} `WITH (!seq_instr_group_x2_enabled);
illegal_bins ILL_EXT_M = {MUL_GROUP, MULTI_MUL_GROUP, DIV_GROUP} `WITH (!ext_m_supported);
illegal_bins ILL_EXT_A = {ALOAD_GROUP, ASTORE_GROUP, AMEM_GROUP} `WITH (!ext_a_supported);
illegal_bins ILL_MISALIGN = {MISALIGN_LOAD_GROUP, MISALIGN_STORE_GROUP} `WITH (!unaligned_access_supported);
}
cp_group_pipe_x3: coverpoint (instr_prev2.group) iff (instr_prev2 != null) {
ignore_bins IGN_X3_OFF = {[0:$]} `WITH (!seq_instr_group_x3_enabled);
illegal_bins ILL_EXT_M = {MUL_GROUP, MULTI_MUL_GROUP, DIV_GROUP} `WITH (!ext_m_supported);
illegal_bins ILL_EXT_A = {ALOAD_GROUP, ASTORE_GROUP, AMEM_GROUP} `WITH (!ext_a_supported);
illegal_bins ILL_MISALIGN = {MISALIGN_LOAD_GROUP, MISALIGN_STORE_GROUP} `WITH (!unaligned_access_supported);
}
cp_group_pipe_x4: coverpoint (instr_prev3.group) iff (instr_prev3 != null) {
ignore_bins IGN_X4_OFF = {[0:$]} `WITH (!seq_instr_group_x4_enabled);
illegal_bins ILL_EXT_M = {MUL_GROUP, MULTI_MUL_GROUP, DIV_GROUP} `WITH (!ext_m_supported);
illegal_bins ILL_EXT_A = {ALOAD_GROUP, ASTORE_GROUP, AMEM_GROUP} `WITH (!ext_a_supported);
illegal_bins ILL_MISALIGN = {MISALIGN_LOAD_GROUP, MISALIGN_STORE_GROUP} `WITH (!unaligned_access_supported);
}
cp_gpr_raw_hazard: coverpoint(raw_hazard) {
@ -1455,10 +1458,23 @@ covergroup cg_sequential(string name,
cross_seq_group_x3: cross cp_group, cp_group_pipe_x2, cp_group_pipe_x3;
cross_seq_group_x4: cross cp_group, cp_group_pipe_x2, cp_group_pipe_x3, cp_group_pipe_x4;
// FIXME: This will need more filtering
cross_seq_gpr_raw_hazard: cross cp_group, cp_group_pipe_x2, cp_gpr_raw_hazard {
// Ignore non-hazard bins
ignore_bins IGN_HAZ = binsof(cp_gpr_raw_hazard) intersect {0};
ignore_bins IGN_GROUP = binsof(cp_group) intersect {UNKNOWN_GROUP,
FENCE_GROUP,
FENCE_I_GROUP,
RET_GROUP,
WFI_GROUP,
ENV_GROUP};
ignore_bins IGN_PREV_GROUP = binsof(cp_group_pipe_x2) intersect {UNKNOWN_GROUP,
FENCE_GROUP,
FENCE_I_GROUP,
RET_GROUP,
WFI_GROUP,
ENV_GROUP,
STORE_GROUP,
BRANCH_GROUP};
}
cross_seq_csr_hazard_x2: cross cp_csr, cp_instr, cp_csr_hazard {
@ -2374,6 +2390,7 @@ function void uvma_isacov_cov_model_c::build_phase(uvm_phase phase);
.seq_instr_group_x4_enabled(cfg.seq_instr_group_x4_enabled),
.seq_instr_x2_enabled(cfg.seq_instr_x2_enabled),
.cfg_illegal_csr(cfg.core_cfg.unsupported_csr_mask),
.unaligned_access_supported(cfg.core_cfg.unaligned_access_supported),
.ext_m_supported(cfg.core_cfg.ext_m_supported),
.ext_c_supported(cfg.core_cfg.ext_c_supported),
.ext_a_supported(cfg.core_cfg.ext_a_supported),

View file

@ -48,10 +48,13 @@ class uvma_isacov_instr_c#(int ILEN=DEFAULT_ILEN,
bit rs2_valid;
bit rd_valid;
// rx for compressed instruction (5-bit encoding)
bit [4:0] c_rdrs1;
bit [2:0] c_rs1s;
bit [2:0] c_rs2s;
bit [2:0] c_rdp;
// rx for compressed instruction (3-bit encoding)
bit [2:0] c_rs1;
bit [2:0] c_rs2;
bit [2:0] c_rd;
bit[XLEN-1:0] rs1_value;
instr_value_t rs1_value_type;
@ -93,6 +96,11 @@ class uvma_isacov_instr_c#(int ILEN=DEFAULT_ILEN,
`uvm_field_int(rd_valid, UVM_ALL_ON | UVM_NOPRINT);
`uvm_field_enum(instr_value_t, rd_value_type, UVM_ALL_ON | UVM_NOPRINT);
`uvm_field_int(c_rdrs1, UVM_ALL_ON | UVM_NOPRINT);
`uvm_field_int(c_rs1, UVM_ALL_ON | UVM_NOPRINT);
`uvm_field_int(c_rs2, UVM_ALL_ON | UVM_NOPRINT);
`uvm_field_int(c_rd, UVM_ALL_ON | UVM_NOPRINT);
`uvm_field_int(immi, UVM_ALL_ON | UVM_NOPRINT);
`uvm_field_enum(instr_value_t, immi_value_type, UVM_ALL_ON | UVM_NOPRINT);
`uvm_field_int(imms, UVM_ALL_ON | UVM_NOPRINT);
@ -126,6 +134,10 @@ class uvma_isacov_instr_c#(int ILEN=DEFAULT_ILEN,
extern function int get_addr_rs1();
extern function int get_addr_rs2();
extern function int get_data_imm();
extern function int decode_rd_c(bit[ILEN-1:0] instr);
extern function int decode_rs1_c(bit[ILEN-1:0] instr);
extern function int decode_rs2_c(bit[ILEN-1:0] instr);
endclass : uvma_isacov_instr_c
@ -174,19 +186,19 @@ function string uvma_isacov_instr_c::convert2string();
instr_str = $sformatf("x%0d, %0d(x2)", this.get_addr_rs2(), this.get_data_imm());
end
if (itype == CIW_TYPE) begin
instr_str = $sformatf("x%0d, x2, %0d", this.get_addr_rd(), this.get_data_imm());
instr_str = $sformatf("x%0d, x2, %0d", this.decode_rd_c($signed(this.rvfi.insn)), this.get_data_imm());
end
if (itype == CL_TYPE) begin
instr_str = $sformatf("x%0d, x%0d, %0d", this.get_addr_rd(), this.get_addr_rs1(), get_data_imm());
instr_str = $sformatf("x%0d, %0d(x%0d)", this.decode_rd_c($signed(this.rvfi.insn)), this.get_data_imm(), this.decode_rs1_c($signed(this.rvfi.insn)));
end
if (itype == CS_TYPE) begin
instr_str = $sformatf("x%0d, %0d(x%0d)", this.get_addr_rs2, this.get_data_imm(), this.get_addr_rs1);
instr_str = $sformatf("x%0d, %0d(x%0d)", this.decode_rs2_c($signed(this.rvfi.insn)), this.get_data_imm(), this.decode_rs1_c($signed(this.rvfi.insn)));
end
if (itype == CA_TYPE) begin
instr_str = $sformatf("x%0d, x%0d", this.get_addr_rd(), this.get_addr_rs2());
instr_str = $sformatf("x%0d, x%0d", this.decode_rs1_c($signed(this.rvfi.insn)), this.decode_rs2_c($signed(this.rvfi.insn)));
end
if (itype == CB_TYPE) begin
instr_str = $sformatf("x%0d, %0x", this.get_addr_rs1(), ($signed(rvfi.pc_rdata) + this.get_data_imm()));
instr_str = $sformatf("x%0d, %0x", this.decode_rs1_c($signed(this.rvfi.insn)), ($signed(rvfi.pc_rdata) + this.get_data_imm()));
end
if (itype == CJ_TYPE) begin
instr_str = $sformatf("%0x", ($signed(rvfi.pc_rdata) + this.get_data_imm()));
@ -211,10 +223,10 @@ function string uvma_isacov_instr_c::convert2string();
instr_str = $sformatf("x%0d, 0x%0x", this.get_addr_rd(), this.get_data_imm());
end
if (name inside {C_SRAI, C_SRLI}) begin
instr_str = $sformatf("x%0d, 0x%0x", this.get_addr_rs1(), this.get_data_imm());
instr_str = $sformatf("x%0d, 0x%0x", this.decode_rs1_c($signed(this.rvfi.insn)), this.get_data_imm());
end
if (name == C_ANDI) begin
instr_str = $sformatf("x%0d, %0d", this.get_addr_rd(), $signed(this.get_data_imm()));
instr_str = $sformatf("x%0d, %0d", this.decode_rs1_c($signed(this.rvfi.insn)), $signed(this.get_data_imm()));
end
if (name == FENCE) begin
instr_str = "iorw, iorw"; // Note: If later found necessary, add support for `fence` arguments other than "iorw"
@ -480,7 +492,7 @@ function int uvma_isacov_instr_c::get_data_imm();
bit [63:0] instr = $signed(this.rvfi.insn);
int imm = this.get_field_imm();
if (this.itype inside {CSS_TYPE, CIW_TYPE, CS_TYPE}) begin
if (this.itype inside {CSS_TYPE, CIW_TYPE, CS_TYPE, CL_TYPE}) begin
return {imm, 2'b 00};
end
if (this.itype inside {CJ_TYPE} || this.name inside {C_BEQZ, C_BNEZ}) begin
@ -497,6 +509,23 @@ function int uvma_isacov_instr_c::get_data_imm();
endfunction : get_data_imm
function int uvma_isacov_instr_c::decode_rd_c(bit[ILEN-1:0] instr); //function to extract the rd' (3 bits) address from a compressed instruction
return instr[4:2] + 8;
endfunction : decode_rd_c
function int uvma_isacov_instr_c::decode_rs1_c(bit[ILEN-1:0] instr); //function to extract the rs1' (3 bits) address from a compressed instruction
return instr[9:7] + 8;
endfunction : decode_rs1_c
function int uvma_isacov_instr_c::decode_rs2_c(bit[ILEN-1:0] instr); //function to extract the rs2' (3 bits) address from a compressed instruction
return instr[4:2] + 8;
endfunction : decode_rs2_c
function bit uvma_isacov_instr_c::is_conditional_branch();

View file

@ -167,9 +167,9 @@ function void uvma_isacov_mon_c::write_rvfi_instr(uvma_rvfi_instr_seq_item_c#(IL
mon_trn.instr.rs2 = dasm_rvc_rs2(instr);
mon_trn.instr.rd = dasm_rvc_rd(instr);
mon_trn.instr.c_rdrs1 = dasm_rvc_rd(instr);
mon_trn.instr.c_rdp = dasm_rvc_rs1s(instr);
mon_trn.instr.c_rs1s = dasm_rvc_rs1s(instr);
mon_trn.instr.c_rs2s = dasm_rvc_rs2s(instr);
mon_trn.instr.c_rd = mon_trn.instr.decode_rd_c(instr);
mon_trn.instr.c_rs1 = mon_trn.instr.decode_rs1_c(instr);
mon_trn.instr.c_rs2 = mon_trn.instr.decode_rs2_c(instr);
end
else begin
mon_trn.instr.rs1 = dasm_rs1(instr);

View file

@ -204,9 +204,10 @@ task uvma_rvfi_instr_mon_c::monitor_rvfi_instr();
end
end
end
dcsr_ret_data = mon_trn.csrs["dcsr"].get_csr_retirement_data();
// In debug mode, detect NMIP event for a data bus error
if (mon_trn.csrs.exists("dcsr")) begin
dcsr_ret_data = mon_trn.csrs["dcsr"].get_csr_retirement_data();
end
// In debug mode, detect NMIP event for a data bus error
if (mon_trn.dbg_mode &&
!last_dcsr_nmip &&
mon_trn.nmip[0] &&

View file

@ -0,0 +1,12 @@
diff --git a/fesvr/fesvr.mk.in b/fesvr/fesvr.mk.in
index 695de5278..43aed6786 100644
--- a/fesvr/fesvr.mk.in
+++ b/fesvr/fesvr.mk.in
@@ -20,6 +20,7 @@ fesvr_install_hdrs = $(fesvr_hdrs)
fesvr_install_config_hdr = yes
fesvr_install_lib = yes
+fesvr_install_shared_lib = yes
fesvr_srcs = \
elfloader.cc \

View file

@ -0,0 +1,15 @@
diff --git a/riscv/extensions.cc b/riscv/extensions.cc
index 347dc5e91..b488aad15 100644
--- a/riscv/extensions.cc
+++ b/riscv/extensions.cc
@@ -27,8 +27,8 @@ std::function<extension_t*()> find_extension(const char* name)
if (!dlh) {
dlh = dlopen(libdefault.c_str(), RTLD_LAZY);
if (!dlh) {
- fprintf(stderr, "couldn't find shared library either '%s' or '%s')\n",
- libname.c_str(), libdefault.c_str());
+ fprintf(stderr, "couldn't load shared library (either '%s' or '%s'), reason: %s\n",
+ libname.c_str(), libdefault.c_str(), dlerror());
exit(-1);
}

View file

@ -0,0 +1,533 @@
diff --git a/customext/customext.mk.in b/customext/customext.mk.in
index a14e771c2..888634b46 100644
--- a/customext/customext.mk.in
+++ b/customext/customext.mk.in
@@ -7,5 +7,6 @@ customext_subproject_deps = \
customext_srcs = \
dummy_rocc.cc \
cflush.cc \
+ cvxif.cc \
customext_install_shared_lib = yes
diff --git a/customext/cvxif.cc b/customext/cvxif.cc
new file mode 100644
index 000000000..dd1a7329a
--- /dev/null
+++ b/customext/cvxif.cc
@@ -0,0 +1,226 @@
+// Copyright (C) 2022 Thales DIS Design Services SAS
+//
+// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0.
+//
+// Original Author: Zbigniew CHAMSKI <zbigniew.chamski@thalesgroup.com>
+
+#include "cvxif.h"
+#include "mmu.h"
+#include <cstring>
+
+// Define custom insns templates.
+// The insn-level wrapper is 'c##n' (default implementation,
+// writeback disabled), the default implementation
+// is 'custom##n': illegal instruction, return 0.
+// The writeback controller 'cvxif_extn_t::do_writeback_p'
+// is in charge of determining if writeback is required or not.
+// Expected instruction encoding is 4 bytes.
+#define customX(n) \
+static reg_t c##n(processor_t* p, insn_t insn, reg_t pc) \
+ { \
+ cvxif_t* cvxif = static_cast<cvxif_t*>(p->get_extension()); \
+ cvxif_insn_t custom_insn; \
+ custom_insn.i = insn; \
+ reg_t xd = cvxif->default_custom##n(custom_insn); \
+ if (cvxif->do_writeback_p(custom_insn)) \
+ WRITE_RD(xd); \
+ return pc+4; \
+ } \
+ \
+ reg_t default_custom##n(cvxif_insn_t insn) \
+ { \
+ return custom##n(insn); \
+ }
+
+// This class instantiates the CV-X-IF interface.
+class cvxif_t : public cvxif_extn_t
+{
+ public:
+ const char* name() { return "cvxif_spike"; }
+
+ bool do_writeback_p(cvxif_insn_t copro_insn)
+ {
+ // INSN_R personality serves to simplify access to standard encoding fields.
+ cvxif_r_insn_t insn_r = copro_insn.r_type;
+
+ if (insn_r.opcode != MATCH_CUSTOM3)
+ return false;
+ else switch (insn_r.funct3)
+ {
+ case 0b000:
+ // CUSTOM_NOP and CUSTOM_EXC have rd == x0.
+ // Return TRUE if destination is NOT x0.
+ return (insn_r.rd != 0x0);
+
+ case 0b010:
+ // Return false for CUS_SD.
+ return false;
+
+ default:
+ // All other cases: writeback is assumed REQUIRED.
+ return true;
+ }
+ }
+
+ // Custom0 instructions: default behaviour.
+ reg_t custom0(cvxif_insn_t incoming_insn)
+ {
+ illegal_instruction();
+ return -1;
+ }
+
+ // Custom1 instructions: default behaviour.
+ reg_t custom1(cvxif_insn_t incoming_insn)
+ {
+ illegal_instruction();
+ return -1;
+ }
+
+ // Custom2 instructions: default behaviour.
+ reg_t custom2(cvxif_insn_t incoming_insn)
+ {
+ illegal_instruction();
+ return -1;
+ }
+
+ // Custom3 instructions: provide an explicit implementation of decode+exec.
+ reg_t custom3(cvxif_insn_t incoming_insn)
+ {
+ // Assume R-type insn: it shares opcode and funct3 fields with other CVXIF insn formats.
+ cvxif_r_insn_t r_insn = incoming_insn.r_type;
+ // INSN_T simplifies access to register values.
+ insn_t insn = incoming_insn.i;
+
+ switch (r_insn.funct3)
+ {
+ case 0:
+
+ // funct7[1:0] == 0b01: three-input RV add.
+ // If rd is x0: illegal instruction.
+ if ((r_insn.funct7 & 0x3) == 0b01)
+ {
+ if (insn.rd() == 0x0)
+ illegal_instruction();
+
+ // Destination is not x0: R4-type insn performing a 3-operand RV add
+ return (reg_t) ((reg_t) RS1 + (reg_t) RS2 + (reg_t) RS3);
+ }
+
+ // Non-memory operations (including NOP and EXC)
+ switch (r_insn.funct7 & 0b1111001)
+ {
+ case 0:
+ {
+ // Single-cycle RV addition with privilege: all non-privilege bits are zero.
+ // funct7[2:1] == 0x0 (PRV_U): CUS_ADD (single-cycle RV ADD, any mode)
+ // funct7[2:1] == 0x1 (PRV_S): CUS_S_ADD (single-cycle S-/M-mode RV ADD)
+ // funct7[2:1] == 0x2 (PRV_HS): ILLEGAL
+ // funct7[2:1] == 0x3 (PRV_M): CUS_M_ADD (single-cycle M-mode RV ADD)
+ reg_t required_priv = (r_insn.funct7 & 0x6) >> 1;
+ if (required_priv != PRV_HS && (p->get_state()->prv & required_priv) == required_priv)
+ return (reg_t) ((reg_t) RS1 + (reg_t) RS2);
+ else
+ illegal_instruction();
+ }
+
+ case 0x8:
+ // Multi-cycle RV add.
+ // TODO FIXME: Represent delay.
+ return (reg_t) ((reg_t) RS1 + (reg_t) RS2);
+
+ case 0x40:
+ // Exception. MCAUSE[4:0] encoded in RS1, MCAUSE[5] assumed to be 0.
+ if (insn.rd() == 0x0 && insn.rs2() == 0x0)
+ {
+ // Raise an exception only if registers rd and rs2 are both x0 (no 'bit 5' extension yet).
+ raise_exception(insn, insn.rs1());
+ // Writeback will be disabled by 'do_writeback_p'.
+ return (reg_t) -1;
+ }
+ else
+ // Illegal instruction.
+ illegal_instruction();
+
+ default:
+ illegal_instruction();
+ }
+
+ case 1:
+ // Perform RV load. If runtime XLEN is not 64, assume 32.
+ if (p->get_xlen() == 64)
+ return MMU.load_int64(RS1 + insn.i_imm());
+ else
+ return MMU.load_int32(RS1 + insn.i_imm());
+
+ case 2:
+ // Perform RV store. If runtime XLEN is not 64, assume 32.
+ if (p->get_xlen() == 64)
+ MMU.store_uint64(RS1 + insn.s_imm(), RS2);
+ else
+ MMU.store_uint32(RS1 + insn.s_imm(), RS2);
+
+ // Writeback will be disabled by 'do_writeback_p'.
+ break;
+
+ default:
+ illegal_instruction();
+ }
+
+ // FORNOW: Return 0xf......f to simplify debugging.
+ return (reg_t) -1;
+ }
+
+ cvxif_t()
+ {
+ }
+
+ void raise_exception(insn_t insn, reg_t exc_index)
+ {
+ switch (exc_index) {
+ case CAUSE_MISALIGNED_LOAD:
+ // Use 0x1 as perfectly unaligned address;-)
+ throw trap_load_address_misaligned((p ? p->get_state()->v : false), 1, 0, 0);
+ case CAUSE_LOAD_ACCESS:
+ // Use 0x1 as invalid address.
+ throw trap_load_access_fault((p ? p->get_state()->v : false), 1, 0, 0);
+ case CAUSE_MISALIGNED_STORE:
+ // Use 0x1 as perfectly unaligned address;-)
+ throw trap_store_address_misaligned((p ? p->get_state()->v : false), 1, 0, 0);
+ case CAUSE_STORE_ACCESS:
+ // Use 0x1 as invalid address.
+ throw trap_store_access_fault((p ? p->get_state()->v : false), 1, 0, 0);
+ case CAUSE_LOAD_PAGE_FAULT:
+ // Use 0x1 as always-faulting address.
+ throw trap_load_page_fault((p ? p->get_state()->v : false), 1, 0, 0);
+ case CAUSE_STORE_PAGE_FAULT:
+ // Use 0x1 as always-faulting address.
+ throw trap_store_page_fault((p ? p->get_state()->v : false), 1, 0, 0);
+ default:
+ illegal_instruction();
+ }
+ }
+
+ // Define templates of new instructions.
+ customX(0)
+ customX(1)
+ customX(2)
+ customX(3)
+
+ // Set instruction handlers for customN opcode patterns.
+ // NOTE: This method may need revisiting if multiple custom extensions are to be loaded
+ // simultaneously in the future.
+ std::vector<insn_desc_t> get_instructions()
+ {
+ std::vector<insn_desc_t> insns;
+ insns.push_back((insn_desc_t){0x0b, 0x7f, &::illegal_instruction, c0});
+ insns.push_back((insn_desc_t){0x2b, 0x7f, &::illegal_instruction, c1});
+ insns.push_back((insn_desc_t){0x5b, 0x7f, &::illegal_instruction, c2});
+ insns.push_back((insn_desc_t){0x7b, 0x7f, &c3, c3});
+ return insns;
+ }
+
+private:
+ // State variables go here.
+};
+
+REGISTER_EXTENSION(cvxif, []() { return new cvxif_t; })
diff --git a/customext/cvxif_test.c b/customext/cvxif_test.c
new file mode 100644
index 000000000..d39ca2229
--- /dev/null
+++ b/customext/cvxif_test.c
@@ -0,0 +1,111 @@
+// Copyright (C) 2022 Thales DIS Design Services SAS
+//
+// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0.
+//
+// Original Author: Zbigniew CHAMSKI <zbigniew.chamski@thalesgroup.com>
+//
+// The following is a RISC-V program to test the functionality of the
+// basic CVXIF accelerator interface on the Core-V side.
+// Compile using "riscv-none-elf-gcc -O2 cvxif_test.elf cvxif_test.c"
+// with -march=/-mabi= settings appropriate for your project.
+// Run using "spike -l --extension=cvxif cvxif_test.elf", adding
+// an --isa= setting appropriate for your project.
+//
+// Upon simulating the compiled program, the trace should contain five
+// instances of custom3 instructions (the third one being decoded as
+// 'unknown').
+// The last occurrence of 'custom3' instruction in the trace, encoded as
+// 0x8002007b, should be immediately followed by exception
+// 'trap_load_address_misaligned' with a tval equal to 0x1 and the
+// execution should terminate correctly with exit code 0.
+//
+// In 64-bit mode, the trace of the last occurrence of custom3
+// instruction should be equivalent to
+//
+// core 0: 0x0000000080002686 (0x8002007b) custom3 (args unknown)
+// core 0: exception trap_load_address_misaligned, epc 0x0000000080002686
+// core 0: tval 0x0000000000000001
+//
+// The corresponding trace in 32-bit mode should be equivalent to
+//
+// core 0: 0x8000205a (0x8002007b) custom3 (args unknown)
+// core 0: exception trap_load_address_misaligned, epc 0x8000205a
+// core 0: tval 0x00000001
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+// Values of MCAUSE corresponding to exceptions coming from the coprocessor I/F
+#define CAUSE_MISALIGNED_LOAD 0x4
+#define CAUSE_LOAD_ACCESS 0x5
+#define CAUSE_MISALIGNED_STORE 0x6
+#define CAUSE_STORE_ACCESS 0x7
+#define CAUSE_LOAD_PAGE_FAULT 0xd
+#define CAUSE_STORE_PAGE_FAULT 0xf
+#define CAUSE_COPROCESSOR_EXCEPTION 0x20
+
+// Value of TVAL to pass around.
+#define COPRO_TVAL_TEST 0x1a
+
+// Macro to read a CSR (from spike's "encoding.h")
+#define read_csr(reg) ({ unsigned long __tmp; \
+ asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
+ __tmp; })
+
+int main() {
+ // "unsigned long int" is always XLEN bits wide.
+ unsigned long int x = 123, y = 456, z = 0, t = 0;
+ static unsigned long int amem = 111, bmem = 0;
+ unsigned long a;
+
+ // Add x + y into z. Funct7 == 0, funct3 == 0x0.
+ asm volatile (".insn r CUSTOM_3, 0, 0, %0, %1, %2" : "=r"(z) : "r"(x), "r"(y));
+ if (z != 123 + 456)
+ {
+ // printf("FAILURE!!!\n");
+ return 1;
+ }
+
+ // Add three operands in a single R4-type add.
+ // Leverage current values of x, y and z (z == x + y).
+ asm volatile (".insn r CUSTOM_3, 0, 0x1, %0, %1, %2, %3" : "=r"(t) : "r"(x), "r"(y), "r"(z));
+ if (t != x + y + z)
+ {
+ // printf("FAILURE");
+ return 2;
+ }
+ // Load 'a' from 'amem'. CUSTOM_LD: opcode == CUSTOM_3, insn_type == I, funct3 == 0x1.
+ asm volatile (".insn i CUSTOM_3, 0x1, %0, %1" : "=r"(a) : "m"(amem), "I"(0));
+ if (a != 111)
+ {
+ // printf("FAILURE!!!\n");
+ return 3;
+ }
+
+ // Store 'a' in 'bmem'. CUSTOM_SD: opcode == CUSTOM_3, insn_type == S, funct3 == 0x2.
+ asm volatile (".insn s CUSTOM_3, 0x2, %0, %1" : : "r"(a), "m"(bmem));
+ if (bmem != 111)
+ {
+ // printf("FAILURE!!!\n");
+ return 4;
+ }
+
+ // Generate a misaligned load exception (mcause == 0x4).
+ asm volatile (".insn r CUSTOM_3, 0x0, 0x40, x0, x4, x0" : : );
+
+ // If we get here, then the exception test failed ==> exit with general failure code.
+ exit(1337);
+}
+
+// Override default trap handler.
+uintptr_t handle_trap(uintptr_t cause, uintptr_t epc, uintptr_t regs[32])
+{
+ if (cause == CAUSE_MISALIGNED_LOAD)
+ // Successfully terminate.
+ exit(0);
+ else
+ // Fail with explicit retcode.
+ exit(5);
+}
diff --git a/riscv/cvxif.h b/riscv/cvxif.h
new file mode 100644
index 000000000..e3a6fba1d
--- /dev/null
+++ b/riscv/cvxif.h
@@ -0,0 +1,77 @@
+// Copyright (C) 2022 Thales DIS Design Services SAS
+//
+// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0.
+//
+// Original Author: Zbigniew CHAMSKI <zbigniew.chamski@thalesgroup.com>
+
+#ifndef _RISCV_CVXIF_H
+#define _RISCV_CVXIF_H
+
+#include "extension.h"
+
+// R-type instruction format
+struct cvxif_r_insn_t
+{
+ unsigned opcode : 7;
+ unsigned rd : 5;
+ unsigned funct3 : 3;
+ unsigned rs1 : 5;
+ unsigned rs2 : 5;
+ unsigned funct7 : 7;
+};
+
+// R4-type instruction format
+struct cvxif_r4_insn_t
+{
+ unsigned opcode : 7;
+ unsigned rd : 5;
+ unsigned funct3 : 3;
+ unsigned rs1 : 5;
+ unsigned rs2 : 5;
+ unsigned funct2 : 2;
+ unsigned rs3 : 5;
+};
+
+// I-type instruction format
+struct cvxif_i_insn_t
+{
+ unsigned opcode : 7;
+ unsigned rd : 5;
+ unsigned funct3 : 3;
+ unsigned rs1 : 5;
+ unsigned imm : 12;
+};
+
+// S-type instruction format
+struct cvxif_s_insn_t
+{
+ unsigned opcode : 7;
+ unsigned imm_low : 5;
+ unsigned funct3 : 3;
+ unsigned rs1 : 5;
+ unsigned rs2 : 5;
+ unsigned imm_high : 7;
+};
+
+union cvxif_insn_t
+{
+ cvxif_r_insn_t r_type;
+ cvxif_r4_insn_t r4_type;
+ cvxif_i_insn_t i_type;
+ cvxif_s_insn_t s_type;
+ insn_t i;
+};
+
+class cvxif_extn_t : public extension_t
+{
+ public:
+ virtual bool do_writeback_p(cvxif_insn_t insn);
+ virtual reg_t custom0(cvxif_insn_t insn);
+ virtual reg_t custom1(cvxif_insn_t insn);
+ virtual reg_t custom2(cvxif_insn_t insn);
+ virtual reg_t custom3(cvxif_insn_t insn);
+ std::vector<insn_desc_t> get_instructions();
+ std::vector<disasm_insn_t*> get_disasms();
+};
+
+#endif
diff --git a/riscv/cvxif_base.cc b/riscv/cvxif_base.cc
new file mode 100644
index 000000000..5097344c5
--- /dev/null
+++ b/riscv/cvxif_base.cc
@@ -0,0 +1,64 @@
+// Copyright (C) 2022 Thales DIS Design Services SAS
+//
+// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.0.
+//
+// Original Author: Zbigniew CHAMSKI <zbigniew.chamski@thalesgroup.com>
+
+#include "cvxif.h"
+#include "trap.h"
+#include <cstdlib>
+
+// Virtual base class of CVXIF.
+
+// Return true if writeback is required.
+// Be on the safe side, disable writeback.
+bool cvxif_extn_t::do_writeback_p(cvxif_insn_t insn)
+{
+ return false;
+}
+
+// Define custom insns templates.
+// The insn-level wrapper is 'c##n' (default implementation,
+// writeback disabled), the default implementation
+// is 'custom##n': illegal instruction, return 0.
+// The writeback controller 'cvxif_extn_t::do_writeback_p'
+// is in charge of determining if writeback is required or not.
+// Expected instruction encoding is 4 bytes.
+#define customX(n) \
+static reg_t c##n(processor_t* p, insn_t insn, reg_t pc) \
+ { \
+ cvxif_extn_t* cvxif = static_cast<cvxif_extn_t*>(p->get_extension()); \
+ cvxif_insn_t custom_insn; \
+ custom_insn.i = insn; \
+ reg_t xd = cvxif->custom##n(custom_insn); \
+ if (cvxif->do_writeback_p(custom_insn)) \
+ WRITE_RD(xd); \
+ return pc+4; \
+ } \
+ \
+ reg_t cvxif_extn_t::custom##n(cvxif_insn_t insn) \
+ { \
+ illegal_instruction(); \
+ return -1; \
+ }
+
+customX(0)
+customX(1)
+customX(2)
+customX(3)
+
+std::vector<insn_desc_t> cvxif_extn_t::get_instructions()
+{
+ std::vector<insn_desc_t> insns;
+ insns.push_back((insn_desc_t){0x0b, 0x7f, &::illegal_instruction, c0});
+ insns.push_back((insn_desc_t){0x2b, 0x7f, &::illegal_instruction, c1});
+ insns.push_back((insn_desc_t){0x5b, 0x7f, &::illegal_instruction, c2});
+ insns.push_back((insn_desc_t){0x7b, 0x7f, &::illegal_instruction, c3});
+ return insns;
+}
+
+std::vector<disasm_insn_t*> cvxif_extn_t::get_disasms()
+{
+ std::vector<disasm_insn_t*> insns;
+ return insns;
+}
diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in
index 56014662c..3da5f6d8b 100644
--- a/riscv/riscv.mk.in
+++ b/riscv/riscv.mk.in
@@ -26,6 +26,7 @@ riscv_hdrs = \
cfg.h \
common.h \
csrs.h \
+ cvxif.h \
debug_defines.h \
debug_module.h \
debug_rom_defines.h \
@@ -58,6 +59,7 @@
extension.cc \
extensions.cc \
rocc.cc \
+ cvxif_base.cc \
devices.cc \
rom.cc \
clint.cc \

View file

@ -0,0 +1,110 @@
diff --git a/vendor/riscv/riscv-isa-sim/riscv/sim.cc b/vendor/riscv/riscv-isa-sim/riscv/sim.cc
index dcbd469d3..8863a5f78 100644
--- a/vendor/riscv/riscv-isa-sim/riscv/sim.cc
+++ b/vendor/riscv/riscv-isa-sim/riscv/sim.cc
@@ -40,7 +40,8 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
const char *log_path,
bool dtb_enabled, const char *dtb_file,
bool socket_enabled,
- FILE *cmd_file) // needed for command line option --cmd
+ FILE *cmd_file, // needed for command line option --cmd
+ size_t max_steps)
: htif_t(args),
isa(cfg->isa(), cfg->priv()),
cfg(cfg),
@@ -52,6 +53,8 @@ sim_t::sim_t(const cfg_t *cfg, bool halted,
cmd_file(cmd_file),
sout_(nullptr),
current_step(0),
+ total_steps(0),
+ max_steps(max_steps),
current_proc(0),
debug(false),
histogram_enabled(false),
@@ -236,6 +239,21 @@ void sim_t::step(size_t n)
procs[current_proc]->step(steps);
current_step += steps;
+ total_steps += steps;
+
+ // max_steps must be non-zero to act as an execution limit.
+ if (max_steps && total_steps >= max_steps)
+ {
+ // "Stepout": max step count reached/exceeded.
+ std::cerr << "*** Maximum step count reached (total_steps = "
+ << std::dec << total_steps << ", max_steps = "
+ << max_steps << "), exiting!" << std::endl;
+ // TODO FIXME: Determine the best method of terminating.
+ // FORNOW: Exit successfully and let the caller of Spike
+ // decide how to proceed in view of simulation results.
+ exit(0);
+ }
+
if (current_step == INTERLEAVE)
{
current_step = 0;
diff --git a/vendor/riscv/riscv-isa-sim/riscv/sim.h b/vendor/riscv/riscv-isa-sim/riscv/sim.h
index 3109173f1..377e96514 100644
--- a/vendor/riscv/riscv-isa-sim/riscv/sim.h
+++ b/vendor/riscv/riscv-isa-sim/riscv/sim.h
@@ -32,7 +32,8 @@ public:
const debug_module_config_t &dm_config, const char *log_path,
bool dtb_enabled, const char *dtb_file,
bool socket_enabled,
- FILE *cmd_file); // needed for command line option --cmd
+ FILE *cmd_file, // needed for command line option --cmd
+ size_t max_steps);
~sim_t();
// run the simulation to completion
@@ -88,6 +89,8 @@ private:
static const size_t INSNS_PER_RTC_TICK = 100; // 10 MHz clock for 1 BIPS core
static const size_t CPU_HZ = 1000000000; // 1GHz CPU
size_t current_step;
+ size_t total_steps;
+ size_t max_steps;
size_t current_proc;
bool debug;
bool histogram_enabled; // provide a histogram of PCs
diff --git a/vendor/riscv/riscv-isa-sim/spike_main/spike.cc b/vendor/riscv/riscv-isa-sim/spike_main/spike.cc
index 7290f38bb..657533cb1 100644
--- a/vendor/riscv/riscv-isa-sim/spike_main/spike.cc
+++ b/vendor/riscv/riscv-isa-sim/spike_main/spike.cc
@@ -86,6 +86,8 @@ static void help(int exit_code = 1)
fprintf(stderr, " --dm-no-halt-groups Debug module won't support halt groups\n");
fprintf(stderr, " --dm-no-impebreak Debug module won't support implicit ebreak in program buffer\n");
fprintf(stderr, " --blocksz=<size> Cache block size (B) for CMO operations(powers of 2) [default 64]\n");
+ fprintf(stderr, " --steps=<n> Stop simulation after reaching specified number of steps "
+ "(default: unlimited)\n");
exit(exit_code);
}
@@ -361,6 +363,7 @@ int main(int argc, char** argv)
.support_haltgroups = true,
.support_impebreak = true
};
+ size_t max_steps = 0;
cfg_arg_t<size_t> nprocs(1);
cfg_t cfg(/*default_initrd_bounds=*/std::make_pair((reg_t)0, (reg_t)0),
@@ -465,6 +468,7 @@ int main(int argc, char** argv)
exit(-1);
}
});
+ parser.option(0, "steps", 1, [&](const char* s){max_steps = strtoull(s, 0, 0);});
parser.option(0, "dm-progsize", 1,
[&](const char* s){dm_config.progbufsize = atoul_safe(s);});
parser.option(0, "dm-no-impebreak", 0,
@@ -564,9 +568,9 @@ int main(int argc, char** argv)
}
sim_t s(&cfg, halted,
- mems, plugin_devices, htif_args, dm_config, log_path, dtb_enabled, dtb_file,
- socket,
- cmd_file);
+ mems, plugin_devices, htif_args, dm_config, log_path, dtb_enabled, dtb_file,
+ socket,
+ cmd_file, max_steps);
std::unique_ptr<remote_bitbang_t> remote_bitbang((remote_bitbang_t *) NULL);
std::unique_ptr<jtag_dtm_t> jtag_dtm(
new jtag_dtm_t(&s.debug_module, dmi_rti));

View file

@ -0,0 +1,14 @@
diff --git a/vendor/riscv/riscv-isa-sim/riscv/sim.cc b/vendor/riscv/riscv-isa-sim/riscv/sim.cc
index 8863a5f7..9179ee4e 100644
--- a/vendor/riscv/riscv-isa-sim/riscv/sim.cc
+++ b/vendor/riscv/riscv-isa-sim/riscv/sim.cc
@@ -257,7 +257,8 @@ void sim_t::step(size_t n)
if (current_step == INTERLEAVE)
{
current_step = 0;
- procs[current_proc]->get_mmu()->yield_load_reservation();
+ if (procs.size() > 1)
+ procs[current_proc]->get_mmu()->yield_load_reservation();
if (++current_proc == procs.size()) {
current_proc = 0;
if (clint) clint->increment(INTERLEAVE / INSNS_PER_RTC_TICK);

View file

@ -0,0 +1,85 @@
diff --git a/vendor/riscv/riscv-isa-sim/customext/cvxif.cc b/vendor/riscv/riscv-isa-sim/customext/cvxif.cc
index ae92b1cc..b1bef8e6 100644
--- a/vendor/riscv/riscv-isa-sim/customext/cvxif.cc
+++ b/vendor/riscv/riscv-isa-sim/customext/cvxif.cc
@@ -134,17 +134,26 @@ class cvxif_t : public cvxif_extn_t
}
break;
case FUNC3_1:
- //Actually only CUS_ADD using func3 equal to one, we don't need to add another switch case
- return (reg_t) ((reg_t) RS1 + (reg_t) RS2);
+ switch(r_insn.funct7) {
+ case 0:
+ return (reg_t) ((reg_t) RS1 + (reg_t) RS2);
+ break;
+ default:
+ illegal_instruction();
+ }
case FUNC3_2:
- //Actually only CUS_EXC using func3 equal to one, we don't need to add another switch case
- if (r_insn.rs2 != 0 || r_insn.rd != 0){
- illegal_instruction();
- } else {
- raise_exception(insn, (reg_t) (r_insn.rs1));
- }
- break;
+ switch (r_insn.funct7) {
+ case (0x60):
+ if (r_insn.rs2 != 0 || r_insn.rd != 0){
+ illegal_instruction();
+ } else {
+ raise_exception(insn, (reg_t) (r_insn.rs1));
+ }
+ break;
+ default:
+ illegal_instruction();
+ }
default:
illegal_instruction();
}
@@ -195,15 +204,15 @@ class cvxif_t : public cvxif_extn_t
// Use 0x1 as always-faulting address.
throw trap_store_page_fault((p ? p->get_state()->v : false), 1, 0, 0);
case CAUSE_FETCH_GUEST_PAGE_FAULT:
- throw trap_instruction_guest_page_fault(1, 0, 0);
+ throw trap_instruction_guest_page_fault(0, 0, 0);
case CAUSE_LOAD_GUEST_PAGE_FAULT:
- throw trap_load_guest_page_fault( 1, 0, 0);
+ throw trap_load_guest_page_fault(0, 0, 0);
case CAUSE_VIRTUAL_INSTRUCTION:
- throw trap_virtual_instruction(1);
+ throw trap_virtual_instruction(0);
case CAUSE_STORE_GUEST_PAGE_FAULT:
- throw trap_store_guest_page_fault(1, 0, 0);
+ throw trap_store_guest_page_fault(0, 0, 0);
default:
- illegal_instruction();
+ throw trap_unknown_instruction(exc_index, (reg_t)0);
}
}
diff --git a/vendor/riscv/riscv-isa-sim/riscv/trap.h b/vendor/riscv/riscv-isa-sim/riscv/trap.h
index 54948fdd..78b549cf 100644
--- a/vendor/riscv/riscv-isa-sim/riscv/trap.h
+++ b/vendor/riscv/riscv-isa-sim/riscv/trap.h
@@ -82,6 +82,12 @@ class mem_trap_t : public trap_t
std::string name() { return "trap_"#x; } \
};
+#define DECLARE_CUSTOM_TRAP(x) class trap_##x : public insn_trap_t { \
+ public: \
+ trap_##x(reg_t n, reg_t tval) : insn_trap_t(n, false, tval) {} \
+ std::string name() { return "trap_"#x; } \
+};
+
#define DECLARE_INST_WITH_GVA_TRAP(n, x) class trap_##x : public insn_trap_t { \
public: \
trap_##x(bool gva, reg_t tval) : insn_trap_t(n, gva, tval) {} \
@@ -119,5 +125,6 @@ DECLARE_MEM_GVA_TRAP(CAUSE_FETCH_GUEST_PAGE_FAULT, instruction_guest_page_fault)
DECLARE_MEM_GVA_TRAP(CAUSE_LOAD_GUEST_PAGE_FAULT, load_guest_page_fault)
DECLARE_INST_TRAP(CAUSE_VIRTUAL_INSTRUCTION, virtual_instruction)
DECLARE_MEM_GVA_TRAP(CAUSE_STORE_GUEST_PAGE_FAULT, store_guest_page_fault)
+DECLARE_CUSTOM_TRAP(unknown_instruction)
#endif

View file

@ -5,3 +5,5 @@ autom4te.cache/
*.o
*.d
.gdb_history
.#*
*~

View file

@ -94,11 +94,11 @@ VPATH := $(addprefix $(src_dir)/, $(sprojs_enabled))
# highest.
default-CFLAGS := -DPREFIX=\"$(prefix)\" -Wall -Wno-unused -Wno-nonportable-include-path -g -O2 -fPIC
default-CXXFLAGS := $(default-CFLAGS) -std=c++11
default-CXXFLAGS := $(default-CFLAGS) -std=c++17
mcppbs-CPPFLAGS := @CPPFLAGS@
mcppbs-CFLAGS := $(default-CFLAGS) @CFLAGS@
mcppbs-CXXFLAGS := $(default-CXXFLAGS) @CXXFLAGS@
mcppbs-CXXFLAGS := $(mcppbs-CFLAGS) $(default-CXXFLAGS) @CXXFLAGS@
CC := @CC@
CXX := @CXX@
@ -219,7 +219,7 @@ $(2)_deps := $$(patsubst %.o, %.d, $$($(2)_objs))
$(2)_deps += $$(patsubst %.o, %.d, $$($(2)_c_objs))
$(2)_deps += $$(patsubst %.h, %.h.d, $$($(2)_precompiled_hdrs))
$$($(2)_pch) : %.h.gch : %.h
$(COMPILE) -x c++-header $$< -o $$@
$(COMPILE) -x c++-header $$< -c -o $$@
$$($(2)_objs) : %.o : %.cc $$($(2)_gen_hdrs) $$($(2)_pch)
$(COMPILE) $(if $(HAVE_CLANG_PCH), $$(if $$($(2)_pch), -include-pch $$($(2)_pch))) $$($(2)_CFLAGS) -c $$<
$$($(2)_c_objs) : %.o : %.c $$($(2)_gen_hdrs)
@ -241,7 +241,8 @@ $(2)_lib_libnames := $$(patsubst %, lib%.a, $$($(2)_lib_libs))
$(2)_lib_libarg := $$(patsubst %, -l%, $$($(2)_lib_libs))
$(2)_lib_libnames_shared := $$(if $$($(2)_install_shared_lib),lib$(1).so,)
lib$(1).a : $$($(2)_objs) $$($(2)_c_objs) $$($(2)_lib_libnames)
lib$(1).a : $$($(2)_objs) $$($(2)_c_objs)
rm -f $$@
$(AR) rcs $$@ $$^
lib$(1).so : $$($(2)_objs) $$($(2)_c_objs) $$($(2)_lib_libnames_shared) $$($(2)_lib_libnames)
$(LINK) -shared -o $$@ $(if $(filter Darwin,$(shell uname -s)),-install_name $(install_libs_dir)/$$@) $$^ $$($(2)_lib_libnames) $(LIBS)
@ -326,10 +327,6 @@ clean-$(1) :
# Update running variables
libs += lib$(1).a
objs += $$($(2)_objs)
srcs += $$(addprefix $(src_dir)/$(1)/, $$($(2)_srcs))
hdrs += $$(addprefix $(src_dir)/$(1)/, $$($(2)_hdrs)) $$($(2)_gen_hdrs)
junk += $$($(2)_junk)
deps += $$($(2)_deps)

View file

@ -27,13 +27,28 @@ Spike supports the following RISC-V ISA features:
- Zbb extension, v1.0
- Zbc extension, v1.0
- Zbs extension, v1.0
- Zfh and Zfhmin half-precision floating-point extensions, v1.0
- Zfinx extension, v1.0
- Zmmul integer multiplication extension, v1.0
- Zicbom, Zicbop, Zicboz cache-block maintenance extensions, v1.0
- Conformance to both RVWMO and RVTSO (Spike is sequentially consistent)
- Machine, Supervisor, and User modes, v1.11
- Hypervisor extension, v1.0
- Svnapot extension, v1.0
- Svpbmt extension, v1.0
- Svinval extension, v1.0
- Debug v0.14
- Sdext extension, v1.0-STABLE
- Sdtrig extension, v1.0-STABLE
- 4 triggers support type={2, 3, 4, 5, 6, 15} (mcontrol, icount, itrigger, etrigger, mcontrol6, disabled)
- Smepmp extension v1.0
- Smstateen extension, v1.0
- Sscofpmf v0.5.2
- Zca extension, v1.0
- Zcb extension, v1.0
- Zcf extension, v1.0
- Zcd extension, v1.0
- Zcmp extension, v1.0
- Zcmt extension, v1.0
As a Spike extension, the remainder of the proposed
[Bit-Manipulation Extensions](https://github.com/riscv/riscv-bitmanip)
@ -41,6 +56,14 @@ is provided under the Spike-custom extension name _Xbitmanip_.
These instructions (and, of course, the extension name) are not RISC-V
standards.
These proposed bit-manipulation extensions can be split into further
groups: Zbp, Zbs, Zbe, Zbf, Zbc, Zbm, Zbr, Zbt. Note that Zbc is
ratified, but the original proposal contained some extra instructions
(64-bit carryless multiplies) which are captured here.
To enable these extensions individually, use the Spike-custom
extension names _XZbp_, _XZbs_, _XZbc_, and so on.
Versioning and APIs
-------------------
@ -211,7 +234,7 @@ OUTPUT_ARCH( "riscv" )
SECTIONS
{
. = 0x10010000;
. = 0x10110000;
.text : { *(.text) }
.data : { *(.data) }
}
@ -221,19 +244,19 @@ $ riscv64-unknown-elf-gcc -g -Og -T spike.lds -nostartfiles -o rot13-64 rot13-64
To debug this program, first run spike telling it to listen for OpenOCD:
```
$ spike --rbb-port=9824 -m0x10000000:0x20000 rot13-64
$ spike --rbb-port=9824 -m0x10100000:0x20000 rot13-64
Listening for remote bitbang connection on port 9824.
```
In a separate shell run OpenOCD with the appropriate configuration file:
```
$ cat spike.cfg
interface remote_bitbang
remote_bitbang_host localhost
remote_bitbang_port 9824
adapter driver remote_bitbang
remote_bitbang host localhost
remote_bitbang port 9824
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0xdeadbeef
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME riscv -chain-position $_TARGETNAME
@ -277,7 +300,7 @@ $2 = 0
(gdb) print text
$3 = "Vafgehpgvba frgf jnag gb or serr!"
(gdb) b done
Breakpoint 1 at 0x10010064: file rot13.c, line 22.
Breakpoint 1 at 0x10110064: file rot13.c, line 22.
(gdb) c
Continuing.
Disabling abstract command writes to CSRs.

View file

@ -0,0 +1,34 @@
TARGET_SIM ?= spike
TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS)
ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),)
$(error Target simulator executable '$(TARGET_SIM)` not found)
endif
RISCV_PREFIX ?= riscv$(XLEN)-unknown-elf-
RISCV_GCC ?= $(RISCV_PREFIX)gcc
RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump
RISCV_GCC_OPTS ?= -g -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles $(RVTEST_DEFINES)
COMPILE_CMD = $$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \
-I$(ROOTDIR)/riscv-test-suite/env/ \
-I$(TARGETDIR)/$(RISCV_TARGET)/ \
-T$(TARGETDIR)/$(RISCV_TARGET)/link.ld \
$$(<) -o $$@
OBJ_CMD = $$(RISCV_OBJDUMP) $$@ -D > $$@.objdump; \
$$(RISCV_OBJDUMP) $$@ --source > $$@.debug
COMPILE_TARGET=\
$(COMPILE_CMD); \
if [ $$$$? -ne 0 ] ; \
then \
echo "\e[31m$$(RISCV_GCC) failed for target $$(@) \e[39m" ; \
exit 1 ; \
fi ; \
$(OBJ_CMD); \
if [ $$$$? -ne 0 ] ; \
then \
echo "\e[31m $$(RISCV_OBJDUMP) failed for target $$(@) \e[39m" ; \
exit 1 ; \
fi ;

View file

@ -0,0 +1,7 @@
include $(TARGETDIR)/spike/device/Makefile_common.inc
RUN_CMD = $(TARGET_SIM) $(TARGET_FLAGS) --isa=rv32ec \
+signature=$(*).signature.output +signature-granularity=4\
$<
RUN_TARGET=\
$(RUN_CMD)

View file

@ -0,0 +1,7 @@
include $(TARGETDIR)/spike/device/Makefile_common.inc
RUN_CMD = $(TARGET_SIM) $(TARGET_FLAGS) --isa=rv32e \
+signature=$(*).signature.output +signature-granularity=4\
$<
RUN_TARGET=\
$(RUN_CMD)

View file

@ -0,0 +1,7 @@
include $(TARGETDIR)/spike/device/Makefile_common.inc
RUN_CMD = $(TARGET_SIM) $(TARGET_FLAGS) --isa=rv32em \
+signature=$(*).signature.output +signature-granularity=4\
$<
RUN_TARGET=\
$(RUN_CMD)

View file

@ -1,37 +1,4 @@
TARGET_SIM ?= spike
TARGET_FLAGS ?= $(RISCV_TARGET_FLAGS)
ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),)
$(error Target simulator executable '$(TARGET_SIM)` not found)
endif
RISCV_PREFIX ?= riscv32-unknown-elf-
RISCV_GCC ?= $(RISCV_PREFIX)gcc
RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump
RISCV_GCC_OPTS ?= -g -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles $(RVTEST_DEFINES)
COMPILE_CMD = $$(RISCV_GCC) $(1) $$(RISCV_GCC_OPTS) \
-I$(ROOTDIR)/riscv-test-suite/env/ \
-I$(TARGETDIR)/$(RISCV_TARGET)/ \
-T$(TARGETDIR)/$(RISCV_TARGET)/link.ld \
$$(<) -o $$@
OBJ_CMD = $$(RISCV_OBJDUMP) $$@ -D > $$@.objdump; \
$$(RISCV_OBJDUMP) $$@ --source > $$@.debug
COMPILE_TARGET=\
$(COMPILE_CMD); \
if [ $$$$? -ne 0 ] ; \
then \
echo "\e[31m$$(RISCV_GCC) failed for target $$(@) \e[39m" ; \
exit 1 ; \
fi ; \
$(OBJ_CMD); \
if [ $$$$? -ne 0 ] ; \
then \
echo "\e[31m $$(RISCV_OBJDUMP) failed for target $$(@) \e[39m" ; \
exit 1 ; \
fi ;
include $(TARGETDIR)/spike/device/Makefile_common.inc
RUN_CMD = $(TARGET_SIM) $(TARGET_FLAGS) --isa=rv32ic \
+signature=$(*).signature.output +signature-granularity=4\
$<

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