diff --git a/.gitignore b/.gitignore index afaddb753e728167a88813968bcf00a3303871cd..19e26994a8d0a3e11cf72f2337176a5d70b3c673 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,7 @@ docs/build ./riscof_work ./env + +sail_cSim + +spike diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b20eb862a5dc97173182e21d746a63dab28195c3..80b38f504beb47a965e04fda986b1cf1bfaae0f4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -35,7 +35,7 @@ deploy: - eval "$(pyenv virtualenv-init -)" - pyenv shell 3.6.10 - pip3 install --upgrade pip - - pip install -U twine semver + - pip install -U twine semver python-gitlab - python setup.py sdist - python -m twine upload --username "__token__" --password $pypitoken dist/* - python /scratch/version-extract.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 97f5f6f649d8773d6100814695828661bdad5bd3..06918596fd385576313da466ce2a2623b9cc1a2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.19.0] - 2021-04-24 +- Added new rv64i and rv32i tests from arch-test repo +- Added K_unratified tests from arch-test repo +- Addded all relevant coverage files +- Updated coverage support to pick local coverage files +- Updated setup phase to dump out sail_cSim reference model +- Updated the config.ini and model setup files +- Updated docs + ## [1.18.4] - 2021-01-27 - Fixed missing coverage.html during pip installation. diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 55a292d5eb12a6867131b8331b3ae1dd9210a630..1206f8ce59d9077e8effcf168bc1faf6574b8533 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -71,6 +71,6 @@ A reminder for the maintainers on how to deploy. Make sure all your changes are committed. Then run:: -$ bumpversion --config-file setup.cfg patch # possible: major / minor / patch +$ bumpversion --no-tag --config-file setup.cfg patch # possible: major / minor / patch $ git push origin name-of-your-branch diff --git a/MANIFEST.in b/MANIFEST.in index 40c30dd3680bf29483e6fc4746023617bf21c8f8..851e3a48bade98fac331fdfa496b81451dc9266c 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,7 @@ recursive-include riscof/suite *.S *.h +recursive-include riscof/coverage * + recursive-include riscof/Templates * recursive-include riscof/framework *.yaml diff --git a/README.rst b/README.rst index 43cd073af12a526e3440c798256bc0005376d845..2e7225da9ecd584eafd33fcb03eb0016f911c3d3 100644 --- a/README.rst +++ b/README.rst @@ -1,10 +1,9 @@ RISCOF =========== -**RISCOF** is a RISC-V Compliance Framework. +**RISCOF** is a RISC-V Architectural Test Framework. LICENSE: BSD-3 Clause. Latest documentation of RISCOF : * `HTML `_ - * `PDF `_ diff --git a/docs/Makefile b/docs/Makefile index eecc2cfaa513dde33a6cb30033155096bac4ad31..6f485c61d213d18fb1f09c492523adae7203a7d3 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -4,7 +4,7 @@ # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build -SPHINXPROJ = RISVComplianceFramework +SPHINXPROJ = RISCVArchTestFramework SOURCEDIR = source BUILDDIR = build @@ -17,4 +17,4 @@ help: # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/requirements.txt b/docs/requirements.txt index a1933e2f457d842a3243d5446aa5ebd4d17bd952..74f7829851cfca413b1d40755f1e59b233ed52fb 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -20,17 +20,17 @@ pytz==2019.1 PyYAML==5.1.1 requests==2.22.0 restructuredtext-lint==1.3.0 -ruamel.yaml==0.15.97 six==1.12.0 smmap2==2.0.5 snowballstemmer==1.2.1 -Sphinx==3.0.4 +Sphinx==3.5.3 sphinx-rtd-theme==0.4.3 sphinxcontrib-autoyaml==0.5.0 sphinxcontrib-mermaid sphinxcontrib-websupport==1.1.2 -sphinxcontrib-bibtex +sphinxcontrib-bibtex==1.0.0 stevedore==1.30.1 urllib3==1.25.3 twine==1.13.0 -sphinx_tabs +sphinx_tabs==2.1.0 +m2r2==0.2.7 diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst new file mode 100644 index 0000000000000000000000000000000000000000..74cca8f1c978c846faff74aab38f995d4acbc68d --- /dev/null +++ b/docs/source/changelog.rst @@ -0,0 +1,8 @@ +.. raw:: latex + + \pagebreak + +.. _revisions: + +.. mdinclude:: ../../CHANGELOG.md + diff --git a/docs/source/conf.py b/docs/source/conf.py index e3b7c23b5731a48431f39c147744ffd784e8279d..d4390f051c86926d3d356043ba5d6bbdaf091a33 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -34,9 +34,9 @@ version = get_version() # The full version, including alpha/beta/rc tags release = version -#def setup(app): -# app.add_stylesheet("custom.css") -# app.add_css_file("_static/custom.css") +def setup(app): + app.add_stylesheet("custom.css") + app.add_css_file("_static/custom.css") # -- General configuration --------------------------------------------------- @@ -57,7 +57,8 @@ extensions = [ 'sphinx.ext.viewcode', 'sphinxcontrib.autoyaml', 'sphinxcontrib.bibtex', - 'sphinx_tabs.tabs' + 'sphinx_tabs.tabs', + 'm2r2' ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -163,7 +164,7 @@ html_show_license = True # Output file base name for HTML help builder. -htmlhelp_basename = 'RISCVComplianceFrameworkdoc' +htmlhelp_basename = 'RISCVArchTestFrameworkdoc' # -- Options for LaTeX output ------------------------------------------------ @@ -261,7 +262,7 @@ latex_elements = { %%% Alternating Footer for two side \fancyfoot[LO, LE]{\small \bf{Copyright \textcopyright \the\year \textbf{ } InCore Semiconductors Pvt. Ltd.}} - %\fancyfoot[LO, LE]{\scriptsize \bf{RISCOF}} + %\fancyfoot[LO, LE]{\scriptsize \bf{RISCOF: RISC-V Architectural Test Framework}} %%% page number \fancyfoot[RO, RE]{\thepage} @@ -303,7 +304,7 @@ latex_elements = { \includegraphics[scale=0.2]{incore_logo.png} \end{figure} \vspace*{40mm} %%% * is used to give space from top - \textbf{\Huge {RISC-V ISA Coverage}} + \textbf{\Huge {RISCOF: RISC-V Architectural Test Framework}} \vspace*{40mm} %%% * is used to give space from top @@ -374,7 +375,7 @@ latex_elements = { # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'RISCVComplianceFramework.tex', 'RISC-V Compliance Framework Documentation', + (master_doc, 'RISCVArchTestFramework.tex', 'RISC-V Architectural Test Framework Documentation', 'InCore Semiconductors Pvt. Ltd.', 'manual'), ] @@ -387,7 +388,7 @@ latex_show_pagerefs = True # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - (master_doc, 'risvcomplianceframework', 'RISCV Compliance Framework Documentation', + (master_doc, 'risvarchtestframework', 'RISCV Architectural Test Framework Documentation', [author], 1) ] @@ -398,8 +399,8 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'RISCVComplianceFramework', 'RISC-V Compliance Framework Documentation', - author, 'RISCVComplianceFramework', 'One line description of project.', + (master_doc, 'RISCVArchTestFramework', 'RISC-V Architectural Test Framework Documentation', + author, 'RISCVArchTestFramework', 'One line description of project.', 'Miscellaneous'), ] diff --git a/docs/source/index.rst b/docs/source/index.rst index 30be28050cf86eb97c3a15bd9791acafc548121f..4350fd69ac390f0f6a9267ccc9ebbecfffd9341f 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -18,3 +18,4 @@ Welcome to RISCOF testformat RISCV-Config [External] code-doc + changelog diff --git a/docs/source/installation.rst b/docs/source/installation.rst index 7a076c2947e7bddfbc2605425bf08c4685e54733..c3fa2ce3a329d06c4bca9dacd155aa8a8445d002 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -1,9 +1,9 @@ .. See LICENSE.incore for details -.. _quickstart: - .. highlight:: shell +.. _quickstart: + ========== Quickstart ========== @@ -175,10 +175,12 @@ Once you have installed RISCOF you can execute ``riscof --help`` to print the he .. code-block:: bash + usage: riscof [-h] [--version] [--verbose] - {gendb,setup,validateyaml,run,testlist} ... + {coverage,gendb,setup,validateyaml,run,testlist} ... - This program checks compliance for a DUT. + RISCOF is a framework used to run the Architectural Tests on a DUT and check + compatibility with the RISC-V ISA optional arguments: --verbose [Default=info] @@ -188,15 +190,27 @@ Once you have installed RISCOF you can execute ``riscof --help`` to print the he Action: The action to be performed by riscof. - {gendb,setup,validateyaml,run,testlist} + {coverage,gendb,setup,validateyaml,run,testlist} List of actions supported by riscof. + coverage Generate Coverage Report for the given YAML spec. gendb Generate Database for the standard suite. setup Initiate setup for riscof. validateyaml Validate the Input YAMLs using riscv-config. run Run the tests on DUT and reference and compare signatures. testlist Generate the test list for the given DUT and suite. - Uses the architectural suite by default. + Action 'coverage' + + usage: riscof coverage [-h] [--config PATH] [--cgf PATH] [--suite PATH] + [--no-browser] + + optional arguments: + --cgf PATH The Path to the cgf file(s). Multiple allowed + --config PATH The Path to the config file. [Default=./config.ini] + --no-browser Do not open the browser for showing the test report. + --suite PATH The Path to the custom suite directory. + -h, --help show this help message and exit + Action 'gendb' usage: riscof gendb [-h] [--suite PATH] @@ -211,7 +225,7 @@ Once you have installed RISCOF you can execute ``riscof --help`` to print the he optional arguments: --dutname NAME Name of DUT plugin. [Default=spike] - --refname NAME Name of Reference plugin. [Default=riscvOVPsim] + --refname NAME Name of Reference plugin. [Default=sail_cSim] -h, --help show this help message and exit Action 'validateyaml' @@ -371,54 +385,85 @@ provide a quick and standard way of building the model, compiling the tests and on the models. Along with the python plugins of each model, one would also have to provide the `YAML` configuration files of the DUT as per the norms of ``riscv-config``. Some models might also require special macros to be executed as prelude or post-testing. These macros can be provided to -RISCOF as a header file: ``compliance_model.h``. +RISCOF as a header file: ``model_test.h``. -For the sake of this guide, we will use some of the pre-built plugins for riscof available at: -`riscof-plugins `_. We will specifically use the -spike_simple and sail_cSim plugins. +For sample templates of pre-built plugins please refer to : `riscof-plugins `_. -.. note:: If you are using `pyenv` as mentioned above, make sure to enable that environment before - performing the following steps since we will now start using riscof. +To make things even simpler, RISCOF generates standard pre-built templates for DUTs and Reference +Models for the user via the ``setup`` command as shown below:: -.. code-block:: bash - - $ git clone https://gitlab.com/incoresemi/riscof-plugins.git + $ riscof setup --dutname=spike -To create necessary environment files use the following command:: +The above command will generate the following files and directories in the current directory:: - $ riscof setup --dutname=spike_simple --refname=sail_cSim + ├──config.ini # configuration file for riscof + ├──spike/ # DUT plugin templates + ├── env + │   ├── link.ld + │   └── model_test.h + ├── riscof_spike.py + ├── spike_isa.yaml + └── spike_platform.yaml + ├──sail_cSim/ # reference plugin templates + ├── env + │   ├── link.ld + │   └── model_test.h + ├── __init__.py + └── riscof_sail_cSim.py -The above command will generate a file named ``config.ini`` and a folder named ``spike_simple``. -The ``config.ini`` file is used to capture specific paths of the plugins of reference and DUT model, -along with the paths to isa and platform input YAMLs. The folder ``spike_simple`` contains -various templates of files that would be required for compliance of any generic DUT. -Components of this folder will be modified by the user as per the DUT spec. -Since we are going to use pre-built plugins for this guide, we will ignore the ``spike_simple`` -folder for now. -.. note:: For specific examples on modifications to environment files, please check the - corresponding files for various targets available in the riscof-plugins directory. -Based on the path you have downloaded the riscof-plugins directory, you will need to modify the -``config.ini`` file to look similar to the following:: +The ``config.ini`` file is used to capture specific paths of the plugins of reference and DUT model, +along with the paths to isa and platform input YAMLs. The ``config.ini`` will look something like this by default:: [RISCOF] ReferencePlugin=sail_cSim - ReferencePluginPath=/path/to/riscof-plugins/sail_cSim - DUTPlugin=spike_simple - DUTPluginPath=/path/to/riscof-plugins/spike_simple + ReferencePluginPath=/path/to/riscof/sail_cSim + DUTPlugin=spike + DUTPluginPath=/path/to/riscof/spike ## Example configuration for spike plugin. - [spike_simple] - pluginpath=/path/to/riscof-plugins/spike_simple/ - ispec=/path/to/riscof-plugins/spike_simple/spike_simple_isa.yaml - pspec=/path/to/riscof-plugins/spike_simple/spike_simple_platform.yaml + [spike] + pluginpath=/path/to/riscof/spike/ + ispec=/path/to/riscof/spike/spike_isa.yaml + pspec=/path/to/riscof/spike/spike_platform.yaml [sail_cSim] - pluginpath=/path/to/riscof-plugins/sail_cSim + pluginpath=/path/to/riscof/sail_cSim + +If the SAIL binaries (i.e. ``riscv_sim_RV32``) are not in your $PATH you may want to add the following to the last line of the +above config:: + + PATH= + + +The folder ``spike`` contains various templates of files that would be required for testing of +any generic DUT. Components of this folder will need to be modified by the user as per the DUT spec. +Since our DUT model in this guide is spike, you will only have to change the execute command at line 100 of +spike/riscof_spike.py to the following: + +.. code-block:: python + + execute += self.dut_exe + ' --log-commits --log dump --isa={0} +signature={1} +signature-granularity=4 {2};'.format(self.isa, sig_file, elf) + + +.. note:: Custom DUTs can go through the various ``#TODO`` comments to figure out what changes need to be + made in the respective python file. + +The configuration of spike we will be using is available in the ``spike/spike_isa.yaml``. Modifying +this will change the tests applicable for the DUT. For now let's leave it as is. For more +information on creating and modifying your plugins can be found in :ref:`plugins` + +The ``sail_cSim`` directory holds the plugin files for the reference SAIL model. Changes to any of +the files in this directory are typically not required (unless you know what you are doing) + +We are now ready to run the architectural tests on the DUT via RISCOF. -We are now ready to run compliance via RISCOF +.. tip:: By default RISCOF resorts to using RISC-V's SAIL C Emulator as a reference model. To generate + templates for a reference model add the argument '--refname myref' to the setup command above. This + will generate a *myref* directory containing template files for defining a reference model plugin. + Lookout for the #TODO in the python file for places where changes will be required. Running RISCOF ============== @@ -435,23 +480,22 @@ This should print the following: .. code-block:: bash - [INFO] : Reading configuration from: /scratch/git-repo/incoresemi/riscof-plugins/config.ini + [INFO] : Reading configuration from: /scratch/git-repo/incoresemi/riscof/config.ini [INFO] : Preparing Models [INFO] : Input-ISA file - [INFO] : Loading input file: /scratch/git-repo/incoresemi/riscof-plugins/spike_simple/sample_isa.yaml + [INFO] : Loading input file: /scratch/git-repo/incoresemi/riscof/spike/sample_isa.yaml [INFO] : Load Schema /home/neel/.pyenv/versions/3.7.0/envs/venv/lib/python3.7/site-packages/riscv_config/schemas/schema_isa.yaml [INFO] : Initiating Validation [INFO] : No Syntax errors in Input ISA Yaml. :) - [INFO] : Dumping out Normalized Checked YAML: /scratch/git-repo/incoresemi/riscof-plugins/riscof_work/sample_isa_checked.yaml + [INFO] : Dumping out Normalized Checked YAML: /scratch/git-repo/incoresemi/riscof/riscof_work/sample_isa_checked.yaml [INFO] : Input-Platform file - [INFO] : Loading input file: /scratch/git-repo/incoresemi/riscof-plugins/spike_simple/sample_platform.yaml + [INFO] : Loading input file: /scratch/git-repo/incoresemi/riscof/spike/sample_platform.yaml [INFO] : Load Schema /home/neel/.pyenv/versions/3.7.0/envs/venv/lib/python3.7/site-packages/riscv_config/schemas/schema_platform.yaml [INFO] : Initiating Validation [INFO] : No Syntax errors in Input Platform Yaml. :) - [INFO] : Dumping out Normalized Checked YAML: /scratch/git-repo/incoresemi/riscof-plugins/riscof_work/sample_platform_checked.yaml + [INFO] : Dumping out Normalized Checked YAML: /scratch/git-repo/incoresemi/riscof/riscof_work/sample_platform_checked.yaml -The next step is generate the list of tests that need to be run on the models for declaring -compliance. +The next step is generate the list of tests that need to be run on the models. .. code-block:: bash @@ -469,17 +513,17 @@ something similar to the following: .. code-block:: yaml suite/rv32i_m/C/C-ADD.S: - work_dir: /scratch/git-repo/incoresemi/riscof-plugins/riscof_work/rv32i_m/C/C-ADD.S + work_dir: /scratch/git-repo/incoresemi/riscof/riscof_work/rv32i_m/C/C-ADD.S macros: [TEST_CASE_1=True, XLEN=32] isa: RV32IC test_path: /home/neel/.pyenv/versions/3.7.0/envs/venv/lib/python3.7/site-packages/riscof/suite/rv32i_m/C/C-ADD.S suite/rv32i_m/C/C-ADDI.S: - work_dir: /scratch/git-repo/incoresemi/riscof-plugins/riscof_work/rv32i_m/C/C-ADDI.S + work_dir: /scratch/git-repo/incoresemi/riscof/riscof_work/rv32i_m/C/C-ADDI.S macros: [TEST_CASE_1=True, XLEN=32] isa: RV32IC test_path: /home/neel/.pyenv/versions/3.7.0/envs/venv/lib/python3.7/site-packages/riscof/suite/rv32i_m/C/C-ADDI.S suite/rv32i_m/C/C-ADDI16SP.S: - work_dir: /scratch/git-repo/incoresemi/riscof-plugins/riscof_work/rv32i_m/C/C-ADDI16SP.S + work_dir: /scratch/git-repo/incoresemi/riscof/riscof_work/rv32i_m/C/C-ADDI16SP.S macros: [TEST_CASE_1=True, XLEN=32] isa: RV32IC ... diff --git a/docs/source/intro.rst b/docs/source/intro.rst index 0201341a2091ea65d1f6ea8e7f281fd101a763dd..dbf9769536364a9ecb6ad0d6ba98406f0c150a54 100644 --- a/docs/source/intro.rst +++ b/docs/source/intro.rst @@ -2,7 +2,7 @@ Introduction ############ -**RISCOF** - The RISC-V Compliance Framework is a python based framework which enables testing of a RISC-V +**RISCOF** - The RISC-V Compatibility Framework is a python based framework which enables testing of a RISC-V target (hard or soft implementations) against a standard RISC-V golden reference model using a suite of RISC-V architectural assembly tests. diff --git a/docs/source/newtest.rst b/docs/source/newtest.rst index aefb2aeb4364a13631b3b6500cc74ee90eacc9b9..45b58784b174e184ec6069ac29752a7fbad72551 100644 --- a/docs/source/newtest.rst +++ b/docs/source/newtest.rst @@ -4,8 +4,8 @@ Adding New Tests ################ -This section pertains to developers who wish to add new tests to the compliance -suite. Please follow the below steps for such contributions: +This section pertains to developers who wish to add new tests to the architectural test suite. +Please follow the below steps for such contributions: 1. All tests should strictly follow the test-spec format available here: :ref:`Test Spec Format` diff --git a/docs/source/overview.rst b/docs/source/overview.rst index ff0b0df4be7cf63faca95eb354f1b5ced0e60d79..0f91b97823b15f543b0ea0cb966c34cb7ebb061b 100644 --- a/docs/source/overview.rst +++ b/docs/source/overview.rst @@ -114,7 +114,7 @@ This subsection describes at an abstract level a typical flow that will have to authors to contribute their tests to RISCOF's architectural test suite. A test by a contributor must always adhere to the :ref:`Test Format Spec `. The -test can either be auto-generated using tools like `RISCV-CTG `_ +test can either be auto-generated using tools like `RISCV-CTG `_ or can be handwritten. Once a suite or directory of tests is available, the contributor can force RISCOF to use only those diff --git a/docs/source/plugins.rst b/docs/source/plugins.rst index 82bfcac2f4f9bb444457d0931f00398cb9d980d1..c0aadd9549bb480ba86c3a6b7a216e2c962bb616 100644 --- a/docs/source/plugins.rst +++ b/docs/source/plugins.rst @@ -36,18 +36,18 @@ Generate Templates A sample template of the plugin and all other required collateral can be generated through RISCOF using the following command:: - $ riscof setup --refname=sail_cSim --dutname=spike_simple + $ riscof setup --refname=sail_cSim --dutname=spike -.. note:: You can change the name from spike_simple to the name of your target +.. note:: You can change the name from spike to the name of your target -This above command should generate a spike_simple folder with the following contents: +This above command should generate a spike folder with the following contents: .. code-block:: bash env # contains sample header file and linker file - riscof_spike_simple.py # sample spike plugin for RISCOF - spike_simple_isa.yaml # sample ISA YAML configuration file - spike_simple_platform.yaml # sample PLATFORM YAML configuration file + riscof_spike.py # sample spike plugin for RISCOF + spike_isa.yaml # sample ISA YAML configuration file + spike_platform.yaml # sample PLATFORM YAML configuration file The command will also generate a sample ``config.ini`` file with the following contents: @@ -56,23 +56,26 @@ The command will also generate a sample ``config.ini`` file with the following c [RISCOF] ReferencePlugin=cSail ReferencePluginPath=/scratch/git-repo/incoresemi/riscof/sail_cSim - DUTPlugin=spike_simple - DUTPluginPath=/scratch/git-repo/incoresemi/riscof/spike_simple + DUTPlugin=spike + DUTPluginPath=/scratch/git-repo/incoresemi/riscof/spike - [spike_simple] - pluginpath=/scratch/git-repo/incoresemi/riscof/spike_simple - ispec=/scratch/git-repo/incoresemi/riscof/spike_simple/spike_simple_isa.yaml - pspec=/scratch/git-repo/incoresemi/riscof/spike_simple/spike_simple_platform.yaml + [spike] + pluginpath=/scratch/git-repo/incoresemi/riscof/spike + ispec=/scratch/git-repo/incoresemi/riscof/spike/spike_isa.yaml + pspec=/scratch/git-repo/incoresemi/riscof/spike/spike_platform.yaml + + [sail_cSim] + pluginpath=/scratch/git-repo/incoresemi/riscof/sail_cSim The following changes need to be made: 1. Fix the paths in the ``config.ini`` to point to the folder containing the respective riscof_*.py files. -2. The macros in the ``spike_simple/env/compliance_model.h`` can be updated based on the model. Definitions of +2. The macros in the ``spike/env/model_test.h`` can be updated based on the model. Definitions of the macros and their use is available in the :ref:`test_format_spec`. 3. Update the ``riscof_.py`` with respective functions as described in the following paragraphs. -The plugin file in the ``spike_simple`` folder: riscof_spike_simple.py is the one that needs to be +The plugin file in the ``spike`` folder: riscof_spike.py is the one that needs to be changed and updated for each model. As can be seen from this python file, it creates a Metaclass for the plugins supported by the abstract base class. This class basically offers the users three basic functions: ``initialize`` , ``build`` and ``runTests``. For each model RISCOF calls these functions in the following order: @@ -89,11 +92,15 @@ Config.ini Syntax The ``config.ini`` file generated using the above ``--setup`` command is used by RISCOF to locate the DUT and Reference plugins (along with their necessary collaterals). The config file also allows you to define specific nodes/fields -which can be used by the respective plugin. For e.g., in the default ``config.ini`` template the -`pluginpath` variable under the `[spike_simple]` header is available to the riscof_spike_simple.py -plugins by RISCOF. Similarly one can define more variables and prefixes here which can directly be +which can be used by the respective model plugins. For e.g., in the default ``config.ini`` template the +`pluginpath` variable under the `[spike]` header is available to the riscof_spike.py +plugin via RISCOF. Similarly one can define more variables and prefixes here which can directly be used in the plugins. +For example, in the case of sail we can define a `PATH` variable which can point to where the C +emulator binaries are located. This allows the plugin to directly probe which variable and use this +as part of the execution commands. + The idea here is to have a single place of change which is easy rather than hard-coding the same within the plugins. @@ -117,6 +124,46 @@ different actions in different functions as opposed to what is outlined in this they comply with the order of the functions being called and the signatures are generated in their respective directories at the end of the `runTest` function. +__init__ (self, *args, **kwargs) +-------------------------------- + +This is the constructor function for the pluginTemplate class. The configuration dictionary of the +plugin, as specified in the ``config.ini``, is passed to the plugin via the kwargs argument. + +In this function you will also need to define the path of the model executable in the `dut_exe` +variable as shown in line-6 below. Note, this variable can be dierctly set in the ``config.ini`` by +setting the `PATH` variable under the model plugin's header. + +The `num_jobs` variable, in line-7, is used to indicate the number of parallel jobs that can be +spawned for simulation. + +Finally, thise constructor will capture the paths to the plugin, the isa yaml and the platform yaml +for further usage (as seen in lines 13-14). + +.. code-block:: python + :linenos: + + def __init__(self, *args, **kwargs): + sclass = super().__init__(*args, **kwargs) + + config = kwargs.get('config') + + self.dut_exe = os.path.join(config['PATH'] if 'PATH' in config else "","spike") + self.num_jobs = str(config['jobs'] if 'jobs' in config else 1) + if config is None: + print("Please enter input file paths in configuration.") + raise SystemExit + else: + self.isa_spec = os.path.abspath(config['ispec']) + self.platform_spec = os.path.abspath(config['pspec']) + self.pluginpath=os.path.abspath(config['pluginpath']) + + return sclass + +.. warning:: if the config is empty or if the isa and platform yamls are not available in the + specified paths, the above function shall generate an error and exit. + + initialize (suite, workdir, env) -------------------------------- @@ -124,60 +171,83 @@ This function is typically meant to create and initialize all necessary variable compilation commands, elf2hex utility command, objdump command, include directories, etc. This function provides the following arguments which can be used: -1. `suite`: This argument holds the absolute path of the directory where the compliance suite +1. `suite`: This argument holds the absolute path of the directory where the architectural test suite exists.This can be used to replace the name of the file to create directories in proper order. 2. `workdir`: This argument holds the absolute path of the work directory where all the execution and meta files/states will be dumped as part of running RISCOF. -3. `compliance_env`: This argument holds the absolute path of the directory where all the compliance header - files are located. This should be used to initialize the include arguments to the +3. `archtest_env`: This argument holds the absolute path of the directory where all the + architectural test header files are located. This should be used to initialize the include arguments to the compiler/assembler. An example of this function is shown below: .. code-block:: python - - def initialise(self, suite, work_dir, compliance_env): - if shutil.which('spike') is None: - logger.error('Please install spike to proceed further') - sys.exit(0) - self.work_dir = work_dir - self.compile_cmd = 'riscv{1}-unknown-elf-gcc -march={0} \ - -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles\ - -T '+self.pluginpath+'/env/link.ld\ - -I '+self.pluginpath+'/env/\ - -I ' + compliance_env + :linenos: + + def initialise(self, suite, work_dir, archtest_env): + if shutil.which(self.dut_exe) is None: + logger.error(self.dut_exe+' Not Found') + logger.error('Please install Executable for spike to proceed further') + sys.exit(0) + self.work_dir = work_dir + + #TODO: The following assumes you are using the riscv-gcc toolchain. If + # not please change appropriately + self.compile_cmd = 'riscv{1}-unknown-elf-gcc -march={0} \ + -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles\ + -T '+self.pluginpath+'/env/link.ld\ + -I '+self.pluginpath+'/env/\ + -I ' + archtest_env + + # set all the necessary variables like compile command, elf2hex + # commands, objdump cmds. etc whichever you feel necessary and required + # for your plugin. + +The `dut_exe` variable in line-2 above, is derived and set in the `__init__` function described +earlier. This function checks if the `dut_exe` is indeed available and throws an error if not. The +above template is used for the riscv-gnu-toolchain. If you are using an alternate or custom +toolchain the `compile_cmd`, in line-10 above, will have to be changed appropriately. + +One can also choose to add moer commands like objdump, elf2hex, etc from line 202 onwards which will +be used further during the build and run phases. build(isa_yaml, platform_yaml) ------------------------------ RISCOF is not limited to validating only a RTL targets, but can also be used to validate instruction set simulators (ISS) or modern day core-generators like rocket or chromite. These ISS -and core generators have to ability to tune themselves to a specific set of options as defined in -the standardized RISCV-CONFIG YAML. Thus the `build` phase can be used as an intermediate stage to -build or configure not only these models/targets but also be used to build respective tool-chains. +and core generators have the ability to tune themselves to a specific set of configurations as defined in +the standardized RISCV-CONFIG YAML. Thus, the `build` phase can be used as an intermediate stage to +build or configure not only these models/targets but also be used to build respective custom tool-chains that may be required. The `build` function provides the following arguments: -1. `isa_spec`: This argument holds the path to the ISA config YAML. This can be used to extract +1. `isa_spec`: This argument holds the path to the validated ISA config YAML. This can be used to extract various fields from the YAML (e.g. ISA) and configure the DUT accordingly. -2. `platform_spec`: This argument holds the path to the PLATFORM config YAML and can be used +2. `platform_spec`: This argument holds the path to the validated PLATFORM config YAML and can be used similarly as above. An example of this function for an ISS like spike is show below: .. code-block:: python - - def build(self, isa_spec, platform_spec): - ispec = utils.load_yaml(isa_yaml)['hart0'] - self.xlen = ('64' if 64 in ispec['supported_xlen'] else '32') - self.isa = 'rv' + self.xlen - self.compile_cmd = self.compile_cmd+' -mabi='+('lp64 ' if 64 in ispec['supported_xlen'] else 'ilp32 ') - if "I" in ispec["ISA"]: - self.isa += 'i' - if "M" in ispec["ISA"]: - self.isa += 'm' - if "C" in ispec["ISA"]: - self.isa += 'c' + :linenos: + + def build(self, isa_spec, platform_spec): + ispec = utils.load_yaml(isa_yaml)['hart0'] + self.xlen = ('64' if 64 in ispec['supported_xlen'] else '32') + self.isa = 'rv' + self.xlen + #TODO: The following assumes you are using the riscv-gcc toolchain. If + # not please change appropriately + self.compile_cmd = self.compile_cmd+' -mabi='+('lp64 ' if 64 in ispec['supported_xlen'] else 'ilp32 ') + if "I" in ispec["ISA"]: + self.isa += 'i' + if "M" in ispec["ISA"]: + self.isa += 'm' + if "C" in ispec["ISA"]: + self.isa += 'c' + + # based on the validated isa and platform configure your simulator or + # build your RTL here .. note:: For RTL targets this phase is typically empty and no actions are required. Though, one could choose to compile the RTL in this phase if required. @@ -204,24 +274,25 @@ performing the same commands. .. code-block:: python + :linenos: - def runTests(self, testList): - for file in testList: - testentry = testList[file] - test = testentry['test_path'] - test_dir = testentry['work_dir'] + def runTests(self, testList): + for file in testList: + testentry = testList[file] + test = testentry['test_path'] + test_dir = testentry['work_dir'] - elf = 'my.elf' - sig_file = os.path.join(test_dir, self.name[:-1] + ".signature") + elf = 'my.elf' + sig_file = os.path.join(test_dir, self.name[:-1] + ".signature") - cmd = self.compile_cmd.format(testentry['isa'].lower(), self.xlen) + ' ' + test + ' -o ' + elf - compile_cmd = cmd + ' -D' + " -D".join(testentry['macros']) - logger.debug('Compiling test: ' + test) - utils.shellCommand(compile_cmd).run(cwd=test_dir) + cmd = self.compile_cmd.format(testentry['isa'].lower(), self.xlen) + ' ' + test + ' -o ' + elf + compile_cmd = cmd + ' -D' + " -D".join(testentry['macros']) + logger.debug('Compiling test: ' + test) + utils.shellCommand(compile_cmd).run(cwd=test_dir) - execute = spike_path + 'spike --isa={0} +signature={1} +signature-granularity=4 {2}'.format(self.isa, sig_file, elf) - logger.debug('Executing on Spike ' + execute) - utils.shellCommand(execute).run(cwd=test_dir) + execute = spike_path + 'spike --isa={0} +signature={1} +signature-granularity=4 {2}'.format(self.isa, sig_file, elf) + logger.debug('Executing on Spike ' + execute) + utils.shellCommand(execute).run(cwd=test_dir) An example which uses the ``makeUtil`` utility is show below. Here a Makefile is first generated where every test is a make target. the utility automatically creates the relevant targets and only @@ -231,25 +302,32 @@ The user can choose to use a different make command by setting the ``make.makeCommand``. More details of this utility are available at: :ref:`utils` .. code-block:: bash + :linenos: def runTests(self, testList): make = utils.makeUtil(makefilePath=os.path.join(self.work_dir, "Makefile." + self.name[:-1])) - make.makeCommand = 'make -j' + parallel_jobs + make.makeCommand = 'make -j' + self.num_jobs for file in testList: testentry = testList[file] test = testentry['test_path'] test_dir = testentry['work_dir'] - elf = 'my.elf' - - execute = "cd "+testentry['work_dir']+";" + elf = 'dut.elf' + + execute = "@cd "+testentry['work_dir']+";" cmd = self.compile_cmd.format(testentry['isa'].lower(), self.xlen) + ' ' + test + ' -o ' + elf + + #TODO: we are using -D to enable compile time macros. If your + # toolchain is not riscv-gcc you may want to change the below code compile_cmd = cmd + ' -D' + " -D".join(testentry['macros']) execute+=compile_cmd+";" sig_file = os.path.join(test_dir, self.name[:-1] + ".signature") - execute += spike_path + 'spike --isa={0} +signature={1} +signature-granularity=4 {2};'.format(self.isa, sig_file, elf) + + #TODO: You will need to add any other arguments to your DUT + # executable if any in the quotes below + execute += self.dut_exe + ' --log-commits --log dump --isa={0} +signature={1} +signature-granularity=4 {2};'.format(self.isa, sig_file, elf) make.add_target(execute) make.execute_all(self.work_dir) diff --git a/docs/source/quickstart.rst b/docs/source/quickstart.rst deleted file mode 100644 index 0d9dbf6a091710b6d83b5a7203b7e5cba8ee5ecb..0000000000000000000000000000000000000000 --- a/docs/source/quickstart.rst +++ /dev/null @@ -1,500 +0,0 @@ -.. _quickstart: - -########## -Quickstart -########## - -This doc is meant to serve as a quick-guide to setup RISCOF and perform a sample compliance check -between ``spike`` (DUT in this case) and ``riscvOVPsim`` (Golden model in this case). - -Install Python -============== - -Ubuntu ------- - -Ubuntu 17.10 and 18.04 by default come with python-3.6.9 which is sufficient for using riscv-config. - -If you are are Ubuntu 16.10 and 17.04 you can directly install python3.6 using the Universe -repository:: - - $ sudo apt-get install python3.6 - $ pip3 install --upgrade pip - -If you are using Ubuntu 14.04 or 16.04 you need to get python3.6 from a Personal Package Archive -(PPA):: - - $ sudo add-apt-repository ppa:deadsnakes/ppa - $ sudo apt-get update - $ sudo apt-get install python3.6 -y - $ pip3 install --upgrade pip - -You should now have 2 binaries: ``python3`` and ``pip3`` available in your $PATH. -You can check the versions as below:: - - $ python3 --version - Python 3.6.9 - $ pip3 --version - pip 20.1 from .local/lib/python3.6/site-packages/pip (python 3.6) - -Centos:7 --------- -The CentOS 7 Linux distribution includes Python 2 by default. However, as of CentOS 7.7, Python 3 -is available in the base package repository which can be installed using the following commands:: - - $ sudo yum update -y - $ sudo yum install -y python3 - $ pip3 install --upgrade pip - -For versions prior to 7.7 you can install python3.6 using third-party repositories, such as the -IUS repository:: - - $ sudo yum update -y - $ sudo yum install yum-utils - $ sudo yum install https://centos7.iuscommunity.org/ius-release.rpm - $ sudo yum install python36u - $ pip3 install --upgrade pip - -You can check the versions:: - - $ python3 --version - Python 3.6.8 - $ pip --version - pip 20.1 from .local/lib/python3.6/site-packages/pip (python 3.6) - - -Using Virtualenv for Python ---------------------------- - -Many a times users face issues in installing and managing multiple python versions. This is actually -a major issue as many gui elements in Linux use the default python versions, in which case installing -python3.6 using the above methods might break other software. We thus advise the use of **pyenv** to -install python3.6. - -For Ubuntu and CentosOS, please follow the steps here: https://github.com/pyenv/pyenv#basic-github-checkout - -RHEL users can find more detailed guides for virtual-env here: https://developers.redhat.com/blog/2018/08/13/install-python3-rhel/#create-env - -Once you have pyenv installed do the following to install python 3.6.0:: - - $ pyenv install 3.6.0 - $ pip3 install --upgrade pip - $ pyenv shell 3.6.0 - -You can check the version in the **same shell**:: - - $ python --version - Python 3.6.0 - $ pip --version - pip 20.1 from .local/lib/python3.6/site-packages/pip (python 3.6) - -Install RISCOF -============== - -.. note:: If you are using `pyenv` as mentioned above, make sure to enable that environment before - performing the following steps. - -.. code-block:: bash - - $ pip3 install riscof - -To update an already installed version of RISCOF to the latest version: - -.. code-block:: bash - - $ pip3 install -U riscof - -To checkout a specific version of riscof: - -.. code-block:: bash - - $ pip3 install riscof==1.x.x - -Once you have RISCOF installed, executing ``riscof --help`` should print the following on the terminal: - -.. code-block:: bash - - - usage: riscof [-h] [--version] [--verbose] - {gendb,setup,validateyaml,run,testlist} ... - - This program checks compliance for a DUT. - - optional arguments: - --verbose [Default=info] - --version, -v Print version of RISCOF being used - -h, --help show this help message and exit - - Action: - The action to be performed by riscof. - - {gendb,setup,validateyaml,run,testlist} - List of actions supported by riscof. - gendb Generate Database for the standard suite. - setup Initiate setup for riscof. - validateyaml Validate the Input YAMLs using riscv-config. - run Run the tests on DUT and reference and compare - signatures. - testlist Generate the test list for the given DUT and suite. - Uses the compliance suite by default. - Action 'gendb' - - usage: riscof gendb [-h] [--suite PATH] - - optional arguments: - --suite PATH The Path to the custom suite directory. - -h, --help show this help message and exit - - Action 'setup' - - usage: riscof setup [-h] [--dutname NAME] [--refname NAME] - - optional arguments: - --dutname NAME Name of DUT plugin. [Default=spike] - --refname NAME Name of Reference plugin. [Default=riscvOVPsim] - -h, --help show this help message and exit - - Action 'validateyaml' - - usage: riscof validateyaml [-h] [--config PATH] - - optional arguments: - --config PATH The Path to the config file. [Default=./config.ini] - -h, --help show this help message and exit - - Action 'run' - - usage: riscof run [-h] [--config PATH] [--suite PATH] [--no-browser] - - optional arguments: - --config PATH The Path to the config file. [Default=./config.ini] - --no-browser Do not open the browser for showing the test report. - --suite PATH The Path to the custom suite directory. - -h, --help show this help message and exit - - Action 'testlist' - - usage: riscof testlist [-h] [--config PATH] [--suite PATH] - - optional arguments: - --config PATH The Path to the config file. [Default=./config.ini] - --suite PATH The Path to the custom suite directory. - -h, --help show this help message and exit - - -Install RISCV-GNU Toolchain -=========================== - -This guide will use the 32-bit riscv-gnu tool chain to compile the compliance suite. -If you already have the 32-bit gnu-toolchain available, you can skip to the next section. - -.. note:: The git clone and installation will take significant time. Please be patient. If you face - issues with any of the following steps please refer to - https://github.com/riscv/riscv-gnu-toolchain for further help in installation. - - -Ubuntu Users ------------- - -.. code-block:: bash - - $ sudo apt-get install autoconf automake autotools-dev curl python3 libmpc-dev \ - libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool \ - patchutils bc zlib1g-dev libexpat-dev - $ git clone --recursive https://github.com/riscv/riscv-gnu-toolchain - $ git clone --recursive https://github.com/riscv/riscv-opcodes.git - $ cd riscv-gnu-toolchain - $ ./configure --prefix=/path/to/install --with-arch=rv32gc --with-abi=ilp32d # for 32-bit toolchain - $ [sudo] make # sudo is required depending on the path chosen in the previous setup - -CentosOS/RHEL -------------- - -.. code-block:: bash - - $ sudo yum install autoconf automake python3 libmpc-devel mpfr-devel gmp-devel \ - gawk bison flex texinfo patchutils gcc gcc-c++ zlib-devel expat-devel - $ git clone --recursive https://github.com/riscv/riscv-gnu-toolchain - $ git clone --recursive https://github.com/riscv/riscv-opcodes.git - $ cd riscv-gnu-toolchain - $ ./configure --prefix=/path/to/install --with-arch=rv32gc --with-abi=ilp32d # for 32-bit toolchain - $ [sudo] make # sudo is required depending on the path chosen in the previous setup - -Make sure to add the path ``/path/to/install`` to your `$PATH` in the .bashrc/cshrc -With this you should now have all the following available as command line arguments:: - - riscv32-unknown-elf-addr2line riscv32-unknown-elf-elfedit - riscv32-unknown-elf-ar riscv32-unknown-elf-g++ - riscv32-unknown-elf-as riscv32-unknown-elf-gcc - riscv32-unknown-elf-c++ riscv32-unknown-elf-gcc-8.3.0 - riscv32-unknown-elf-c++filt riscv32-unknown-elf-gcc-ar - riscv32-unknown-elf-cpp riscv32-unknown-elf-gcc-nm - riscv32-unknown-elf-gcc-ranlib riscv32-unknown-elf-gprof - riscv32-unknown-elf-gcov riscv32-unknown-elf-ld - riscv32-unknown-elf-gcov-dump riscv32-unknown-elf-ld.bfd - riscv32-unknown-elf-gcov-tool riscv32-unknown-elf-nm - riscv32-unknown-elf-gdb riscv32-unknown-elf-objcopy - riscv32-unknown-elf-gdb-add-index riscv32-unknown-elf-objdump - riscv32-unknown-elf-ranlib riscv32-unknown-elf-readelf - riscv32-unknown-elf-run riscv32-unknown-elf-size - riscv32-unknown-elf-strings riscv32-unknown-elf-strip - -Install DUT and Golden Models -============================= - -This guide is going to prove compliance of the spike model (the DUT) against the riscvOVPsim model -(the Golden model), both of which need to be installed. - -Installing SPIKE (a.k.a riscv-isa-sim) --------------------------------------- - -.. code-block:: bash - - $ git clone https://github.com/riscv/riscv-isa-sim.git - $ cd riscv-isa-sim - $ mkdir build - $ cd build - $ ../configure --prefix=/path/to/install - $ make - $ [sudo] make install #sudo is required depending on the path chosen in the previous setup - -Make sure to add the path ``/path/to/install`` to your `$PATH` in the .bashrc/cshrc -Once installed, executing ``spike`` on the terminal should print the following:: - - usage: spike [host options] [target options] - Host Options: - -p Simulate processors [default 1] - -m Provide MiB of target memory [default 2048] - -m Provide memory regions of size m and n bytes - at base addresses a and b (with 4 KiB alignment) - -d Interactive debug mode - -g Track histogram of PCs - -l Generate a log of execution - -h Print this help message - -H Start halted, allowing a debugger to connect - --isa= RISC-V ISA string [default RV64IMAFDC] - --pc=
Override ELF entry point - --hartids= Explicitly specify hartids, default is 0,1,... - --ic=:: Instantiate a cache model with S sets, - --dc=:: W ways, and B-byte blocks (with S and - --l2=:: B both powers of 2). - --extension= Specify RoCC Extension - --extlib= Shared library to load - --rbb-port= Listen on for remote bitbang connection - --dump-dts Print device tree string and exit - --disable-dtb Don't write the device tree blob into memory - --progsize= Progsize for the debug module [default 2] - --debug-sba= Debug bus master supports up to wide accesses [default 0] - --debug-auth Debug module requires debugger to authenticate - - -Installing riscvOVPsim ----------------------- - -.. code-block:: bash - - $ git clone https://github.com/riscv/riscv-ovpsim.git --recursive - $ export PATH=$PATH:/riscv-ovpsim/bin/Linux64/ - -Once installed, open a new terminal and check the version:: - - $ riscvOVPsim.exe --version - 20200206.0 - - -Create Necessary Env Files -========================== - -RISCOF requires python plugins for each model (DUT and Golden) to be submitted. These plugins -provide a quick and standard way of building the model, compiling the tests and executing the tests -on the models. Along with the python plugins of each model, one would also have to provide the -`YAML` configuration files of the DUT as per the norms of ``riscv-config``. Some models might also -require special macros to be executed as prelude or post-testing. These macros can be provided to -RISCOF as a header file: ``compliance_model.h``. - -For the sake of this guide, we will use some of the pre-built plugins for riscof available at: -`riscof-plugins `_. We will specifically use the -spike_simple and riscvOVPsim plugins. - -.. note:: If you are using `pyenv` as mentioned above, make sure to enable that environment before - performing the following steps since we will now start using riscof. - -.. code-block:: bash - - $ git clone https://gitlab.com/incoresemi/riscof-plugins.git - -To create necessary environment files use the following command:: - - $ riscof setup --dutname=spike_simple --refname=riscvOVPsim - -The above command will generate a file named ``config.ini`` and a folder named ``spike_simple``. -The ``config.ini`` file is used to capture specific paths of the plugins of reference and DUT model, -along with the paths to isa and platform input YAMLs. The folder ``spike_simple`` contains -various templates of files that would be required for compliance of any generic DUT. -Components of this folder will be modified by the user as per the DUT spec. -Since we are going to use pre-built plugins for this guide, we will ignore the ``spike_simple`` -folder for now. - -.. note:: For specific examples on modifications to environment files, please check the - corresponding files for various targets available in the riscof-plugins directory. - -Based on the path you have downloaded the riscof-plugins directory, you will need to modify the -``config.ini`` file to look similar to the following:: - - - [RISCOF] - ReferencePlugin=riscvOVPsim - ReferencePluginPath=/path/to/riscof-plugins/riscvOVPsim - DUTPlugin=spike_simple - DUTPluginPath=/path/to/riscof-plugins/spike_simple - - ## Example configuration for spike plugin. - [spike_simple] - pluginpath=/path/to/riscof-plugins/spike_simple/ - ispec=/path/to/riscof-plugins/spike_simple/spike_simple_isa.yaml - pspec=/path/to/riscof-plugins/spike_simple/spike_simple_platform.yaml - -We are now ready to run compliance via RISCOF - -Running RISCOF -============== - -The RISCOF run is divided into three steps as shown in the overview Figure. -The first step is to check if the input yaml files are configured correctly. This step internally calls -the ``riscv-config`` on both the isa and platform yaml files indicated in the ``config.ini`` file. - -.. code-block:: bash - - riscof validateyaml --config=config.ini - -This should print the following: - -.. code-block:: bash - - [INFO] : Reading configuration from: /scratch/git-repo/incoresemi/riscof-plugins/config.ini - [INFO] : Preparing Models - [INFO] : Input-ISA file - [INFO] : Loading input file: /scratch/git-repo/incoresemi/riscof-plugins/spike_simple/sample_isa.yaml - [INFO] : Load Schema /home/neel/.pyenv/versions/3.7.0/envs/venv/lib/python3.7/site-packages/riscv_config/schemas/schema_isa.yaml - [INFO] : Initiating Validation - [INFO] : No Syntax errors in Input ISA Yaml. :) - [INFO] : Dumping out Normalized Checked YAML: /scratch/git-repo/incoresemi/riscof-plugins/riscof_work/sample_isa_checked.yaml - [INFO] : Input-Platform file - [INFO] : Loading input file: /scratch/git-repo/incoresemi/riscof-plugins/spike_simple/sample_platform.yaml - [INFO] : Load Schema /home/neel/.pyenv/versions/3.7.0/envs/venv/lib/python3.7/site-packages/riscv_config/schemas/schema_platform.yaml - [INFO] : Initiating Validation - [INFO] : No Syntax errors in Input Platform Yaml. :) - [INFO] : Dumping out Normalized Checked YAML: /scratch/git-repo/incoresemi/riscof-plugins/riscof_work/sample_platform_checked.yaml - -The next step is generate the list of tests that need to be run on the models for declaring -compliance. - -.. code-block:: bash - - riscof testlist --config=config.ini - -This step calls the validate-step and thus the output adds one more line to the above dump: - -.. code-block:: bash - - [INFO] : Selecting Tests. - -The tests are listed in the file: ``riscof_work/test_list.yaml`` which should probably look -something similar to the following: - -.. code-block:: yaml - - suite/rv32i_m/C/C-ADD.S: - work_dir: /scratch/git-repo/incoresemi/riscof-plugins/riscof_work/rv32i_m/C/C-ADD.S - macros: [TEST_CASE_1=True, XLEN=32] - isa: RV32IC - test_path: /home/neel/.pyenv/versions/3.7.0/envs/venv/lib/python3.7/site-packages/riscof/suite/rv32i_m/C/C-ADD.S - suite/rv32i_m/C/C-ADDI.S: - work_dir: /scratch/git-repo/incoresemi/riscof-plugins/riscof_work/rv32i_m/C/C-ADDI.S - macros: [TEST_CASE_1=True, XLEN=32] - isa: RV32IC - test_path: /home/neel/.pyenv/versions/3.7.0/envs/venv/lib/python3.7/site-packages/riscof/suite/rv32i_m/C/C-ADDI.S - suite/rv32i_m/C/C-ADDI16SP.S: - work_dir: /scratch/git-repo/incoresemi/riscof-plugins/riscof_work/rv32i_m/C/C-ADDI16SP.S - macros: [TEST_CASE_1=True, XLEN=32] - isa: RV32IC - ... - ... - ... - -The last step is to run the tests on the each of the models and compare the signature values to -guarantee correctness. - -.. code-block:: bash - - riscof run --config=config.ini - -This should compile and execute the tests on each of the models and end up with the following log: - - -.. code-block:: bash - - ... - ... - ... - [INFO] : Initiating signature checking. - [INFO] : Following 55 tests have been run : - - [INFO] : TEST NAME : COMMIT ID : STATUS - [INFO] : suite/rv32i_m/I/I-ADD-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-ADDI-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-AND-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-ANDI-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-AUIPC-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-BEQ-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-BGE-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-BGEU-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-BLT-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-BLTU-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-BNE-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-CSRRC-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-CSRRCI-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-CSRRS-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-CSRRSI-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-CSRRW-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-CSRRWI-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-DELAY_SLOTS-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-EBREAK-01.S : 3a4a3a576666d5153ae6a844e74a45f953245e57 : Passed - [INFO] : suite/rv32i_m/I/I-ECALL-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-ENDIANESS-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-FENCE.I-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-IO.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-JAL-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-JALR-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-LB-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-LBU-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-LH-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-LHU-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-LUI-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-LW-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-MISALIGN_JMP-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-MISALIGN_LDST-02.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-NOP-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-OR-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-ORI-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-RF_size-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-RF_width-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-RF_x0-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-SB-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-SH-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-SLL-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-SLLI-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-SLT-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-SLTI-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-SLTIU-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-SLTU-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-SRA-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-SRAI-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-SRL-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-SRLI-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-SUB-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-SW-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-XOR-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - [INFO] : suite/rv32i_m/I/I-XORI-01.S : d50921ef64708678832770fd842355aa2b0684af : Passed - -And will also open a HTML page with all the information. diff --git a/docs/source/testformat.rst b/docs/source/testformat.rst index 7b764087130ec804c34f1856b10ca53c1db668ef..928e595a7f39b9a2ad95aa2d7049f322f1537bb0 100644 --- a/docs/source/testformat.rst +++ b/docs/source/testformat.rst @@ -196,7 +196,7 @@ significant amount of the framework shall depend on the existence of these macro - condStr is evaluated to determine if the test-case is enabled and sets name variable + - condStr can also define compile time macros required for the test-case to be enabled. + - the test-case must be delimited with an #ifdef CaseName/#endif pair + - - the format of CondStr can be found in https://riscof.readthedocs.io/en/latest/cond_spec.html#cond-spec + - the format of CondStr can be found in https://riscof.readthedocs.io/en/latest/testformat.html#rvtest-case-condition-formating Required, Model-defined Macros ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -339,8 +339,8 @@ Instead, each of those should be a separate :ref:`The test case ` who the common reference document entry for that test and test case number. -RVTEST_CASE Condition Formating -------------------------------- +RVTEST_CASE Condition Formatting +-------------------------------- This section describes the format for the conditions `CondStr` to be followed while writing the ``RVTEST_CASE`` macro. Each of the statements within this macro ends with a ';' . diff --git a/docs/source/testlist.rst b/docs/source/testlist.rst index 4dc276243a1dc73a254e5f77e76d77f583f9be35..6e7680dd33ff6f488d9790d4c2eaece3c3b6cc77 100644 --- a/docs/source/testlist.rst +++ b/docs/source/testlist.rst @@ -5,7 +5,7 @@ Test List Format ################ For a given ISA and PLATFORM YAML configuration files, RISCOF is capable of generating a list of -tests that need to be executed on the DUT and Golden model for compliance. This test list can be +tests that need to be executed on the DUT and Golden model. This test list can be generated using the following command: .. code-block:: bash @@ -24,7 +24,7 @@ syntax: test_path: The test-list is meant to be used by the DUT/Golden model plugins to generate execution -environments/Makefile for compliance testing. +environments/Makefile for architectural suite testing. A sample test_list.yaml would look like the following: diff --git a/riscof/Templates/setup/model/env/compliance_model.h b/riscof/Templates/setup/model/env/compliance_model.h deleted file mode 100644 index b37463cde4d780b70bf522399293d3e788c009b7..0000000000000000000000000000000000000000 --- a/riscof/Templates/setup/model/env/compliance_model.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _COMPLIANCE_MODEL_H -#define _COMPLIANCE_MODEL_H - -//----------------------------------------------------------------------- -// Model specific Macros -//----------------------------------------------------------------------- - -#define RVMODEL_DATA_SECTION \ -//Define the data section required for debugging and io operations here. - -//RV_COMPLIANCE_HALT -#define RVMODEL_HALT \ -//Define the halt sequence for the implementation here. - -#define RVMODEL_BOOT \ -//Define the boot sequence for the implementation here. - -//RV_COMPLIANCE_DATA_BEGIN -//Change the definition in the following macros if the implementation expects -//different labels for identifying the signature section. -#define RVMODEL_DATA_BEGIN \ - RVMODEL_DATA_SECTION \ - .align 4; .global begin_signature; begin_signature: - -//RV_COMPLIANCE_DATA_END -#define RVMODEL_DATA_END \ - .align 4; .global end_signature; end_signature: - - -//Define the IO macros as required. -//RVTEST_IO_INIT -#define RVMODEL_IO_INIT \ - -//RVTEST_IO_WRITE_STR -#define RVMODEL_IO_WRITE_STR(_R, _STR) \ - -//RVTEST_IO_CHECK -#define RVMODEL_IO_CHECK() \ - -//RVTEST_IO_ASSERT_GPR_EQ -#define RVMODEL_IO_ASSERT_GPR_EQ(_S, _R, _I) \ - -//RVTEST_IO_ASSERT_SFPR_EQ -#define RVMODEL_IO_ASSERT_SFPR_EQ(_F, _R, _I) \ - -//RVTEST_IO_ASSERT_DFPR_EQ -#define RVMODEL_IO_ASSERT_DFPR_EQ(_D, _R, _I) \ - -#endif // _COMPLIANCE_MODEL_H diff --git a/riscof/Templates/setup/model/env/link.ld b/riscof/Templates/setup/model/env/link.ld index 187ef6f81e381b827754580d42cb6efd8b2a5bd9..8ad95e049bedb9b8c3619ed3608028828425628a 100644 --- a/riscof/Templates/setup/model/env/link.ld +++ b/riscof/Templates/setup/model/env/link.ld @@ -1,5 +1,5 @@ OUTPUT_ARCH( "riscv" ) -ENTRY(_start) +ENTRY(rvtest_entry_point) SECTIONS { diff --git a/riscof/Templates/setup/model/env/model_test.h b/riscof/Templates/setup/model/env/model_test.h new file mode 100644 index 0000000000000000000000000000000000000000..ef4cc44990e7bf9975064f1f8ed774ac29fe8bde --- /dev/null +++ b/riscof/Templates/setup/model/env/model_test.h @@ -0,0 +1,65 @@ +#ifndef _COMPLIANCE_MODEL_H +#define _COMPLIANCE_MODEL_H +#if XLEN == 64 + #define ALIGNMENT 3 +#else + #define ALIGNMENT 2 +#endif + +#define RVMODEL_DATA_SECTION \ + .pushsection .tohost,"aw",@progbits; \ + .align 8; .global tohost; tohost: .dword 0; \ + .align 8; .global fromhost; fromhost: .dword 0; \ + .popsection; \ + .align 8; .global begin_regstate; begin_regstate: \ + .word 128; \ + .align 8; .global end_regstate; end_regstate: \ + .word 4; + +//RV_COMPLIANCE_HALT +#define RVMODEL_HALT \ + li x1, 1; \ + write_tohost: \ + sw x1, tohost, t5; \ + j write_tohost; + +#define RVMODEL_BOOT + +//RV_COMPLIANCE_DATA_BEGIN +#define RVMODEL_DATA_BEGIN \ + RVMODEL_DATA_SECTION \ + .align ALIGNMENT;\ + .global begin_signature; begin_signature: + +//RV_COMPLIANCE_DATA_END +#define RVMODEL_DATA_END \ + .global end_signature; end_signature: + +//RVTEST_IO_INIT +#define RVMODEL_IO_INIT +//RVTEST_IO_WRITE_STR +#define RVMODEL_IO_WRITE_STR(_R, _STR) +//RVTEST_IO_CHECK +#define RVMODEL_IO_CHECK() +//RVTEST_IO_ASSERT_GPR_EQ +#define RVMODEL_IO_ASSERT_GPR_EQ(_S, _R, _I) +//RVTEST_IO_ASSERT_SFPR_EQ +#define RVMODEL_IO_ASSERT_SFPR_EQ(_F, _R, _I) +//RVTEST_IO_ASSERT_DFPR_EQ +#define RVMODEL_IO_ASSERT_DFPR_EQ(_D, _R, _I) + +#define RVMODEL_SET_MSW_INT \ + li t1, 1; \ + li t2, 0x2000000; \ + sw t1, 0(t2); + +#define RVMODEL_CLEAR_MSW_INT \ + li t2, 0x2000000; \ + sw x0, 0(t2); + +#define RVMODEL_CLEAR_MTIMER_INT + +#define RVMODEL_CLEAR_MEXT_INT + + +#endif // _COMPLIANCE_MODEL_H diff --git a/riscof/Templates/setup/model/model_isa.yaml b/riscof/Templates/setup/model/model_isa.yaml index d3f2b75d7e3204e95f415d2a01c26ea2a051fd59..fe8f8b115971aefd3231aa5a952c38dfe5e08c20 100644 --- a/riscof/Templates/setup/model/model_isa.yaml +++ b/riscof/Templates/setup/model/model_isa.yaml @@ -1,6 +1,29 @@ hart_ids: [0] hart0: ISA: RV32IMCZicsr_Zifencei + physical_addr_sz: 32 User_Spec_Version: '2.3' supported_xlen: [32] - physical_addr_sz: 32 + misa: + reset-val: 0x40001104 + rv32: + accessible: true + mxl: + implemented: true + type: + warl: + dependency_fields: [] + legal: + - mxl[1:0] in [0x1] + wr_illegal: + - Unchanged + extensions: + implemented: true + type: + warl: + dependency_fields: [] + legal: + - extensions[25:0] bitmask [0x0001104, 0x0000000] + wr_illegal: + - Unchanged + diff --git a/riscof/Templates/setup/model/model_platform.yaml b/riscof/Templates/setup/model/model_platform.yaml index 4b99ed9c113e26e8a018687b9692ee6fd0749cfe..8e1a3d8e30f0a2e51a5c158a4f55cd612aa52eb1 100644 --- a/riscof/Templates/setup/model/model_platform.yaml +++ b/riscof/Templates/setup/model/model_platform.yaml @@ -1,3 +1,9 @@ +mtime: + implemented: true + address: 0xbff8 +mtimecmp: + implemented: true + address: 0x4000 nmi: label: nmi_vector reset: diff --git a/riscof/Templates/setup/model/riscof_model.py b/riscof/Templates/setup/model/riscof_model.py index 7a4c05cab199037ae644371d78412e2924e3b48d..122a8cc21875effd1e49aa2e993538b01c937841 100644 --- a/riscof/Templates/setup/model/riscof_model.py +++ b/riscof/Templates/setup/model/riscof_model.py @@ -15,14 +15,19 @@ from riscof.pluginTemplate import pluginTemplate logger = logging.getLogger() -class spike_simple(pluginTemplate): - __model__ = "Spike" - __version__ = "0.5.0" +class dutname(pluginTemplate): + __model__ = "dutname" + + #TODO: please update the below to indicate family, version, etc of your DUT. + __version__ = "XXX" def __init__(self, *args, **kwargs): sclass = super().__init__(*args, **kwargs) config = kwargs.get('config') + + self.dut_exe = os.path.join(config['PATH'] if 'PATH' in config else "","dutname") + self.num_jobs = str(config['jobs'] if 'jobs' in config else 1) if config is None: print("Please enter input file paths in configuration.") raise SystemExit @@ -33,29 +38,66 @@ class spike_simple(pluginTemplate): return sclass - def initialise(self, suite, work_dir, compliance_env): + def initialise(self, suite, work_dir, archtest_env): + if shutil.which(self.dut_exe) is None: + logger.error(self.dut_exe+' Not Found') + logger.error('Please install Executable for dutname to proceed further') + sys.exit(0) self.work_dir = work_dir - self.compile_cmd = '' + + #TODO: The following assumes you are using the riscv-gcc toolchain. If + # not please change appropriately + self.compile_cmd = 'riscv{1}-unknown-elf-gcc -march={0} \ + -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles\ + -T '+self.pluginpath+'/env/link.ld\ + -I '+self.pluginpath+'/env/\ + -I ' + archtest_env # set all the necessary variables like compile command, elf2hex # commands, objdump cmds. etc whichever you feel necessary and required # for your plugin. def build(self, isa_yaml, platform_yaml): - ispec = utils.load_yaml(isa_yaml) - self.isa = ispec["ISA"] + ispec = utils.load_yaml(isa_yaml)['hart0'] + self.xlen = ('64' if 64 in ispec['supported_xlen'] else '32') + self.isa = 'rv' + self.xlen + #TODO: The following assumes you are using the riscv-gcc toolchain. If + # not please change appropriately + self.compile_cmd = self.compile_cmd+' -mabi='+('lp64 ' if 64 in ispec['supported_xlen'] else 'ilp32 ') + if "I" in ispec["ISA"]: + self.isa += 'i' + if "M" in ispec["ISA"]: + self.isa += 'm' + if "C" in ispec["ISA"]: + self.isa += 'c' - # based on the validated isa and platform configure your simulator ro + # based on the validated isa and platform configure your simulator or # build your RTL here - def runTests(self, testList): + def runTests(self, testList, cgf_file=None): + make = utils.makeUtil(makefilePath=os.path.join(self.work_dir, "Makefile." + self.name[:-1])) + make.makeCommand = 'make -j' + self.num_jobs for file in testList: testentry = testList[file] - test = os.path.join(constants.root, str(file)) + test = testentry['test_path'] test_dir = testentry['work_dir'] - # compile each test - # execute each test on simulator/DUT - # fix signature format if required + elf = 'dut.elf' + execute = "@cd "+testentry['work_dir']+";" + + cmd = self.compile_cmd.format(testentry['isa'].lower(), self.xlen) + ' ' + test + ' -o ' + elf + + #TODO: we are using -D to enable compile time macros. If your + # toolchain is not riscv-gcc you may want to change the below code + compile_cmd = cmd + ' -D' + " -D".join(testentry['macros']) + execute+=compile_cmd+";" + + sig_file = os.path.join(test_dir, self.name[:-1] + ".signature") + + #TODO: You will need to add any other arguments to your DUT + # executable if any in the quotes below + execute += self.dut_exe + '' + make.add_target(execute) + make.execute_all(self.work_dir) diff --git a/riscof/Templates/setup/reference/env/link.ld b/riscof/Templates/setup/reference/env/link.ld new file mode 100644 index 0000000000000000000000000000000000000000..8ad95e049bedb9b8c3619ed3608028828425628a --- /dev/null +++ b/riscof/Templates/setup/reference/env/link.ld @@ -0,0 +1,18 @@ +OUTPUT_ARCH( "riscv" ) +ENTRY(rvtest_entry_point) + +SECTIONS +{ + . = 0x80000000; + .text.init : { *(.text.init) } + . = ALIGN(0x1000); + .tohost : { *(.tohost) } + . = ALIGN(0x1000); + .text : { *(.text) } + . = ALIGN(0x1000); + .data : { *(.data) } + .data.string : { *(.data.string)} + .bss : { *(.bss) } + _end = .; +} + diff --git a/riscof/Templates/setup/reference/env/model_test.h b/riscof/Templates/setup/reference/env/model_test.h new file mode 100644 index 0000000000000000000000000000000000000000..cc8cfde1019f93afdb9580b15fd3538877cc1c2d --- /dev/null +++ b/riscof/Templates/setup/reference/env/model_test.h @@ -0,0 +1,59 @@ +#ifndef _COMPLIANCE_MODEL_H +#define _COMPLIANCE_MODEL_H +#if XLEN == 64 + #define ALIGNMENT 3 +#else + #define ALIGNMENT 2 +#endif + +#define RVMODEL_DATA_SECTION \ + .pushsection .tohost,"aw",@progbits; \ + .align 8; .global tohost; tohost: .dword 0; \ + .align 8; .global fromhost; fromhost: .dword 0; \ + .popsection; \ + .align 8; .global begin_regstate; begin_regstate: \ + .word 128; \ + .align 8; .global end_regstate; end_regstate: \ + .word 4; + +//RV_COMPLIANCE_HALT +#define RVMODEL_HALT \ + li x1, 1; \ + write_tohost: \ + sw x1, tohost, t5; \ + j write_tohost; + +#define RVMODEL_BOOT + +//RV_COMPLIANCE_DATA_BEGIN +#define RVMODEL_DATA_BEGIN \ + .align 4; .global begin_signature; begin_signature: + +//RV_COMPLIANCE_DATA_END +#define RVMODEL_DATA_END \ + .align 4; .global end_signature; end_signature: \ + RVMODEL_DATA_SECTION \ + +//RVTEST_IO_INIT +#define RVMODEL_IO_INIT +//RVTEST_IO_WRITE_STR +#define RVMODEL_IO_WRITE_STR(_R, _STR) +//RVTEST_IO_CHECK +#define RVMODEL_IO_CHECK() +//RVTEST_IO_ASSERT_GPR_EQ +#define RVMODEL_IO_ASSERT_GPR_EQ(_S, _R, _I) +//RVTEST_IO_ASSERT_SFPR_EQ +#define RVMODEL_IO_ASSERT_SFPR_EQ(_F, _R, _I) +//RVTEST_IO_ASSERT_DFPR_EQ +#define RVMODEL_IO_ASSERT_DFPR_EQ(_D, _R, _I) + +#define RVMODEL_SET_MSW_INT + +#define RVMODEL_CLEAR_MSW_INT + +#define RVMODEL_CLEAR_MTIMER_INT + +#define RVMODEL_CLEAR_MEXT_INT + + +#endif // _COMPLIANCE_MODEL_H diff --git a/riscof/Templates/setup/reference/riscof_model.py b/riscof/Templates/setup/reference/riscof_model.py new file mode 100644 index 0000000000000000000000000000000000000000..4a1a5016824c16fbc88ff1249ece1d00647110dd --- /dev/null +++ b/riscof/Templates/setup/reference/riscof_model.py @@ -0,0 +1,122 @@ +import os +import re +import shutil +import subprocess +import shlex +import logging +import random +import string +from string import Template +import sys + +import riscof.utils as utils +import riscof.constants as constants +from riscof.pluginTemplate import pluginTemplate + +logger = logging.getLogger() + +class refname(pluginTemplate): + __model__ = "refname" + + #TODO: please update the below to indicate family, version, etc of your DUT. + __version__ = "XXX" + + def __init__(self, *args, **kwargs): + sclass = super().__init__(*args, **kwargs) + + config = kwargs.get('config') + + self.ref_exe = os.path.join(config['PATH'] if 'PATH' in config else "","refname") + self.num_jobs = str(config['jobs'] if 'jobs' in config else 1) + self.pluginpath=os.path.abspath(config['pluginpath']) + + return sclass + + def initialise(self, suite, work_dir, archtest_env): + self.suite = suite + if shutil.which(self.ref_exe) is None: + logger.error('Please install Executable for DUTNAME to proceed further') + sys.exit(0) + self.work_dir = work_dir + + #TODO: The following assumes you are using the riscv-gcc toolchain. If + # not please change appropriately + self.objdump_cmd = 'riscv{1}-unknown-elf-objdump -D {0} > {2};' + self.compile_cmd = 'riscv{1}-unknown-elf-gcc -march={0} \ + -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles\ + -T '+self.pluginpath+'/env/link.ld\ + -I '+self.pluginpath+'/env/\ + -I ' + archtest_env + + # set all the necessary variables like compile command, elf2hex + # commands, objdump cmds. etc whichever you feel necessary and required + # for your plugin. + + def build(self, isa_yaml, platform_yaml): + ispec = utils.load_yaml(isa_yaml)['hart0'] + self.xlen = ('64' if 64 in ispec['supported_xlen'] else '32') + self.isa = 'rv' + self.xlen + #TODO: The following assumes you are using the riscv-gcc toolchain. If + # not please change appropriately + self.compile_cmd = self.compile_cmd+' -mabi='+('lp64 ' if 64 in ispec['supported_xlen'] else 'ilp32 ') + if "I" in ispec["ISA"]: + self.isa += 'i' + if "M" in ispec["ISA"]: + self.isa += 'm' + if "C" in ispec["ISA"]: + self.isa += 'c' + if "F" in ispec["ISA"]: + self.isa += 'f' + if "D" in ispec["ISA"]: + self.isa += 'd' + + # based on the validated isa and platform configure your simulator or + # build your RTL here + + def runTests(self, testList, cgf_file=None): + make = utils.makeUtil(makefilePath=os.path.join(self.work_dir, "Makefile." + self.name[:-1])) + make.makeCommand = 'make -j' + self.num_jobs + for file in testList: + testentry = testList[file] + test = testentry['test_path'] + test_dir = testentry['work_dir'] + test_name = test.rsplit('/',1)[1][:-2] + + elf = 'ref.elf' + + execute = "@cd "+testentry['work_dir']+";" + + cmd = self.compile_cmd.format(testentry['isa'].lower(), self.xlen) + ' ' + test + ' -o ' + elf + + #TODO: we are using -D to enable compile time macros. If your + # toolchain is not riscv-gcc you may want to change the below code + compile_cmd = cmd + ' -D' + " -D".join(testentry['macros']) + execute+=compile_cmd+";" + + execute += self.objdump_cmd.format(elf, self.xlen, 'ref.disass') + sig_file = os.path.join(test_dir, self.name[:-1] + ".signature") + + #TODO: You will need to add any other arguments to your DUT + # executable if any in the quotes below + execute += self.ref_exe + '' + + #TODO: The following is useful only if your reference model can + # support coverage extraction from riscv-isac. Else leave it + # commented out + + #cov_str = ' ' + #for label in testentry['coverage_labels']: + # cov_str+=' -l '+label + #if cgf_file is not None: + # coverage_cmd = 'riscv_isac --verbose info coverage -d \ + # -t {0}.log --mode c_sail -o coverage.rpt \ + # --sig-label begin_signature end_signature \ + # --test-label rvtest_code_begin rvtest_code_end \ + # -e {0}.elf -c {1} -x{2} {3};'.format(\ + # test_name, ' -c '.join(cgf_file), self.xlen, cov_str) + #else: + # coverage_cmd = '' + #execute+=coverage_cmd + + make.add_target(execute) + make.execute_all(self.work_dir) diff --git a/riscof/Templates/setup/sail_cSim/__init__.py b/riscof/Templates/setup/sail_cSim/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..0bfb5a62b4f6c2c8cb1a6a865bc2d4b36ebfa64e --- /dev/null +++ b/riscof/Templates/setup/sail_cSim/__init__.py @@ -0,0 +1,2 @@ +from pkgutil import extend_path +__path__ = extend_path(__path__, __name__) \ No newline at end of file diff --git a/riscof/Templates/setup/sail_cSim/env/link.ld b/riscof/Templates/setup/sail_cSim/env/link.ld new file mode 100644 index 0000000000000000000000000000000000000000..8ad95e049bedb9b8c3619ed3608028828425628a --- /dev/null +++ b/riscof/Templates/setup/sail_cSim/env/link.ld @@ -0,0 +1,18 @@ +OUTPUT_ARCH( "riscv" ) +ENTRY(rvtest_entry_point) + +SECTIONS +{ + . = 0x80000000; + .text.init : { *(.text.init) } + . = ALIGN(0x1000); + .tohost : { *(.tohost) } + . = ALIGN(0x1000); + .text : { *(.text) } + . = ALIGN(0x1000); + .data : { *(.data) } + .data.string : { *(.data.string)} + .bss : { *(.bss) } + _end = .; +} + diff --git a/riscof/Templates/setup/sail_cSim/env/model_test.h b/riscof/Templates/setup/sail_cSim/env/model_test.h new file mode 100644 index 0000000000000000000000000000000000000000..5a362683c0c84649e00feb71ba2e5ae54e765f8e --- /dev/null +++ b/riscof/Templates/setup/sail_cSim/env/model_test.h @@ -0,0 +1,60 @@ +#ifndef _COMPLIANCE_MODEL_H +#define _COMPLIANCE_MODEL_H +#if XLEN == 64 + #define ALIGNMENT 3 +#else + #define ALIGNMENT 2 +#endif + +#define RVMODEL_DATA_SECTION \ + .pushsection .tohost,"aw",@progbits; \ + .align 8; .global tohost; tohost: .dword 0; \ + .align 8; .global fromhost; fromhost: .dword 0; \ + .popsection; \ + .align 8; .global begin_regstate; begin_regstate: \ + .word 128; \ + .align 8; .global end_regstate; end_regstate: \ + .word 4; + +//RV_COMPLIANCE_HALT +#define RVMODEL_HALT \ + li x1, 1; \ + write_tohost: \ + sw x1, tohost, t5; \ + j write_tohost; + +#define RVMODEL_BOOT + +//RV_COMPLIANCE_DATA_BEGIN +#define RVMODEL_DATA_BEGIN \ + RVMODEL_DATA_SECTION \ + .align ALIGNMENT;\ + .global begin_signature; begin_signature: + +//RV_COMPLIANCE_DATA_END +#define RVMODEL_DATA_END \ + .global end_signature; end_signature: + +//RVTEST_IO_INIT +#define RVMODEL_IO_INIT +//RVTEST_IO_WRITE_STR +#define RVMODEL_IO_WRITE_STR(_R, _STR) +//RVTEST_IO_CHECK +#define RVMODEL_IO_CHECK() +//RVTEST_IO_ASSERT_GPR_EQ +#define RVMODEL_IO_ASSERT_GPR_EQ(_S, _R, _I) +//RVTEST_IO_ASSERT_SFPR_EQ +#define RVMODEL_IO_ASSERT_SFPR_EQ(_F, _R, _I) +//RVTEST_IO_ASSERT_DFPR_EQ +#define RVMODEL_IO_ASSERT_DFPR_EQ(_D, _R, _I) + +#define RVMODEL_SET_MSW_INT + +#define RVMODEL_CLEAR_MSW_INT + +#define RVMODEL_CLEAR_MTIMER_INT + +#define RVMODEL_CLEAR_MEXT_INT + + +#endif // _COMPLIANCE_MODEL_H diff --git a/riscof/Templates/setup/sail_cSim/riscof_sail_cSim.py b/riscof/Templates/setup/sail_cSim/riscof_sail_cSim.py new file mode 100644 index 0000000000000000000000000000000000000000..9914a8ffbaf24ba55306232f73ecc9072acbabb4 --- /dev/null +++ b/riscof/Templates/setup/sail_cSim/riscof_sail_cSim.py @@ -0,0 +1,99 @@ +import os +import re +import shutil +import subprocess +import shlex +import logging +import random +import string +from string import Template + +import riscof.utils as utils +from riscof.pluginTemplate import pluginTemplate +import riscof.constants as constants +from riscv_isac.isac import isac + +logger = logging.getLogger() + +class sail_cSim(pluginTemplate): + __model__ = "sail_c_simulator" + __version__ = "0.5.0" + + def __init__(self, *args, **kwargs): + sclass = super().__init__(*args, **kwargs) + + config = kwargs.get('config') + self.num_jobs = str(config['jobs'] if 'jobs' in config else 1) + self.pluginpath = os.path.abspath(config['pluginpath']) + self.sail_exe = { '32' : os.path.join(config['PATH'] if 'PATH' in config else "","riscv_sim_RV32"), + '64' : os.path.join(config['PATH'] if 'PATH' in config else "","riscv_sim_RV64")} + + return sclass + + def initialise(self, suite, work_dir, archtest_env): + self.suite = suite + self.work_dir = work_dir + self.objdump_cmd = 'riscv{1}-unknown-elf-objdump -D {0} > {2};' + self.compile_cmd = 'riscv{1}-unknown-elf-gcc -march={0} \ + -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles\ + -T '+self.pluginpath+'/env/link.ld\ + -I '+self.pluginpath+'/env/\ + -I ' + archtest_env + + def build(self, isa_yaml, platform_yaml): + ispec = utils.load_yaml(isa_yaml)['hart0'] + self.xlen = ('64' if 64 in ispec['supported_xlen'] else '32') + self.isa = 'rv' + self.xlen + self.compile_cmd = self.compile_cmd+' -mabi='+('lp64 ' if 64 in ispec['supported_xlen'] else 'ilp32 ') + if "I" in ispec["ISA"]: + self.isa += 'i' + if "M" in ispec["ISA"]: + self.isa += 'm' + if "C" in ispec["ISA"]: + self.isa += 'c' + if "F" in ispec["ISA"]: + self.isa += 'f' + if "D" in ispec["ISA"]: + self.isa += 'd' + + def runTests(self, testList, cgf_file=None): + make = utils.makeUtil(makefilePath=os.path.join(self.work_dir, "Makefile." + self.name[:-1])) + make.makeCommand = 'make -j' + self.num_jobs + for file in testList: + testentry = testList[file] + test = testentry['test_path'] + test_dir = testentry['work_dir'] + test_name = test.rsplit('/',1)[1][:-2] + + elf = 'ref.elf' + + execute = "@cd "+testentry['work_dir']+";" + + cmd = self.compile_cmd.format(testentry['isa'].lower(), self.xlen) + ' ' + test + ' -o ' + elf + compile_cmd = cmd + ' -D' + " -D".join(testentry['macros']) + execute+=compile_cmd+";" + + execute += self.objdump_cmd.format(elf, self.xlen, 'ref.disass') + sig_file = os.path.join(test_dir, self.name[:-1] + ".signature") + + execute += self.sail_exe[self.xlen] + ' --test-signature={0} {1} > {2}.log 2>&1;'.format(sig_file, elf, test_name) + + cov_str = ' ' + for label in testentry['coverage_labels']: + cov_str+=' -l '+label + + if cgf_file is not None: + coverage_cmd = 'riscv_isac --verbose info coverage -d \ + -t {0}.log --mode c_sail -o coverage.rpt \ + --sig-label begin_signature end_signature \ + --test-label rvtest_code_begin rvtest_code_end \ + -e ref.elf -c {1} -x{2} {3};'.format(\ + test_name, ' -c '.join(cgf_file), self.xlen, cov_str) + else: + coverage_cmd = '' + + + execute+=coverage_cmd + + make.add_target(execute) + make.execute_all(self.work_dir) diff --git a/riscof/__init__.py b/riscof/__init__.py index 4a3e2ef0a3d0db018d9913ee479b21bda8ec0a6e..5a100ade8f626fb043cf7015c3cfd5771ed78654 100644 --- a/riscof/__init__.py +++ b/riscof/__init__.py @@ -1,7 +1,7 @@ # See LICENSE.incore for details -"""Top-level package for RISCOF - RISC-V Compliance Framework.""" +"""Top-level package for RISCOF - RISC-V Architectural Test Framework.""" __author__ = """InCore Semiconductors Pvt Ltd""" __email__ = 'info@incoresemi.com' -__version__ = '1.18.4' +__version__ = '1.19.0' diff --git a/riscof/constants.py b/riscof/constants.py index 3db494f18605312a81b9a5afeac22599fb24c64a..d59e72eb7e35497a03bb637956759930381830db 100644 --- a/riscof/constants.py +++ b/riscof/constants.py @@ -3,7 +3,16 @@ import os root = os.path.abspath(os.path.dirname(__file__)) suite = os.path.join(root,"suite/") -cgf_file = os.path.join(root,"suite/compliance.cgf") +cgf_dir = os.path.join(root,"coverage/") + +cgf_file = [] +cgf_file.append(os.path.join(root,"coverage/dataset.cgf")) +for path in os.listdir(cgf_dir): + if path != 'dataset.cgf': + full_path = os.path.join(cgf_dir, path) + if os.path.isfile(full_path): + cgf_file.append(full_path) + framework_db = os.path.join(root, "framework/database.yaml") cwd = os.getcwd() work_dir = os.path.join(cwd, "riscof_work/") @@ -11,6 +20,7 @@ html_template = os.path.join(root, 'Templates/report.html') coverage_template = os.path.join(root, 'Templates/coverage.html') css = os.path.join(root, 'Templates/style.css') env = os.path.join(root, suite + "env/") + config_temp = '''[RISCOF] ReferencePlugin={0} ReferencePluginPath={1} @@ -21,6 +31,9 @@ DUTPluginPath={3} pluginpath={3} ispec={3}/{2}_isa.yaml pspec={3}/{2}_platform.yaml + +[{0}] +pluginpath={1} ''' diff --git a/riscof/coverage/dataset.cgf b/riscof/coverage/dataset.cgf new file mode 100644 index 0000000000000000000000000000000000000000..d786910062aabdac0f9dafb3170c0bffde9d2cf2 --- /dev/null +++ b/riscof/coverage/dataset.cgf @@ -0,0 +1,323 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +datasets: + rv32e_regs_mx0: &rv32e_regs_mx0 + x1: 0 + x2: 0 + x3: 0 + x4: 0 + x5: 0 + x6: 0 + x7: 0 + x8: 0 + x9: 0 + x10: 0 + x11: 0 + x12: 0 + x13: 0 + x14: 0 + x15: 0 + rv32e_regs: &rv32e_regs + x0: 0 + x1: 0 + x2: 0 + x3: 0 + x4: 0 + x5: 0 + x6: 0 + x7: 0 + x8: 0 + x9: 0 + x10: 0 + x11: 0 + x12: 0 + x13: 0 + x14: 0 + x15: 0 + + all_regs: &all_regs + x0: 0 + x1: 0 + x2: 0 + x3: 0 + x4: 0 + x5: 0 + x6: 0 + x7: 0 + x8: 0 + x9: 0 + x10: 0 + x11: 0 + x12: 0 + x13: 0 + x14: 0 + x15: 0 + x16: 0 + x17: 0 + x18: 0 + x19: 0 + x20: 0 + x21: 0 + x22: 0 + x23: 0 + x24: 0 + x25: 0 + x26: 0 + x27: 0 + x28: 0 + x29: 0 + x30: 0 + x31: 0 + + c_regs: &c_regs + x8: 0 + x9: 0 + x10: 0 + x11: 0 + x12: 0 + x13: 0 + x14: 0 + x15: 0 + + all_regs_mx2: &all_regs_mx2 + x1: 0 + x3: 0 + x4: 0 + x5: 0 + x6: 0 + x7: 0 + x8: 0 + x9: 0 + x10: 0 + x11: 0 + x12: 0 + x13: 0 + x14: 0 + x15: 0 + x16: 0 + x17: 0 + x18: 0 + x19: 0 + x20: 0 + x21: 0 + x22: 0 + x23: 0 + x24: 0 + x25: 0 + x26: 0 + x27: 0 + x28: 0 + x29: 0 + x30: 0 + x31: 0 + + all_regs_mx0: &all_regs_mx0 + x1: 0 + x2: 0 + x3: 0 + x4: 0 + x5: 0 + x6: 0 + x7: 0 + x8: 0 + x9: 0 + x10: 0 + x11: 0 + x12: 0 + x13: 0 + x14: 0 + x15: 0 + x16: 0 + x17: 0 + x18: 0 + x19: 0 + x20: 0 + x21: 0 + x22: 0 + x23: 0 + x24: 0 + x25: 0 + x26: 0 + x27: 0 + x28: 0 + x29: 0 + x30: 0 + x31: 0 + + cbfmt_immval_sgn: &cbfmt_immval_sgn + 'imm_val == (-2**(6-1))': 0 + 'imm_val == 0': 0 + 'imm_val == (2**(6-1)-1)': 0 + 'imm_val == 1': 0 + + rfmt_op_comb: &rfmt_op_comb + 'rs1 == rs2 != rd': 0 + 'rs1 == rd != rs2': 0 + 'rs2 == rd != rs1': 0 + 'rs1 == rs2 == rd': 0 + 'rs1 != rs2 and rs1 != rd and rs2 != rd': 0 + + ifmt_op_comb: &ifmt_op_comb + 'rs1 == rd': 0 + 'rs1 != rd': 0 + + sfmt_op_comb: &sfmt_op_comb + 'rs1 == rs2': 0 + 'rs1 != rs2': 0 + + base_rs1val_sgn: &base_rs1val_sgn + 'rs1_val == (-2**(xlen-1))': 0 + 'rs1_val == 0': 0 + 'rs1_val == (2**(xlen-1)-1)': 0 + 'rs1_val == 1': 0 + + base_rs2val_sgn: &base_rs2val_sgn + 'rs2_val == (-2**(xlen-1))': 0 + 'rs2_val == 0': 0 + 'rs2_val == (2**(xlen-1)-1)': 0 + 'rs2_val == 1': 0 + + base_rs1val_unsgn: &base_rs1val_unsgn + 'rs1_val == 0': 0 + 'rs1_val == (2**(xlen)-1)': 0 + 'rs1_val == 1': 0 + + base_rs2val_unsgn: &base_rs2val_unsgn + 'rs2_val == 0': 0 + 'rs2_val == (2**(xlen)-1)': 0 + 'rs2_val == 1': 0 + + rfmt_val_comb_sgn: &rfmt_val_comb_sgn + 'rs1_val > 0 and rs2_val > 0': 0 + 'rs1_val > 0 and rs2_val < 0': 0 + 'rs1_val < 0 and rs2_val < 0': 0 + 'rs1_val < 0 and rs2_val > 0': 0 + 'rs1_val == rs2_val': 0 + 'rs1_val != rs2_val': 0 + + rfmt_val_comb_unsgn: &rfmt_val_comb_unsgn + 'rs1_val > 0 and rs2_val > 0': 0 + 'rs1_val == rs2_val and rs1_val > 0 and rs2_val > 0': 0 + 'rs1_val != rs2_val and rs1_val > 0 and rs2_val > 0': 0 + + ifmt_val_comb_sgn: &ifmt_val_comb_sgn + 'rs1_val == imm_val': 0 + 'rs1_val != imm_val': 0 + 'rs1_val > 0 and imm_val > 0': 0 + 'rs1_val > 0 and imm_val < 0': 0 + 'rs1_val < 0 and imm_val > 0': 0 + 'rs1_val < 0 and imm_val < 0': 0 + + ifmt_val_comb_unsgn: &ifmt_val_comb_unsgn + 'rs1_val == imm_val and rs1_val > 0 and imm_val > 0': 0 + 'rs1_val != imm_val and rs1_val > 0 and imm_val > 0': 0 + + ifmt_base_immval_sgn: &ifmt_base_immval_sgn + 'imm_val == (-2**(12-1))': 0 + 'imm_val == 0': 0 + 'imm_val == (2**(12-1)-1)': 0 + 'imm_val == 1': 0 + + ifmt_base_immval_unsgn: &ifmt_base_immval_unsgn + 'imm_val == 0': 0 + 'imm_val == (2**(12)-1)': 0 + 'imm_val == 1': 0 + + ifmt_base_shift: &ifmt_base_shift + 'rs1_val < 0 and imm_val > 0 and imm_val < xlen': 0 + 'rs1_val > 0 and imm_val > 0 and imm_val < xlen': 0 + 'rs1_val < 0 and imm_val == 0': 0 + 'rs1_val > 0 and imm_val == 0': 0 + 'rs1_val < 0 and imm_val == (xlen-1)': 0 + 'rs1_val > 0 and imm_val == (xlen-1)': 0 + 'rs1_val == imm_val and imm_val > 0 and imm_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val >= 0 and imm_val < xlen': 0 + 'rs1_val == 0 and imm_val >= 0 and imm_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val >= 0 and imm_val < xlen': 0 + 'rs1_val == 1 and imm_val >= 0 and imm_val < xlen': 0 + + ifmt_base_shift_32w: &ifmt_base_shift_32w + 'rs1_val < 0 and imm_val > 0 and imm_val < 32': 0 + 'rs1_val > 0 and imm_val > 0 and imm_val < 32': 0 + 'rs1_val < 0 and imm_val == 0': 0 + 'rs1_val > 0 and imm_val == 0': 0 + 'rs1_val < 0 and imm_val == 31': 0 + 'rs1_val > 0 and imm_val == 31': 0 + 'rs1_val == imm_val and imm_val > 0 and imm_val < 32': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val >= 0 and imm_val < 32': 0 + 'rs1_val == 0 and imm_val >= 0 and imm_val < 32': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val >= 0 and imm_val < 32': 0 + 'rs1_val == 1 and imm_val >= 0 and imm_val < 32': 0 + + + rfmt_base_shift: &rfmt_base_shift + 'rs1_val < 0 and rs2_val > 0 and rs2_val < xlen': 0 + 'rs1_val > 0 and rs2_val > 0 and rs2_val < xlen': 0 + 'rs1_val < 0 and rs2_val == 0': 0 + 'rs1_val > 0 and rs2_val == 0': 0 + 'rs1_val == rs2_val and rs2_val > 0 and rs2_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and rs2_val >= 0 and rs2_val < xlen': 0 + 'rs1_val == 0 and rs2_val >= 0 and rs2_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and rs2_val >= 0 and rs2_val < xlen': 0 + 'rs1_val == 1 and rs2_val >= 0 and rs2_val < xlen': 0 + + bfmt_base_branch_val_align_sgn: &bfmt_base_branch_val_align_sgn + 'rs1_val > 0 and rs2_val > 0 and imm_val & 0x03 == 0': 0 + 'rs1_val > 0 and rs2_val < 0 and imm_val & 0x03 == 0': 0 + 'rs1_val < 0 and rs2_val < 0 and imm_val & 0x03 == 0': 0 + 'rs1_val < 0 and rs2_val > 0 and imm_val & 0x03 == 0': 0 + 'rs1_val == rs2_val and imm_val > 0 and imm_val & 0x03 == 0': 0 + 'rs1_val == rs2_val and imm_val < 0 and imm_val & 0x03 == 0': 0 + 'rs1_val > rs2_val and imm_val > 0 and imm_val & 0x03 == 0': 0 + 'rs1_val > rs2_val and imm_val < 0 and imm_val & 0x03 == 0': 0 + 'rs1_val < rs2_val and imm_val > 0 and imm_val & 0x03 == 0': 0 + 'rs1_val < rs2_val and imm_val < 0 and imm_val & 0x03 == 0': 0 + + bfmt_base_branch_val_align_unsgn: &bfmt_base_branch_val_align_unsgn + 'rs1_val > 0 and rs2_val > 0': 0 + 'rs1_val > 0 and rs2_val > 0 and rs1_val == rs2_val and imm_val > 0': 0 + 'rs1_val > 0 and rs2_val > 0 and rs1_val == rs2_val and imm_val < 0': 0 + 'rs1_val > 0 and rs2_val > 0 and rs1_val > rs2_val and imm_val > 0 ': 0 + 'rs1_val > 0 and rs2_val > 0 and rs1_val > rs2_val and imm_val < 0 ': 0 + 'rs1_val > 0 and rs2_val > 0 and rs1_val < rs2_val and imm_val > 0 ': 0 + 'rs1_val > 0 and rs2_val > 0 and rs1_val < rs2_val and imm_val < 0 ': 0 + + rs1val_walking: &rs1val_walking + 'walking_ones("rs1_val", xlen)': 0 + 'walking_zeros("rs1_val", xlen)': 0 + 'alternate("rs1_val",xlen)': 0 + + rs2val_walking: &rs2val_walking + 'walking_ones("rs2_val", xlen)': 0 + 'walking_zeros("rs2_val", xlen)': 0 + 'alternate("rs2_val",xlen)': 0 + + ifmt_immval_walking: &ifmt_immval_walking + 'walking_ones("imm_val", 12)': 0 + 'walking_zeros("imm_val", 12)': 0 + 'alternate("imm_val",12)': 0 + + rs1val_walking_unsgn: &rs1val_walking_unsgn + 'walking_ones("rs1_val", xlen,False)': 0 + 'walking_zeros("rs1_val", xlen,False)': 0 + 'alternate("rs1_val",xlen,False)': 0 + + rs2val_walking_unsgn: &rs2val_walking_unsgn + 'walking_ones("rs2_val", xlen,False)': 0 + 'walking_zeros("rs2_val", xlen,False)': 0 + 'alternate("rs2_val",xlen,False)': 0 + + crfmt_val_comb_sgn: &crfmt_val_comb_sgn + 'rs2_val > 0': 0 + 'rs2_val < 0': 0 + + cbimm_val_walking: &cbimm_val_walking + 'walking_ones("imm_val", 6)': 0 + 'walking_zeros("imm_val", 6)': 0 + 'alternate("imm_val",6)': 0 + + ifmt_immval_walking_unsgn: &ifmt_immval_walking_unsgn + 'walking_ones("imm_val", 12,False)': 0 + 'walking_zeros("imm_val", 12,False)': 0 + 'alternate("imm_val",12,False)': 0 + diff --git a/riscof/coverage/rvi.cgf b/riscof/coverage/rvi.cgf new file mode 100644 index 0000000000000000000000000000000000000000..899bea46bfa5bfe93ec1962610ba5343a1fc9fa6 --- /dev/null +++ b/riscof/coverage/rvi.cgf @@ -0,0 +1,1003 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +fence: + config: + - check ISA:=regex(.*I.*) + opcode: + fence: 0 + +addi: + config: + - check ISA:=regex(.*I.*) + opcode: + addi: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [ *ifmt_val_comb_sgn, *base_rs1val_sgn, *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +slti: + config: + - check ISA:=regex(.*I.*) + opcode: + slti: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +sltiu: + config: + - check ISA:=regex(.*I.*) + opcode: + sltiu: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_unsgn , *base_rs1val_unsgn , *ifmt_base_immval_unsgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)],signed=False)': 0 + <<: [*rs1val_walking_unsgn, *ifmt_immval_walking_unsgn] + +andi: + config: + - check ISA:=regex(.*I.*) + opcode: + andi: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +ori: + config: + - check ISA:=regex(.*I.*) + opcode: + ori: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +xori: + config: + - check ISA:=regex(.*I.*) + opcode: + xori: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [*ifmt_val_comb_sgn , *base_rs1val_sgn , *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +slli: + config: + - check ISA:=regex(.*I.*) + opcode: + slli: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +srai: + config: + - check ISA:=regex(.*I.*) + opcode: + srai: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +srli: + config: + - check ISA:=regex(.*I.*) + opcode: + srli: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +add: + config: + - check ISA:=regex(.*I.*) + opcode: + add: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +sub: + config: + - check ISA:=regex(.*I.*) + opcode: + sub: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +slt: + config: + - check ISA:=regex(.*I.*) + opcode: + slt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +sltu: + config: + - check ISA:=regex(.*I.*) + opcode: + sltu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'sp_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +and: + config: + - check ISA:=regex(.*I.*) + opcode: + and: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +or: + config: + - check ISA:=regex(.*I.*) + opcode: + or: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +xor: + config: + - check ISA:=regex(.*I.*) + opcode: + xor: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +sll: + config: + - check ISA:=regex(.*I.*) + opcode: + sll: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'sp_dataset(xlen,var_lst=["rs1_val"])': 0 + 'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0 + 'alternate("rs2_val", ceil(log(xlen,2)), False)': 0 + +srl: + config: + - check ISA:=regex(.*I.*) + opcode: + srl: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'sp_dataset(xlen,var_lst=["rs1_val"])': 0 + 'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0 + 'alternate("rs2_val", ceil(log(xlen,2)), False)': 0 + +sra: + config: + - check ISA:=regex(.*I.*) + opcode: + sra: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'sp_dataset(xlen,var_lst=["rs1_val"])': 0 + 'walking_ones("rs2_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("rs2_val", ceil(log(xlen,2)), False)': 0 + 'alternate("rs2_val", ceil(log(xlen,2)), False)': 0 + +beq: + config: + - check ISA:=regex(.*I.*) + opcode: + beq: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + 'sp_dataset(xlen)': 0 + +bge: + config: + - check ISA:=regex(.*I.*) + opcode: + bge: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + 'sp_dataset(xlen)': 0 + +bgeu: + config: + - check ISA:=regex(.*I.*) + opcode: + bgeu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_unsgn + abstract_comb: + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + 'sp_dataset(xlen,signed=False)': 0 + +blt: + config: + - check ISA:=regex(.*I.*) + opcode: + blt: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + 'sp_dataset(xlen)': 0 + +bltu: + config: + - check ISA:=regex(.*I.*) + opcode: + bltu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_unsgn + abstract_comb: + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + 'sp_dataset(xlen,signed=False)': 0 + +bne: + config: + - check ISA:=regex(.*I.*) + opcode: + bne: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: *bfmt_base_branch_val_align_sgn + abstract_comb: + <<: [*rs1val_walking, *rs2val_walking] + 'sp_dataset(xlen)': 0 + +lhu-align: + config: + - check ISA:=regex(.*I.*) + opcode: + lhu: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lh-align: + config: + - check ISA:=regex(.*I.*) + opcode: + lh: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lbu-align: + config: + - check ISA:=regex(.*I.*) + opcode: + lbu: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'ea_align == 1 and (imm_val % 4) == 0': 0 + 'ea_align == 1 and (imm_val % 4) == 1': 0 + 'ea_align == 1 and (imm_val % 4) == 2': 0 + 'ea_align == 1 and (imm_val % 4) == 3': 0 + 'ea_align == 3 and (imm_val % 4) == 0': 0 + 'ea_align == 3 and (imm_val % 4) == 1': 0 + 'ea_align == 3 and (imm_val % 4) == 2': 0 + 'ea_align == 3 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lb-align: + config: + - check ISA:=regex(.*I.*) + opcode: + lb: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'ea_align == 1 and (imm_val % 4) == 0': 0 + 'ea_align == 1 and (imm_val % 4) == 1': 0 + 'ea_align == 1 and (imm_val % 4) == 2': 0 + 'ea_align == 1 and (imm_val % 4) == 3': 0 + 'ea_align == 3 and (imm_val % 4) == 0': 0 + 'ea_align == 3 and (imm_val % 4) == 1': 0 + 'ea_align == 3 and (imm_val % 4) == 2': 0 + 'ea_align == 3 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +lw-align: + config: + - check ISA:=regex(.*I.*) + opcode: + lw: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + + +sh-align: + config: + - check ISA:=regex(.*I.*) + opcode: + sh: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + <<: [ *base_rs2val_sgn] + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + abstract_comb: + <<: [*rs2val_walking] + +sb-align: + config: + - check ISA:=regex(.*I.*) + opcode: + sb: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'ea_align == 2 and (imm_val % 4) == 0': 0 + 'ea_align == 2 and (imm_val % 4) == 1': 0 + 'ea_align == 2 and (imm_val % 4) == 2': 0 + 'ea_align == 2 and (imm_val % 4) == 3': 0 + 'ea_align == 1 and (imm_val % 4) == 0': 0 + 'ea_align == 1 and (imm_val % 4) == 1': 0 + 'ea_align == 1 and (imm_val % 4) == 2': 0 + 'ea_align == 1 and (imm_val % 4) == 3': 0 + 'ea_align == 3 and (imm_val % 4) == 0': 0 + 'ea_align == 3 and (imm_val % 4) == 1': 0 + 'ea_align == 3 and (imm_val % 4) == 2': 0 + 'ea_align == 3 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +sw-align: + config: + - check ISA:=regex(.*I.*) + opcode: + sw: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +auipc: + config: + - check ISA:=regex(.*I.*) + opcode: + auipc: 0 + rd: + <<: *all_regs + val_comb: + 'imm_val == 0': 0 + 'imm_val > 0': 0 + 'imm_val == ((2**20)-1)': 0 + abstract_comb: + 'sp_dataset(20,["imm_val"],signed=False)': 0 + 'walking_ones("imm_val", 20, False)': 0 + 'walking_zeros("imm_val", 20, False)': 0 + 'alternate("imm_val", 20, False)': 0 + +lui: + config: + - check ISA:=regex(.*I.*) + opcode: + lui: 0 + rd: + <<: *all_regs + val_comb: + 'imm_val == 0': 0 + 'imm_val > 0': 0 + 'imm_val == ((2**20)-1)': 0 + abstract_comb: + 'sp_dataset(20,["imm_val"],signed=False)': 0 + 'walking_ones("imm_val", 20, False)': 0 + 'walking_zeros("imm_val", 20, False)': 0 + 'alternate("imm_val", 20, False)': 0 + +jal: + config: + - check ISA:=regex(.*I.*) + opcode: + jal: 0 + rd: + <<: *all_regs + val_comb: + 'imm_val < 0' : 0 + 'imm_val > 0': 0 + 'imm_val == (-(2**(18)))': 0 + 'imm_val == ((2**(18)))': 0 + +jalr: + config: + - check ISA:=regex(.*I.*) + opcode: + jalr: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'imm_val > 0': 0 + 'imm_val < 0': 0 + abstract_comb: + <<: *ifmt_immval_walking + +lwu-align: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + lwu: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 4) == 0': 0 + 'ea_align == 0 and (imm_val % 4) == 1': 0 + 'ea_align == 0 and (imm_val % 4) == 2': 0 + 'ea_align == 0 and (imm_val % 4) == 3': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +ld-align: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + ld: 0 + rs1: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + 'ea_align == 0 and (imm_val % 8) == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 1': 0 + 'ea_align == 0 and (imm_val % 8) == 2': 0 + 'ea_align == 0 and (imm_val % 8) == 3': 0 + 'ea_align == 0 and (imm_val % 8) == 4': 0 + 'ea_align == 0 and (imm_val % 8) == 5': 0 + 'ea_align == 0 and (imm_val % 8) == 6': 0 + 'ea_align == 0 and (imm_val % 8) == 7': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + +sd-align: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + sd: 0 + rs1: + <<: *all_regs_mx0 + rs2: + <<: *all_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'ea_align == 0 and (imm_val % 8) == 0': 0 + 'ea_align == 0 and (imm_val % 8) == 1': 0 + 'ea_align == 0 and (imm_val % 8) == 2': 0 + 'ea_align == 0 and (imm_val % 8) == 3': 0 + 'ea_align == 0 and (imm_val % 8) == 4': 0 + 'ea_align == 0 and (imm_val % 8) == 5': 0 + 'ea_align == 0 and (imm_val % 8) == 6': 0 + 'ea_align == 0 and (imm_val % 8) == 7': 0 + 'imm_val > 0': 0 + 'imm_val < 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + +addiw: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + addiw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: [ *ifmt_val_comb_sgn, *base_rs1val_sgn, *ifmt_base_immval_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",12)])': 0 + <<: [*rs1val_walking, *ifmt_immval_walking] + +slliw: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + slliw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift_32w + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", 5, False)': 0 + 'walking_zeros("imm_val", 5, False)': 0 + 'alternate("imm_val", 5, False)': 0 + +srliw: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + srliw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift_32w + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", 5, False)': 0 + 'walking_zeros("imm_val", 5, False)': 0 + 'alternate("imm_val", 5, False)': 0 + +sraiw: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + sraiw: 0 + rs1: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *ifmt_op_comb + val_comb: + <<: *ifmt_base_shift_32w + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", 5, False)': 0 + 'walking_zeros("imm_val", 5, False)': 0 + 'alternate("imm_val", 5, False)': 0 + +addw: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + addw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +subw: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + subw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +sllw: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + sllw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'sp_dataset(xlen,var_lst=["rs1_val"])': 0 + 'walking_ones("rs2_val", 5, False)': 0 + 'walking_zeros("rs2_val", 5, False)': 0 + 'alternate("rs2_val", 5, False)': 0 + +srlw: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + srlw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'sp_dataset(xlen,var_lst=["rs1_val"])': 0 + 'walking_ones("rs2_val", 5, False)': 0 + 'walking_zeros("rs2_val", 5, False)': 0 + 'alternate("rs2_val", 5, False)': 0 +sraw: + config: + - check ISA:=regex(.*RV64.*I.*) + opcode: + sraw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: *rfmt_base_shift + abstract_comb: + <<: [*rs1val_walking] + 'sp_dataset(xlen,var_lst=["rs1_val"])': 0 + 'walking_ones("rs2_val", 5, False)': 0 + 'walking_zeros("rs2_val", 5, False)': 0 + 'alternate("rs2_val", 5, False)': 0 diff --git a/riscof/coverage/rvi_c.cgf b/riscof/coverage/rvi_c.cgf new file mode 100644 index 0000000000000000000000000000000000000000..13642915d5f563a3318844fc358fce9913d7ddf0 --- /dev/null +++ b/riscof/coverage/rvi_c.cgf @@ -0,0 +1,586 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +cebreak: + config: + - check ISA:=regex(.*I.*Zicsr.*.C*) + opcode: + c.ebreak: 0 + +caddi4spn: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.addi4spn: 0 + rd: + <<: *c_regs + val_comb: + 'imm_val > 0' : 0 + 'imm_val == 1020': 0 + abstract_comb: + 'walking_ones("imm_val", 8,False,scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val", 8,False,scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",8,False,scale_func = lambda x: x*4)': 0 + +clw: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.lw: 0 + rs1: + <<: *c_regs + rd: + <<: *c_regs + op_comb: + 'rs1 == rd': 0 + 'rs1 != rd': 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + abstract_comb: + 'walking_ones("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",5, False,scale_func = lambda x: x*4)': 0 + +cld: + config: + - check ISA:=regex(.*RV64.*I.*C.*) + opcode: + c.ld: 0 + rs1: + <<: *c_regs + rd: + <<: *c_regs + op_comb: + 'rs1 == rd': 0 + 'rs1 != rd': 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + abstract_comb: + 'walking_ones("imm_val",5,False, scale_func = lambda x: x*8)': 0 + 'walking_zeros("imm_val",5,False, scale_func = lambda x: x*8)': 0 + 'alternate("imm_val",5, False,scale_func = lambda x: x*8)': 0 + +csw: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.sw: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + 'walking_ones("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",5,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",5, False,scale_func = lambda x: x*4)': 0 + +csd: + config: + - check ISA:=regex(.*RV64.*I.*C.*) + opcode: + c.sd: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + 'rs1 != rs2': 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + 'walking_ones("imm_val",5,False, scale_func = lambda x: x*8)': 0 + 'walking_zeros("imm_val",5,False, scale_func = lambda x: x*8)': 0 + 'alternate("imm_val",5, False,scale_func = lambda x: x*8)': 0 + +cnop: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.nop: 0 + val_comb: + abstract_comb: + <<: *cbimm_val_walking + +caddi: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.addi: 0 + rd: + <<: *all_regs_mx0 + val_comb: + <<: [*base_rs1val_sgn, *cbfmt_immval_sgn, *ifmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",6)])': 0 + <<: [*rs1val_walking, *cbimm_val_walking] + +cjal: + config: + - check ISA:=regex(.*RV32.*I.*C.*) + opcode: + c.jal: 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val < 0': 0 + abstract_comb: + 'walking_ones("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'walking_zeros("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'alternate("imm_val",11, fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030) ,scale_func = lambda x: x*2)': 0 + + +caddiw: + config: + - check ISA:=regex(.*RV64.*I.*C.*) + opcode: + c.addiw: 0 + rd: + <<: *all_regs_mx0 + val_comb: + 'rs1_val == (-2**(xlen-1))': 0 + 'rs1_val == 0': 0 + 'rs1_val == (2**(xlen-1)-1)': 0 + 'rs1_val == 1': 0 + <<: [*cbfmt_immval_sgn, *ifmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",6)])': 0 + 'walking_ones("rs1_val", xlen)': 0 + 'walking_zeros("rs1_val", xlen)': 0 + 'alternate("rs1_val",xlen)': 0 + <<: [*cbimm_val_walking] + +cli: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.li: 0 + rd: + <<: *all_regs + val_comb: + <<: [*cbfmt_immval_sgn] + abstract_comb: + 'walking_ones("imm_val", 6)': 0 + 'walking_zeros("imm_val", 6)': 0 + 'alternate("imm_val", 6)': 0 + +caddi16sp: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.addi16sp: 0 + rd: + x2: 0 + val_comb: + <<: [*base_rs1val_sgn,*ifmt_val_comb_sgn] + 'imm_val == -512': 0 + 'imm_val == 496': 0 + abstract_comb: + <<: [*rs1val_walking] + 'walking_ones("imm_val", 6,True,scale_func = lambda x: x*16)': 0 + 'walking_zeros("imm_val", 6,True,scale_func = lambda x: x*16)': 0 + 'alternate("imm_val",6,True,scale_func = lambda x: x*16)': 0 + +clui: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.lui: 0 + rd: + x0: 0 + x1: 0 + x3: 0 + x4: 0 + x5: 0 + x6: 0 + x7: 0 + x8: 0 + x9: 0 + x10: 0 + x11: 0 + x12: 0 + x13: 0 + x14: 0 + x15: 0 + x16: 0 + x17: 0 + x18: 0 + x19: 0 + x20: 0 + x21: 0 + x22: 0 + x23: 0 + x24: 0 + x25: 0 + x26: 0 + x27: 0 + x28: 0 + x29: 0 + x30: 0 + x31: 0 + + val_comb: + 'rs1_val > 0 and imm_val > 32': 0 + 'rs1_val > 0 and imm_val < 32 and imm_val !=0 ': 0 + 'rs1_val < 0 and imm_val > 32': 0 + 'rs1_val < 0 and imm_val < 32 and imm_val !=0 ': 0 + abstract_comb: + 'walking_ones("imm_val", 6, False)': 0 + 'walking_zeros("imm_val", 6, False)': 0 + 'alternate("imm_val", 6, False)': 0 + +csrli: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.srli: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val < 0 and imm_val < xlen': 0 + 'rs1_val > 0 and imm_val < xlen': 0 + 'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0 + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +csrai: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.srai: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val < 0 and imm_val < xlen': 0 + 'rs1_val > 0 and imm_val < xlen': 0 + 'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0 + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +candi: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.andi: 0 + rs1: + <<: *c_regs + val_comb: + <<: [*base_rs1val_sgn,*cbfmt_immval_sgn,*ifmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val",("imm_val",6)])': 0 + <<: [*rs1val_walking, *cbimm_val_walking] + +csub: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.sub: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +cxor: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.xor: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +cor: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.or: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +cand: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.and: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +csubw: + config: + - check ISA:=regex(.*RV64.*I.*C.*) + opcode: + c.subw: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +caddw: + config: + - check ISA:=regex(.*RV64.*I.*C.*) + opcode: + c.addw: 0 + rs1: + <<: *c_regs + rs2: + <<: *c_regs + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn, *base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +cj: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.j: 0 + val_comb: + 'imm_val > 0': 0 + 'imm_val < 0': 0 + abstract_comb: + 'walking_ones("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'walking_zeros("imm_val", 11,fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030),scale_func = lambda x: x*2)': 0 + 'alternate("imm_val",11, fltr_func =lambda x: (x>=10 and x<2030) or (x<=-8 and x>-2030) ,scale_func = lambda x: x*2)': 0 + +cbeqz: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.beqz: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val > 0 and imm_val > 0': 0 + 'rs1_val < 0 and imm_val > 0': 0 + 'rs1_val == 0 and imm_val > 0': 0 + 'rs1_val > 0 and imm_val < 0': 0 + 'rs1_val < 0 and imm_val < 0': 0 + 'rs1_val == 0 and imm_val < 0': 0 + <<: [*base_rs1val_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + +cbnez: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.bnez: 0 + rs1: + <<: *c_regs + val_comb: + 'rs1_val > 0 and imm_val > 0': 0 + 'rs1_val < 0 and imm_val > 0': 0 + 'rs1_val == 0 and imm_val > 0': 0 + 'rs1_val > 0 and imm_val < 0': 0 + 'rs1_val < 0 and imm_val < 0': 0 + 'rs1_val == 0 and imm_val < 0': 0 + <<: [*base_rs1val_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + +cslli: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.slli: 0 + rd: + <<: *c_regs + val_comb: + 'rs1_val < 0 and imm_val < xlen': 0 + 'rs1_val > 0 and imm_val < xlen': 0 + 'rs1_val == imm_val and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (-2**(xlen-1)) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 0 and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == (2**(xlen-1)-1) and imm_val != 0 and imm_val < xlen': 0 + 'rs1_val == 1 and imm_val != 0 and imm_val < xlen': 0 + abstract_comb: + 'sp_dataset(xlen,["rs1_val"])': 0 + <<: [*rs1val_walking] + 'walking_ones("imm_val", ceil(log(xlen,2)), False)': 0 + 'walking_zeros("imm_val", ceil(log(xlen,2)), False)': 0 + 'alternate("imm_val", ceil(log(xlen,2)), False)': 0 + +clwsp: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.lwsp: 0 + rd: + <<: *all_regs_mx0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + abstract_comb: + 'walking_ones("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",6, False,scale_func = lambda x: x*4)': 0 + +cldsp: + config: + - check ISA:=regex(.*RV64.*I.*C.*) + opcode: + c.ldsp: 0 + rd: + <<: *all_regs_mx0 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + abstract_comb: + 'walking_ones("imm_val",6,False, scale_func = lambda x: x*8)': 0 + 'walking_zeros("imm_val",6,False, scale_func = lambda x: x*8)': 0 + 'alternate("imm_val",6, False,scale_func = lambda x: x*8)': 0 + +cjr: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.jr: 0 + rs1: + <<: *all_regs_mx0 + +cmv: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.mv: 0 + rs2: + <<: *all_regs_mx0 + rd: + <<: *all_regs + op_comb: + 'rs2 == rd and rs2 != 0': 0 + 'rs2 != rd and rs2 != 0': 0 + val_comb: + <<: [*base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen,["rs2_val"])': 0 + <<: [*rs2val_walking] + +cadd: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.add: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs_mx0 + op_comb: + <<: *sfmt_op_comb + val_comb: + <<: [*crfmt_val_comb_sgn, *base_rs1val_sgn,*base_rs2val_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking,*rs2val_walking] + +cjalr: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.jalr: 0 + rs1: + <<: *all_regs_mx0 + +cswsp: + config: + - check ISA:=regex(.*I.*C.*) + opcode: + c.swsp: 0 + rs2: + <<: *all_regs_mx2 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + 'walking_ones("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'walking_zeros("imm_val",6,False, scale_func = lambda x: x*4)': 0 + 'alternate("imm_val",6, False,scale_func = lambda x: x*4)': 0 + +csdsp: + config: + - check ISA:=regex(.*RV64.*I.*C.*) + opcode: + c.sdsp: 0 + rs2: + <<: *all_regs_mx2 + val_comb: + 'imm_val > 0': 0 + 'imm_val == 0': 0 + <<: [ *base_rs2val_sgn] + abstract_comb: + <<: [*rs2val_walking] + 'walking_ones("imm_val",6,False, scale_func = lambda x: x*8)': 0 + 'walking_zeros("imm_val",6,False, scale_func = lambda x: x*8)': 0 + 'alternate("imm_val",6, False,scale_func = lambda x: x*8)': 0 diff --git a/riscof/coverage/rvi_fencei.cgf b/riscof/coverage/rvi_fencei.cgf new file mode 100644 index 0000000000000000000000000000000000000000..9a32e494d4c3eb967511a07908cc2a296a6fc258 --- /dev/null +++ b/riscof/coverage/rvi_fencei.cgf @@ -0,0 +1,8 @@ + +fencei: + config: + - check ISA:=regex(.*I.*Zifencei.*) + opcode: + fence.i: 0 + + diff --git a/riscof/coverage/rvi_m.cgf b/riscof/coverage/rvi_m.cgf new file mode 100644 index 0000000000000000000000000000000000000000..88dd077e7f8f0d76b320944576cf7616372a9477 --- /dev/null +++ b/riscof/coverage/rvi_m.cgf @@ -0,0 +1,250 @@ +# For Licence details look at https://gitlab.com/incoresemi/riscv-compliance/riscv_ctg/-/blob/master/LICENSE.incore + +mul: + config: + - check ISA:=regex(.*I.*M.*) + opcode: + mul: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +mulh: + config: + - check ISA:=regex(.*I.*M.*) + opcode: + mulh: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +mulhu: + config: + - check ISA:=regex(.*I.*M.*) + opcode: + mulhu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'sp_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +mulhsu: + config: + - check ISA:=regex(.*I.*M.*) + opcode: + mulhsu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_unsgn, *rfmt_val_comb_unsgn] + 'rs1_val < 0 and rs2_val > 0': 0 + abstract_comb: + 'sp_dataset(xlen,[("rs1_val",xlen),("rs2_val",xlen,False)])': 0 + <<: [*rs1val_walking, *rs2val_walking_unsgn] + +div: + config: + - check ISA:=regex(.*I.*M.*) + opcode: + div: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +divu: + config: + - check ISA:=regex(.*I.*M.*) + opcode: + divu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'sp_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +rem: + config: + - check ISA:=regex(.*I.*M.*) + opcode: + rem: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +remu: + config: + - check ISA:=regex(.*I.*M.*) + opcode: + remu: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'sp_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +mulw: + config: + - check ISA:=regex(.*RV64.*I.*M.*) + opcode: + mulw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +divw: + config: + - check ISA:=regex(.*RV64.*I.*M.*) + opcode: + divw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +divuw: + config: + - check ISA:=regex(.*RV64.*I.*M.*) + opcode: + divuw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'sp_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + +remw: + config: + - check ISA:=regex(.*RV64.*I.*M.*) + opcode: + remw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_sgn , *base_rs2val_sgn , *rfmt_val_comb_sgn] + abstract_comb: + 'sp_dataset(xlen)': 0 + <<: [*rs1val_walking, *rs2val_walking] + +remuw: + config: + - check ISA:=regex(.*RV64.*I.*M.*) + opcode: + remuw: 0 + rs1: + <<: *all_regs + rs2: + <<: *all_regs + rd: + <<: *all_regs + op_comb: + <<: *rfmt_op_comb + val_comb: + <<: [*base_rs1val_unsgn , *base_rs2val_unsgn , *rfmt_val_comb_unsgn] + abstract_comb: + 'sp_dataset(xlen,signed=False)': 0 + <<: [*rs1val_walking_unsgn, *rs2val_walking_unsgn] + diff --git a/riscof/coverage/rvi_priv.cgf b/riscof/coverage/rvi_priv.cgf new file mode 100644 index 0000000000000000000000000000000000000000..c36521eca118da27915860c4cab0508263b3f059 --- /dev/null +++ b/riscof/coverage/rvi_priv.cgf @@ -0,0 +1,201 @@ +ecall: + config: + - check ISA:=regex(.*I.*); def rvtest_mtrap_routine=True + opcode: + ecall: 0 + +ebreak: + config: + - check ISA:=regex(.*I.*); def rvtest_mtrap_routine=True + opcode: + ebreak: 0 + +misalign-lh: + cond: check ISA:=regex(.*I.*Zicsr.*) + config: + - check ISA:=regex(.*I.*); check hw_data_misaligned_support:=True + - check ISA:=regex(.*I.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True + opcode: + lh: 0 + val_comb: + 'ea_align == 1': 0 + +misalign-lhu: + config: + - check ISA:=regex(.*I.*); check hw_data_misaligned_support:=True + - check ISA:=regex(.*I.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*Zicsr.*) + opcode: + lhu: 0 + val_comb: + 'ea_align == 1': 0 + +misalign-lwu: + config: + - check ISA:=regex(.*I.*); check hw_data_misaligned_support:=True + - check ISA:=regex(.*I.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*64.*I.*Zicsr.*) + opcode: + lwu: 0 + val_comb: + 'ea_align == 1': 0 + 'ea_align == 2': 0 + 'ea_align == 3': 0 + +misalign-sd: + config: + - check ISA:=regex(.*I.*); check hw_data_misaligned_support:=True + - check ISA:=regex(.*I.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*64.*I.*Zicsr.*) + opcode: + sd: 0 + val_comb: + 'ea_align == 1': 0 + 'ea_align == 2': 0 + 'ea_align == 3': 0 + 'ea_align == 4': 0 + 'ea_align == 5': 0 + 'ea_align == 6': 0 + 'ea_align == 7': 0 + +misalign-ld: + config: + - check ISA:=regex(.*I.*); check hw_data_misaligned_support:=True + - check ISA:=regex(.*I.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*64.*I.*) + opcode: + ld: 0 + val_comb: + 'ea_align == 1': 0 + 'ea_align == 2': 0 + 'ea_align == 3': 0 + 'ea_align == 4': 0 + 'ea_align == 5': 0 + 'ea_align == 6': 0 + 'ea_align == 7': 0 + +misalign-lw: + config: + - check ISA:=regex(.*I.*); check hw_data_misaligned_support:=True + - check ISA:=regex(.*I.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*Zicsr.*) + opcode: + lw: 0 + val_comb: + 'ea_align == 1': 0 + 'ea_align == 2': 0 + 'ea_align == 3': 0 + +misalign-sh: + config: + - check ISA:=regex(.*I.*); check hw_data_misaligned_support:=True + - check ISA:=regex(.*I.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*Zicsr.*) + opcode: + sh: 0 + val_comb: + 'ea_align == 1': 0 + +misalign-sw: + config: + - check ISA:=regex(.*I.*); check hw_data_misaligned_support:=True + - check ISA:=regex(.*I.*Zicsr.*); check hw_data_misaligned_support:=False; def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*Zicsr.*) + opcode: + sw: 0 + val_comb: + 'ea_align == 1': 0 + 'ea_align == 2': 0 + 'ea_align == 3': 0 + +misalign2-jalr: + config: + - check ISA:=regex(.*I.*C.*) + - check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*) + opcode: + jalr: 0 + val_comb: + 'imm_val%2 == 1 and ea_align == 2': 0 + 'imm_val%2 == 0 and ea_align == 2': 0 + +misalign1-jalr: + config: + - check ISA:=regex(.*I.*) + opcode: + jalr: 0 + val_comb: + 'imm_val%2 == 1 and ea_align == 1': 0 + 'imm_val%2 == 0 and ea_align == 1': 0 + +misalign-jal: + config: + - check ISA:=regex(.*I.*C.*) + - check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*) + opcode: + jal: 0 + val_comb: + 'ea_align == 2': 0 + +misalign-bge: + config: + - check ISA:=regex(.*I.*C.*) + - check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*) + opcode: + bge: 0 + val_comb: + ' rs1_val>rs2_val and ea_align == 2': 0 + +misalign-bgeu: + config: + - check ISA:=regex(.*I.*C.*) + - check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*) + opcode: + bgeu: 0 + val_comb: + ' rs1_val>rs2_val and ea_align == 2': 0 + +misalign-blt: + config: + - check ISA:=regex(.*I.*C.*) + - check ISA:=regex(.*I.*Zicsr.*); check ISA:=regex(^[^C]+$); def rvtest_mtrap_routine=True + cond: check ISA:=regex(.*I.*) + opcode: + blt: 0 + val_comb: + ' rs1_val ****/ + /**** 12: <--------------------- Vect+mode ----------> ****/ + /*********************************************************************/ + /* in general, CSRs loaded in t2, addresses into t3 */ + + common_mhandler: /* enter with link in t6 */ + SREG t5, 5*REGWIDTH(sp) + SREG t4, 4*REGWIDTH(sp) + SREG t3, 3*REGWIDTH(sp) + SREG t2, 2*REGWIDTH(sp) + SREG t1, 1*REGWIDTH(sp) /* save other temporaries */ + + LREG t1, 0(sp) /* load trap sig pointer (runs backwards from DATA_END) */ + + LA( t3, mtrampoline) + sub t2, t6, t3 /* reloc “link” to 0..63 to show which int vector was taken */ + addi t2, t2, MMODE_SIG /* insert mode# into 1:0 */ + SREG t2, 0*REGWIDTH(t1) /* save 1st sig value, (vect, trapmode) */ + sv_mcause: + csrr t2, CSR_MCAUSE + SREG t2, 1*REGWIDTH(t1) /* save 2nd sig value, (mcause) */ + + bltz t2, common_mint_handler /* this is a interrupt, not a trap */ + + /********************************************************************/ + /**** This is the exceptions specific code, storing relative mepc****/ + /**** & relative tval signatures. tval is relocated by code or ****/ + /**** data start, or 0 depending on mcause. mepc signature value ****/ + /**** is relocated by code start, and restored adjusted depending****/ + /**** on op alignment so trapped op isn't re-executed. ****/ + /********************************************************************/ + common_mexcpt_handler: + csrr t2, CSR_MEPC + sv_mepc: + LA( t3, rvtest_prolog_done) /* offset to compensate for different loader offsets */ + sub t4, t2, t3 /* convert mepc to rel offset of beginning of test*/ + SREG t4, 2*REGWIDTH(t1) /* save 3rd sig value, (rel mepc) into trap signature area */ + adj_mepc: //adj mepc so there is padding after op, and its 8B aligned + andi t4, t2, 0x2 /* set to 2 if mepc was misaligned */ + sub t2, t2, t4 /* adjust mepc to prev 4B alignment */ + addi t2, t2, 0x8 /* adjust mepc, so it skips past the op, has padding & is 4B aligned */ + csrw CSR_MEPC, t2 /* restore adjusted value, has 1,2, or 3 bytes of padding */ + + + /* calculate relative mtval if it’s an address (by code_begin or data_begin amt) */ + /* note that masks that determine this are implementation specific from YAML */ + + /* masks are bit reversed, so mcause==0 bit is in MSB (so different for RV32 and RV64) */ + + adj_mtval: + csrr t2, CSR_MCAUSE /* code begin adjustment amount already in t3 */ + + LI(t4, CODE_REL_TVAL_MSK) /* trap#s 12, 3,1,0, -- adjust w/ code_begin */ + sll t4, t4, t2 /* put bit# in MSB */ + bltz t4, sv_mtval /* correct adjustment is code_begin in t3 */ + + LA( t3, mtrap_sigptr) /* adjustment assuming access is to signature region */ + LI(t4, DATA_REL_TVAL_MSK) /* trap#s not 14, 11..8, 2 adjust w/ data_begin */ + sll t4, t4, t2 /* put bit# in MSB */ + bgez t4, no_adj /* correct adjustment is data_begin in t3 */ + sigbound_chk: + csrr t4, CSR_MTVAL /* do a bounds check on mtval */ + bge t3, t4, sv_mtval /* if mtval is greater than the rvmodel_data_begin then use that as anchor */ + LA( t3, rvtest_data_begin) /* else change anchor to rvtest_data_begin */ + blt t3, t4, sv_mtval /* before the signature, use data_begin adj */ + mv t4, t3 /* use sig relative adjust */ + no_adj: + LI(t3, 0) /* else zero adjustment amt */ + + // For Illegal op handling + addi t2, t2, -2 /* check if mcause==2 (illegal op) */ + bnez t2, sv_mtval /* not illegal op, no special treatment */ + csrr t2, CSR_MTVAL + bnez t2, sv_mtval /* mtval isn’t zero, no special treatment */ + illop: + LI(t5, 0x20000) /* get mprv mask */ + csrrs t5, CSR_MSTATUS, t5 /* set mprv while saving the old value */ + csrr t3, CSR_MEPC + lhu t2, 0(t3) /* load 1st 16b of opc w/ old priv, endianess*/ + andi t4, t2, 0x3 + addi t4, t4, -0x3 /* does opcode[1:0]==0b11? (Meaning >16b op) */ + bnez t4, sv_mtval /* entire mtval is in tt2, adj amt will be set to zero */ + lhu t4, 2(t3) + sll t4, t4, 16 + or t3, t2, t4 /* get 2nd hwd, align it & insert it into opcode */ + csrw CSR_MSTATUS, t5 /* restore mstatus */ + +/*******FIXME: this will not handle 48 or 64b opcodes in an RV64) ********/ + + sv_mtval: + csrr t2, CSR_MTVAL + sub t2, t2, t3 /* perform mtval adjust by either code or data position or zero*/ + SREG t2, 3*REGWIDTH(t1) /* save 4th sig value, (rel mtval) into trap signature area */ + + resto_rtn: /* restore and return */ + addi t1, t1,4*REGWIDTH /* adjust trap signature ptr (traps always save 4 words) */ + SREG t1, 0*REGWIDTH(sp) /* save updated trap sig pointer (pts to trap_sigptr */ + + LREG t1, 1*REGWIDTH(sp) + LREG t2, 2*REGWIDTH(sp) + LREG t3, 3*REGWIDTH(sp) + LREG t4, 4*REGWIDTH(sp) + LREG t5, 5*REGWIDTH(sp) + LREG t6, 6*REGWIDTH(sp) /* restore temporaries */ + + csrrw sp, CSR_MSCRATCH, sp /* restore sp from scratch */ + mret + + common_mint_handler: /* t1 has sig ptr, t2 has mcause */ + + LI(t3, 1) + sll t3, t3, t2 /* create mask 1<