mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-19 03:44:46 -04:00
Vendorize 'riscv-config' tool in order to test/support local extensions. (#2045)
This commit is contained in:
parent
75f695f665
commit
c51fad1d0e
59 changed files with 40518 additions and 0 deletions
31
vendor/riscv/riscv-config/.git_hooks/pre-commit
vendored
Executable file
31
vendor/riscv/riscv-config/.git_hooks/pre-commit
vendored
Executable file
|
@ -0,0 +1,31 @@
|
|||
#!/bin/bash
|
||||
|
||||
### Pre Commit Hook For The Shakti BLUESPEC codebase
|
||||
status=0;
|
||||
### Check for Dependencies
|
||||
yapf --help
|
||||
status=$?;
|
||||
if [ $status -ne 0 ]; then
|
||||
echo "Please install yapf from :: https://github.com/google/yapf "
|
||||
exit $status;
|
||||
fi
|
||||
|
||||
### Hook Script Body
|
||||
echo "Running Pre-Commit YAPF Hook";
|
||||
|
||||
files=`git diff --cached --name-status | awk '$1 != "D" { print $2 }'`
|
||||
|
||||
echo "$files"
|
||||
|
||||
|
||||
for f in $files
|
||||
do
|
||||
if [[ $f == *.py ]]; then
|
||||
echo "Formatting $f using YAPF."
|
||||
yapf -i --style google $f
|
||||
git add $f
|
||||
fi
|
||||
done
|
||||
|
||||
status=$?;
|
||||
exit $status;
|
13
vendor/riscv/riscv-config/.git_hooks/setup.sh
vendored
Normal file
13
vendor/riscv/riscv-config/.git_hooks/setup.sh
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Setup the git hooks
|
||||
echo "Setting up git-hooks"
|
||||
echo "===================="
|
||||
|
||||
echo "Launched from" $(pwd)
|
||||
echo ""
|
||||
|
||||
echo "Setting up pre-commit"
|
||||
ln -s -f ../../.git_hooks/pre-commit ./.git/hooks/pre-commit
|
||||
chmod a+x ./.git/hooks/pre-commit
|
||||
echo "Done"
|
15
vendor/riscv/riscv-config/.gitignore
vendored
Normal file
15
vendor/riscv/riscv-config/.gitignore
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
docs/build
|
||||
docs/source/schema_isa.rst
|
||||
docs/source/schema_platform.rst
|
||||
docs/source/schema_debug.rst
|
||||
|
||||
run.log
|
||||
|
||||
__pycache__/*
|
||||
|
||||
*.pyc
|
||||
|
||||
riscv_config_work/*
|
||||
.python-version
|
||||
|
||||
riscv_config.egg-info/
|
458
vendor/riscv/riscv-config/CHANGELOG.md
vendored
Normal file
458
vendor/riscv/riscv-config/CHANGELOG.md
vendored
Normal file
|
@ -0,0 +1,458 @@
|
|||
# Changelog
|
||||
|
||||
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [3.18.1] - 2024-04-10
|
||||
- mprv should not be implemented when U mode is absent.
|
||||
|
||||
## [3.18.0] - 2024-04-02
|
||||
- mabi generation to account for E extension
|
||||
|
||||
## [3.17.1] - 2024-02-25
|
||||
- add unratified Ssdbltrp, Smdbltrp, and Sddbltrp extensions
|
||||
|
||||
## [3.17.0] - 2024-01-09
|
||||
- support march generation without custom extensions
|
||||
|
||||
## [3.16.0] - 2024-01-03
|
||||
- use the "hartX" naming for the merged dict
|
||||
- improve logging statements
|
||||
- update the "fields" node of each csr in the normalized custom yaml
|
||||
|
||||
## [3.15.0] - 2024-01-01
|
||||
- Added function that returns the march and mabi for gcc from a given ISA
|
||||
|
||||
## [3.14.3] - 2023-12-01
|
||||
- Add support for Zimop extension
|
||||
|
||||
## [3.14.2] - 2023-12-01
|
||||
- Add Zcmop extension.
|
||||
|
||||
## [3.14.1] - 2023-12-01
|
||||
- Add support for Zicfilp and Zicfiss extensions
|
||||
|
||||
## [3.14.0] - 2023-11-30
|
||||
- Include Sdext in the list of S extensions
|
||||
|
||||
## [3.13.4] - 2023-10-30
|
||||
- Add support for Zabha extension
|
||||
|
||||
## [3.13.3] - 2023-09-23
|
||||
- do not assign subfield to None
|
||||
|
||||
## [3.13.2] - 2023-09-20
|
||||
- Perform satp checks only when the CSR is accessible.
|
||||
|
||||
## [3.13.1] - 2023-08-21
|
||||
- Add support for Code Size Reduction (Zce) extension
|
||||
|
||||
## [3.13.0] - 2023-08-14
|
||||
- Fixed issue #110
|
||||
- Fixed issue #108
|
||||
- Fixed issue #114
|
||||
- Fixed issue #127
|
||||
- Fixed issue #82
|
||||
- Fixed issue #103
|
||||
- updated contribution guidelines on versioning
|
||||
- added docs for indexed CSRs
|
||||
|
||||
## [3.12.0] - 2023-08-12
|
||||
- Add support for Svadu extension
|
||||
|
||||
## [3.11.0] - 2023-08-12
|
||||
- Add support for Zacas extension
|
||||
|
||||
## [3.10.0] - 2023-08-12
|
||||
- Add support for Zfa extension
|
||||
|
||||
## [3.9.2] - 2023-07-21
|
||||
- Fix Checks for FCSR, FFLAGS and FRM to depend on F instead of U.
|
||||
|
||||
## [3.9.1] - 2023-06-21
|
||||
- Check if YAMLs are None before they're merged for performing CSR checks.
|
||||
- Perform XLEN specific satp checks based on XLEN value.
|
||||
- Check triggers only when debug CSRs are available.
|
||||
|
||||
## [3.9.0] - 2023-05-06
|
||||
- Add support to include hidden uarch dependencies in YAML definitions of CSRs.
|
||||
- Perform checks on all CSRs together instead of handling each spec seperately.
|
||||
- Add a schema for custom CSR specification. Add a node for listing uarch signals.
|
||||
|
||||
## [3.8.1] - 2023-04-25
|
||||
- fix the address for mnstatus
|
||||
|
||||
## [3.8.0] - 2023-04-18
|
||||
- Add support for Srnmi extension
|
||||
- All extension existence checks to be performed on extension\_list from isa validator.
|
||||
|
||||
## [3.7.2] - 2023-04-06
|
||||
- Add support for Zicond extension
|
||||
|
||||
## [3.7.1] - 2023-03-14
|
||||
- change all hpmcounters to be read-only shadows of the corresponding machine mode mhpmcounters.
|
||||
|
||||
## [3.7.0] - 2023-03-13
|
||||
- adding Zicntr and Zihpm extensions
|
||||
|
||||
## [3.6.0] - 2023-03-07
|
||||
- add V extensions ISA string constraints check
|
||||
|
||||
## [3.5.2] - 2022-12-26
|
||||
- special checks for vxsat csr added which apply only the max-xlen subsections of the csr
|
||||
|
||||
## [3.5.1] - 2022-12-12
|
||||
- Added Zbpbo, Zpn, Zpsfoperand into constants.py
|
||||
- Added ISA string legality checker for Zp* extension into isa_validator.py
|
||||
- Added vxsat CSR into schema_isa.yaml (Credits: chuanhua)
|
||||
|
||||
## [3.5.0] - 2022-10-28
|
||||
- Add support for indexed registers
|
||||
- Add schemas for triggers
|
||||
- Fix bugs in WARL class
|
||||
- Add function to get a legal value from WARL fields.
|
||||
|
||||
## [3.4.0] - 2022-10-13
|
||||
- support x-extension parsing in ISA string
|
||||
- added check to capture duplicates in the extensions present in the isa string
|
||||
|
||||
## [3.3.1] - 2022-09-26
|
||||
- documentation cleanup for adding new extensions in riscv-config
|
||||
- disabled pdf asset generation for each release.
|
||||
|
||||
## [3.3.0] - 2022-09-24
|
||||
- rewrote regular expression for determining legal ISA/extension strings to fix bugs and simplify maintenance. (#104)
|
||||
- updated example and regex in new-extensions.rst to match
|
||||
|
||||
## [3.2.0] - 2022-09-07
|
||||
- adding new function to get a legal value from a warl node
|
||||
|
||||
## [3.1.2] - 2022-08-23
|
||||
- if the value being tested is out of bounds, then skip with error immediately
|
||||
|
||||
## [3.1.1] - 2022-08-18
|
||||
- fix pypi dependencies for docs
|
||||
|
||||
## [3.1.0] - 2022-08-17
|
||||
|
||||
- scounteren can be a ro\_constant now
|
||||
- the maxval checks for mask/fixedval should be based on the length of the part
|
||||
- adding support for mtval\_update field
|
||||
- adding support for pte\_ad\_hw\_update field
|
||||
- cleaned up documentation
|
||||
|
||||
## [3.0.0] - 2022-08-16
|
||||
|
||||
- created new warl class for warl node handling
|
||||
|
||||
- better comments
|
||||
- more functions to keep things simple
|
||||
- fixed a lot of bugs in checking legal values
|
||||
- bitmask and range values can now co-exist in a legal string
|
||||
- added new and improved checks for syntax validity of warl strings
|
||||
|
||||
- fixed validationError function to correctly print all errors (dict and/or list)
|
||||
- removed wr\_illegal checks from the schema since they are now done as part of the new warl class
|
||||
checks
|
||||
- updates to the new warl checks and reset-value checks
|
||||
- satp.mode should have one of sv\* translation schemes as a legal value. (#89)
|
||||
- default setters for pmps fixed
|
||||
- pmp checks have been improved (#88)
|
||||
- improve WARL documentation
|
||||
|
||||
## [2.17.0] - 2022-08-08
|
||||
|
||||
- Support for Zfinx, Zdinx, Zfh, Zhinx, Zhinxmin in ISA string added.
|
||||
|
||||
## [2.16.1] - 2022-07-21
|
||||
|
||||
- fixed bug in regex where Zk and Zknh were missing an underscore
|
||||
|
||||
## [2.16.0] - 2022-07-20
|
||||
|
||||
- fixed overlap checks for crypto extensions
|
||||
- removing K and P extension strings from regex
|
||||
|
||||
## [2.15.1] - 2022-06-18
|
||||
|
||||
- added missing Z extensions from Kcrypto
|
||||
- fixed ordering of the Z extensions as per isa spec.
|
||||
|
||||
## [2.15.0] - 2022-06-16
|
||||
|
||||
- moved ISA validation as a separate api function to enable import in other python tools
|
||||
|
||||
## [2.14.1] - 2022-06-02
|
||||
|
||||
- add support for Zicbo* extensions
|
||||
- add new node in platform_schema: zicbo_cache_block_sz
|
||||
|
||||
## [2.14.0] - 2022-05-13
|
||||
|
||||
- fix for index-based dependency checks in warl string.
|
||||
|
||||
## [2.13.1] - 2022-03-23
|
||||
|
||||
- Added setup.cfg to automate bumpversion
|
||||
- Fix wording for legal strings in dependency warl fields.
|
||||
|
||||
## [2.13.0] - 2022-03-09
|
||||
- add support for detection of svnapot in ISA string
|
||||
- genralize conversion of hex, oct, bin values to int in warl functions
|
||||
- machine flat schema to include wlrl types as well
|
||||
|
||||
## [2.12.1] - 2021-12-18
|
||||
### Fixed
|
||||
|
||||
- added mbe and sbe fields in mstatush
|
||||
- fixed default setter for vsstatus in RV32 mode
|
||||
|
||||
## [2.12.0] - 2021-12-10
|
||||
|
||||
### Added
|
||||
|
||||
- support for hypervisor csrs
|
||||
- change default for dcsr.v and fix the `check_with` function for the same
|
||||
- ensures proper checks for csrs defined as 32-bit only registers
|
||||
|
||||
## [2.11.2] - 2021-11-29
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed the relationship between fflags, frm and fcsr
|
||||
- Enable subfield to be shadow field of whole csr, and vice versa
|
||||
|
||||
## [2.11.1] - 2021-11-19
|
||||
|
||||
### Added
|
||||
|
||||
- adding the missing shadow_type field for hpmcounter17
|
||||
|
||||
## [2.11.0] - 2021-10-15
|
||||
### Fixed
|
||||
- canonical ordering requirement of `_Z` extensions fixed
|
||||
### Added
|
||||
- adding support for Zmmul extension in ISA regex
|
||||
|
||||
## [2.10.2] - 2021-10-06
|
||||
### Fixed
|
||||
- islegal function under the warl_interpreter class fixed. The based and bound values are not
|
||||
extracted correctly as either hex or decimal values. Also removed the logic to truncate values
|
||||
|
||||
## [2.10.1] - 2021-08-26
|
||||
### Fixed
|
||||
- Changed the default value of 'accessible' to false so input yamls need not declare unsupported xlen
|
||||
|
||||
|
||||
## [2.10.0] - 2021-07-30
|
||||
### Added
|
||||
- added default-setters for misa's reset value to match the ISA extensions, to modify warl function of extensions under misa
|
||||
- added default setter for reset value of mstatus
|
||||
### Fixed
|
||||
- changed default values of types for subfields in mstatus
|
||||
- changed default values of types for mhpmevent*, mcountinhibit, mcounteren and mhpmcounter* to read only constant 0
|
||||
- changed default values of types for fflags, frm and fcsr to warl if F is present, else read-only constant 0
|
||||
- changed default values of types for mcycle[h], minstret[h] to warl
|
||||
- changed default values of types and added checks for subfields of scause, satp, stvec, sie, sip and sstatus
|
||||
|
||||
## [2.9.1] - 2021-06-02
|
||||
### Fixed
|
||||
- removed an unadded feature in rv32i_platform.yaml
|
||||
- removed debug_interrupts under mip in rv64i_isa.yaml
|
||||
|
||||
## [2.9.0] - 2021-05-24
|
||||
### Fixed
|
||||
- fixed issue #58 by adding extra checks for bitmask
|
||||
- fixed issue #59 by removing custom cause from platform yaml
|
||||
- resolved inconsistencies in the use of "xlen" and "supported_xlen" in schemaValidator
|
||||
### Added
|
||||
- added extra "shadow_type" fields in the csr schemas. These indicate the nature of shadow
|
||||
(read-only, read-write, etc).
|
||||
- added parking_loop node in debug_schema to indicate the address of debug rom. Can be empty in
|
||||
implementations which do not have this feature
|
||||
|
||||
## [2.8.0] - 2021-03-02
|
||||
### Added
|
||||
- Added checks for K (sub)extension(s)
|
||||
- Updated docs with information on adding new extension, csrs or specs.
|
||||
- Added github actions based CI
|
||||
|
||||
## [2.7.0] - 2021-02-25
|
||||
### Added
|
||||
- added new debug schema for debug based csrs and spec
|
||||
- cli now takes debug spec as input as well along with isa-spec
|
||||
- added support for defining custom exceptions and interrupts
|
||||
|
||||
## [2.6.3] - 2021-01-19
|
||||
### Fixed
|
||||
- added priv_mode field to sedeleg and sideleg csrs
|
||||
|
||||
## [2.6.2] - 2021-01-18
|
||||
### Fixed
|
||||
- Allow B extension in ISA schema
|
||||
|
||||
## [2.6.1] - 2021-01-13
|
||||
### Fixed
|
||||
- msb,lsb values of "SD" field in mstatus must be 63 in rv64 mode
|
||||
- added checks for reset value of misa to adhere to the extensions enabled in the input yaml
|
||||
- fixed dead-link in the docs.
|
||||
|
||||
## [2.6.0] - 2021-01-5
|
||||
### Added
|
||||
- Added support for custom csr yaml
|
||||
- Added new nodes in isa_schema: pmp_granularity and physical_addr_sz
|
||||
- Checks for pmp, counters and custom csrs
|
||||
- medeleg, mideleg check for S or N extension
|
||||
- updated the warl syntax slightly for easier parsing.
|
||||
|
||||
### Changed
|
||||
- fixed warl parsing and islegal function to check reset values
|
||||
|
||||
## [2.5.1] - 2020-11-6
|
||||
### Changed
|
||||
- modified sn_check and su_check
|
||||
- scounteren checks to make it depend only on u
|
||||
- medeleg, mideleg check for S or N extension
|
||||
|
||||
|
||||
## [2.5.0] - 2020-11-6
|
||||
### Added
|
||||
- added all n extension csrs
|
||||
- added missing supervisor csrs
|
||||
- added default setters for subfields in sip, sie , uip and uie to make it depend as shadows on machine csrs
|
||||
|
||||
## [2.4.1] - 2020-10-22
|
||||
### Changed
|
||||
- default mpp value to 0
|
||||
- adding defaults to sub-fields of mtvec
|
||||
|
||||
## [2.4.0] - 2020-10-19
|
||||
### Added
|
||||
- Added support for pmp csrs in the schema
|
||||
- Added support for mcycleh and minstreth
|
||||
- Added special checks for ensuring the shadows are implemented correctly.
|
||||
- Added support for the following supervisor csrs in the schema: sstatus, sie, sip, stvec, sepc, stval, scause and satp
|
||||
- Added support for user performance counters, frm, fcsr, time[h], cycle[h] and instret[h] csrs in
|
||||
the schema.
|
||||
### Changed
|
||||
- all fields are now subsumed under a hartid. This allows specifying multiple harts in the same
|
||||
yaml
|
||||
- logging mechanism improved.
|
||||
- isa spec is now validated independently of the platform spec
|
||||
- privilege and unprivilege version checks are no longer required. This satisfied via the
|
||||
"allowed" field now.
|
||||
- improved the 'implemented/accessible' checks for s, u and n extensions
|
||||
- the "fields" node is now populated by subfields in the increasing order of the placement in the
|
||||
csr.
|
||||
- using aliases to reduce the code size
|
||||
|
||||
## [2.3.1] - 2020-10-6
|
||||
### Changed
|
||||
- Added Zihintpause to ISA string (for PAUSE Hint instruction extension)..
|
||||
|
||||
## [2.3.0] - 2020-07-27
|
||||
### Changed
|
||||
- Size of the isa schema has been reduced significantly.
|
||||
- Using anchors in the schema.
|
||||
- Provided a command line argument to disable anchors in the checked yaml dump.
|
||||
- adding mycycle, minstret, pmpcfgs and pmpaddrs
|
||||
- added support for defining multiple harts
|
||||
|
||||
## [2.2.2] - 2020-06-09
|
||||
### Changed
|
||||
- Changed quickstart 'riscv_config' to 'riscv-config'
|
||||
- Changed checker.py to add check_reset_fill_fields() description
|
||||
|
||||
## [2.2.1] - 2020-05-18
|
||||
### Changed
|
||||
- Changed minimum python version requirement to 3.6.0 which is typically easy to install on all
|
||||
major distributions
|
||||
- Updated readme with better installation instructions
|
||||
|
||||
## [2.2.0] - 2020-04-07
|
||||
### Changed
|
||||
- Renamed the 'implemented' field in rv32 and rv64 nodes to 'accessible'.
|
||||
- Modified appropriate definitions for fields dependent on specific extensions like NSU.
|
||||
|
||||
## [2.1.1] - 2020-03-29
|
||||
## [Fixed
|
||||
- doc issue for mtimecmp
|
||||
- mimpid is now part of the default setters list
|
||||
|
||||
## [2.1.0] - 2020-03-29
|
||||
## [Fixed
|
||||
- Moved machine timer nodes to platform yaml.
|
||||
## [Added
|
||||
- `--version` option to arguments to print version and exit when specified.
|
||||
- Print help and exit when no options/arguments are specified.
|
||||
|
||||
## [2.0.2] - 2020-03-28
|
||||
### Fixed
|
||||
- Redundant reset-val check for mtvec and misa registers.
|
||||
|
||||
## [2.0.1] - 2020-03-25
|
||||
### Fixed
|
||||
- typos in quickstart doc
|
||||
- disabled deployment to repository until authentication issue is fixed.
|
||||
|
||||
## [2.0.0] - 2020-03-25
|
||||
### Added
|
||||
- adding support for warl fields and support
|
||||
- documentation for the warl fields added
|
||||
- reset-value checks added
|
||||
### Changed
|
||||
- using a new common template for defining all csrs
|
||||
- updated docs with new template
|
||||
- using special function within conf.py to extract comments from yaml file as docs.
|
||||
### Fixed
|
||||
- closed issues #10, #11, #12, #13
|
||||
|
||||
## [1.0.2] - 2019-08-09
|
||||
### Changed
|
||||
- Log is generated only if specified(for API calls to checker.check_specs).
|
||||
### Fixed
|
||||
- link in readme now points to github instead of gitlab.
|
||||
|
||||
## [1.0.0] - 2019-07-30
|
||||
### Changed
|
||||
- Work directory isnt deleted if the directory exists, although the files of the same name will be overwritten.
|
||||
### Fixed
|
||||
- Checked yaml passes validation too.
|
||||
|
||||
## [0.1.0] - 2019-07-29
|
||||
### Added
|
||||
- Added work_dir as arg and always outputs to that dir.
|
||||
- Added reset vector and nmi vector to platform.yaml
|
||||
- Vendor description fields in schema.
|
||||
- An xlen field added for internal use.
|
||||
### Fixed
|
||||
- In ISA field in isa_specs subsequent 'Z' extensions should be prefixed by an underscore '_'
|
||||
- Fixed `cerberus.validator.DocumentError: document is missing` error when platform specs is empty.
|
||||
- mtvec:mode max value is set to 1.
|
||||
- privilege-spec and user-spec are taken as strings instead of float.
|
||||
### Changed
|
||||
- The representation of the int fields is preserved in the checked-yaml.
|
||||
- mepc is a required field.
|
||||
- check_specs function now returns the paths to the dumped normalized files.
|
||||
- No other entries in node where implemented is False.
|
||||
- Readonly fields are purged by default.
|
||||
- Multiple values/entries for the same node is not allowed.
|
||||
### Removed
|
||||
- remove *_checked.yaml files from Examples.
|
||||
- changed templates_platform.yaml to template_platform.yaml in docs.
|
||||
|
||||
## [0.0.3] - 2019-07-19
|
||||
### Fixed
|
||||
- doc update
|
||||
|
||||
## [0.0.2] - 2019-07-19
|
||||
### Fixed
|
||||
- pdf documentation
|
||||
- ci-cd to host pdf as well
|
||||
|
||||
## [0.0.1] - 2019-07-18
|
||||
### Added
|
||||
- Documentation to install and use pyenv
|
||||
|
||||
## [0.0.0] - 2019-07-18
|
||||
### Added
|
||||
- Initial schemas for M mode and S mode csrs with constraints as specified in the spec.
|
92
vendor/riscv/riscv-config/CONTRIBUTING.rst
vendored
Normal file
92
vendor/riscv/riscv-config/CONTRIBUTING.rst
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
.. See LICENSE.incore for details
|
||||
|
||||
.. highlight:: shell
|
||||
|
||||
============
|
||||
Contributing
|
||||
============
|
||||
|
||||
Contributions are welcome, and they are greatly appreciated and credit will always be given.
|
||||
|
||||
You can contribute in many ways:
|
||||
|
||||
Types of Contributions
|
||||
----------------------
|
||||
|
||||
Report Bugs
|
||||
~~~~~~~~~~~
|
||||
|
||||
Report bugs at https://github.com/riscv-software-src/riscv-config/issues/ .
|
||||
|
||||
Submit Feedback
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
The best way to send feedback is to file an issue at https://github.com/riscv-software-src/riscv-config/issues/.
|
||||
|
||||
If you are proposing a feature:
|
||||
|
||||
* Explain in detail how it would work.
|
||||
* Keep the scope as narrow as possible, to make it easier to implement.
|
||||
* Remember that this is a volunteer-driven project, and that contributions
|
||||
are welcome :)
|
||||
|
||||
Get Started!
|
||||
------------
|
||||
|
||||
Ready to contribute? Here's how to set up `riscv_config` for local development.
|
||||
|
||||
1. Fork the `riscv_config` repo on GitHub.
|
||||
2. Clone your fork locally::
|
||||
|
||||
$ git clone https://github.com/riscv-software-src/riscv-config.git
|
||||
|
||||
3. Create an issue and WIP merge request that creates a working branch for you::
|
||||
|
||||
$ git checkout -b name-of-your-bugfix-or-feature
|
||||
|
||||
Now you can make your changes locally.
|
||||
|
||||
|
||||
5. Commit your changes and push your branch to GitLab::
|
||||
|
||||
$ git add .
|
||||
$ git commit -m "Your detailed description of your changes."
|
||||
$ git push origin name-of-your-bugfix-or-feature
|
||||
|
||||
6. Submit a merge request through the GitHub website.
|
||||
|
||||
|
||||
Versioning
|
||||
----------
|
||||
|
||||
When issuing pull requests, an entry in the CHANGELOG.md is mandatory. The tool adheres to
|
||||
the [`Semantic Versioning`](https://semver.org/spec/v2.0.0.html) scheme. Following guidelines must
|
||||
be followed while assigning a new version number :
|
||||
|
||||
- Patch-updates: all doc updates (like typos, more clarification,etc).
|
||||
- Minor-updates: Fixing bugs in current features, adding new features which do not break current
|
||||
features or working. Adding new extensions.
|
||||
- Major-updates: Backward incompatible changes.
|
||||
|
||||
Note: You can have either a patch or minor or major update.
|
||||
Note: In case of a conflict, the maintainers will decide the final version to be assigned.
|
||||
|
||||
To update the version of the python package for deployment you can use `bumpversion` (installed
|
||||
using ``pip install bumpversion``)::
|
||||
|
||||
$ bumpversion --no-tag --config-file setup.cfg patch # last arg can be: major or minor or patch
|
||||
|
||||
If you don't have bumpversion installed you can manually update the version in the following files:
|
||||
|
||||
- change the value of variable ``current_version`` in `./setup.cfg`
|
||||
- change the value of variable ``__version__`` in `./riscv-config/__init__.py`
|
||||
|
||||
|
||||
Merge Request Guidelines
|
||||
----------------------------
|
||||
|
||||
Before you submit a merge request, check that it meets these guidelines:
|
||||
|
||||
1. The merge request should include tests (if any).
|
||||
2. If the merge request adds functionality, the docs should be updated.
|
||||
|
29
vendor/riscv/riscv-config/LICENSE
vendored
Normal file
29
vendor/riscv/riscv-config/LICENSE
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2019, InCore Semiconductors Pvt. Ltd.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
2
vendor/riscv/riscv-config/MANIFEST.in
vendored
Normal file
2
vendor/riscv/riscv-config/MANIFEST.in
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
recursive-include schemas *.yaml
|
||||
exclude *.pyc
|
8
vendor/riscv/riscv-config/README.rst
vendored
Normal file
8
vendor/riscv/riscv-config/README.rst
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
RISCV-Config
|
||||
==============
|
||||
|
||||
RISC-V Configuration Validator
|
||||
|
||||
LICENSE: BSD-3 Clause.
|
||||
|
||||
Latest Documentation of RISCV-Config: `HTML <https://riscv-config.readthedocs.io/>`_
|
26
vendor/riscv/riscv-config/docs/Makefile
vendored
Normal file
26
vendor/riscv/riscv-config/docs/Makefile
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
# See LICENSE for details
|
||||
|
||||
# Minimal makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS =
|
||||
SPHINXBUILD = sphinx-build
|
||||
SPHINXPROJ = riscv_config
|
||||
SOURCEDIR = source
|
||||
BUILDDIR = build
|
||||
|
||||
# Put it first so that "make" without argument is like "make help".
|
||||
help:
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
.PHONY: help Makefile
|
||||
|
||||
# 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)
|
||||
|
||||
clean:
|
||||
@$(SPHINXBUILD) -M clean "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
15
vendor/riscv/riscv-config/docs/README.md
vendored
Normal file
15
vendor/riscv/riscv-config/docs/README.md
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
# Build the docs
|
||||
|
||||
## For PDF
|
||||
```
|
||||
pip install -r requirements.txt
|
||||
make latexpdf
|
||||
evince build/latex/*.pdf
|
||||
```
|
||||
|
||||
## HTML
|
||||
```
|
||||
pip install -r requirements.txt
|
||||
make html
|
||||
firefox build/html/index.html
|
||||
```
|
38
vendor/riscv/riscv-config/docs/requirements.txt
vendored
Normal file
38
vendor/riscv/riscv-config/docs/requirements.txt
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
alabaster==0.7.12
|
||||
Babel==2.7.0
|
||||
Cerberus==1.3.1
|
||||
certifi==2019.6.16
|
||||
chardet==3.0.4
|
||||
doc8==0.8.0
|
||||
docutils==0.14
|
||||
gitdb2==2.0.5
|
||||
idna==2.8
|
||||
imagesize==1.1.0
|
||||
Jinja2==2.10.1
|
||||
MarkupSafe==1.1.1
|
||||
oyaml==0.9
|
||||
packaging==19.0
|
||||
pbr==5.3.1
|
||||
Pygments==2.4.2
|
||||
pyparsing==2.4.0
|
||||
python-dateutil==2.8.0
|
||||
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-rtd-theme==0.4.3
|
||||
sphinxcontrib-autoyaml==0.5.0
|
||||
sphinxcontrib-mermaid
|
||||
sphinxcontrib-websupport==1.1.2
|
||||
sphinxcontrib-bibtex==1.0.0
|
||||
stevedore==1.30.1
|
||||
urllib3==1.25.3
|
||||
twine==1.13.0
|
||||
sphinx_tabs
|
||||
m2r2==0.2.7
|
||||
mistune==0.8.4
|
92
vendor/riscv/riscv-config/docs/source/CONTRIBUTING.rst
vendored
Normal file
92
vendor/riscv/riscv-config/docs/source/CONTRIBUTING.rst
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
.. See LICENSE.incore for details
|
||||
|
||||
.. highlight:: shell
|
||||
|
||||
============
|
||||
Contributing
|
||||
============
|
||||
|
||||
Contributions are welcome, and they are greatly appreciated and credit will always be given.
|
||||
|
||||
You can contribute in many ways:
|
||||
|
||||
Types of Contributions
|
||||
----------------------
|
||||
|
||||
Report Bugs
|
||||
~~~~~~~~~~~
|
||||
|
||||
Report bugs at https://github.com/riscv-software-src/riscv-config/issues/ .
|
||||
|
||||
Submit Feedback
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
The best way to send feedback is to file an issue at https://github.com/riscv-software-src/riscv-config/issues/.
|
||||
|
||||
If you are proposing a feature:
|
||||
|
||||
* Explain in detail how it would work.
|
||||
* Keep the scope as narrow as possible, to make it easier to implement.
|
||||
* Remember that this is a volunteer-driven project, and that contributions
|
||||
are welcome :)
|
||||
|
||||
Get Started!
|
||||
------------
|
||||
|
||||
Ready to contribute? Here's how to set up `riscv_config` for local development.
|
||||
|
||||
1. Fork the `riscv_config` repo on GitHub.
|
||||
2. Clone your fork locally::
|
||||
|
||||
$ git clone https://github.com/riscv-software-src/riscv-config.git
|
||||
|
||||
3. Create an issue and WIP merge request that creates a working branch for you::
|
||||
|
||||
$ git checkout -b name-of-your-bugfix-or-feature
|
||||
|
||||
Now you can make your changes locally.
|
||||
|
||||
|
||||
5. Commit your changes and push your branch to GitLab::
|
||||
|
||||
$ git add .
|
||||
$ git commit -m "Your detailed description of your changes."
|
||||
$ git push origin name-of-your-bugfix-or-feature
|
||||
|
||||
6. Submit a merge request through the GitHub website.
|
||||
|
||||
|
||||
Versioning
|
||||
----------
|
||||
|
||||
When issuing pull requests, an entry in the CHANGELOG.md is mandatory. The tool adheres to
|
||||
the [`Semantic Versioning`](https://semver.org/spec/v2.0.0.html) scheme. Following guidelines must
|
||||
be followed while assigning a new version number :
|
||||
|
||||
- Patch-updates: all doc updates (like typos, more clarification,etc).
|
||||
- Minor-updates: Fixing bugs in current features, adding new features which do not break current
|
||||
features or working. Adding new extensions.
|
||||
- Major-updates: Backward incompatible changes.
|
||||
|
||||
Note: You can have either a patch or minor or major update.
|
||||
Note: In case of a conflict, the maintainers will decide the final version to be assigned.
|
||||
|
||||
To update the version of the python package for deployment you can use `bumpversion` (installed
|
||||
using ``pip install bumpversion``)::
|
||||
|
||||
$ bumpversion --no-tag --config-file setup.cfg patch # last arg can be: major or minor or patch
|
||||
|
||||
If you don't have bumpversion installed you can manually update the version in the following files:
|
||||
|
||||
- change the value of variable ``current_version`` in `./setup.cfg`
|
||||
- change the value of variable ``__version__`` in `./riscv-config/__init__.py`
|
||||
|
||||
|
||||
Merge Request Guidelines
|
||||
----------------------------
|
||||
|
||||
Before you submit a merge request, check that it meets these guidelines:
|
||||
|
||||
1. The merge request should include tests (if any).
|
||||
2. If the merge request adds functionality, the docs should be updated.
|
||||
|
BIN
vendor/riscv/riscv-config/docs/source/_static/Tall_2.png
vendored
Executable file
BIN
vendor/riscv/riscv-config/docs/source/_static/Tall_2.png
vendored
Executable file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
305
vendor/riscv/riscv-config/docs/source/_static/custom.css
vendored
Normal file
305
vendor/riscv/riscv-config/docs/source/_static/custom.css
vendored
Normal file
|
@ -0,0 +1,305 @@
|
|||
/* -- Extra CSS styles for Zephyr content (RTD theme) ----------------------- */
|
||||
|
||||
/* make the page width fill the window */
|
||||
.wy-nav-content {
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
/* pygments tweak for white-on-black console */
|
||||
/* hold off on this change for now
|
||||
|
||||
.highlight-console .highlight {
|
||||
background-color: black;
|
||||
}
|
||||
.highlight-console .highlight .go, .highlight-console .highlight .gp {
|
||||
color: white;
|
||||
}
|
||||
.highlight-console .highlight .hll {
|
||||
background-color: white;
|
||||
}
|
||||
.highlight-console .highlight .hll .go, .highlight-console .highlight .hll .gp {
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
}
|
||||
*/
|
||||
|
||||
/* tweak doc version selection */
|
||||
.rst-versions {
|
||||
position: static !important;
|
||||
}
|
||||
|
||||
|
||||
.rst-versions .rst-current-version {
|
||||
padding: 5px;
|
||||
background-color: #2980B9;
|
||||
color: #80FF80;
|
||||
}
|
||||
|
||||
.rst-versions .rst-other-versions {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
div.rst-other-versions dl {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* tweak spacing after a toctree, fixing issue from sphinx-tabs */
|
||||
.toctree-wrapper ul, ul.simple ol.simple {
|
||||
margin-bottom: 24px !important;
|
||||
}
|
||||
|
||||
/* code block highlight color in rtd changed to lime green, no no no */
|
||||
|
||||
.rst-content tt.literal, .rst-content code.literal, .highlight {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
.rst-content tt.literal, .rst-content code.literal {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
/* code literal links should be blue, and purple after visiting */
|
||||
a.internal code.literal {
|
||||
color: #2980B9;
|
||||
}
|
||||
a.internal:visited code.literal {
|
||||
color: #9B59B9;
|
||||
}
|
||||
|
||||
/* Make the version number more visible */
|
||||
.wy-side-nav-search>div.version {
|
||||
color: rgba(255,255,255,1);
|
||||
}
|
||||
|
||||
/* squish the space between a paragraph before a list */
|
||||
div > p + ul, div > p + ol {
|
||||
margin-top: -20px;
|
||||
}
|
||||
|
||||
/* squish space before an hlist in a list */
|
||||
li table.hlist {
|
||||
margin-top: -10px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
/* add some space before the figure caption */
|
||||
p.caption {
|
||||
# border-top: 1px solid;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
/* decrease line leading a bit, 24px is too wide */
|
||||
|
||||
p {
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
/* add a colon after the figure/table number (before the caption) */
|
||||
span.caption-number::after {
|
||||
content: ": ";
|
||||
}
|
||||
|
||||
p.extrafooter {
|
||||
text-align: right;
|
||||
margin-top: -36px;
|
||||
}
|
||||
|
||||
table.align-center {
|
||||
display: table !important;
|
||||
}
|
||||
|
||||
/* put the table caption at the bottom, as done for figures */
|
||||
table {
|
||||
caption-side: bottom;
|
||||
}
|
||||
|
||||
.code-block-caption {
|
||||
color: #000;
|
||||
font: italic 85%/1 arial,sans-serif;
|
||||
padding: 1em 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* make .. hlist:: tables fill the page */
|
||||
table.hlist {
|
||||
width: 95% !important;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
/* override rtd theme white-space no-wrap in table heading and content */
|
||||
th,td {
|
||||
white-space: normal !important;
|
||||
}
|
||||
|
||||
/* dbk tweak for doxygen-generated API headings (for RTD theme) */
|
||||
.rst-content dl.group>dt, .rst-content dl.group>dd>p {
|
||||
display:none !important;
|
||||
}
|
||||
.rst-content dl.group {
|
||||
margin: 0 0 12px 0px;
|
||||
}
|
||||
.rst-content dl.group>dd {
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
.rst-content p.breathe-sectiondef-title {
|
||||
text-decoration: underline; /* dbk for API sub-headings */
|
||||
font-size: 1.25rem;
|
||||
font-weight: bold;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.rst-content div.breathe-sectiondef {
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
/* doxygenXX item color tweaks, light blue background with dark blue top border */
|
||||
.rst-content dl:not(.docutils) dl dt, dl:not(.docutils,.rst-other-versions) dt {
|
||||
background: #e7f2fa !important;
|
||||
border-top: none !important;
|
||||
border-left: none !important; */
|
||||
}
|
||||
|
||||
|
||||
/* tweak display of option tables to make first column wider */
|
||||
col.option {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
/* tweak format for <kbd> (:kbd:`F10`) */
|
||||
kbd
|
||||
{
|
||||
-moz-border-radius:3px;
|
||||
-moz-box-shadow:0 1px 0 rgba(0,0,0,0.2),0 0 0 2px #fff inset;
|
||||
-webkit-border-radius:3px;
|
||||
-webkit-box-shadow:0 1px 0 rgba(0,0,0,0.2),0 0 0 2px #fff inset;
|
||||
background-color:#f7f7f7;
|
||||
border:1px solid #ccc;
|
||||
border-radius:3px;
|
||||
box-shadow:0 1px 0 rgba(0,0,0,0.2),0 0 0 2px #fff inset;
|
||||
color:#333;
|
||||
display:inline-block;
|
||||
font-family:Arial,Helvetica,sans-serif;
|
||||
font-size:11px;
|
||||
line-height:1.4;
|
||||
margin:0 .1em;
|
||||
padding:.1em .6em;
|
||||
text-shadow:0 1px 0 #fff;
|
||||
}
|
||||
|
||||
/* home page grid display */
|
||||
|
||||
.grid {
|
||||
list-style-type: none !important;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-ms-flex-wrap: wrap;
|
||||
flex-wrap: wrap;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
margin: 1rem auto;
|
||||
max-width: calc((250px + 2rem) * 4);
|
||||
}
|
||||
|
||||
.grid-item {
|
||||
list-style-type: none !important;
|
||||
-webkit-box-flex: 0;
|
||||
-ms-flex: 0 0 auto;
|
||||
flex: 0 0 auto;
|
||||
width: 200px;
|
||||
text-align: center;
|
||||
margin: 1rem;
|
||||
}
|
||||
|
||||
.grid-item a {
|
||||
display: block;
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
padding: 20px;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
border: 1px solid #c6cbce;
|
||||
background-color: #1ab4e7;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.grid-item h2 {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.grid-item img {
|
||||
margin-bottom: 1.1rem;
|
||||
max-width: 75%;
|
||||
}
|
||||
|
||||
|
||||
.grid-item a:hover {
|
||||
background-color: #1892BA;
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
.grid-item p {
|
||||
margin-top: 0.5rem;
|
||||
color: #333e48;
|
||||
}
|
||||
|
||||
.grid-icon {
|
||||
line-height: 1.8;
|
||||
font-size: 4rem;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* add a class for multi-column support
|
||||
* in docs to replace use of .hlist with
|
||||
* a .. rst-class:: rst-columns
|
||||
*/
|
||||
|
||||
.rst-columns {
|
||||
column-width: 18em;
|
||||
}
|
||||
|
||||
/* numbered "h2" steps */
|
||||
|
||||
body {
|
||||
counter-reset: step-count;
|
||||
}
|
||||
|
||||
div.numbered-step h2::before {
|
||||
counter-increment: step-count;
|
||||
content: counter(step-count);
|
||||
background: #cccccc;
|
||||
border-radius: 0.8em;
|
||||
-moz-border-radius: 0.8em;
|
||||
-webkit-border-radius: 0.8em;
|
||||
color: #ffffff;
|
||||
display: inline-block;
|
||||
font-weight: bold;
|
||||
line-height: 1.6em;
|
||||
margin-right: 5px;
|
||||
text-align: center;
|
||||
width: 1.6em;
|
||||
}
|
||||
|
||||
/* tweak bottom margin of a code block in a list */
|
||||
|
||||
.tab div[class^='highlight']:last-child {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
/* force table content font-size in responsive tables to be 100%
|
||||
* fixing larger font size for paragraphs in the kconfig tables */
|
||||
|
||||
.wy-table-responsive td p {
|
||||
font-size:100%;
|
||||
}
|
13
vendor/riscv/riscv-config/docs/source/_static/theme_overrides.css
vendored
Normal file
13
vendor/riscv/riscv-config/docs/source/_static/theme_overrides.css
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
/* override table width restrictions */
|
||||
@media screen and (min-width: 767px) {
|
||||
|
||||
.wy-table-responsive table td {
|
||||
/* !important prevents the common CSS stylesheets from overriding
|
||||
this as on RTD they are loaded after this stylesheet */
|
||||
white-space: normal !important;
|
||||
}
|
||||
|
||||
.wy-table-responsive {
|
||||
overflow: visible !important;
|
||||
}
|
||||
}
|
14
vendor/riscv/riscv-config/docs/source/_templates/breadcrumbs.html
vendored
Normal file
14
vendor/riscv/riscv-config/docs/source/_templates/breadcrumbs.html
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
{% extends "!breadcrumbs.html" %}
|
||||
{% block breadcrumbs %}
|
||||
<!-- {{ docs_title }} -->
|
||||
{# parameterize default name "Docs" in breadcrumb via docs_title in conf.py #}
|
||||
{% if not docs_title %}
|
||||
{% set docs_title = "Docs" %}
|
||||
{% endif %}
|
||||
|
||||
<li><a href="{{ pathto(master_doc) }}">{{ docs_title }}</a> »</li>
|
||||
{% for doc in parents %}
|
||||
<li><a href="{{ doc.link|e }}">{{ doc.title }}</a> »</li>
|
||||
{% endfor %}
|
||||
<li>{{ title }}</li>
|
||||
{% endblock %}
|
14
vendor/riscv/riscv-config/docs/source/_templates/layout.html
vendored
Normal file
14
vendor/riscv/riscv-config/docs/source/_templates/layout.html
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
{% extends "!layout.html" %}
|
||||
{% block document %}
|
||||
{% if is_release %}
|
||||
<div class="wy-alert wy-alert-danger">
|
||||
The <a href="/latest/{{ pagename }}.html">latest development version</a>
|
||||
of this page may be more current than this released {{ version }} version.
|
||||
</div>
|
||||
{% endif %}
|
||||
{{ super() }}
|
||||
{% endblock %}
|
||||
{% block menu %}
|
||||
{% include "versions.html" %}
|
||||
{{ super() }}
|
||||
{% endblock %}
|
25
vendor/riscv/riscv-config/docs/source/_templates/versions.html
vendored
Normal file
25
vendor/riscv/riscv-config/docs/source/_templates/versions.html
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
{# Add rst-badge after rst-versions for small badge style. #}
|
||||
<div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="versions">
|
||||
<span class="rst-current-version" data-toggle="rst-current-version">
|
||||
<span class="fa fa-book"> RISC-V Compatibility Test Generator </span>
|
||||
v: {{ current_version }}
|
||||
<span class="fa fa-caret-down"></span>
|
||||
</span>
|
||||
<div class="rst-other-versions">
|
||||
<dl>
|
||||
<dt>{{ _('Release Versions') }}</dt>
|
||||
{% for slug, url in versions %}
|
||||
<dd><a href="{{ url }}">{{ slug }}</a></dd>
|
||||
{% endfor %}
|
||||
</dl>
|
||||
<dl>
|
||||
<dt>{{ _('Quick Links') }}</dt>
|
||||
<dd>
|
||||
<a href="https://github.com/riscv/riscv-config">Project Home</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="https://github.com/riscv/riscv-config/tags">Releases</a>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
38
vendor/riscv/riscv-config/docs/source/code-doc.rst
vendored
Normal file
38
vendor/riscv/riscv-config/docs/source/code-doc.rst
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
##################
|
||||
Code Documentation
|
||||
##################
|
||||
.. _checker:
|
||||
|
||||
riscv_config.checker
|
||||
---------------------
|
||||
|
||||
.. automodule:: riscv_config.checker
|
||||
:members:
|
||||
:special-members:
|
||||
:private-members:
|
||||
|
||||
.. _schemaValidator:
|
||||
|
||||
riscv_config.schemaValidator
|
||||
----------------------------
|
||||
.. automodule:: riscv_config.schemaValidator
|
||||
:members:
|
||||
:special-members:
|
||||
:private-members:
|
||||
|
||||
|
||||
Utils
|
||||
-----
|
||||
|
||||
.. automodule:: riscv_config.utils
|
||||
:members:
|
||||
:special-members:
|
||||
:private-members:
|
||||
|
||||
WARL
|
||||
----
|
||||
|
||||
.. automodule:: riscv_config.warl
|
||||
:members:
|
||||
:special-members:
|
||||
:private-members:
|
456
vendor/riscv/riscv-config/docs/source/conf.py
vendored
Normal file
456
vendor/riscv/riscv-config/docs/source/conf.py
vendored
Normal file
|
@ -0,0 +1,456 @@
|
|||
# See LICENSE for details
|
||||
|
||||
|
||||
# riscv_config documentation build configuration file,
|
||||
|
||||
import sys
|
||||
import os
|
||||
import shlex
|
||||
import re
|
||||
import textwrap
|
||||
|
||||
def gen_schema_doc(infile, outfile):
|
||||
text = open(infile,'r').read()
|
||||
rst_file = open(outfile,'w')
|
||||
x = re.findall("^\s*###(?:(?:\r\n|[\r\n]).+$)*",text,re.M|re.U)
|
||||
for y in x:
|
||||
y = y.replace('#','')
|
||||
y = textwrap.dedent(y)
|
||||
rst_file.write(y+'\n')
|
||||
|
||||
rst_file.close()
|
||||
|
||||
def get_version():
|
||||
changelog = open('../../CHANGELOG.md','r').read()
|
||||
x = re.findall(r'## \[(.*?)\] -',changelog)[0]
|
||||
return str(x)
|
||||
|
||||
gen_schema_doc('../../riscv_config/schemas/schema_isa.yaml', 'schema_isa.rst')
|
||||
gen_schema_doc('../../riscv_config/schemas/schema_platform.yaml', 'schema_platform.rst')
|
||||
gen_schema_doc('../../riscv_config/schemas/schema_debug.yaml', 'schema_debug.rst')
|
||||
|
||||
sys.path.insert(0, os.path.abspath('../..'))
|
||||
sys.setrecursionlimit(1500)
|
||||
|
||||
# General information about the project.
|
||||
project = 'RISC-V Configuration Validator'
|
||||
copyright = u'2022 InCore Semiconductors Pvt. Ltd'
|
||||
|
||||
author = ''
|
||||
|
||||
version = str(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")
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
# needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
needs_sphinx = '1.7.5'
|
||||
extensions = [
|
||||
'sphinx.ext.autodoc',
|
||||
'sphinx.ext.doctest',
|
||||
'sphinx.ext.intersphinx',
|
||||
'sphinx.ext.todo',
|
||||
'sphinx.ext.coverage',
|
||||
'sphinx.ext.mathjax',
|
||||
'sphinx.ext.viewcode',
|
||||
'sphinxcontrib.autoyaml',
|
||||
'sphinxcontrib.bibtex',
|
||||
'sphinx_tabs.tabs',
|
||||
'm2r2'
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix(es) of source filenames.
|
||||
# You can specify multiple suffix as a list of string:
|
||||
source_suffix = ['.rst', '.md']
|
||||
#source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = True
|
||||
|
||||
|
||||
# -- Options for HTML output ----------------------------------------------
|
||||
|
||||
github_url = 'https://github.com/riscv-software-src/riscv-config'
|
||||
html_show_sourcelink = True
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
#html_theme = 'bootstrap'
|
||||
#html_theme = 'alabaster'
|
||||
import sphinx_rtd_theme
|
||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
html_theme_options = {
|
||||
'prev_next_buttons_location': 'both',
|
||||
'display_version': True,
|
||||
'includehidden': False,
|
||||
'collapse_navigation':True,
|
||||
'sticky_navigation': True,
|
||||
'navigation_depth': 4,
|
||||
'includehidden': True,
|
||||
'titles_only': False
|
||||
}
|
||||
#html_sidebars = {
|
||||
# "**": ["about.html", "navigation.html", "searchbox.html", "donate.html"]
|
||||
#}
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
html_logo='_static/Tall_2.png'
|
||||
html_show_license = True
|
||||
docs_title = 'Docs / %s' %(version)
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = '_static/onlyC.png'
|
||||
html_context = {
|
||||
'show_license': html_show_license,
|
||||
'docs_title': docs_title,
|
||||
'is_release': False,
|
||||
'theme_logo_only': False,
|
||||
'current_version': version,
|
||||
}
|
||||
html_last_updated_fmt = '%b %d, %Y'
|
||||
# If false, no module index is generated.
|
||||
html_domain_indices = False
|
||||
|
||||
# If false, no index is generated.
|
||||
html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
html_split_index = True
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
html_show_sourcelink = False
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
html_show_sphinx = False
|
||||
|
||||
# If true, license is shown in the HTML footer. Default is True.
|
||||
html_show_license = True
|
||||
|
||||
# Custom sidebar templates, must be a dictionary that maps document names
|
||||
# to template names.
|
||||
#
|
||||
# The default sidebars (for documents that don't match any pattern) are
|
||||
# defined by theme itself. Builtin themes are using these templates by
|
||||
# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
|
||||
# 'searchbox.html']``.
|
||||
#
|
||||
# html_sidebars = {}
|
||||
|
||||
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'RISCV-Configdoc'
|
||||
|
||||
# -- Options for LaTeX output ---------------------------------------------
|
||||
|
||||
# -- Options for LaTeX output ------------------------------------------------
|
||||
latex_engine='xelatex'
|
||||
numfig = True
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#
|
||||
'papersize': 'letterpaper',
|
||||
'releasename':version,
|
||||
'extraclassoptions': 'openany, twoside',
|
||||
|
||||
# Sonny, Lenny, Glenn, Conny, Rejne, Bjarne and Bjornstrup
|
||||
#'fncychap': '\\usepackage[Bjornstrup]{fncychap}',
|
||||
'fncychap': '\\usepackage{fancyhdr}',
|
||||
'fontpkg': '\\usepackage{amsmath,amsfonts,amssymb,amsthm}',
|
||||
|
||||
'figure_align':'htbp',
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#
|
||||
'pointsize': '12pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#
|
||||
'preamble': r'''
|
||||
% change the fon to san-serif
|
||||
%\renewcommand{\familydefault}{\sfdefault}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%% Meher %%%%%%%%%%%%%%%%%%
|
||||
%%%add number to subsubsection 2=subsection, 3=subsubsection
|
||||
%%% below subsubsection is not good idea.
|
||||
\setcounter{secnumdepth}{3}
|
||||
%
|
||||
%%%% Table of content upto 2=subsection, 3=subsubsection
|
||||
\setcounter{tocdepth}{2}
|
||||
|
||||
\usepackage{amsmath,amsfonts,amssymb,amsthm}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{array, caption, tabularx, ragged2e, booktabs, longtable}
|
||||
\usepackage{stfloats}
|
||||
\usepackage{multirow}
|
||||
\usepackage{gensymb}
|
||||
\usepackage{fontspec}
|
||||
\setmainfont{Ubuntu Light}
|
||||
\definecolor{light-gray}{gray}{0.85}
|
||||
\usepackage{color,xesearch}
|
||||
\usepackage{soul}
|
||||
\sethlcolor{light-gray}
|
||||
\makeatletter
|
||||
|
||||
%%% reduce spaces for Table of contents, figures and tables
|
||||
%%% it is used "\addtocontents{toc}{\vskip -1.2cm}" etc. in the document
|
||||
\usepackage[notlot,nottoc,notlof]{}
|
||||
|
||||
\usepackage{color}
|
||||
\usepackage{transparent}
|
||||
\usepackage{eso-pic}
|
||||
\usepackage{lipsum}
|
||||
|
||||
\usepackage{footnotebackref} %%link at the footnote to go to the place of footnote in the text
|
||||
|
||||
%% spacing between line
|
||||
\usepackage{setspace}
|
||||
%%%%\onehalfspacing
|
||||
%%%%\doublespacing
|
||||
\singlespacing
|
||||
|
||||
|
||||
%%%%%%%%%%% datetime
|
||||
\usepackage{datetime}
|
||||
|
||||
\newdateformat{MonthYearFormat}{%
|
||||
\monthname[\THEMONTH], \THEYEAR}
|
||||
|
||||
|
||||
%% RO, LE will not work for 'oneside' layout.
|
||||
%% Change oneside to twoside in document class
|
||||
\pagestyle{fancy}
|
||||
\makeatletter
|
||||
\fancypagestyle{normal}{
|
||||
\fancyhf{}
|
||||
|
||||
%%% Alternating Header for oneside
|
||||
%\fancyhead[L]{\ifthenelse{\isodd{\value{page}}}{ \small \nouppercase{\leftmark} }{}}
|
||||
%\fancyhead[R]{\ifthenelse{\isodd{\value{page}}}{}{ \small \nouppercase{\rightmark} }}
|
||||
|
||||
%%% Alternating Header for two side
|
||||
\fancyhead[RO]{\small \nouppercase{\leftmark}}
|
||||
\fancyhead[RE]{\small \nouppercase{\leftmark}}
|
||||
\fancyhead[LE,LO]{\py@HeaderFamily \@title\sphinxheadercomma\releasename}
|
||||
%\fancyhead[RE,RO]{\py@HeaderFamily \c@chapter}
|
||||
|
||||
%% for oneside: change footer at right side. If you want to use Left and right then use same as header defined above.
|
||||
%\fancyfoot[R]{\ifthenelse{\isodd{\value{page}}}{{\tiny Meher Krishna Patel} }{\href{http://pythondsp.readthedocs.io/en/latest/pythondsp/toc.html}{\tiny PythonDSP}}}
|
||||
|
||||
%%% Alternating Footer for two side
|
||||
\fancyfoot[LO, LE]{\small \bf{Copyright \textcopyright \the\year \textbf{ } InCore Semiconductors Pvt. Ltd.}}
|
||||
%\fancyfoot[LO, LE]{\scriptsize \bf{RISC-V Config}}
|
||||
|
||||
%%% page number
|
||||
\fancyfoot[RO, RE]{\thepage}
|
||||
|
||||
\renewcommand{\headrulewidth}{0.4pt}
|
||||
\renewcommand{\footrulewidth}{0.4pt}
|
||||
}
|
||||
\makeatother
|
||||
\RequirePackage{tocbibind} %%% comment this to remove page number for following
|
||||
\addto\captionsenglish{\renewcommand{\contentsname}{Table of contents}}
|
||||
\addto\captionsenglish{\renewcommand{\listfigurename}{List of figures}}
|
||||
\addto\captionsenglish{\renewcommand{\listtablename}{List of tables}}
|
||||
% \addto\captionsenglish{\renewcommand{\chaptername}{Chapter}}
|
||||
|
||||
|
||||
%%reduce spacing for itemize
|
||||
\usepackage{enumitem}
|
||||
\setlist{nosep}
|
||||
|
||||
%%%%%%%%%%% Quote Styles at the top of chapter
|
||||
\usepackage{epigraph}
|
||||
\setlength{\epigraphwidth}{0.8\columnwidth}
|
||||
\newcommand{\chapterquote}[2]{\epigraphhead[60]{\epigraph{\textit{#1}}{\textbf {\textit{--#2}}}}}
|
||||
%%%%%%%%%%% Quote for all places except Chapter
|
||||
\newcommand{\sectionquote}[2]{{\quote{\textit{``#1''}}{\textbf {\textit{--#2}}}}}
|
||||
|
||||
\linespread{1}
|
||||
''',
|
||||
|
||||
|
||||
'maketitle': r'''
|
||||
\pagenumbering{Roman} %%% to avoid page 1 conflict with actual page 1
|
||||
|
||||
\begin{titlepage}
|
||||
\centering
|
||||
|
||||
\begin{figure}[!h]
|
||||
\centering
|
||||
\includegraphics[scale=0.2]{incore_logo.png}
|
||||
\end{figure}
|
||||
\vspace*{40mm} %%% * is used to give space from top
|
||||
\textbf{\Huge {RISC-V Configuration Validator}}
|
||||
\vspace*{40mm} %%% * is used to give space from top
|
||||
|
||||
|
||||
\vspace{10mm}
|
||||
\Large \textbf{{Release: \releasename}}
|
||||
\vspace{10mm}
|
||||
|
||||
Last update on : \today
|
||||
|
||||
\vspace*{0mm}
|
||||
%\small Last updated : \MonthYearFormat\today
|
||||
|
||||
|
||||
%% \vfill adds at the bottom
|
||||
\vfill
|
||||
Copyright \textcopyright \the\year \textbf{ } InCore Semiconductors Pvt. Ltd.
|
||||
\end{titlepage}
|
||||
\sloppy
|
||||
|
||||
\clearpage
|
||||
% \pagenumbering{roman}
|
||||
\tableofcontents
|
||||
\clearpage
|
||||
\listoffigures
|
||||
\clearpage
|
||||
\listoftables
|
||||
\clearpage
|
||||
\pagenumbering{arabic}
|
||||
''',
|
||||
# Latex figure (float) alignment
|
||||
#
|
||||
# 'figure_align': 'htbp',
|
||||
'sphinxsetup': \
|
||||
'hmargin={0.7in,0.7in}, vmargin={1in,1in}, \
|
||||
verbatimwithframe=true, \
|
||||
TitleColor={rgb}{0,0,0}, \
|
||||
HeaderFamily=\\rmfamily\\bfseries, \
|
||||
InnerLinkColor={rgb}{0,0,1}, \
|
||||
OuterLinkColor={rgb}{0,0,1}',
|
||||
|
||||
'tableofcontents':' ',
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
#latex_elements = {
|
||||
# # The paper size ('letterpaper' or 'a4paper').
|
||||
# #
|
||||
# 'papersize': 'letterpaper',
|
||||
#
|
||||
# # The font size ('10pt', '11pt' or '12pt').
|
||||
# #
|
||||
# 'pointsize': '10pt',
|
||||
#
|
||||
# # Additional stuff for the LaTeX preamble.
|
||||
# #
|
||||
# 'preamble': '',
|
||||
#
|
||||
# # Latex figure (float) alignment
|
||||
# #
|
||||
# 'figure_align': 'htbp',
|
||||
#
|
||||
# 'atendofbody' : ' InCore Semiconductors Pvt. Ltd.'
|
||||
#}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
(master_doc, 'riscv_config.tex', 'RISC-V Configuration Validator Documentation',
|
||||
'InCore Semiconductors Pvt. Ltd.', 'manual'),
|
||||
]
|
||||
|
||||
#latex_logo = '_static/incore_logo.png'
|
||||
|
||||
latex_show_pagerefs = True
|
||||
|
||||
# -- Options for manual page output ------------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
(master_doc, 'riscvfeaturelegalizer', 'RISC-V Configuration Validator Documentation',
|
||||
[author], 1)
|
||||
]
|
||||
|
||||
|
||||
# -- Options for Texinfo output ----------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(master_doc, 'riscv_config', 'RISC-V Configuration Validator Documentation',
|
||||
author, 'InCore Semicondutors', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
# -- Options for Epub output -------------------------------------------------
|
||||
|
||||
# Bibliographic Dublin Core info.
|
||||
epub_title = project
|
||||
epub_author = author
|
||||
epub_publisher = author
|
||||
epub_copyright = copyright
|
||||
|
||||
# The unique identifier of the text. This can be a ISBN number
|
||||
# or the project homepage.
|
||||
#
|
||||
# epub_identifier = ''
|
||||
|
||||
# A unique identification for the text.
|
||||
#
|
||||
# epub_uid = ''
|
||||
|
||||
# A list of files that should not be packed into the epub file.
|
||||
epub_exclude_files = ['search.html']
|
||||
|
||||
|
||||
# -- Extension configuration -------------------------------------------------
|
||||
|
||||
# -- Options for intersphinx extension ---------------------------------------
|
||||
|
||||
# Example configuration for intersphinx: refer to the Python standard library.
|
||||
intersphinx_mapping = {'https://docs.python.org/': None}
|
||||
|
||||
# -- Options for todo extension ----------------------------------------------
|
||||
|
||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
||||
todo_include_todos = True
|
29
vendor/riscv/riscv-config/docs/source/index.rst
vendored
Normal file
29
vendor/riscv/riscv-config/docs/source/index.rst
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
#######################
|
||||
Welcome to RISCV-Config
|
||||
#######################
|
||||
|
||||
Welcome to RISC-V Configuration Validator documentation.
|
||||
|
||||
For information about the changes and additions for releases,
|
||||
please refer to the :ref:`Revisions <revisions>` documentation.
|
||||
|
||||
.. toctree::
|
||||
:glob:
|
||||
:numbered:
|
||||
|
||||
intro
|
||||
overview
|
||||
quickstart
|
||||
yaml-specs
|
||||
new-extensions
|
||||
CONTRIBUTING
|
||||
code-doc
|
||||
revisions
|
||||
|
||||
Indices and tables
|
||||
------------------
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
|
13
vendor/riscv/riscv-config/docs/source/intro.rst
vendored
Normal file
13
vendor/riscv/riscv-config/docs/source/intro.rst
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
############
|
||||
Introduction
|
||||
############
|
||||
|
||||
**RISCV-Config** (RISCV Configuration Leagalizer) is a YAML based framework which can be used to validate the specifications of a RISC-V implementation against the RISC-V privileged and unprivileged ISA spec and generate standard specification yaml file.
|
||||
|
||||
**Caution**: This is still a work in progress and non-backward compatible changes are expected to happen.
|
||||
|
||||
For more information on the official RISC-V spec please visit: `RISC-V Specs <https://riscv.org/specifications/>`_
|
||||
|
||||
RISCV-Config [`Repository <https://github.com/riscv/riscv-config>`_]
|
||||
|
||||
|
326
vendor/riscv/riscv-config/docs/source/new-extensions.rst
vendored
Normal file
326
vendor/riscv/riscv-config/docs/source/new-extensions.rst
vendored
Normal file
|
@ -0,0 +1,326 @@
|
|||
#################################
|
||||
Adding support for new Extensions
|
||||
#################################
|
||||
|
||||
Adding support for a new ISA extension or an adjoining spec to RISCV-CONFIG could entail one or more of the following updates:
|
||||
|
||||
1. Updating the ISA string and its constraints to recognize valid configurations of the new
|
||||
extension
|
||||
2. Updating the schema_isa.yaml with new CSRs defined by the new ISA extension
|
||||
3. Adding new schemas and a new cli argument for supporting adjoining RISC-V specs like debug, trace, etc.
|
||||
|
||||
This chapter will descrive how one can go about RISC-V achieving the above tasks.
|
||||
|
||||
Updates to the ISA string
|
||||
=========================
|
||||
|
||||
Modifications in constants.py
|
||||
----------------------------------------
|
||||
|
||||
As shown in the example below, any new extensions and sub extensions have to be enabled by adding them in
|
||||
the regex expression of the `isa_regex <https://github.com/riscv/riscv-config/blob/master/riscv_config/constants.py>`_ node. Following is an instance of the node
|
||||
for reference:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
Z_extensions = [
|
||||
"Zicbom", "Zicbop", "Zicboz", "Zicsr", "Zifencei", "Zihintpause",
|
||||
"Zam",
|
||||
"Zfh",
|
||||
"Zfinx", "Zdinx", "Zhinx", "Zhinxmin",
|
||||
"Ztso",
|
||||
"Zba", "Zbb", "Zbc", "Zbe", "Zbf", "Zbkb", "Zbkc", "Zbkx", "Zbm", "Zbp", "Zbr", "Zbs", "Zbt",
|
||||
"Zk", "Zkn", "Zknd", "Zkne", "Zknh", "Zkr", "Zks", "Zksed", "Zksh", "Zkt",
|
||||
"Zmmul",
|
||||
"Svnapot"
|
||||
]
|
||||
isa_regex = \
|
||||
re.compile("^RV(32|64|128)[IE][ACDFGHJLMNPQSTUVX]*(("+'|'.join(Z_extensions)+")(_("+'|'.join(Z_extensions)+"))*){,1}$")
|
||||
|
||||
.. note:: If you are adding a new Z extension, note that it must be added to the list (Z_extensions) above the regex.
|
||||
This list will be used to generate the correct matching regex, with two instances of each Z extension; first one
|
||||
immediately after the standard extension in the format `|Zgargle`. This is to support
|
||||
that fact that the new Z extension could start immediately after the standard extensions which an
|
||||
underscore. The second will be after the first set of Z extensions in the format `(_(...|Zgargle)`.
|
||||
|
||||
|
||||
Adding constraints in the isa_validator.py file
|
||||
---------------------------------------------------------
|
||||
|
||||
While adding a new extension to the ISA string, there can be certain legal and illegal combinations which cannot be
|
||||
easily expressed using the regex above. These checks need to be added to the function
|
||||
`get_extension_list <https://github.com/riscv-software-src/riscv-config/blob/master/riscv_config/isa_validator.py#L4>`_
|
||||
present in the `isa_validatory.py` file.
|
||||
|
||||
The above function returns a tuple of 3 elements:
|
||||
|
||||
1. ``extension_list``: A list of all valid extensions that can be extracted from the ISA string.
|
||||
2. ``err``: a boolean value indicating if an error exists in the ISA string
|
||||
3. ``err_list``: A list of all errors encountered during the parsing of the string.
|
||||
|
||||
The function behaves as follows:
|
||||
|
||||
1. The input ISA string is matched against the above regex. A mismatch will cause a return from the
|
||||
function with ``err`` set to True and ``extension_list`` containing the required message
|
||||
(`here <https://github.com/riscv-software-src/riscv-config/blob/master/riscv_config/isa_validator.py#L8-L11>`_).
|
||||
2. Next we split the string into a list where each element is a valid extension (standard,
|
||||
Z-extension or S-extension) present in the ISA string. The ordering of the extensions in the
|
||||
list corresponds to their ordering present in the ISA string (`here <https://github.com/riscv-software-src/riscv-config/blob/master/riscv_config/isa_validator.py#L14-L28>`_).
|
||||
3. We then check for valid canonical ordering of extensions in the ISA string. If any issues are
|
||||
found, then ``err`` is set to True and ``err_list`` is updated with a corresponding error message.
|
||||
(`here <https://github.com/riscv-software-src/riscv-config/blob/master/riscv_config/isa_validator.py#L29-L38>`_)
|
||||
|
||||
4. Similar canonical ordering checks for performed for the Z extension subsets as well
|
||||
(`here <https://github.com/riscv-software-src/riscv-config/blob/master/riscv_config/isa_validator.py#L40-L51>`_).
|
||||
5. Finally, a series of `if` based checks are performed on the ``extension_list`` to see if any
|
||||
illegal combination exists (`here <https://github.com/riscv-software-src/riscv-config/blob/master/riscv_config/isa_validator.py#L53-L58>`_)
|
||||
|
||||
For a majority of new extension additions - only point 5 above needs attention.
|
||||
|
||||
Following is an example of the constraints imposed by the Crypto-Scalar extesions which require
|
||||
additional checks according to point-5 above. The sub-extensions Zkn and Zks are supersets of a
|
||||
combination of other Zk* abbreviations. Thus, if the superset extension exists in the ISA,
|
||||
none of the corresponding subset ZK* should be present in the ISA at the same time.
|
||||
|
||||
|
||||
**Constraints used here** :
|
||||
|
||||
1.If Zkn is present , its subset extensions Zkne, Zknh, Zknd, Zbkc and Zbkb cannot be present in the ISA string.
|
||||
|
||||
2.If Zks is present , its subset extensions Zksed, Zksh, Zbkx, Zbkc and Zbkb cannot be present in the ISA string.
|
||||
|
||||
The pythone snippet to capture the above is presented below:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
(...)
|
||||
if 'Zkn' in extension_list and ( set(['Zbkb', 'Zbkc', 'Zbkx', 'Zkne', 'Zknd', 'Zknh']) & set(extension_list)):
|
||||
err_list.append( "Zkn is a superset of Zbkb, Zbkc, Zbkx, Zkne, Zknd, Zknh. In presence of Zkn the subsets must be ignored in the ISA string.")
|
||||
err = True
|
||||
if 'Zks' in extension_list and ( set(['Zbkb', 'Zbkc', 'Zbkx', 'Zksed', 'Zksh']) & set(extension_list) ):
|
||||
err_list.append( "Zks is a superset of Zbkb, Zbkc, Zbkx, Zksed, Zksh. In presence of Zks the subsets must be ignored in the ISA string.")
|
||||
err = True
|
||||
|
||||
At the end, the function returns the tuple ``(extension_list, err, err_list)``. One should consider
|
||||
treating the contents of the ``extension_list`` as valid, only when ``err`` is set to False.
|
||||
|
||||
Assing new CSR definitions
|
||||
===========================
|
||||
|
||||
There are two parts to addition of a new csr definition to riscv-config
|
||||
|
||||
Addition of new csrs to schema
|
||||
------------------------------
|
||||
|
||||
The first step is to add the schema of the new csr in the `schema_isa.yaml
|
||||
<https://github.com/riscv/riscv-config/blob/master/riscv_config/schemas/schema_isa.yaml>`_ file.
|
||||
Following is an example of how the `stval` csr of the "S" extension is a added to the schema.
|
||||
|
||||
For each csr the author is free to define and re-use existing ``check_with`` functions to impose
|
||||
further legal conditions. These ``check_with`` functions are defined in the file:
|
||||
`schemaValidator.py <https://github.com/riscv/riscv-config/blob/master/riscv_config/schemaValidator.py>`_.
|
||||
|
||||
.. note:: in the schemaValidator the function name must be prefixed with ``_check_with`` followed by
|
||||
the name of the function defined in the ``check_with`` field of the csr.
|
||||
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
stval:
|
||||
type: dict
|
||||
schema:
|
||||
description:
|
||||
type: string
|
||||
default: The stval is a warl register that holds the address of the instruction
|
||||
which caused the exception.
|
||||
address: {type: integer, default: 0x143, allowed: [0x143]}
|
||||
priv_mode: {type: string, default: S, allowed: [S]}
|
||||
reset-val:
|
||||
type: integer
|
||||
default: 0
|
||||
check_with: max_length
|
||||
rv32:
|
||||
type: dict
|
||||
check_with: s_check
|
||||
schema:
|
||||
fields: {type: list, default: []}
|
||||
shadow: {type: string, default: , nullable: True}
|
||||
msb: {type: integer, default: 31, allowed: [31]}
|
||||
lsb: {type: integer, default: 0, allowed: [0]}
|
||||
type:
|
||||
type: dict
|
||||
schema: { warl: *ref_warl }
|
||||
default:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- stval[31:0] in [0x00000000:0xFFFFFFFF]
|
||||
wr_illegal:
|
||||
- unchanged
|
||||
|
||||
accessible:
|
||||
type: boolean
|
||||
default: true
|
||||
check_with: rv32_check
|
||||
default: {accessible: false}
|
||||
rv64:
|
||||
type: dict
|
||||
check_with: s_check
|
||||
schema:
|
||||
fields: {type: list, default: []}
|
||||
shadow: {type: string, default: , nullable: True}
|
||||
msb: {type: integer, default: 63, allowed: [63]}
|
||||
lsb: {type: integer, default: 0, allowed: [0]}
|
||||
type:
|
||||
type: dict
|
||||
schema: { warl: *ref_warl }
|
||||
default:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- stval[63:0] in [0x00000000:0xFFFFFFFFFFFFFFFF]
|
||||
wr_illegal:
|
||||
- unchanged
|
||||
|
||||
accessible:
|
||||
default: true
|
||||
check_with: rv64_check
|
||||
default: {accessible: false}
|
||||
|
||||
The check_with function used in stval above would be defined as follows :
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def _check_with_rv32_check(self, field, value):
|
||||
global xlen
|
||||
if value:
|
||||
if not rv32:
|
||||
self._error( field, "Register cannot be implemented in rv32 mode due to unsupported xlen.")
|
||||
|
||||
def _check_with_rv64_check(self, field, value):
|
||||
global xlen
|
||||
if value:
|
||||
if not rv64:
|
||||
self._error( field, "Register cannot be implemented in rv64 mode due to unsupported xlen.")
|
||||
|
||||
def _check_with_max_length(self, field, value):
|
||||
'''Function to check whether the given value is less than the maximum value that can be stored(2^xlen-1).'''
|
||||
global supported_xlen
|
||||
global extensions
|
||||
maxv = max(supported_xlen)
|
||||
if value > (2**maxv) - 1:
|
||||
self._error(field, "Value exceeds max supported length")
|
||||
|
||||
def _check_with_s_check(self, field, value):
|
||||
s = 18
|
||||
check = False
|
||||
if 'implemented' in value:
|
||||
if value['implemented']:
|
||||
check = True
|
||||
if 'accessible' in value:
|
||||
if value['accessible']:
|
||||
check = True
|
||||
|
||||
if rv64 and check:
|
||||
mxl = format(extensions, '#066b')
|
||||
if (mxl[65 - s:66 - s] != '1'):
|
||||
self._error(field, "should not be implemented since S is not present")
|
||||
|
||||
elif rv32 and check:
|
||||
mxl = format(extensions, '#034b')
|
||||
if (mxl[33 - s:34 - s] != '1'):
|
||||
self._error(field, "should not be implemented S is not present")
|
||||
|
||||
|
||||
|
||||
|
||||
Adding default setters in checker.py
|
||||
------------------------------------
|
||||
|
||||
The next step in adding a new csr definition is to add its default values. This is done in
|
||||
`checker.py <https://github.com/riscv/riscv-config/blob/master/riscv_config/checker.py>`_
|
||||
|
||||
Example of adding a default setter for `stval` is show below. This code basically makes the stval
|
||||
csr accessible by default when the "S" extension is enabled in the ISA string.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
schema_yaml['stval']['default_setter'] = sregsetter
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def sregset():
|
||||
'''Function to set defaults based on presence of 'S' extension.'''
|
||||
global inp_yaml
|
||||
temp = {'rv32': {'accessible': False}, 'rv64': {'accessible': False}}
|
||||
if 'S' in inp_yaml['ISA']:
|
||||
if 32 in inp_yaml['supported_xlen']:
|
||||
temp['rv32']['accessible'] = True
|
||||
if 64 in inp_yaml['supported_xlen']:
|
||||
temp['rv64']['accessible'] = True
|
||||
return temp
|
||||
|
||||
|
||||
|
||||
Adding support for Adjoining RISC-V specs
|
||||
=========================================
|
||||
|
||||
Adding new CLI
|
||||
--------------
|
||||
|
||||
For supporting any new adjoining specs, they need to be supplied via a new cli (command line
|
||||
interface) argument. This new argument needs to be added in the to the parser module in
|
||||
`Utils.py <https://github.com/riscv/riscv-config/tree/master/riscv_config/utils.py#L106>`_.
|
||||
|
||||
The code below shows an example of how the debug spec is added as an argument to the cli parser
|
||||
module:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
parser.add_argument('--debug_spec', '-dspec', type=str, metavar='YAML', default=None, help='The YAML which contains the debug csr specs.')
|
||||
|
||||
|
||||
Adding a new schema
|
||||
-------------------
|
||||
|
||||
Each new adjoining spec must have a YAML schema defined in the `schemas
|
||||
<https://github.com/riscv/riscv-config/tree/master/riscv_config/schemas>`_ directory.
|
||||
|
||||
|
||||
Adding checks through checker.py and SchemaValidator.py
|
||||
-------------------------------------------------------
|
||||
|
||||
The user might want to add more custom checks in checker.py and SchemaValidator.py for the adjoining
|
||||
spec.
|
||||
|
||||
For example the check_debug_specs() is a function that ensures the isa and debug specifications
|
||||
conform to their schemas. For details on check_debug_specs() check here : :ref:`checker`.
|
||||
|
||||
Details on the checks like s_debug_check() and u_debug_check, that can also be added to
|
||||
SchemaValidator.py are here: :ref:`schemaValidator`.
|
||||
|
||||
Modifications in Constants.py
|
||||
-----------------------------
|
||||
|
||||
The new schema must be added in the constants.py to detect its path globally across other files.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
debug_schema = os.path.join(root, 'schemas/schema_debug.yaml')
|
||||
|
||||
Performing new spec checks
|
||||
--------------------------
|
||||
|
||||
Finally, in the main.py file the user must call the relevant functions from checker.py for
|
||||
validating the inputs against the schema.
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
if args.debug_spec is not None:
|
||||
if args.isa_spec is None:
|
||||
logger.error(' Isa spec missing, Compulsory for debug')
|
||||
checker.check_debug_specs(os.path.abspath(args.debug_spec), isa_file, work_dir, True, args.no_anchors)
|
||||
|
||||
|
||||
|
20
vendor/riscv/riscv-config/docs/source/overview.rst
vendored
Normal file
20
vendor/riscv/riscv-config/docs/source/overview.rst
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
########
|
||||
Overview
|
||||
########
|
||||
|
||||
The following diagram captures the overall-flow of RISCV-Config.
|
||||
|
||||
.. image:: riscv_config-flow.png
|
||||
:align: center
|
||||
:alt: riscof-flow
|
||||
|
||||
The user is required to provide 2 YAML files as input:
|
||||
|
||||
1. **ISA Spec**: This YAML file is meant to capture the ISA related features implemented by the user. Details of this input file can be found here : :ref:`isa_yaml_spec`.
|
||||
2. **Platform Spec**: This YAML file is meant to capture the platform specific features implemented by the user. Details of this input file can be found here : :ref:`platform_yaml_spec`.
|
||||
|
||||
Working
|
||||
=======
|
||||
|
||||
The ISA and Platform spec are first checked by the validator for any inconsistencies. Checks like 'F' to exist for 'D' are performed by the validator. The validator exits with an error if any illegal configuration for the spec is provided. Once the validator checks pass, two separate standard yaml files are generated, one for each input type. These standard yaml files contain all fields elaborated and additional info for each node. While the user need not specify all the fields in the input yaml files, the validator will assign defaults to those fields and generate a standard exhaustive yaml for both ISA and Platform spec.
|
||||
|
174
vendor/riscv/riscv-config/docs/source/quickstart.rst
vendored
Normal file
174
vendor/riscv/riscv-config/docs/source/quickstart.rst
vendored
Normal file
|
@ -0,0 +1,174 @@
|
|||
##########
|
||||
Quickstart
|
||||
##########
|
||||
|
||||
This doc is meant to serve as a quick-guide to setup RISCV-CONFIG and perform a \
|
||||
sample validation of target specifications.
|
||||
|
||||
Install Python
|
||||
==============
|
||||
|
||||
RISCV-CONFIG requires `pip` and `python` (>=3.6) to be available on your system.
|
||||
|
||||
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 <user-path>.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 <user-path>.local/lib/python3.6/site-packages/pip (python 3.6)
|
||||
|
||||
|
||||
Using Virtualenv for Python
|
||||
---------------------------
|
||||
|
||||
Many a times folks face issues in installing and managing python versions, which 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 <user-path>.local/lib/python3.6/site-packages/pip (python 3.6)
|
||||
|
||||
|
||||
Install RISCV-CONFIG
|
||||
====================
|
||||
|
||||
.. note:: If you are using a virtual environment make sure to enable that environment before
|
||||
performing the following steps.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ pip3 install riscv-config
|
||||
|
||||
To update an already installed version of RISCV-CONFIG to the latest version:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ pip3 install -U riscv-config
|
||||
|
||||
To checkout a specific version of riscv-config:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ pip3 install riscv-config--1.x.x
|
||||
|
||||
Once you have RISCV-CONFIG installed, executing ``riscv-config --help`` should print the following
|
||||
output ::
|
||||
|
||||
riscv-config [-h] [--version] [--isa_spec YAML] [--platform_spec YAML]
|
||||
[--work_dir DIR] [--verbose]
|
||||
|
||||
RISC-V Configuration Validator
|
||||
|
||||
optional arguments:
|
||||
--isa_spec YAML, -ispec YAML
|
||||
The YAML which contains the ISA specs.
|
||||
--platform_spec YAML, -pspec YAML
|
||||
The YAML which contains the Platfrorm specs.
|
||||
--verbose debug | info | warning | error
|
||||
--version, -v Print version of RISCV-CONFIG being used
|
||||
--work_dir DIR The name of the work dir to dump the output files to.
|
||||
-h, --help show this help message and exit
|
||||
|
||||
RISCV-CONFIG for Developers
|
||||
===========================
|
||||
|
||||
Clone the repository from git and install required dependencies.
|
||||
|
||||
.. note:: you will still need python (>=3.6.0) and pip.
|
||||
If you are using `pyenv` as mentioned above, make sure to enable that environment before
|
||||
performing the following steps.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ git clone https://github.com/riscv/riscv-config.git
|
||||
$ cd riscv-config
|
||||
$ pip3 install -r requirements.txt
|
||||
|
||||
Executing ``python -m riscv-config.main --help`` should display the same help message as above.
|
||||
|
||||
Usage Example
|
||||
=============
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ riscv-config -ispec examples/rv32i_isa.yaml -pspec examples/rv32i_platform.yaml
|
||||
|
||||
Executing the above command should display the following on the terminal:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
[INFO] : Input-ISA file
|
||||
[INFO] : Loading input file: /scratch/git-repo/github/riscv-config/examples/rv32i_isa.yaml
|
||||
[INFO] : Load Schema /scratch/git-repo/github/riscv-config/riscv-config/schemas/schema_isa.yaml
|
||||
[INFO] : Initiating Validation
|
||||
[INFO] : No Syntax errors in Input ISA Yaml. :)
|
||||
[INFO] : Initiating post processing and reset value checks.
|
||||
[INFO] : Dumping out Normalized Checked YAML: /scratch/git-repo/github/riscv-config/riscv_config_work/rv32i_isa_checked.yaml
|
||||
[INFO] : Input-Platform file
|
||||
[INFO] : Loading input file: /scratch/git-repo/github/riscv-config/examples/rv32i_platform.yaml
|
||||
[INFO] : Load Schema /scratch/git-repo/github/riscv-config/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/github/riscv-config/riscv_config_work/rv32i_platform_checked.yaml
|
||||
|
||||
|
7
vendor/riscv/riscv-config/docs/source/revisions.rst
vendored
Normal file
7
vendor/riscv/riscv-config/docs/source/revisions.rst
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
.. raw:: latex
|
||||
|
||||
\pagebreak
|
||||
|
||||
.. _revisions:
|
||||
|
||||
.. mdinclude:: ../../CHANGELOG.md
|
BIN
vendor/riscv/riscv-config/docs/source/riscv_config-flow.png
vendored
Normal file
BIN
vendor/riscv/riscv-config/docs/source/riscv_config-flow.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
33
vendor/riscv/riscv-config/docs/source/schema_custom.rst
vendored
Normal file
33
vendor/riscv/riscv-config/docs/source/schema_custom.rst
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
Any Custom CSR
|
||||
--------------
|
||||
|
||||
All custom CSRs follow the same schema as an architecture-defined CSR.
|
||||
|
||||
uArch signals
|
||||
-------------
|
||||
|
||||
- **^uarch_ signal/group name**
|
||||
|
||||
All signal or group names must contain the ``uarch_`` prefix.
|
||||
|
||||
- **msb**
|
||||
|
||||
An integer value indicating the msb position of the signal.
|
||||
|
||||
- **lsb**
|
||||
|
||||
An integer indicating the lsb position of the group.
|
||||
|
||||
- **reset-val**
|
||||
|
||||
An integer indicating the reset value of a signal/group.
|
||||
In case of a group, this value resides outside the subfields dict.
|
||||
|
||||
- **legal**
|
||||
|
||||
A list of legal values for this signal.
|
||||
|
||||
- **subfields**
|
||||
|
||||
An optional way to structure signals. A subfield would contain msb, lsb, legal fields.
|
||||
|
636
vendor/riscv/riscv-config/docs/source/yaml-specs.rst
vendored
Normal file
636
vendor/riscv/riscv-config/docs/source/yaml-specs.rst
vendored
Normal file
|
@ -0,0 +1,636 @@
|
|||
###################
|
||||
YAML Specifications
|
||||
###################
|
||||
|
||||
This section provides details of the ISA and Platform spec YAML files that need to be provided by the user.
|
||||
|
||||
.. _isa_yaml_spec:
|
||||
|
||||
ISA YAML Spec
|
||||
=============
|
||||
|
||||
.. note::
|
||||
|
||||
All integer fields accept values as integers or hexadecimals (can be used interchangeably) unless specified otherwise.
|
||||
|
||||
Different examples of the input yamls and the generated checked YAMLs can be found here : `Examples <https://github.com/riscv/riscv-config/tree/master/examples>`_
|
||||
|
||||
.. include:: schema_isa.rst
|
||||
.. include:: schema_custom.rst
|
||||
|
||||
CSR Template
|
||||
============
|
||||
All csrs are defined using a common template. Two variants are available: csrs with subfields and
|
||||
those without
|
||||
|
||||
CSRs with sub-fields
|
||||
--------------------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
<name>: # name of the csr
|
||||
description: <text> # textual description of the csr
|
||||
address: <hex> # address of the csr
|
||||
priv_mode: <D/M/H/S/U> # privilege mode that owns the register
|
||||
reset-val: <hex> # Reset value of the register. This an accumulation
|
||||
# of the all reset values of the sub-fields
|
||||
rv32: # this node and its subsequent fields can exist
|
||||
# if [M/S/U]XL value can be 1
|
||||
accessible: <boolean> # indicates if the csr is accessible in rv32 mode or not.
|
||||
# When False, all fields below will be trimmed off
|
||||
# in the checked yaml. False also indicates that
|
||||
# access-exception should be generated.
|
||||
fields: # a quick summary of the list of all fields of the
|
||||
# csr including a list of WPRI fields of the csr.
|
||||
- <field_name1>
|
||||
- <field_name2>
|
||||
- - [23,30] # A list which contains a squashed pair
|
||||
- 6 # (of form [lsb,msb]) of all WPRI bits within the
|
||||
# csr. Does not exist if there are no WPRI bits
|
||||
|
||||
<field_name1>: # name of the field
|
||||
description: <text> # textual description of the csr
|
||||
shadow: <csr-name>::<field> # which this field shadows,'none' indicates that
|
||||
# this field does not shadow anything.
|
||||
shadow_type: <text> # indicates the type of shadowing used. Can be one of -
|
||||
# rw or ro
|
||||
msb: <integer> # msb index of the field. max: 31, min:0
|
||||
lsb: <integer> # lsb index of the field. max: 31, min:0
|
||||
implemented: <boolean> # indicates if the user has implemented this field
|
||||
# or not. When False, all
|
||||
# fields below this will be trimmed.
|
||||
type: # type of field. Can be only one of the following
|
||||
wlrl: [list of value-descriptors] # field is wlrl and the set of legal values.
|
||||
ro_constant: <hex> # field is readonly and will return the same value.
|
||||
ro_variable: True # field is readonly but the value returned depends
|
||||
# on other arch-states
|
||||
warl: # field is warl type. Refer to WARL section
|
||||
dependency_fields: [list]
|
||||
legal: [list of warl-string]
|
||||
wr_illegal: [list of warl-string]
|
||||
rv64: # this node and its subsequent fields can exist
|
||||
# if [M/S/U]XL value can be 2
|
||||
accessible: <boolean> # indicates if this register exists in rv64 mode
|
||||
# or not. Same definition as for rv32 node.
|
||||
rv128: # this node and its subsequent fields can exist if
|
||||
# [M/S/U]XL value can be 3
|
||||
accessible: <boolean> # indicates if this register exists in rv128 mode
|
||||
# or not. Same definition as for rv32 node.
|
||||
|
||||
See register `mstatus` for an example.
|
||||
|
||||
CSRs without sub-fields
|
||||
-----------------------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
<name>: # name of the csr
|
||||
description: <text> # textual description of the csr
|
||||
address: <hex> # address of the csr
|
||||
priv_mode: <D/M/H/S/U> # privilege mode that owns the register
|
||||
reset-val: <hex> # Reset value of the register. This an accumulation
|
||||
# of the all reset values of the sub-fields
|
||||
rv32: # this node and its subsequent fields can exist
|
||||
# if [M/S/U]XL value can be 1
|
||||
accessible: <boolean> # indicates if the csr is accessible in rv32 mode or not.
|
||||
# When False, all fields below will be trimmed off
|
||||
# in the checked yaml. False also indicates that
|
||||
# access-exception should be generated
|
||||
fields: [] # This should be empty always.
|
||||
shadow: <csr-name>::<register> # which this register shadows,'none' indicates that
|
||||
# this register does not shadow anything.
|
||||
shadow_type: <text> # indicates the type of shadowing used. Can be one of -
|
||||
# rw or ro
|
||||
msb: <int> # msb index of the csr. max: 31, min:0
|
||||
lsb: <int> # lsb index of the csr. max: 31, min:0
|
||||
type: # type of field. Can be only one of the following
|
||||
wlrl: [list of value-descriptors] # field is wlrl and the set of legal values.
|
||||
ro_constant: <hex> # field is readonly and will return the same value.
|
||||
ro_variable: True # field is readonly but the value returned depends
|
||||
# on other arch-states
|
||||
warl: # field is warl type. Refer to WARL section
|
||||
dependency_fields: [list]
|
||||
legal: [list of warl-string]
|
||||
wr_illegal: [list of warl-string]
|
||||
rv64: # this node and its subsequent fields can exist
|
||||
# if [M/S/U]XL value can be 2
|
||||
accessible: <boolean> # indicates if this register exists in rv64 mode
|
||||
# or not. Same definition as for rv32 node.
|
||||
rv128: # this node and its subsequent fields can exist if
|
||||
# [M/S/U]XL value can be 3
|
||||
accessible: <boolean> # indicates if this register exists in rv128 mode
|
||||
|
||||
See register `mscratch` for an example.
|
||||
|
||||
Indexed CSRs
|
||||
------------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
<name>: # name of the csr
|
||||
description: <text> # textual description of the csr
|
||||
address: <hex> # address of the csr
|
||||
priv_mode: <D/M/H/S/U> # privilege mode that owns the register
|
||||
indexing_reg: <true/false> # indicates that this register is an indexed type CSR
|
||||
rv32: # this node and its subsequent fields can exist
|
||||
# if [M/S/U]XL value can be 1
|
||||
accessible: <boolean> # indicates if the csr is accessible in rv32 mode or not.
|
||||
# When False, all fields below will be trimmed off
|
||||
# in the checked yaml. False also indicates that
|
||||
# access-exception should be generated
|
||||
msb: <int> # msb index of the csr. max: 31, min:0
|
||||
lsb: <int> # lsb index of the csr. max: 31, min:0
|
||||
index_select_reg: <text> # this field should contain the name the CSR that is used
|
||||
# as an index select register
|
||||
index_list: <dictionary> # this field is a list of dictionaries.
|
||||
- index_val: # value of the index select register that will select
|
||||
# this particular element
|
||||
reset-val: # reset value of this element in the list
|
||||
shadow: <csr-name>::<register> # which this register shadows,'none' indicates that
|
||||
# this register does not shadow anything.
|
||||
shadow_type: <text> # indicates the type of shadowing used. Can be one of -
|
||||
# rw or ro
|
||||
type: # type of field. Can be only one of the following
|
||||
wlrl: [list of value-descriptors] # field is wlrl and the set of legal values.
|
||||
ro_constant: <hex> # field is readonly and will return the same value.
|
||||
ro_variable: True # field is readonly but the value returned depends
|
||||
# on other arch-states
|
||||
warl: # field is warl type. Refer to WARL section
|
||||
dependency_fields: [list]
|
||||
legal: [list of warl-string]
|
||||
wr_illegal: [list of warl-string]
|
||||
rv64: # this node and its subsequent fields can exist
|
||||
# if [M/S/U]XL value can be 2
|
||||
accessible: <boolean> # indicates if this register exists in rv64 mode
|
||||
# or not. Same definition as for rv32 node.
|
||||
rv128: # this node and its subsequent fields can exist if
|
||||
# [M/S/U]XL value can be 3
|
||||
accessible: <boolean> # indicates if this register exists in rv128 mode
|
||||
|
||||
See register `tdata` in debug yaml for an example.
|
||||
|
||||
|
||||
Constraints
|
||||
-----------
|
||||
|
||||
Each csr undergoes the following checks:
|
||||
|
||||
1. All implemented fields at the csr-level, if set to True, are checked if
|
||||
they comply with the supported_xlen field of the ISA yaml.
|
||||
2. The reset-val is checked against compliance with the type field specified
|
||||
by the user. All unimplemented fields are considered to be hardwired to 0.
|
||||
|
||||
For each of the above templates the following fields for all standard csrs
|
||||
defined by the spec are frozen and **CANNOT** be modified by the user.
|
||||
|
||||
* description
|
||||
* address
|
||||
* priv_mode
|
||||
* fields
|
||||
* shadow
|
||||
* msb
|
||||
* lsb
|
||||
* The type field for certain csrs (like readonly) is also constrained.
|
||||
* fields names also cannot be modified for standard csrs
|
||||
|
||||
Only the following fields can be modified by the user:
|
||||
|
||||
* reset-value
|
||||
* type
|
||||
* implemented
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
Following is an example of how a user can define the mtvec csr in the input ISA YAML for a
|
||||
32-bit core:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
mtvec:
|
||||
reset-val: 0x80010000
|
||||
rv32:
|
||||
accessible: true
|
||||
base:
|
||||
implemented: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: [mtvec::mode]
|
||||
legal:
|
||||
- "mode[1:0] in [0] -> base[29:0] in [0x20000000, 0x20004000]" # can take only 2 fixed values in direct mode.
|
||||
- "mode[1:0] in [1] -> base[29:6] in [0x000000:0xF00000] base[5:0] in [0x00]" # 256 byte aligned values only in vectored mode.
|
||||
wr_illegal:
|
||||
- "mode[1:0] in [0] -> Unchanged"
|
||||
- "mode[1:0] in [1] && writeval in [0x2000000:0x4000000] -> 0x2000000"
|
||||
- "mode[1:0] in [1] && writeval in [0x4000001:0x3FFFFFFF] -> Unchanged"
|
||||
mode:
|
||||
implemented: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- "mode[1:0] in [0x0:0x1] # Range of 0 to 1 (inclusive)"
|
||||
wr_illegal:
|
||||
- "Unchanged"
|
||||
|
||||
The following is what the riscv-config will output after performing relevant checks on the
|
||||
above user-input:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
mtvec:
|
||||
description: MXLEN-bit read/write register that holds trap vector configuration.
|
||||
address: 773
|
||||
priv_mode: M
|
||||
reset-val: 0x80010000
|
||||
rv32:
|
||||
accessible: true
|
||||
base:
|
||||
implemented: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: [mtvec::mode, writeval]
|
||||
legal:
|
||||
- 'mode[1:0] in [0] -> base[29:0] in [0x20000000, 0x20004000]' # can take only 2 fixed values in direct mode.
|
||||
- 'mode[1:0] in [1] -> base[29:6] in [0x000000:0xF00000] base[5:0] in [0x00]' # 256 byte aligned values only in vectored mode.
|
||||
wr_illegal:
|
||||
- 'mode[1:0] in [0] -> Unchanged'
|
||||
- 'mode[1:0] in [1] && writeval in [0x2000000:0x4000000] -> 0x2000000'
|
||||
- 'mode[1:0] in [1] && writeval in [0x4000001:0x3FFFFFFF] -> Unchanged'
|
||||
description: Vector base address.
|
||||
shadow: none
|
||||
msb: 31
|
||||
lsb: 2
|
||||
mode:
|
||||
implemented: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- 'mode[1:0] in [0x0:0x1] # Range of 0 to 1 (inclusive)'
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
|
||||
description: Vector mode.
|
||||
shadow: none
|
||||
msb: 1
|
||||
lsb: 0
|
||||
fields:
|
||||
- mode
|
||||
- base
|
||||
rv64:
|
||||
accessible: false
|
||||
|
||||
WARL field Definition
|
||||
=====================
|
||||
|
||||
Since the RISC-V privilege spec indicates several csrs and sub-fields of csrs to be WARL (Write-Any-Read-Legal),
|
||||
it is necessary to provide a common scheme of representation which can precisely
|
||||
define the functionality of any such WARL field/register.
|
||||
|
||||
|
||||
Value Descriptors
|
||||
-----------------
|
||||
|
||||
Value descriptors are standard syntaxes that are used to define values in any
|
||||
part of the WARL string. The 2 basic descriptors are : distinct-values and
|
||||
range-values as described below:
|
||||
|
||||
* **distinct-values** - This specifies that only the particular value should be added to the set.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
val
|
||||
|
||||
* **range** - This specifies that all the values greater than or equal to lower and less than or equal to upper is to be included in the set.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
lower:upper
|
||||
|
||||
For any variable in the WARL string, the values can an amalgamation of
|
||||
distinct-values and/or range-values. They are typically captured in a list as
|
||||
shown in the below examples:
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# To represent the set {0, 1, 2, 3, 4, 5}
|
||||
[0:5]
|
||||
|
||||
# To represent the set {5, 10, 31}
|
||||
[5, 10, 31]
|
||||
|
||||
# To represent the set {2, 3, 4, 5, 10, 11, 12, 13, 50}
|
||||
[2:5, 10:13, 50]
|
||||
|
||||
WARL Node definition
|
||||
--------------------
|
||||
|
||||
A typical WARL node (used for a WARL csr or subfield) has the following skeleton
|
||||
in the riscv-config:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
warl:
|
||||
dependency_fields: [list of csrs/subfields that legal values depend on]
|
||||
legal: [list of strings adhering to the warl-syntax for legal assignments]
|
||||
wr_illegal: [list of strings ahdering to the warl-syntax for illegal assignments]
|
||||
|
||||
- **dependency_fields** : This is a list of csrs/subfields whose values affect
|
||||
the legal values of the csr under question. ``::`` is used as a hierarchy
|
||||
separator to indicate subfields. This list can be empty to indicate that the
|
||||
csr under question is not affected by any other architectural state. The
|
||||
ordering of the csr/subfields has no consequence. Examples of the list are
|
||||
provided below:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- dependency_fields: [mtvec::mode]
|
||||
- dependency_fields: [misa::mxl, mepc]
|
||||
|
||||
The following keywords are reserved and can be used accordingly in the
|
||||
dependency_fields list:
|
||||
|
||||
- ``writeval`` : to represent dependency on the current value being written
|
||||
to the csr/subfield
|
||||
- ``currval`` : to represent dependency on the value of the csr/subfield
|
||||
before performing the write operation
|
||||
|
||||
**Restrictions imposed**: The following restrictions are imposed on the
|
||||
elements of the list:
|
||||
|
||||
1. The csrs/subfields mentioned in the list must have their
|
||||
accessible/implemented fields set to True in the isa yaml.
|
||||
|
||||
**Micro-Architectural Dependencies**
|
||||
|
||||
riscv-config supports the notion of listing micro-architectural dependencies
|
||||
in the dependency_fields list.
|
||||
|
||||
**Listing uArch Dependencies**
|
||||
|
||||
All uArch dependencies need to be listed in the custom specification. An example
|
||||
node has been described as follows:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
uarch_signals:
|
||||
uarch_signal_1:
|
||||
msb: integer
|
||||
lsb: integer
|
||||
reset-val: integer
|
||||
legal: list
|
||||
uarch_signal_2:
|
||||
msb: integer
|
||||
lsb: integer
|
||||
reset-val: integer
|
||||
legal: list
|
||||
uarch_group_1:
|
||||
subfields:
|
||||
uarch_signal_3:
|
||||
msb: integer
|
||||
lsb: integer
|
||||
reset-val: integer
|
||||
legal: list
|
||||
uarch_signal_4:
|
||||
msb: integer
|
||||
lsb: integer
|
||||
reset-val: integer
|
||||
legal: list
|
||||
|
||||
.. note:: The custom csr specification is now validated using a custom_schema.yaml
|
||||
|
||||
**Restrictions imposed**:
|
||||
|
||||
1. uArch depedencies can be listed in either of the two ways,
|
||||
as a uArch group or as an independent list of uArch signals. While using a uArch
|
||||
group, the name of the group must have a ``uarch_`` prefix. The following is
|
||||
an example of a uArch group listed in the dependencies:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
warl:
|
||||
dependency_fields: [uarch_cachecontrol::global_valid, uarch_cachecontrol::global_dirty]
|
||||
legal:
|
||||
- global_valid[3:0] in [0] and global_dirty[3:0] in [0]
|
||||
-> base[61:0] bitmask [0x3FFFFFFFFFFFFFFF, 0x0000000000000000]
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
|
||||
**NOTE**: The above example shows a dependency string only consisting of uArch
|
||||
signals grouped under the name ``uarch_cachecontrol``. We can also include other
|
||||
spec based dependencies in the same list.
|
||||
|
||||
2. While listing the uArch dependencies as an independent list, the name of the
|
||||
uArch signals must not have a ``uarch_`` prefix. The following is an example
|
||||
of a uArch dependency listed as an independent list:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
warl:
|
||||
dependency_fields: [uarch_global_valid, uarch_global_dirty, mstatus::mpp]
|
||||
legal:
|
||||
- uarch_global_valid[3:0] in [0] and uarch_global_dirty[3:0] in [0]
|
||||
-> base[61:0] bitmask [0x3FFFFFFFFFFFFFFF, 0x0000000000000000]
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
|
||||
**NOTE**: In the above example, the uArch signals are listed as independent
|
||||
signals, not grouped under any name. The riscv-config tool will automatically
|
||||
group them under the name ``uarch_signals`` (internally) for ease of
|
||||
parsing the rest of the YAML. These signals would be expected to reside as
|
||||
independent uArch signals in the custom specification.
|
||||
|
||||
**Parsing uArch dependencies**
|
||||
|
||||
riscv-config internally creates a ``uarch_depends`` dictionary in a ``warl_class``
|
||||
object. This dictionary is used to store the uArch dependencies. It performs
|
||||
a lookup on the ``uarch_signals`` node from the custom spec for all checks.
|
||||
None of these dependencies are removed while generating the checked output YAML.
|
||||
|
||||
- **legal** : This field is a list of strings which define the warl functions of
|
||||
the csr/subfield. Each string needs to adhere to the following warl-syntax:
|
||||
|
||||
.. code-block::
|
||||
|
||||
dependency_string -> legal_value_string
|
||||
|
||||
The ``dependency_string`` substring is basically a string defining a boolean
|
||||
condition based on the dependent csrs (those listed in the
|
||||
``dependency_fields``). Only when the boolean condition is satisfied, the
|
||||
corresponding warl function defined in ``legal_value_string`` substring is
|
||||
evaluated. A write only occurs when the evaluation of the
|
||||
``legal_value_string`` also is True. The symbol ``->`` is used to denote
|
||||
`implies` and is primarily used to split the string in to the above two
|
||||
substrings. If none of the entries in the list evaluate to True, then the
|
||||
current write value is considered illegal and the actions defined by the
|
||||
`wr_illegal` field is carried out.
|
||||
|
||||
The substrings ``dependency_string ->`` is optional. If the ``dependency_fields`` list is
|
||||
empty, then the substring ``dependency_string ->`` must be omitted from the warl string.
|
||||
|
||||
The ``dependency_string`` and the ``legal_value_string`` both follow the same
|
||||
legal syntax:
|
||||
|
||||
.. code-block::
|
||||
|
||||
<variable-name>[<hi-index>:<lo-index>] <op> <value-descriptors>
|
||||
|
||||
The ``variable-name`` field can be the name a csr or a subfield (without the
|
||||
hierarchical delimiter ``::``). Within the ``dependency_string`` substring the variable
|
||||
names can only be those listed in the ``dependency_fields`` list. In the
|
||||
``legal_value_string`` substring however, the ``variable-name`` should be
|
||||
either `writeval` or the name the csr or the subfield (without the
|
||||
hierarchical delimiter ``::``) that the warl node belongs to.
|
||||
|
||||
The indices fields ``hi-index`` and ``lo-index`` are used to indicate the bit
|
||||
range of the variable that being looked-up or modified. The basic constraints
|
||||
are that ``hi-index`` must be greater than the ``lo-index``. If only a
|
||||
single-bit is being looked-up/assigned, then ``:lo-index`` can be skipped.
|
||||
This definition applies to both the ``dependency_string`` and the
|
||||
``legal_value_string``.
|
||||
|
||||
The ``op`` field in the ``dependency_string`` substring can be one of ``in``
|
||||
or ``not in`` to indicate that the variable takes the values defined in the
|
||||
``value-descriptors`` field or does not take those values respectively. In
|
||||
addition to the above operators, the ``legal_value_string`` can include one
|
||||
more operator : ``bitmask``. When using the ``bitmask`` operator the
|
||||
value-descriptors have to be a list of two distinct-values as follows:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
csr_name[hi:lo] bitmask [mask, fixedval]
|
||||
|
||||
Both the ``mask`` and ``fixedval`` fields are integers. All bits set in the
|
||||
mask indicates writable bits of the variable. All bits bits cleared in the
|
||||
mask indicate bits with a constant value which is derived from the
|
||||
corresponding bit in the fixedval field.
|
||||
|
||||
Since the ``dependency_string`` is supposed to represent a boolean condition,
|
||||
it also has the flexibility to use basic boolean operators like ``&&`` and
|
||||
``||`` around the above legal syntax. Examples are provided below:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
(csrA[2:0] in [0, 1]) && (csrB[5:0] in [0:25] || csrB[5:0] in [31,30]) ->
|
||||
|
||||
|
||||
**Restrictions imposed**: The following restrictions are imposed on the above
|
||||
substrings:
|
||||
|
||||
1. No element of the value-descriptors must exceed the maximum value which
|
||||
can be supported by the indices of the csr/subfield.
|
||||
2. The csrs/subfields used in the ``dependency_string`` must be in those
|
||||
listed in the ``dependency_fields`` list.
|
||||
3. Valid operators in the ``dependency_string`` substring are ``in`` and ``not in``.
|
||||
4. Valid operators in the ``legal_value_string`` substring are ``in``, ``not in`` and ``bitmask``
|
||||
5. Within the ``legal_value_string`` substrings the legal values of all bits
|
||||
of the csr/subfield must be specified. No bits must be left undefined.
|
||||
6. If the ``dependency_fields`` is empty, then only one legal string must be
|
||||
defined in this list.
|
||||
7. The first combination of the ``dependency_string`` and ``legal_value_string``
|
||||
to evaluate to True, starting from the top of the list is given highest
|
||||
priority to define the next legal value of the csr/subfield.
|
||||
8. The reset-value of the csr/subfield must cause atleast one of the legal
|
||||
strings in the list to evaluate to True.
|
||||
|
||||
**Assumptions**
|
||||
|
||||
1. Since the list of all ``dependency_string`` substrings is not required to
|
||||
be exhaustively defined
|
||||
by the user, if none of the ``dependency_strings`` in the list evaluate to
|
||||
true, then the current write operation should be treated as an illegal
|
||||
write operation, and the action defined by the ``wr_illegal`` node must be
|
||||
carried out.
|
||||
2. If one of the dependent csrs/subfield defined in the
|
||||
``dependency_fields`` is not used in the ``dependency_strings``, then it
|
||||
implictly assumed that, the variable does not affect the legal value for
|
||||
that string
|
||||
|
||||
- **wr_illegal** : This field takes in a list of strings which define the next
|
||||
legal value of the field when an illegal value is being written to the
|
||||
csr/subfield. Each string needs to adhere to the following syntax:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
dependency_string -> update_mode
|
||||
|
||||
The ``dependency_string`` follows the same rules, assumptions and restrictions
|
||||
described above. When the ``dependency_string`` evaluates to True the
|
||||
``update_mode`` substring defines the next legal value of the csr/subfield.
|
||||
The supported values of the ``update_mode`` string are :
|
||||
|
||||
- **Unchanged**: The value remains unchanged to the current legal value held in the csr/subfield.
|
||||
- **<val>**: A single value can also be specified
|
||||
- **Nextup**: ceiling(*writeval*) i.e. the next larger or the largest element of the legal list
|
||||
- **Nextdown**: floor(*writeval*) i.e. the next smallest or the smallest element of the legal list
|
||||
- **Nearup**: celing(*writeval*) i.e. the closest element in the list, with the larger element being chosen in case of a tie.
|
||||
- **Neardown**: floor(*writeval*) i.e. the closes element in the list, with the smaller element being chosen in case of a tie
|
||||
- **Max**: maximum of all legal values
|
||||
- **Min**: minimum of all legal values
|
||||
- **Addr**:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
if ( val < base || val > bound)
|
||||
return Flip-MSB of field
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# When base of mtvec depends on the mode field.
|
||||
WARL:
|
||||
dependency_fields: [mtvec::mode]
|
||||
legal:
|
||||
- "mode[1:0] in [0] -> base[29:0] in [0x20000000, 0x20004000]" # can take only 2 fixed values when mode==0.
|
||||
- "mode[1:0] in [1] -> base[29:6] in [0x000000:0xF00000] base[5:0] in [0x00]" # 256 byte aligned when mode==1
|
||||
wr_illegal:
|
||||
- "mode[1:0] in [0] -> unchanged"
|
||||
- "mode[1:0] in [1] && writeval in [0x2000000:0x4000000] -> 0x2000000" # predefined value if write value is
|
||||
- "mode[1:0] in [1] && writeval in [0x4000001:0x3FFFFFFF] -> unchanged"
|
||||
|
||||
# When base of mtvec depends on the mode field. Using bitmask instead of range
|
||||
WARL:
|
||||
dependency_fields: [mtvec::mode]
|
||||
legal:
|
||||
- "mode[1:0] in [0] -> base[29:0] in [0x20000000, 0x20004000]" # can take only 2 fixed values when mode==0.
|
||||
- "mode[1:0] in [1] -> base[29:0] bitmask [0x3FFFFFC0, 0x00000000]" # 256 byte aligned when mode==1
|
||||
wr_illegal:
|
||||
- "mode[1:0] in [0] -> unchanged" # no illegal for bitmask defined legal strings.
|
||||
- Unchanged
|
||||
|
||||
|
||||
# no dependencies. Mode field of mtvec can take only 2 legal values using range-descriptor
|
||||
WARL:
|
||||
dependency_fields:
|
||||
legal:
|
||||
- "mode[1:0] in [0x0:0x1] # Range of 0 to 1 (inclusive)"
|
||||
wr_illegal:
|
||||
- "0x00"
|
||||
|
||||
# no dependencies. using single-value-descriptors
|
||||
WARL:
|
||||
dependency_fields:
|
||||
legal:
|
||||
- "mode[1:0] in [0x0,0x1] # Range of 0 to 1 (inclusive)"
|
||||
wr_illegal:
|
||||
- "0x00"
|
||||
|
||||
.. _platform_yaml_spec:
|
||||
|
||||
Platform YAML Spec
|
||||
==================
|
||||
|
||||
This section describes each node of the PLATFORM-YAML. For each node, we have identified the fields required from the user and also the various constraints involved.
|
||||
|
||||
.. include:: schema_platform.rst
|
||||
|
||||
Debug YAML Spec
|
||||
===============
|
||||
|
||||
.. include:: schema_debug.rst
|
64
vendor/riscv/riscv-config/examples/rv32i_custom.yaml
vendored
Normal file
64
vendor/riscv/riscv-config/examples/rv32i_custom.yaml
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
hart_ids: [0]
|
||||
hart0:
|
||||
dtim_base:
|
||||
reset-val: 0x0
|
||||
rv64:
|
||||
accessible: false
|
||||
rv32:
|
||||
accessible: true
|
||||
type:
|
||||
ro_constant: 0x0
|
||||
shadow:
|
||||
shadow_type:
|
||||
msb: 31
|
||||
lsb: 0
|
||||
fields:
|
||||
description: dtim base
|
||||
address: 0x7C3
|
||||
priv_mode: M
|
||||
customcontrol:
|
||||
reset-val: 0x7
|
||||
rv64:
|
||||
accessible: false
|
||||
rv32:
|
||||
accessible: true
|
||||
ienable:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0x1
|
||||
description: bit for cache-enable of instruction cache, part of rg_customcontrol
|
||||
shadow:
|
||||
shadow_type:
|
||||
msb: 0
|
||||
lsb: 0
|
||||
denable:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0x1
|
||||
description: bit for cache-enable of data cache, part of rg_customcontrol
|
||||
shadow:
|
||||
shadow_type:
|
||||
msb: 1
|
||||
lsb: 1
|
||||
bpuenable:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0x1
|
||||
description: bit for enabling branch predictor unit, part of rg_customcontrol
|
||||
shadow:
|
||||
shadow_type:
|
||||
msb: 2
|
||||
lsb: 2
|
||||
arith_excep:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0x0
|
||||
description: bit for enabling arithmetic exceptions, part of rg_customcontrol
|
||||
shadow:
|
||||
shadow_type:
|
||||
msb: 3
|
||||
lsb: 3
|
||||
fields:
|
||||
description: the register holds enable bits for arithmetic exceptions, branch predictor unit, i-cache, d-cache units
|
||||
address: 0x800
|
||||
priv_mode: U
|
67
vendor/riscv/riscv-config/examples/rv32i_debug.yaml
vendored
Normal file
67
vendor/riscv/riscv-config/examples/rv32i_debug.yaml
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
hart_ids: [0]
|
||||
hart0: &hart0
|
||||
Debug_Spec_Version: '1.0.0'
|
||||
supported_xlen: [32]
|
||||
debug_mode: true
|
||||
dcsr:
|
||||
reset-val: 0x0
|
||||
rv64:
|
||||
accessible: false
|
||||
rv32:
|
||||
accessible: true
|
||||
prv:
|
||||
implemented: true
|
||||
step:
|
||||
implemented: true
|
||||
nmip:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0x0
|
||||
mprven:
|
||||
implemented: true
|
||||
v:
|
||||
implemented: True
|
||||
type:
|
||||
ro_constant: 0x0
|
||||
cause:
|
||||
implemented: True
|
||||
type:
|
||||
ro_constant: 0x0
|
||||
stoptime:
|
||||
implemented: True
|
||||
stopcount:
|
||||
implemented: True
|
||||
stepie:
|
||||
implemented: True
|
||||
ebreaku:
|
||||
implemented: True
|
||||
ebreaks:
|
||||
implemented: True
|
||||
ebreakm:
|
||||
implemented: True
|
||||
ebreakvu:
|
||||
implemented: True
|
||||
ebreakvs:
|
||||
implemented: True
|
||||
debugver:
|
||||
implemented: True
|
||||
type:
|
||||
ro_constant: 0x0
|
||||
dpc:
|
||||
reset-val: 0x0
|
||||
rv32:
|
||||
accessible: true
|
||||
rv64:
|
||||
accessible: false
|
||||
dscratch0:
|
||||
reset-val: 0x0
|
||||
rv32:
|
||||
accessible: true
|
||||
rv64:
|
||||
accessible: false
|
||||
dscratch1:
|
||||
reset-val: 0x0
|
||||
rv32:
|
||||
accessible: true
|
||||
rv64:
|
||||
accessible: false
|
3091
vendor/riscv/riscv-config/examples/rv32i_isa.yaml
vendored
Normal file
3091
vendor/riscv/riscv-config/examples/rv32i_isa.yaml
vendored
Normal file
File diff suppressed because it is too large
Load diff
8126
vendor/riscv/riscv-config/examples/rv32i_isa_checked.yaml
vendored
Normal file
8126
vendor/riscv/riscv-config/examples/rv32i_isa_checked.yaml
vendored
Normal file
File diff suppressed because it is too large
Load diff
7
vendor/riscv/riscv-config/examples/rv32i_platform.yaml
vendored
Normal file
7
vendor/riscv/riscv-config/examples/rv32i_platform.yaml
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
nmi:
|
||||
label: nmi_vector
|
||||
reset:
|
||||
label: reset_vector
|
||||
mtime:
|
||||
implemented: True
|
||||
address: 0x20000
|
16
vendor/riscv/riscv-config/examples/rv32i_platform_checked.yaml
vendored
Normal file
16
vendor/riscv/riscv-config/examples/rv32i_platform_checked.yaml
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
nmi:
|
||||
label: nmi_vector
|
||||
reset:
|
||||
label: reset_vector
|
||||
mtime:
|
||||
implemented: false
|
||||
mtimecmp:
|
||||
implemented: false
|
||||
mcause_non_standard:
|
||||
implemented: true
|
||||
mtval_condition_writes:
|
||||
implemented: false
|
||||
scause_non_standard:
|
||||
implemented: false
|
||||
stval_condition_writes:
|
||||
implemented: false
|
57
vendor/riscv/riscv-config/examples/rv64i_custom.yaml
vendored
Normal file
57
vendor/riscv/riscv-config/examples/rv64i_custom.yaml
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
hart_ids: [0]
|
||||
hart0:
|
||||
dtim_base:
|
||||
reset-val: 0x0
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
type:
|
||||
ro_constant: 0x0
|
||||
shadow:
|
||||
msb: 63
|
||||
lsb: 0
|
||||
description: dtim base
|
||||
address: 0x7C3
|
||||
priv_mode: M
|
||||
customcontrol:
|
||||
reset-val: 0x7
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
ienable:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0x1
|
||||
description: bit for cache-enable of instruction cache, part of rg_customcontrol
|
||||
shadow:
|
||||
msb: 0
|
||||
lsb: 0
|
||||
denable:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0x1
|
||||
description: bit for cache-enable of data cache, part of rg_customcontrol
|
||||
shadow:
|
||||
msb: 1
|
||||
lsb: 1
|
||||
bpuenable:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0x1
|
||||
description: bit for enabling branch predictor unit, part of rg_customcontrol
|
||||
shadow:
|
||||
msb: 2
|
||||
lsb: 2
|
||||
arith_excep:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0x0
|
||||
description: bit for enabling arithmetic exceptions, part of rg_customcontrol
|
||||
shadow:
|
||||
msb: 3
|
||||
lsb: 3
|
||||
description: the register holds enable bits for arithmetic exceptions, branch predictor unit, i-cache, d-cache units
|
||||
address: 0x800
|
||||
priv_mode: U
|
138
vendor/riscv/riscv-config/examples/rv64i_debug.yaml
vendored
Normal file
138
vendor/riscv/riscv-config/examples/rv64i_debug.yaml
vendored
Normal file
|
@ -0,0 +1,138 @@
|
|||
hart_ids: [0]
|
||||
hart0: &hart0
|
||||
Debug_Spec_Version: '1.0.0'
|
||||
supported_xlen: [64]
|
||||
debug_mode: true
|
||||
parking_loop: 0x800
|
||||
tselect:
|
||||
rv32:
|
||||
accessible: False
|
||||
rv64:
|
||||
accessible: True
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- tselect[63:0] in [0x00000000:0x3]
|
||||
wr_illegal:
|
||||
- unchanged
|
||||
tinfo:
|
||||
rv32:
|
||||
accessible: False
|
||||
rv64:
|
||||
accessible: True
|
||||
index_select_reg: tselect
|
||||
index_list:
|
||||
- reset-val: 0x78
|
||||
index_val: 0
|
||||
shadow:
|
||||
shadow_type:
|
||||
type:
|
||||
ro_constant: 0x78
|
||||
- reset-val: 0x8
|
||||
index_val: 1
|
||||
shadow:
|
||||
shadow_type:
|
||||
type:
|
||||
ro_constant: 0x8
|
||||
- reset-val: 0x10
|
||||
index_val: 2
|
||||
shadow:
|
||||
shadow_type:
|
||||
type:
|
||||
ro_constant: 0x10
|
||||
tdata1:
|
||||
rv32:
|
||||
accessible: False
|
||||
rv64:
|
||||
accessible: True
|
||||
index_select_reg: tselect
|
||||
index_list:
|
||||
- reset-val: 0xdeadbeef
|
||||
index_val: 0
|
||||
shadow:
|
||||
shadow_type:
|
||||
type:
|
||||
ro_constant: 0xdeadbeef
|
||||
- reset-val: 0
|
||||
index_val: 1
|
||||
shadow:
|
||||
shadow_type:
|
||||
type: &mywarl
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- writeval[63:0] in [0x0000000000000000:0xFFFFFFFFFFFFFFFF]
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
- reset-val: 0
|
||||
index_val: 2
|
||||
shadow:
|
||||
shadow_type:
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- writeval[63:0] in [0x0000000000000000:0xFFFFFFFFFFFFFFFF]
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
dcsr:
|
||||
reset-val: 0x40000003
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
prv:
|
||||
implemented: true
|
||||
step:
|
||||
implemented: true
|
||||
nmip:
|
||||
implemented: true
|
||||
type:
|
||||
ro_variable: true
|
||||
mprven:
|
||||
implemented: true
|
||||
v:
|
||||
implemented: True
|
||||
cause:
|
||||
implemented: True
|
||||
type:
|
||||
ro_variable: true
|
||||
stoptime:
|
||||
implemented: True
|
||||
stopcount:
|
||||
implemented: True
|
||||
stepie:
|
||||
implemented: True
|
||||
ebreaku:
|
||||
implemented: True
|
||||
ebreaks:
|
||||
implemented: True
|
||||
ebreakm:
|
||||
implemented: True
|
||||
ebreakvu:
|
||||
implemented: True
|
||||
ebreakvs:
|
||||
implemented: True
|
||||
debugver:
|
||||
implemented: True
|
||||
type:
|
||||
ro_constant: 0x4
|
||||
dpc:
|
||||
reset-val: 0x0
|
||||
rv64:
|
||||
accessible: true
|
||||
rv32:
|
||||
accessible: false
|
||||
dscratch0:
|
||||
reset-val: 0x0
|
||||
rv64:
|
||||
accessible: true
|
||||
rv32:
|
||||
accessible: false
|
||||
dscratch1:
|
||||
reset-val: 0x0
|
||||
rv64:
|
||||
accessible: true
|
||||
rv32:
|
||||
accessible: false
|
449
vendor/riscv/riscv-config/examples/rv64i_isa.yaml
vendored
Normal file
449
vendor/riscv/riscv-config/examples/rv64i_isa.yaml
vendored
Normal file
|
@ -0,0 +1,449 @@
|
|||
hart_ids: [0]
|
||||
hart0:
|
||||
custom_exceptions:
|
||||
- cause_val: 25
|
||||
cause_name: halt_ebreak
|
||||
priv_mode: M
|
||||
- cause_val: 26
|
||||
cause_name: halt_trigger
|
||||
priv_mode: M
|
||||
- cause_val: 28
|
||||
cause_name: halt_step
|
||||
priv_mode: M
|
||||
- cause_val: 29
|
||||
cause_name: halt_reset
|
||||
priv_mode: M
|
||||
custom_interrupts:
|
||||
- cause_val: 16
|
||||
cause_name: debug_interrupt
|
||||
on_reset_enable: 1
|
||||
priv_mode : M
|
||||
ISA: RV64IMAFDCNSUZicsr_Zifencei
|
||||
User_Spec_Version: '2.3'
|
||||
pmp_granularity: 1
|
||||
physical_addr_sz: 32
|
||||
supported_xlen:
|
||||
- 64
|
||||
sscratch:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- sscratch[63:0] in [0x0000000000000000:0xFFFFFFFFFFFFFFFF]
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
|
||||
reset-val: 0
|
||||
sepc:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- "sepc[63:60] in [1,2] spec[59:0] not in [1,2]"
|
||||
wr_illegal:
|
||||
- "Unchanged"
|
||||
reset-val: 0x2000000000000000
|
||||
stval:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- stval[63:0] in [0x0000000000000000:0xFFFFFFFFFFFFFFFF]
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
reset-val: 0
|
||||
scause:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
exception_code:
|
||||
implemented: True
|
||||
interrupt:
|
||||
implemented: True
|
||||
reset-val: 0
|
||||
mepc:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- "mepc[63:0] bitmask [0xFFFFFFFFFFFFFFFE, 0x0000000000000000]"
|
||||
wr_illegal:
|
||||
- "Unchanged"
|
||||
reset-val: 0
|
||||
mtval:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- mtval[63:0] in [0x0000000000000000:0xFFFFFFFFFFFFFFFF]
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
reset-val: 0
|
||||
mcause:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
reset-val: 0
|
||||
mcycle:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- mcycle[63:0] in [0x0000000000000000:0xFFFFFFFFFFFFFFFF]
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
reset-val: 0
|
||||
minstret:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- minstret[63:0] in [0x0000000000000000:0xFFFFFFFFFFFFFFFF]
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
reset-val: 0
|
||||
fcsr:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
fflags:
|
||||
implemented: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- fflags[4:0] in [0x00:0x1F]
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
frm:
|
||||
implemented: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- frm[2:0] in [0x0:0x7]
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
time:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
type:
|
||||
ro_variable: true
|
||||
reset-val: 0
|
||||
mideleg:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- mideleg[63:0] bitmask [0x000000000000F7FF,0x0000000000000000]
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
medeleg:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- medeleg[63:0] bitmask [0x000000000000F7FF,0x0000000000000000]
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
pmpcfg0:
|
||||
reset-val: 0
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
pmp0cfg:
|
||||
implemented: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: [pmpcfg0::pmp0cfg]
|
||||
legal:
|
||||
- "pmp0cfg[7] in [0] -> pmp0cfg[7] in [0x0:0x1] pmp0cfg[6:5] in [0] pmp0cfg[4:3] not in [2] pmp0cfg[2:0] not in [2,6]"
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
pmp1cfg:
|
||||
implemented: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: [pmpcfg0::pmp1cfg]
|
||||
legal:
|
||||
- "pmp1cfg[7] in [0] -> pmp1cfg[7] in [0x0,0x1] pmp1cfg[6:5] in [0] pmp1cfg[4:3] not in [2] pmp1cfg[2:0] not in [2,6]"
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
pmp2cfg:
|
||||
implemented: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: [pmpcfg0::pmp2cfg]
|
||||
legal:
|
||||
- "pmp2cfg[7] in [0] -> pmp2cfg[7] in [0x0,0x1] pmp2cfg[6:5] in [0] pmp2cfg[4:3] not in [2] pmp2cfg[2:0] not in [2,6]"
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
pmp3cfg:
|
||||
implemented: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: [pmpcfg0::pmp3cfg]
|
||||
legal:
|
||||
- "pmp3cfg[7] in [0] -> pmp3cfg[7] in [0x0,0x1] pmp3cfg[6:5] in [0] pmp3cfg[4:3] not in [2] pmp3cfg[2:0] not in [2,6]"
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
pmp4cfg:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0
|
||||
pmp5cfg:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0
|
||||
pmp6cfg:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0
|
||||
pmp7cfg:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0
|
||||
pmpcfg2:
|
||||
reset-val: 0
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
pmp8cfg:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0
|
||||
pmp9cfg:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0
|
||||
pmp10cfg:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0
|
||||
pmp11cfg:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0
|
||||
pmp12cfg:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0
|
||||
pmp13cfg:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0
|
||||
pmp14cfg:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0
|
||||
pmp15cfg:
|
||||
implemented: true
|
||||
type:
|
||||
ro_constant: 0
|
||||
pmpaddr0:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: [pmpcfg0::pmp0cfg]
|
||||
legal:
|
||||
- "pmp0cfg[7] in [0] -> pmpaddr0[63:0] bitmask [0xFFFFFFFFFFFFFFFE,0x0000000000000000]"
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
reset-val: 0
|
||||
pmpaddr1:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: [pmpcfg0::pmp1cfg]
|
||||
legal:
|
||||
- "pmp1cfg[7] in [0] -> pmpaddr1[63:0] bitmask [0xFFFFFFFFFFFFFFFE,0x0000000000000000]"
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
reset-val: 0
|
||||
pmpaddr2:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: [pmpcfg0::pmp2cfg]
|
||||
legal:
|
||||
- "pmp2cfg[7] in [0] -> pmpaddr2[63:0] bitmask [0xFFFFFFFFFFFFFFFE,0x0000000000000000]"
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
reset-val: 0
|
||||
pmpaddr3:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: [pmpcfg0::pmp3cfg]
|
||||
legal:
|
||||
- "pmp3cfg[7] in [0] -> pmpaddr3[63:0] bitmask [0xFFFFFFFFFFFFFFFE,0x0000000000000000]"
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
reset-val: 0
|
||||
pmpaddr4: &pmp_const
|
||||
rv32:
|
||||
accessible: False
|
||||
rv64:
|
||||
accessible: True
|
||||
type:
|
||||
ro_constant : 0
|
||||
pmpaddr5:
|
||||
<<: *pmp_const
|
||||
pmpaddr6:
|
||||
<<: *pmp_const
|
||||
pmpaddr7:
|
||||
<<: *pmp_const
|
||||
pmpaddr8:
|
||||
<<: *pmp_const
|
||||
pmpaddr9:
|
||||
<<: *pmp_const
|
||||
pmpaddr10:
|
||||
<<: *pmp_const
|
||||
pmpaddr11:
|
||||
<<: *pmp_const
|
||||
pmpaddr12:
|
||||
<<: *pmp_const
|
||||
pmpaddr13:
|
||||
<<: *pmp_const
|
||||
pmpaddr14:
|
||||
<<: *pmp_const
|
||||
pmpaddr15:
|
||||
<<: *pmp_const
|
||||
mhpmcounter3:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- "mhpmcounter3[63:0] in [0x0000000000000000:0xFFFFFFFFFFFFFFFF]"
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
reset-val: 0
|
||||
mhpmcounter4:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- "mhpmcounter4[63:0] in [0x0000000000000000:0xFFFFFFFFFFFFFFFF]"
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
reset-val: 0
|
||||
mhpmevent3:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- "mhpmevent3[63:0] in [0x0000000000000000:0x000000000000001C]"
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
reset-val: 0
|
||||
mhpmevent4:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- "mhpmevent4[63:0] in [0x0000000000000000:0x000000000000001C]"
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
reset-val: 0
|
||||
satp:
|
||||
rv32:
|
||||
accessible: false
|
||||
rv64:
|
||||
accessible: true
|
||||
ppn:
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- "ppn[43:0] in [0x00000000000:0xFFFFFFFFFFF]"
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
asid:
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- "asid[15:0] in [0x0000:0x00FF]"
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
mode:
|
||||
type:
|
||||
warl:
|
||||
dependency_fields: []
|
||||
legal:
|
||||
- "mode[3:0] in [0,8]"
|
||||
wr_illegal:
|
||||
- Unchanged
|
||||
reset-val: 0x0000000000000000
|
||||
|
5447
vendor/riscv/riscv-config/examples/rv64i_isa_checked.yaml
vendored
Normal file
5447
vendor/riscv/riscv-config/examples/rv64i_isa_checked.yaml
vendored
Normal file
File diff suppressed because it is too large
Load diff
18
vendor/riscv/riscv-config/examples/rv64i_platform.yaml
vendored
Normal file
18
vendor/riscv/riscv-config/examples/rv64i_platform.yaml
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
nmi:
|
||||
label: nmi_vector
|
||||
address: 12288
|
||||
reset:
|
||||
label: reset_vector
|
||||
address: 16384
|
||||
mtime:
|
||||
implemented: false
|
||||
mtimecmp:
|
||||
implemented: false
|
||||
mcause_non_standard:
|
||||
implemented: true
|
||||
mtval_condition_writes:
|
||||
implemented: false
|
||||
scause_non_standard:
|
||||
implemented: false
|
||||
stval_condition_writes:
|
||||
implemented: false
|
16
vendor/riscv/riscv-config/examples/rv64i_platform_checked.yaml
vendored
Normal file
16
vendor/riscv/riscv-config/examples/rv64i_platform_checked.yaml
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
nmi:
|
||||
label: nmi_vector
|
||||
reset:
|
||||
label: reset_vector
|
||||
mtime:
|
||||
implemented: false
|
||||
mtimecmp:
|
||||
implemented: false
|
||||
mcause_non_standard:
|
||||
implemented: true
|
||||
mtval_condition_writes:
|
||||
implemented: false
|
||||
scause_non_standard:
|
||||
implemented: false
|
||||
stval_condition_writes:
|
||||
implemented: false
|
3
vendor/riscv/riscv-config/requirements.txt
vendored
Normal file
3
vendor/riscv/riscv-config/requirements.txt
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
Cerberus>=1.3.1
|
||||
ruamel.yaml==0.17.16
|
||||
pyyaml==5.2
|
4
vendor/riscv/riscv-config/riscv_config/__init__.py
vendored
Normal file
4
vendor/riscv/riscv-config/riscv_config/__init__.py
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
from pkgutil import extend_path
|
||||
__path__ = extend_path(__path__, __name__)
|
||||
__version__ = '3.18.1'
|
||||
|
2132
vendor/riscv/riscv-config/riscv_config/checker.py
vendored
Normal file
2132
vendor/riscv/riscv-config/riscv_config/checker.py
vendored
Normal file
File diff suppressed because it is too large
Load diff
41
vendor/riscv/riscv-config/riscv_config/constants.py
vendored
Normal file
41
vendor/riscv/riscv-config/riscv_config/constants.py
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
import os
|
||||
import re
|
||||
|
||||
root = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
isa_schema = os.path.join(root, 'schemas/schema_isa.yaml')
|
||||
debug_schema = os.path.join(root, 'schemas/schema_debug.yaml')
|
||||
platform_schema = os.path.join(root, 'schemas/schema_platform.yaml')
|
||||
custom_schema = os.path.join(root, 'schemas/schema_custom.yaml')
|
||||
Zvl_extensions = [
|
||||
"Zvl32b", "Zvl64b", "Zvl128b", "Zvl256b", "Zve512b", "Zvl1024b"
|
||||
]
|
||||
Zvef_extensions = [
|
||||
"Zve32f", "Zve64f"
|
||||
]
|
||||
Zved_extensions = [
|
||||
"Zve64d"
|
||||
]
|
||||
Zve_extensions = [
|
||||
"Zve32x", "Zve64x"
|
||||
] + Zvef_extensions + Zved_extensions
|
||||
|
||||
Z_extensions = [
|
||||
"Zicbom", "Zicbop", "Zicboz", "Zicntr", "Zicsr", "Zicond", "Zicfilp", "Zicfiss", "Zifencei", "Zihintpause", "Zihpm", "Zimop",
|
||||
"Zmmul",
|
||||
"Zam", "Zabha", "Zacas",
|
||||
"Zca", "Zcb", "Zcf", "Zcd" , "Zcmp", "Zcmt", "Zcmop",
|
||||
"Zfh", "Zfa",
|
||||
"Zfinx", "Zdinx", "Zhinx", "Zhinxmin",
|
||||
"Ztso",
|
||||
"Zba", "Zbb", "Zbc", "Zbe", "Zbf", "Zbkb", "Zbkc", "Zbkx", "Zbm", "Zbp", "Zbpbo", "Zbr", "Zbs", "Zbt",
|
||||
"Zk", "Zkn", "Zknd", "Zkne", "Zknh", "Zkr", "Zks", "Zksed", "Zksh", "Zkt",
|
||||
"Zpn", "Zpsf"
|
||||
] + Zve_extensions + Zvl_extensions
|
||||
|
||||
S_extensions = ['Smrnmi','Smdbltrp', 'Ssdbltrp', 'Svnapot','Svadu', 'Sddbltrp', 'Sdext']
|
||||
|
||||
sub_extensions = Z_extensions + S_extensions
|
||||
|
||||
isa_regex = \
|
||||
re.compile("^RV(32|64|128)[IE][ACDFGHJLMNPQSTUV]*(("+'|'.join(sub_extensions)+")(_("+'|'.join(sub_extensions)+"))*){,1}(X[a-z0-9]*)*(_X[a-z0-9]*)*$")
|
29
vendor/riscv/riscv-config/riscv_config/errors.py
vendored
Normal file
29
vendor/riscv/riscv-config/riscv_config/errors.py
vendored
Normal file
|
@ -0,0 +1,29 @@
|
|||
class ValidationError(Exception):
|
||||
|
||||
def __init__(self, message, errors):
|
||||
super().__init__(message)
|
||||
self.message = message
|
||||
self.errors = errors
|
||||
|
||||
def __errPrint__(self, foo, space=' '):
|
||||
'''
|
||||
Function to petty print the error from cerberus.
|
||||
'''
|
||||
error = ''
|
||||
for key in foo.keys():
|
||||
error += space + str(key) + ":"
|
||||
if isinstance(foo[key], list):
|
||||
for e in foo[key]:
|
||||
error += f'\n{space} - {e}'
|
||||
elif isinstance(foo[key][0], dict):
|
||||
error += "\n" + self.__errPrint__(foo[key][0], space + space)
|
||||
elif isinstance(foo[key][0], list):
|
||||
for e in foo[key][0]:
|
||||
error += f'\n{space} - {e}'
|
||||
else:
|
||||
error += str(foo[key][0])
|
||||
error += "\n"
|
||||
return error.rstrip()
|
||||
|
||||
def __str__(self):
|
||||
return self.message + "\n" + self.__errPrint__(self.errors)
|
248
vendor/riscv/riscv-config/riscv_config/isa_validator.py
vendored
Normal file
248
vendor/riscv/riscv-config/riscv_config/isa_validator.py
vendored
Normal file
|
@ -0,0 +1,248 @@
|
|||
import riscv_config.constants as constants
|
||||
from collections import Counter
|
||||
import re
|
||||
|
||||
def get_extension_list(isa):
|
||||
extension_list = []
|
||||
err = False
|
||||
err_list = []
|
||||
if not constants.isa_regex.match(isa):
|
||||
err = True
|
||||
err_list.append(f'Input ISA string : {isa} does not match accepted canonical ordering')
|
||||
return (extension_list, err, err_list)
|
||||
|
||||
|
||||
str_match = re.findall('(?P<stdisa>[^\d]*?)(?!_)*(?P<zext>Z.*?)*(?P<sext>S[a-z]*)*(?P<xext>X[a-z0-9]*)*(_|$)',isa)
|
||||
extension_list= []
|
||||
standard_isa = ''
|
||||
zext_list = []
|
||||
for match in str_match:
|
||||
stdisa, zext, sext, xext, ignore = match
|
||||
if stdisa != '':
|
||||
for e in stdisa:
|
||||
extension_list.append(e)
|
||||
standard_isa = stdisa
|
||||
if zext != '':
|
||||
extension_list.append(zext)
|
||||
zext_list.append(zext)
|
||||
if sext != '':
|
||||
extension_list.append(sext)
|
||||
if xext != '':
|
||||
extension_list.append(xext)
|
||||
# check for duplicates
|
||||
counts = Counter(extension_list)
|
||||
duplicate_list = list([item for item in counts if counts[item]>1])
|
||||
if duplicate_list:
|
||||
err = True
|
||||
err_list.append(f'Found duplicate extensions in ISA string: {duplicate_list}')
|
||||
return (extension_list, err, err_list)
|
||||
|
||||
# check ordering of ISA
|
||||
canonical_ordering = 'IEMAFDQLCBJKTPVNSHU'
|
||||
order_index = {c: i for i, c in enumerate(canonical_ordering)}
|
||||
for i in range(len(standard_isa)-1):
|
||||
a1 = standard_isa[i]
|
||||
a2 = standard_isa[i+1]
|
||||
|
||||
if order_index[a1] > order_index[a2]:
|
||||
err = True
|
||||
err_list.append( "Alphabet '" + a1 + "' should occur after '" + a2)
|
||||
|
||||
# check canonical ordering within Zextensions
|
||||
for i in range(len(zext_list)-1):
|
||||
a1 = zext_list[i][1].upper()
|
||||
a2 = zext_list[i+1][1].upper()
|
||||
a3 = zext_list[i][2]
|
||||
a4 = zext_list[i+1][2]
|
||||
if order_index[a1] > order_index[a2]:
|
||||
err = True
|
||||
err_list.append( f"Z extension {zext_list[i]} must occur after {zext_list[i+1]}")
|
||||
elif a1 == a2 and a3 > a4:
|
||||
err = True
|
||||
err_list.append( f"Within the Z{a1.lower()} category extension {zext_list[i]} must occur after {zext_list[i+1]}")
|
||||
|
||||
if 'I' not in extension_list and 'E' not in extension_list:
|
||||
err_list.append( 'Either of I or E base extensions need to be present in the ISA string')
|
||||
err = True
|
||||
if 'F' in extension_list and not "Zicsr" in extension_list:
|
||||
err_list.append( "F cannot exist without Zicsr.")
|
||||
err = True
|
||||
if 'D' in extension_list and not 'F' in extension_list:
|
||||
err_list.append( "D cannot exist without F.")
|
||||
err = True
|
||||
if 'Q' in extension_list and not 'D' in extension_list:
|
||||
err_list.append( "Q cannot exist without D and F.")
|
||||
err = True
|
||||
if 'Zam' in extension_list and not 'A' in extension_list:
|
||||
err_list.append( "Zam cannot exist without A.")
|
||||
err = True
|
||||
if 'N' in extension_list and not 'U' in extension_list:
|
||||
err_list.append( "N cannot exist without U.")
|
||||
err = True
|
||||
if 'S' in extension_list and not 'U' in extension_list:
|
||||
err_list.append( "S cannot exist without U.")
|
||||
err = True
|
||||
if 'Zkn' in extension_list and ( set(['Zbkb', 'Zbkc', 'Zbkx', 'Zkne', 'Zknd', 'Zknh']) & set(extension_list)):
|
||||
err_list.append( "Zkn is a superset of Zbkb, Zbkc, Zbkx, Zkne, Zknd, Zknh. In presence of Zkn the subsets must be ignored in the ISA string.")
|
||||
err = True
|
||||
if 'Zks' in extension_list and ( set(['Zbkb', 'Zbkc', 'Zbkx', 'Zksed', 'Zksh']) & set(extension_list) ):
|
||||
err_list.append( "Zks is a superset of Zbkb, Zbkc, Zbkx, Zksed, Zksh. In presence of Zks the subsets must be ignored in the ISA string.")
|
||||
err = True
|
||||
if 'Zk' in extension_list and ( set(['Zbkb', 'Zbkc', 'Zbkx', 'Zkne', 'Zknd',
|
||||
'Zknh', 'Zkn','Zkr','Zkt']) & set(extension_list)):
|
||||
err_list.append( "Zk is a superset of Zbkb, Zbkc, Zbkx, Zkne, Zknd, Zknh, Zkn, Zkt, Zkr. In presence of Zk the subsets must be ignored in the ISA string.")
|
||||
err = True
|
||||
if 'Zfinx' in extension_list and not "Zicsr" in extension_list:
|
||||
err_list.append( "Zfinx cannot exist without Zicsr.")
|
||||
err = True
|
||||
if 'F' in extension_list and "Zfinx" in extension_list:
|
||||
err_list.append( "F and Zfinx cannot exist together")
|
||||
err = True
|
||||
if 'Zdinx' in extension_list and not 'Zfinx' in extension_list:
|
||||
err_list.append( "Zdinx cannot exist without Zfinx.")
|
||||
err = True
|
||||
if 'Zhinx' in extension_list and not 'Zfinx' in extension_list:
|
||||
err_list.append( "Zhinx cannot exist without Zfinx.")
|
||||
err = True
|
||||
if 'Zhinx' in extension_list and 'Zfh' in extension_list:
|
||||
err_list.append( "Zhinx and Zfh cannot exist together.")
|
||||
err = True
|
||||
if 'Zhinxmin' in extension_list and not 'Zfinx' in extension_list:
|
||||
err_list.append( "Zhinxmin cannot exist without Zfinx.")
|
||||
err = True
|
||||
if 'Zhinxmin' in extension_list and 'Zfh' in extension_list:
|
||||
err_list.append( "Zhinxmin and Zfh cannot exist together.")
|
||||
err = True
|
||||
if 'Zfa' in extension_list and not 'Zfh' in extension_list:
|
||||
err_list.append( "Zfa cannot exist without Zfh.")
|
||||
if 'Zbpbo' in extension_list :
|
||||
if not 'Zpn' in extension_list :
|
||||
err_list.append( "'Zpn' is required.")
|
||||
err = True
|
||||
if 'Zpn' in extension_list :
|
||||
if not 'Zbpbo' in extension_list :
|
||||
err_list.append( "'Zbpbo' is required.")
|
||||
err = True
|
||||
if '64' in isa and not 'Zpsf' in extension_list :
|
||||
err_list.append( "RV64 requires 'Zpsf'.")
|
||||
err = True
|
||||
if not ('M' in extension_list or 'Zmmul' in extension_list):
|
||||
err_list.append("baseline multiplication extension not found.")
|
||||
if 'Zpsf' in extension_list and not err :
|
||||
if not 'Zbpbo' in extension_list :
|
||||
err_list.append( "'Zbpbo' is required.")
|
||||
err = True
|
||||
if not 'Zpn' in extension_list :
|
||||
err_list.append( "'Zpn' is required.")
|
||||
err = True
|
||||
|
||||
# Check V extensions
|
||||
if 'V' in extension_list and 'D' not in extension_list:
|
||||
err_list.append("V cannot exist without D and F.")
|
||||
err = True
|
||||
if len(set(['V'] + constants.Zve_extensions) & set(extension_list)) > 1:
|
||||
err_list.append(f"V and Zve* cannot exist together.")
|
||||
err = True
|
||||
if (set(constants.Zvl_extensions) & set(extension_list)) and not (
|
||||
set(['V'] + constants.Zve_extensions) & set(extension_list)
|
||||
):
|
||||
err_list.append("Zvl* cannot exist without V or Zve*.")
|
||||
err = True
|
||||
if set(constants.Zvef_extensions) & set(extension_list) and (
|
||||
{"F", "Zfinx"} & set(extension_list)
|
||||
):
|
||||
err_list.append("Zve*f cannot exist without F or Zfinx.")
|
||||
err = True
|
||||
if (set(constants.Zved_extensions) & set(extension_list)) and not (
|
||||
{"D", "Zdinx"} & set(extension_list)
|
||||
):
|
||||
err_list.append("Zve64d cannot exist without D or Zdinx.")
|
||||
err = True
|
||||
|
||||
return (extension_list, err, err_list)
|
||||
|
||||
def get_march_mabi (isa : str, opt_remove_custom_exts: bool = False):
|
||||
'''
|
||||
This function returns the corresponding march and mabi argument values
|
||||
for RISC-V GCC
|
||||
|
||||
arguments:
|
||||
isa: (string) this is the isa string in canonical order
|
||||
|
||||
returns:
|
||||
march: (string) this is the string to be passed to -march to gcc for a given isa
|
||||
mabi: (string) this is the string to be passed to -mabi for given isa
|
||||
march_list: (list) gives march as a list of all extensions as elements
|
||||
None: if ISA validation throws error
|
||||
'''
|
||||
|
||||
# march generation
|
||||
|
||||
march = 'rv32' if '32' in isa else 'rv64'
|
||||
march_list = []
|
||||
march_list.append(march)
|
||||
|
||||
# get extension list
|
||||
(ext_list, err, err_list) = get_extension_list(isa)
|
||||
|
||||
# if isa validation throws errors, return None
|
||||
if err:
|
||||
return None
|
||||
|
||||
# extensions to be nullified
|
||||
null_ext = [
|
||||
# privilege modes
|
||||
'U',
|
||||
'S',
|
||||
|
||||
# rnmi
|
||||
'Smrnmi',
|
||||
|
||||
# debug mode
|
||||
'Sdext',
|
||||
|
||||
# performance counter
|
||||
'Zicntr',
|
||||
'Zihpm',
|
||||
|
||||
# unratified Zb* extensions
|
||||
'Zbe',
|
||||
'Zbf',
|
||||
'Zbm',
|
||||
'Zbr',
|
||||
]
|
||||
|
||||
# add Zbp and Zbt to null_ext if Zbpbo is present
|
||||
if 'Zbpbo' in ext_list:
|
||||
null_ext += ['Zbp', 'Zbt']
|
||||
|
||||
# remove all custom extensions
|
||||
for ext in ext_list:
|
||||
if ext.startswith('X'):
|
||||
if opt_remove_custom_exts:
|
||||
ext_list.remove(ext)
|
||||
|
||||
# construct march
|
||||
for ext in ext_list:
|
||||
if ext not in null_ext:
|
||||
march_list.append(ext.lower())
|
||||
# suffix multicharacter extensions with '_'
|
||||
if len(ext) == 1:
|
||||
march += ext.lower()
|
||||
else:
|
||||
# suffix multiline extensions with '_'
|
||||
march = march + '_' + ext.lower()
|
||||
|
||||
# mabi generation
|
||||
mabi = 'ilp32'
|
||||
if 'E' in ext_list:
|
||||
mabi += 'e'
|
||||
if 'F' in ext_list and 'D' in ext_list:
|
||||
mabi += 'd'
|
||||
elif 'F' in ext_list:
|
||||
mabi += 'f'
|
||||
|
||||
if 'rv64' in march:
|
||||
mabi = mabi.replace('ilp32', 'lp64')
|
||||
|
||||
return (march, mabi, march_list)
|
60
vendor/riscv/riscv-config/riscv_config/main.py
vendored
Normal file
60
vendor/riscv/riscv-config/riscv_config/main.py
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
import logging
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
from riscv_config import __version__ as version
|
||||
import riscv_config.checker as checker
|
||||
import riscv_config.utils as utils
|
||||
from riscv_config.errors import ValidationError
|
||||
|
||||
def main():
|
||||
'''
|
||||
Entry point for riscv_config.
|
||||
'''
|
||||
# Set up the parser
|
||||
parser = utils.riscv_config_cmdline_args()
|
||||
args = parser.parse_args()
|
||||
if len(sys.argv) < 2:
|
||||
parser.print_help()
|
||||
raise SystemExit
|
||||
if (args.version):
|
||||
print('RISCV-CONFIG: RISC-V Configuration Validator')
|
||||
print('Version: ' + version)
|
||||
return 0
|
||||
|
||||
# Set up the logger
|
||||
utils.setup_logging(args.verbose)
|
||||
logger = logging.getLogger()
|
||||
logger.handlers = []
|
||||
ch = logging.StreamHandler()
|
||||
ch.setFormatter(utils.ColoredFormatter())
|
||||
logger.addHandler(ch)
|
||||
fh = logging.FileHandler('run.log', 'w')
|
||||
logger.addHandler(fh)
|
||||
|
||||
work_dir = os.path.join(os.getcwd(), args.work_dir)
|
||||
if not os.path.exists(work_dir):
|
||||
logger.debug('Creating new work directory: ' + work_dir)
|
||||
os.mkdir(work_dir)
|
||||
|
||||
try:
|
||||
checked_specs = checker.check_csr_specs(ispec=args.isa_spec,
|
||||
customspec=args.custom_spec,
|
||||
dspec=args.debug_spec,
|
||||
pspec=args.platform_spec,
|
||||
work_dir=work_dir,
|
||||
logging=True,
|
||||
no_anchors=args.no_anchors)
|
||||
isa_file = checked_specs[0]
|
||||
custom_file = checked_specs[1]
|
||||
debug_file = checked_specs[2]
|
||||
platform_file = checked_specs[3]
|
||||
except ValidationError as msg:
|
||||
logger.error(str(msg))
|
||||
return 1
|
||||
|
||||
logger.info('Done.')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
exit(main())
|
450
vendor/riscv/riscv-config/riscv_config/schemaValidator.py
vendored
Normal file
450
vendor/riscv/riscv-config/riscv_config/schemaValidator.py
vendored
Normal file
|
@ -0,0 +1,450 @@
|
|||
from cerberus import Validator
|
||||
import riscv_config.constants as constants
|
||||
from riscv_config.isa_validator import *
|
||||
import re
|
||||
from riscv_config.warl import warl_class
|
||||
|
||||
|
||||
class schemaValidator(Validator):
|
||||
''' Custom validator for schema having the custom rules necessary for implementation and checks.'''
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
global rv32
|
||||
global rv64
|
||||
global extensions
|
||||
global xlen
|
||||
global supported_xlen
|
||||
supported_xlen = kwargs.get('xlen')
|
||||
xlen = 0 if len(supported_xlen)==0 else max(supported_xlen)
|
||||
global isa_string
|
||||
isa_string = kwargs.get('isa_string')
|
||||
global extension_list
|
||||
global ext_err
|
||||
global ext_err_list
|
||||
if isa_string :
|
||||
(extension_list, ext_err, ext_err_list) = get_extension_list(isa_string)
|
||||
if 32 in supported_xlen:
|
||||
rv32 = True
|
||||
else:
|
||||
rv32 = False
|
||||
if 64 in supported_xlen:
|
||||
rv64 = True
|
||||
else:
|
||||
rv64 = False
|
||||
super(schemaValidator, self).__init__(*args, **kwargs)
|
||||
|
||||
def _check_with_smrnmi_check(self, field, value):
|
||||
global extension_list
|
||||
if value and 'Smrnmi' not in extension_list:
|
||||
self._error(field,
|
||||
"Register cannot be implemented without Smrnmi extension in ISA."
|
||||
)
|
||||
|
||||
def _check_with_zicfiss_check(self, field, value):
|
||||
global extension_list
|
||||
if value and 'Zicfiss' not in extension_list:
|
||||
self._error(field,
|
||||
"Register cannot be implemented without Zicfiss extension in ISA."
|
||||
)
|
||||
|
||||
def _check_with_satp_modes64(self, field, value):
|
||||
pass
|
||||
|
||||
def _check_with_isa_xlen(self, field, value):
|
||||
global supported_xlen
|
||||
global isa_string
|
||||
if str(max(supported_xlen)) not in isa_string:
|
||||
self._error(field, 'XLEN in ISA and supported_xlen fields do not match')
|
||||
|
||||
def _check_with_phy_addr(self, field, value):
|
||||
if rv32 and value > 34:
|
||||
self._error(field, "Physical address size should not exceed 34 for RV32")
|
||||
if rv64 and value > 56:
|
||||
self._error(field, "Physical address size should not exceed 56 for RV64")
|
||||
|
||||
def _check_with_cache_block_size(self, field, value):
|
||||
if value & (value - 1) != 0:
|
||||
self._error(field, "Cache block size should be power of 2")
|
||||
|
||||
def _check_with_cannot_be_false_rv64(self, field, value):
|
||||
''' Functions ensures that the field cannot be False in rv64 mode'''
|
||||
if rv64 and not value:
|
||||
self._error(field, "This field cannot be False")
|
||||
def _check_with_cannot_be_false_rv64f(self, field, value):
|
||||
''' Functions ensures that the field cannot be False in rv64 mode when F is present'''
|
||||
global extension_list
|
||||
if rv64 and 'F' in extension_list and not value:
|
||||
self._error(field, "This field cannot be False")
|
||||
def _check_with_cannot_be_false_rv32f(self, field, value):
|
||||
''' Functions ensures that the field cannot be False in rv32 mode when F is present'''
|
||||
if rv32 and 'F' in extension_list and not value:
|
||||
self._error(field, "This field cannot be False")
|
||||
|
||||
def _check_with_cannot_be_false_rv32(self, field, value):
|
||||
''' Functions ensures that the field cannot be False in rv32 mode'''
|
||||
if rv32 and not value:
|
||||
self._error(field, "This field cannot be False")
|
||||
|
||||
def _check_with_capture_isa_specifics(self, field, value):
|
||||
'''
|
||||
Function to extract and store ISA specific information(such as xlen,user
|
||||
spec version and extensions present)
|
||||
and check whether the dependencies in ISA extensions are satisfied.
|
||||
'''
|
||||
global xlen
|
||||
global extensions
|
||||
global extension_list
|
||||
global ext_err_list
|
||||
global ext_err
|
||||
extension_enc = list("00000000000000000000000000")
|
||||
if "32" in value:
|
||||
xlen = 32
|
||||
ext = value[4:]
|
||||
elif "64" in value:
|
||||
xlen = 64
|
||||
ext = value[4:]
|
||||
elif "128" in value:
|
||||
xlen = 128
|
||||
ext = value[5:]
|
||||
else:
|
||||
self._error(field, "Invalid width in ISA.")
|
||||
|
||||
if not constants.isa_regex.match(value):
|
||||
self._error(field, 'Input ISA string does not match regex')
|
||||
if ext_err:
|
||||
for e in ext_err_list:
|
||||
self._error(field, e)
|
||||
|
||||
#ISA encoding for future use.
|
||||
for x in "ABCDEFHIJKLMNPQSTUVX":
|
||||
if (x in extension_list):
|
||||
extension_enc[25 - int(ord(x) - ord('A'))] = "1"
|
||||
extensions = int("".join(extension_enc), 2)
|
||||
extensions = int("".join(extension_enc), 2)
|
||||
|
||||
def _check_with_rv32_check(self, field, value):
|
||||
global xlen
|
||||
if value:
|
||||
if not rv32:
|
||||
self._error(
|
||||
field,
|
||||
"Register cannot be implemented in rv32 mode due to unsupported xlen."
|
||||
)
|
||||
|
||||
def _check_with_rv64_check(self, field, value):
|
||||
global xlen
|
||||
if value:
|
||||
if not rv64:
|
||||
self._error(
|
||||
field,
|
||||
"Register cannot be implemented in rv64 mode due to unsupported xlen."
|
||||
)
|
||||
|
||||
def _check_with_max_length(self, field, value):
|
||||
'''Function to check whether the given value is less than the maximum value that can be stored(2^xlen-1).'''
|
||||
global supported_xlen
|
||||
global extensions
|
||||
maxv = max(supported_xlen)
|
||||
if value > (2**maxv) - 1:
|
||||
self._error(field, "Value exceeds max supported length")
|
||||
|
||||
def _check_with_max_length32(self, field, value):
|
||||
'''Function to check whether the given value is less than the maximum value that can be stored(2^xlen-1).'''
|
||||
maxv = 32
|
||||
if value > (2**maxv) - 1:
|
||||
self._error(field, "Value exceeds max supported length")
|
||||
|
||||
def _check_with_xtveccheck(self, field, value):
|
||||
'''Function to check whether the inputs in range type in mtvec are valid.'''
|
||||
global xlen
|
||||
maxv = 2**(xlen - 2)
|
||||
for list in value:
|
||||
if (len(list) > 2):
|
||||
self._error(field,
|
||||
"Only two values are allowed in each sub list.")
|
||||
for val in list:
|
||||
if not (val < maxv):
|
||||
self._error(field, "Invalid values.")
|
||||
|
||||
def _check_with_s_exists(self, field, value):
|
||||
'''Function to check that the value can be true only when 'S' mode
|
||||
exists in the ISA string'''
|
||||
global extension_list
|
||||
|
||||
if value and 'S' not in extension_list:
|
||||
self._error(field, "cannot be set to True without 'S' mode support")
|
||||
|
||||
def _check_with_mtval_update(self, field, value):
|
||||
'''Function to check if the mtval_update bitmap adhered to the required
|
||||
restrictions.
|
||||
'''
|
||||
global extension_list
|
||||
if (((value & 0xFFFF000F4000) != 0) or (value > 0xFFFFFFFFFFFFFFFF)):
|
||||
self._error(field, 'Bits corresponding to reserved cause values should not be set')
|
||||
if (value & 0xB000) != 0 and 'S' not in extension_list:
|
||||
self._error(field, 'Bits corresponding to page-faults can only be set when S mode is supported')
|
||||
if (value & 0xF00000) != 0 and 'H' not in extension_list:
|
||||
self._error(field, 'Bits corresponding to guest-page faults can only be set when H mode is supported')
|
||||
|
||||
def _check_with_s_check(self, field, value):
|
||||
s = 18
|
||||
check = False
|
||||
if 'implemented' in value:
|
||||
if value['implemented']:
|
||||
check = True
|
||||
if 'accessible' in value:
|
||||
if value['accessible']:
|
||||
check = True
|
||||
|
||||
if rv64 and check:
|
||||
mxl = format(extensions, '#066b')
|
||||
if (mxl[65 - s:66 - s] != '1'):
|
||||
self._error(field, "should not be implemented since S is not present")
|
||||
|
||||
elif rv32 and check:
|
||||
mxl = format(extensions, '#034b')
|
||||
if (mxl[33 - s:34 - s] != '1'):
|
||||
self._error(field, "should not be implemented S is not present")
|
||||
|
||||
def _check_with_fs_check(self, field, value):
|
||||
f = 5
|
||||
s = 18
|
||||
check = False
|
||||
if 'implemented' in value:
|
||||
if value['implemented']:
|
||||
check = True
|
||||
if 'accessible' in value:
|
||||
if value['accessible']:
|
||||
check = True
|
||||
|
||||
if rv64 and check:
|
||||
mxl = format(extensions, '#066b')
|
||||
if (mxl[65 - s:66 - s] != '1') and (mxl[65 - f:66 - f] != '1'):
|
||||
self._error(field, "neither S nor F is present")
|
||||
|
||||
elif rv32 and check:
|
||||
mxl = format(extensions, '#034b')
|
||||
if (mxl[33 - s:34 - s] != '1') and (mxl[33 - f:34 - f] != '1'):
|
||||
self._error(field, "neither S nor F is present")
|
||||
|
||||
|
||||
def _check_with_f_check(self, field, value):
|
||||
f = 5
|
||||
check = False
|
||||
if 'implemented' in value:
|
||||
if value['implemented']:
|
||||
check = True
|
||||
if 'accessible' in value:
|
||||
if value['accessible']:
|
||||
check = True
|
||||
if rv64 and check:
|
||||
mxl = format(extensions, '#066b')
|
||||
if (mxl[65 - f:66 - f] != '1'):
|
||||
self._error(field, "should not be implemented since F is not present")
|
||||
elif rv32 and check:
|
||||
mxl = format(extensions, '#034b')
|
||||
if (mxl[33 - f:34 - f] != '1'):
|
||||
self._error(field, "should not be implemented since F is not present")
|
||||
|
||||
|
||||
def _check_with_u_check(self, field, value):
|
||||
u = 20
|
||||
check = False
|
||||
if 'implemented' in value:
|
||||
if value['implemented']:
|
||||
check = True
|
||||
if 'accessible' in value:
|
||||
if value['accessible']:
|
||||
check = True
|
||||
if rv64 and check:
|
||||
mxl = format(extensions, '#066b')
|
||||
if (mxl[65 - u:66 - u] != '1'):
|
||||
self._error(field, "should not be implemented since U is not present")
|
||||
|
||||
elif rv32 and check:
|
||||
mxl = format(extensions, '#034b')
|
||||
if (mxl[33 - u:34 - u] != '1'):
|
||||
self._error(field, "should not be implemented since U is not present")
|
||||
|
||||
def _check_with_s_debug_check(self, field, value):
|
||||
''' Function ensures that the ro_constant is hardwired to zero when S is present in the ISA string
|
||||
Used mainly for debug schema'''
|
||||
global extension_list
|
||||
|
||||
if 'S' not in extension_list :
|
||||
if 'ro_constant' not in value:
|
||||
self._error(field, "S is not present to dcsr.v should be ro_constant = 0")
|
||||
elif value['ro_constant'] != 0:
|
||||
self._error(field, "S is not present but ro constant is not hardwired to zero")
|
||||
|
||||
def _check_with_u_debug_check(self, field, value):
|
||||
''' Function ensures that the ro_constant is hardwired to zero when U is present in the ISA string
|
||||
Used mainly for debug schema'''
|
||||
global extension_list
|
||||
|
||||
if 'U' not in extension_list :
|
||||
if value['ro_constant'] != 0:
|
||||
self._error(field, "U is not present but ro constant is not hardwired to zero")
|
||||
|
||||
def _check_with_su_check(self, field, value):
|
||||
s = 18
|
||||
u = 20
|
||||
check = False
|
||||
if 'implemented' in value:
|
||||
if value['implemented']:
|
||||
check = True
|
||||
if 'accessible' in value:
|
||||
if value['accessible']:
|
||||
check = True
|
||||
|
||||
if rv64 and check:
|
||||
mxl = format(extensions, '#066b')
|
||||
if (mxl[65 - s:66 - s] != '1') and (mxl[65 - u:66 - u] != '1'):
|
||||
self._error(field, "neither S nor U is present")
|
||||
|
||||
elif rv32 and check:
|
||||
mxl = format(extensions, '#034b')
|
||||
if (mxl[33 - s:34 - s] != '1') and (mxl[33 - u:34 - u] != '1'):
|
||||
self._error(field, "neither S nor U is present")
|
||||
|
||||
def _check_with_reset_ext(self, field, value):
|
||||
|
||||
if rv64:
|
||||
mxl = format(extensions, '#066b')
|
||||
reset = format(value, '#066b')
|
||||
if (mxl[40:66] != reset[40:66] ):
|
||||
self._error(field, "reset value does not match with extensions enabled")
|
||||
|
||||
elif rv32 :
|
||||
mxl = format(extensions, '#034b')
|
||||
reset = format(value, '#034b')
|
||||
if (mxl[8:34] != reset[8:34] ):
|
||||
self._error(field, "reset value does not match with extensions enabled")
|
||||
|
||||
def _check_with_sn_check(self, field, value):
|
||||
s = 18
|
||||
n = 13
|
||||
check = False
|
||||
if 'implemented' in value:
|
||||
if value['implemented']:
|
||||
check = True
|
||||
if 'accessible' in value:
|
||||
if value['accessible']:
|
||||
check = True
|
||||
|
||||
if rv64 and check:
|
||||
mxl = format(extensions, '#066b')
|
||||
if (mxl[65 - s:66 - s] != '1') and (mxl[65 - n:66 - n] != '1'):
|
||||
self._error(field, "neither S nor N is present")
|
||||
|
||||
elif rv32 and check:
|
||||
mxl = format(extensions, '#034b')
|
||||
if (mxl[33 - s:34 - s] != '1') and (mxl[33 - n:34 - n] != '1'):
|
||||
self._error(field, "neither S nor N is present")
|
||||
|
||||
def _check_with_n_check(self, field, value):
|
||||
n = 13
|
||||
check = False
|
||||
if 'implemented' in value:
|
||||
if value['implemented']:
|
||||
check = True
|
||||
if 'accessible' in value:
|
||||
if value['accessible']:
|
||||
check = True
|
||||
if rv64 and check:
|
||||
mxl = format(extensions, '#066b')
|
||||
if (mxl[65 - n:66 - n] != '1'):
|
||||
self._error(field, "should not be implemented since N is not present")
|
||||
|
||||
elif rv32 and check:
|
||||
mxl = format(extensions, '#034b')
|
||||
if (mxl[33 - n:34 - n] != '1'):
|
||||
self._error(field, "should not be implemented since N is not present")
|
||||
|
||||
def _check_with_h_check(self, field, value):
|
||||
h = 7
|
||||
check = False
|
||||
if 'implemented' in value:
|
||||
if value['implemented']:
|
||||
check = True
|
||||
if 'accessible' in value:
|
||||
if value['accessible']:
|
||||
check = True
|
||||
if rv64 and check:
|
||||
mxl = format(extensions, '#066b')
|
||||
if (mxl[65 - h:66 - h] != '1'):
|
||||
self._error(field, "h is not present")
|
||||
|
||||
elif rv32 and check:
|
||||
mxl = format(extensions, '#034b')
|
||||
if (mxl[33 - h:34 - h] != '1'):
|
||||
self._error(field, "h is not present")
|
||||
|
||||
def _check_with_mdeleg_checks(self, field, value):
|
||||
global extension_list
|
||||
if rv32:
|
||||
if (value['rv32']['accessible'] == True and
|
||||
(not 'S' in extension_list and
|
||||
not 'N' in extension_list)):
|
||||
value['rv32']['accessible'] = False
|
||||
self._error(field, "S and N are not present")
|
||||
|
||||
if rv64:
|
||||
if (value['rv64']['accessible'] == True and
|
||||
(not 'S' in extension_list and
|
||||
not 'N' in extension_list)):
|
||||
value['rv64']['accessible'] = False
|
||||
self._error(field, "S and N are not present")
|
||||
|
||||
def _check_with_ndeleg_checks(self, field, value):
|
||||
global extension_list
|
||||
if rv32:
|
||||
if (value['rv32']['accessible'] == True and
|
||||
not 'N' in extension_list):
|
||||
value['rv32']['accessible'] = False
|
||||
self._error(field, "should not be implemented since N is not present")
|
||||
|
||||
if rv64:
|
||||
if (value['rv64']['accessible'] == True and
|
||||
not 'N' in extension_list):
|
||||
value['rv64']['accessible'] = False
|
||||
self._error(field, "should not be implemented since N is not present")
|
||||
|
||||
def _check_with_xcause_check(self, field, value):
|
||||
'''Function to verify the inputs for mcause.'''
|
||||
if (min(value) < 16):
|
||||
self._error(
|
||||
field, "Invalid platform specific values for exception cause.")
|
||||
|
||||
def _check_with_key_check(self, field, value):
|
||||
if value['base']['type']['warl']['dependency_fields'] != []:
|
||||
par = re.split(
|
||||
"::", value['base']['type']['warl']['dependency_fields'][0])
|
||||
if not par[1] in value:
|
||||
self._error(field, " {} not present".format(par[1]))
|
||||
|
||||
def _check_with_medeleg_reset(self, field, value):
|
||||
global supported_xlen
|
||||
s = format(value, '#{}b'.format(supported_xlen[0] + 2))
|
||||
if (s[-11:-10]) != '0' and value >= int("0x400", 16):
|
||||
self._error(field, " 11th bit must be hardwired to 0")
|
||||
|
||||
def _check_with_sedeleg_reset(self, field, value):
|
||||
global supported_xlen
|
||||
s = format(value, '#{}b'.format(supported_xlen[0] + 2))
|
||||
if (s[-11:-8]) != '000' and value >= int("400", 16):
|
||||
self._error(field, " 11,10,9 bits should be hardwired to 0")
|
||||
|
||||
def _check_with_vxsat_check(self, field, value):
|
||||
check = False
|
||||
xlen_str = 'rv32' if rv32 else 'rv64'
|
||||
global extension_list
|
||||
if 'Zpn' in extension_list and not value[xlen_str]['accessible']:
|
||||
self._error(field,f'[{xlen_str}] Field should be accessible since Zpn is present')
|
||||
if not 'Zpn' in extension_list and value[xlen_str]['accessible']:
|
||||
self._error(field,f'[{xlen_str}] Field should be accessible only when Zpn is present')
|
||||
if not 'Zpn' in extension_list and value[xlen_str]['ov']['implemented']:
|
||||
self._error(field, f'[{xlen_str}] Subfield ov should not be implemented since Zpn is not present')
|
||||
if 'Zpn' in extension_list and not value[xlen_str]['ov']['implemented']:
|
||||
self._error(field, f'[{xlen_str}] Subfield ov should be implemented since Zpn is present in isa')
|
||||
|
175
vendor/riscv/riscv-config/riscv_config/schemas/schema_custom.yaml
vendored
Normal file
175
vendor/riscv/riscv-config/riscv_config/schemas/schema_custom.yaml
vendored
Normal file
|
@ -0,0 +1,175 @@
|
|||
hart_schema:
|
||||
type: dict
|
||||
schema:
|
||||
keysrules:
|
||||
regex: '^(?!uarch_)'
|
||||
type: dict
|
||||
schema:
|
||||
description:
|
||||
type: string
|
||||
default: custom csr.
|
||||
address:
|
||||
type: integer
|
||||
priv_mode:
|
||||
type: string
|
||||
default: M
|
||||
reset-val:
|
||||
type: integer
|
||||
default: 0x0
|
||||
rv32:
|
||||
type: dict
|
||||
schema:
|
||||
fields:
|
||||
type: list
|
||||
default: []
|
||||
keysrules:
|
||||
type: dict
|
||||
regex: '[a-zA_Z0-9_]*'
|
||||
schema:
|
||||
description:
|
||||
type: string
|
||||
default: subfield.
|
||||
shadow:
|
||||
type: string
|
||||
default:
|
||||
nullable: True
|
||||
shadow_type:
|
||||
type: string
|
||||
default: rw
|
||||
nullable: True
|
||||
allowed: ['rw', 'ro']
|
||||
msb:
|
||||
type: integer
|
||||
lsb:
|
||||
type: integer
|
||||
implemented:
|
||||
type: boolean
|
||||
default: false
|
||||
type:
|
||||
type: dict
|
||||
oneof:
|
||||
- schema:
|
||||
ro_constant:
|
||||
type: integer
|
||||
- schema:
|
||||
ro_variable:
|
||||
type: boolean
|
||||
- schema:
|
||||
warl:
|
||||
type: dict
|
||||
schema:
|
||||
dependency_fields:
|
||||
type: list
|
||||
empty: true
|
||||
schema:
|
||||
type: string
|
||||
nullable: true
|
||||
legal:
|
||||
type: list
|
||||
schema:
|
||||
type: string
|
||||
wr_illegal:
|
||||
type: list
|
||||
schema:
|
||||
type: string
|
||||
rv64:
|
||||
type: dict
|
||||
schema:
|
||||
fields:
|
||||
type: list
|
||||
default: []
|
||||
keysrules:
|
||||
type: dict
|
||||
regex: '[a-zA_Z0-9_]*'
|
||||
schema:
|
||||
description:
|
||||
type: string
|
||||
default: subfield.
|
||||
shadow:
|
||||
type: string
|
||||
default:
|
||||
nullable: True
|
||||
shadow_type:
|
||||
type: string
|
||||
default: rw
|
||||
nullable: True
|
||||
allowed: ['rw', 'ro']
|
||||
msb:
|
||||
type: integer
|
||||
lsb:
|
||||
type: integer
|
||||
implemented:
|
||||
type: boolean
|
||||
default: false
|
||||
type:
|
||||
type: dict
|
||||
oneof:
|
||||
- schema:
|
||||
ro_constant:
|
||||
type: integer
|
||||
- schema:
|
||||
ro_variable:
|
||||
type: boolean
|
||||
- schema:
|
||||
warl:
|
||||
type: dict
|
||||
schema:
|
||||
dependency_fields:
|
||||
type: list
|
||||
empty: true
|
||||
schema:
|
||||
type: string
|
||||
nullable: true
|
||||
legal:
|
||||
type: list
|
||||
schema:
|
||||
type: string
|
||||
wr_illegal:
|
||||
type: list
|
||||
schema:
|
||||
type: string
|
||||
uarch_signals:
|
||||
required: false
|
||||
type: dict
|
||||
schema:
|
||||
keysrules:
|
||||
regex: '^uarch_'
|
||||
type: dict
|
||||
oneof:
|
||||
- schema:
|
||||
msb:
|
||||
type: integer
|
||||
required: true
|
||||
lsb:
|
||||
type: integer
|
||||
required: true
|
||||
reset-val:
|
||||
type: integer
|
||||
required: true
|
||||
min: 0
|
||||
legal:
|
||||
type: list
|
||||
required: false
|
||||
nullable: true
|
||||
schema:
|
||||
type: integer
|
||||
- schema:
|
||||
subfields:
|
||||
type: dict
|
||||
schema:
|
||||
msb:
|
||||
type: integer
|
||||
required: true
|
||||
lsb:
|
||||
type: integer
|
||||
required: true
|
||||
legal:
|
||||
type: list
|
||||
required: false
|
||||
nullable: true
|
||||
schema:
|
||||
type: integer
|
||||
reset-val:
|
||||
type: integer
|
||||
required: true
|
||||
min: 0
|
1511
vendor/riscv/riscv-config/riscv_config/schemas/schema_debug.yaml
vendored
Normal file
1511
vendor/riscv/riscv-config/riscv_config/schemas/schema_debug.yaml
vendored
Normal file
File diff suppressed because it is too large
Load diff
14110
vendor/riscv/riscv-config/riscv_config/schemas/schema_isa.yaml
vendored
Normal file
14110
vendor/riscv/riscv-config/riscv_config/schemas/schema_isa.yaml
vendored
Normal file
File diff suppressed because it is too large
Load diff
328
vendor/riscv/riscv-config/riscv_config/schemas/schema_platform.yaml
vendored
Normal file
328
vendor/riscv/riscv-config/riscv_config/schemas/schema_platform.yaml
vendored
Normal file
|
@ -0,0 +1,328 @@
|
|||
###
|
||||
#reset
|
||||
#-----
|
||||
#
|
||||
# - **Description**: Stores the value for the reset vector. It can either be a label or an address.
|
||||
#
|
||||
# * label: A string field equal to the label in the assembly code
|
||||
# * address: A value equal to the absolute address where the vector is present
|
||||
# - **Constraints**: label and address both cannot be defined
|
||||
# - **Examples**:
|
||||
#
|
||||
# .. code-block:: yaml
|
||||
#
|
||||
# reset:
|
||||
# label: reset_vector
|
||||
# reset:
|
||||
# label: 0x80000000
|
||||
|
||||
reset:
|
||||
type: dict
|
||||
schema:
|
||||
label:
|
||||
type: string
|
||||
excludes: ['address']
|
||||
address:
|
||||
type: integer
|
||||
excludes: ['label']
|
||||
required: True
|
||||
|
||||
###
|
||||
#nmi
|
||||
#---
|
||||
#
|
||||
# - **Description**: Stores the value for the nmi vector. It can either be a label or an address.
|
||||
#
|
||||
# * label: A string field equal to the label in the assembly code.
|
||||
# * address: A value equal to the absolute address where the vector is present.
|
||||
# - **Constraints**: label and address both cannot be defined
|
||||
# - **Examples**:
|
||||
#
|
||||
# .. code-block:: yaml
|
||||
#
|
||||
# nmi:
|
||||
# label: nmi_vector
|
||||
# address: 0x8000000
|
||||
|
||||
nmi:
|
||||
type: dict
|
||||
schema:
|
||||
label:
|
||||
type: string
|
||||
excludes: ['address']
|
||||
address:
|
||||
type: integer
|
||||
excludes: ['label']
|
||||
required: False
|
||||
default:
|
||||
label: nmi_vector
|
||||
address: 0x0
|
||||
|
||||
###
|
||||
#mtime
|
||||
#-----
|
||||
#
|
||||
# - **Description**: Stores the fields for memory mapped *mtime* register.
|
||||
#
|
||||
# * implemented: A boolean field indicating that the register has been implemented.
|
||||
# * address: A value equal to the physical address at which the register is present.
|
||||
#
|
||||
# - **Examples**:
|
||||
#
|
||||
# .. code-block:: yaml
|
||||
#
|
||||
# mtime:
|
||||
# implemented: True
|
||||
# address: 0x458
|
||||
|
||||
mtime:
|
||||
type: dict
|
||||
schema:
|
||||
address:
|
||||
type: integer
|
||||
implemented:
|
||||
type: boolean
|
||||
default: False
|
||||
default:
|
||||
implemented: False
|
||||
|
||||
###
|
||||
#mtimecmp
|
||||
#--------
|
||||
#
|
||||
# - **Description**: Stores the fields for memory mapped *mtimecmp* register.
|
||||
#
|
||||
# * implemented: A boolean field indicating that the register has been implemented.
|
||||
# * address: A value equal to the physical address at which the register is present.
|
||||
#
|
||||
# - **Examples**:
|
||||
#
|
||||
# .. code-block:: yaml
|
||||
#
|
||||
# mtimecmp:
|
||||
# implemented: True
|
||||
# address: 0x458
|
||||
|
||||
mtimecmp:
|
||||
type: dict
|
||||
schema:
|
||||
address:
|
||||
type: integer
|
||||
implemented:
|
||||
type: boolean
|
||||
default: False
|
||||
default:
|
||||
implemented: False
|
||||
|
||||
###
|
||||
#mtval_condition_writes
|
||||
#----------------------
|
||||
#
|
||||
# - **Description**: Stores the fields for *mtval_condition_writes* register.
|
||||
#
|
||||
# * implemented: A Boolean value indicating whether the register is implemented.
|
||||
# * behaviour: A dictionary type to specify which of the exceptions modify the mtval_condition_writes reg
|
||||
#
|
||||
# - e0: A string type describing the behaviour of exception 0.
|
||||
# - e1: A string type describing the behaviour of exception 1.
|
||||
# - e2: A string type describing the behaviour of exception 2.
|
||||
# - e3: A string type describing the behaviour of exception 3.
|
||||
# - e4: A string type describing the behaviour of exception 4.
|
||||
# - e5: A string type describing the behaviour of exception 5.
|
||||
# - e6: A string type describing the behaviour of exception 6.
|
||||
# - e7: A string type describing the behaviour of exception 7.
|
||||
# - e8: A string type describing the behaviour of exception 8.
|
||||
# - e9: A string type describing the behaviour of exception 9.
|
||||
# - e10: A string type describing the behaviour of exception 10.
|
||||
# - e11: A string type describing the behaviour of exception 11.
|
||||
# - e12: A string type describing the behaviour of exception 12.
|
||||
# - e13: A string type describing the behaviour of exception 13.
|
||||
# - e15: A string type describing the behaviour of exception 15.
|
||||
#
|
||||
# - **Examples**:
|
||||
#
|
||||
# .. code-block:: yaml
|
||||
#
|
||||
# TBD: Provide a concrete use-case for the above.
|
||||
|
||||
mtval_condition_writes:
|
||||
type: dict
|
||||
schema:
|
||||
implemented:
|
||||
type: boolean
|
||||
default: False
|
||||
behaviour:
|
||||
type: dict
|
||||
schema:
|
||||
e00:
|
||||
type: string
|
||||
e01:
|
||||
type: string
|
||||
e02:
|
||||
type: string
|
||||
e03:
|
||||
type: string
|
||||
e04:
|
||||
type: string
|
||||
e05:
|
||||
type: string
|
||||
e06:
|
||||
type: string
|
||||
e07:
|
||||
type: string
|
||||
e08:
|
||||
type: string
|
||||
e09:
|
||||
type: string
|
||||
e10:
|
||||
type: string
|
||||
e11:
|
||||
type: string
|
||||
e12:
|
||||
type: string
|
||||
e13:
|
||||
type: string
|
||||
e15:
|
||||
type: string
|
||||
default:
|
||||
implemented: False
|
||||
|
||||
###
|
||||
#scause_non_standard
|
||||
#-------------------
|
||||
#
|
||||
# - **Description**: Stores the fields for the *scause* register.
|
||||
#
|
||||
# * implemented: A boolean field indicating that the register has been implemented.
|
||||
# * values: The list of exception values greater than 16 as assumed by the platform as integers.
|
||||
#
|
||||
# - **Examples**:
|
||||
#
|
||||
# .. code-block:: yaml
|
||||
#
|
||||
# scause_non_standard:
|
||||
# implemented: True
|
||||
# value: [16,17,20]
|
||||
|
||||
scause_non_standard:
|
||||
type: dict
|
||||
schema:
|
||||
implemented:
|
||||
type: boolean
|
||||
values:
|
||||
type: list
|
||||
check_with: xcause_check
|
||||
default:
|
||||
implemented: False
|
||||
|
||||
###
|
||||
#stval_condition_writes
|
||||
#----------------------
|
||||
#
|
||||
# - **Description**: Stores the fields for *stval_condition_writes* register.
|
||||
#
|
||||
# - implemented: A Boolean value indicating whether the field is implemented.
|
||||
# - behaviour: A dictionary type to specify which of the exceptions modify the stval_condition_writes reg
|
||||
#
|
||||
# - e0: A string type describing the behaviour of exception 0.
|
||||
# - e1: A string type describing the behaviour of exception 1.
|
||||
# - e2: A string type describing the behaviour of exception 2.
|
||||
# - e3: A string type describing the behaviour of exception 3.
|
||||
# - e4: A string type describing the behaviour of exception 4.
|
||||
# - e5: A string type describing the behaviour of exception 5.
|
||||
# - e6: A string type describing the behaviour of exception 6.
|
||||
# - e7: A string type describing the behaviour of exception 7.
|
||||
# - e8: A string type describing the behaviour of exception 8.
|
||||
# - e9: A string type describing the behaviour of exception 9.
|
||||
# - e10: A string type describing the behaviour of exception 10.
|
||||
# - e11: A string type describing the behaviour of exception 11.
|
||||
# - e12: A string type describing the behaviour of exception 12.
|
||||
# - e13: A string type describing the behaviour of exception 13.
|
||||
# - e15: A string type describing the behaviour of exception 15.
|
||||
#
|
||||
# - **Examples**:
|
||||
#
|
||||
# .. code-block:: yaml
|
||||
#
|
||||
# TBD: Provide a concrete use-case for the above.
|
||||
|
||||
stval_condition_writes:
|
||||
type: dict
|
||||
schema:
|
||||
implemented:
|
||||
type: boolean
|
||||
default: False
|
||||
behaviour:
|
||||
type: dict
|
||||
schema:
|
||||
e00:
|
||||
type: string
|
||||
e01:
|
||||
type: string
|
||||
e02:
|
||||
type: string
|
||||
e03:
|
||||
type: string
|
||||
e04:
|
||||
type: string
|
||||
e05:
|
||||
type: string
|
||||
e06:
|
||||
type: string
|
||||
e07:
|
||||
type: string
|
||||
e08:
|
||||
type: string
|
||||
e09:
|
||||
type: string
|
||||
e10:
|
||||
type: string
|
||||
e11:
|
||||
type: string
|
||||
e12:
|
||||
type: string
|
||||
e13:
|
||||
type: string
|
||||
e15:
|
||||
type: string
|
||||
default:
|
||||
implemented: False
|
||||
|
||||
###
|
||||
#zicbo_cache_block_sz
|
||||
#--------------------
|
||||
#
|
||||
# - **Description**: byte size of the cache block
|
||||
# - **Constraints**:
|
||||
#
|
||||
# - zicbom_sz cannot exceed 4096
|
||||
# - zicboz_sz cannot exceed 4096
|
||||
# - for both the above variables the integer must be a power of 2
|
||||
#
|
||||
# - **Examples**:
|
||||
#
|
||||
# .. code-block:: yaml
|
||||
#
|
||||
# zicbo_cache_block_sz :
|
||||
# implemented: true
|
||||
# zicbom_sz: 64
|
||||
# zicboz_sz: 64
|
||||
|
||||
zicbo_cache_block_sz:
|
||||
type: dict
|
||||
schema:
|
||||
implemented:
|
||||
type: boolean
|
||||
default: False
|
||||
zicbom_sz:
|
||||
type: integer
|
||||
max: [4096]
|
||||
default: 0
|
||||
check_with: cache_block_size
|
||||
zicboz_sz:
|
||||
type: integer
|
||||
max: [4096]
|
||||
default: 0
|
||||
check_with: cache_block_size
|
||||
default:
|
||||
implemented: False
|
160
vendor/riscv/riscv-config/riscv_config/utils.py
vendored
Normal file
160
vendor/riscv/riscv-config/riscv_config/utils.py
vendored
Normal file
|
@ -0,0 +1,160 @@
|
|||
import logging
|
||||
import argparse
|
||||
import operator
|
||||
|
||||
import ruamel
|
||||
from ruamel.yaml import YAML
|
||||
import yaml as pyyaml
|
||||
|
||||
def hexint_presenter(dumper, data):
|
||||
return dumper.represent_int(hex(data))
|
||||
|
||||
class NoAliasDumper(pyyaml.Dumper):
|
||||
def ignore_aliases(self, data):
|
||||
return True
|
||||
|
||||
|
||||
def dump_yaml(foo, outfile, no_anchors=False):
|
||||
if no_anchors:
|
||||
pyyaml.add_representer(int, hexint_presenter)
|
||||
pyyaml.dump(foo, outfile, Dumper=NoAliasDumper)
|
||||
else:
|
||||
yaml = YAML(typ="rt")
|
||||
yaml.default_flow_style = False
|
||||
yaml.allow_unicode = True
|
||||
yaml.compact(seq_seq=False, seq_map=False)
|
||||
yaml.indent = 4
|
||||
yaml.block_seq_indent = 2
|
||||
yaml.dump(foo, outfile)
|
||||
|
||||
|
||||
def load_yaml(foo, no_anchors=False):
|
||||
|
||||
if no_anchors:
|
||||
yaml = YAML(typ="safe")
|
||||
else:
|
||||
yaml = YAML(typ="rt")
|
||||
yaml.default_flow_style = False
|
||||
yaml.allow_unicode = True
|
||||
yaml.compact(seq_seq=False, seq_map=False)
|
||||
yaml.indent = 4
|
||||
yaml.block_seq_indent = 2
|
||||
|
||||
try:
|
||||
with open(foo, "r") as file:
|
||||
return yaml.load(file)
|
||||
except ruamel.yaml.constructor.DuplicateKeyError as msg:
|
||||
logger = logging.getLogger(__name__)
|
||||
error = "\n".join(str(msg).split("\n")[2:-7])
|
||||
logger.error(error)
|
||||
raise SystemExit
|
||||
|
||||
|
||||
class ColoredFormatter(logging.Formatter):
|
||||
"""
|
||||
Class to create a log output which is colored based on level.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(ColoredFormatter, self).__init__(*args, **kwargs)
|
||||
self.colors = {
|
||||
'DEBUG': '\033[94m',
|
||||
'INFO': '\033[92m',
|
||||
'WARNING': '\033[93m',
|
||||
'ERROR': '\033[91m',
|
||||
}
|
||||
|
||||
self.reset = '\033[0m'
|
||||
|
||||
def format(self, record):
|
||||
msg = str(record.msg)
|
||||
level_name = str(record.levelname)
|
||||
name = str(record.name)
|
||||
color_prefix = self.colors[level_name]
|
||||
return '{0}{1:<9s} {4}: {2}{3}'.format(color_prefix,
|
||||
'[' + level_name + ']', msg,
|
||||
self.reset, name)
|
||||
|
||||
|
||||
def setup_logging(log_level):
|
||||
"""Setup logging
|
||||
|
||||
Verbosity decided on user input
|
||||
|
||||
:param log_level: User defined log level
|
||||
|
||||
:type log_level: str
|
||||
"""
|
||||
numeric_level = getattr(logging, log_level.upper(), None)
|
||||
|
||||
if not isinstance(numeric_level, int):
|
||||
print(
|
||||
"\033[91mInvalid log level passed. Please select from debug | info | warning | error\033[0m"
|
||||
)
|
||||
raise ValueError("{}-Invalid log level.".format(log_level))
|
||||
|
||||
logging.basicConfig(level=numeric_level)
|
||||
|
||||
|
||||
class SortingHelpFormatter(argparse.HelpFormatter):
|
||||
|
||||
def add_arguments(self, actions):
|
||||
actions = sorted(actions, key=operator.attrgetter('option_strings'))
|
||||
super(SortingHelpFormatter, self).add_arguments(actions)
|
||||
|
||||
|
||||
def riscv_config_cmdline_args():
|
||||
parser = argparse.ArgumentParser(
|
||||
formatter_class=SortingHelpFormatter,
|
||||
prog="riscv_config",
|
||||
description="RISC-V Configuration Validator")
|
||||
parser.add_argument('--version',
|
||||
'-v',
|
||||
help='Print version of RISCV-CONFIG being used',
|
||||
action='store_true')
|
||||
parser.add_argument('--isa_spec',
|
||||
'-ispec',
|
||||
type=str,
|
||||
metavar='YAML',
|
||||
default=None,
|
||||
help='The YAML which contains the ISA specs.')
|
||||
parser.add_argument('--platform_spec',
|
||||
'-pspec',
|
||||
type=str,
|
||||
metavar='YAML',
|
||||
default=None,
|
||||
help='The YAML which contains the Platfrorm specs.')
|
||||
parser.add_argument('--debug_spec',
|
||||
'-dspec',
|
||||
type=str,
|
||||
metavar='YAML',
|
||||
default=None,
|
||||
help='The YAML which contains the debug csr specs.')
|
||||
parser.add_argument('--custom_spec',
|
||||
'-cspec',
|
||||
type=str,
|
||||
metavar='YAML',
|
||||
default=None,
|
||||
help='The YAML which contains the custom csr specs.')
|
||||
parser.add_argument(
|
||||
'--work_dir',
|
||||
type=str,
|
||||
default="riscv_config_work",
|
||||
metavar='DIR',
|
||||
help='The name of the work dir to dump the output files to.')
|
||||
parser.add_argument('--verbose',
|
||||
action='store',
|
||||
default='info',
|
||||
help='debug | info | warning | error',
|
||||
metavar="")
|
||||
parser.add_argument('--no_anchors',
|
||||
action='store_true',
|
||||
help='Unroll/Disable all anchors')
|
||||
return parser
|
||||
|
||||
def pretty_print_yaml(yaml):
|
||||
res = ''''''
|
||||
for line in ruamel.yaml.round_trip_dump(yaml, indent=5, block_seq_indent=3).splitlines(True):
|
||||
res += line
|
||||
return res
|
||||
|
750
vendor/riscv/riscv-config/riscv_config/warl.py
vendored
Normal file
750
vendor/riscv/riscv-config/riscv_config/warl.py
vendored
Normal file
|
@ -0,0 +1,750 @@
|
|||
import re
|
||||
import os
|
||||
import logging
|
||||
import riscv_config.utils as utils
|
||||
import textwrap
|
||||
import random
|
||||
import pprint as pp
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class warl_class():
|
||||
"""This is a class for handling various operations and checks for the WARL
|
||||
type of registers and/or subfields as defined by the riscv-config spec<TODO:
|
||||
link here>. While riscv-config remains to be the major user of this package,
|
||||
this class can be used as an importable python package as well in several
|
||||
other scenarios to perform checks on a particular WARL string.
|
||||
|
||||
The basic WARL node should be dict adhering to the following syntax:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
warl:
|
||||
dependency_fields: [list]
|
||||
legal: [list of warl-string]
|
||||
wr_illegal: [list of warl-string]
|
||||
|
||||
:param node: This input is the dict adhering to the above syntax.
|
||||
:type node: dict
|
||||
:param csrname: this is string indicating the name of the csr or
|
||||
csr::subfield which is defined as a WARL type. This primarily used to
|
||||
generate a series of legible error and debug messages. If the input warl
|
||||
node is for a subfield, then use ``::`` as the delimiter between the csr
|
||||
name and the subfield name.
|
||||
:type csrname: str
|
||||
:param f_msb: the max msb location of the csr or subfield.
|
||||
:type f_msb: int
|
||||
:param f_lsb: the min lsb location of the csr or subfield.
|
||||
:type f_lsb: int
|
||||
:param spec: This is the entire isa-spec of a single hart. This dict is
|
||||
primarily used by this class to perform specific checks on reset-vals
|
||||
and on dependency_vals string validity.
|
||||
:type spec: dict
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, node, csrname, f_msb, f_lsb, spec=None):
|
||||
"""Constructor Method
|
||||
"""
|
||||
|
||||
self.node = node
|
||||
self.f_msb = f_msb
|
||||
self.f_lsb = f_lsb
|
||||
self.bitlen = f_msb - f_lsb + 1
|
||||
self.maxval = (2**(self.bitlen))-1
|
||||
self.spec = spec
|
||||
self.regex_legal = re.compile('\[(.*?)\]\s*(bitmask|in|not in)\s*\[(.*?)\]')
|
||||
self.regex_dep_legal = re.compile('(?P<csrname>.*?)\s*\[(?P<indices>.*?)\]\s*(?P<op>in|not in.*?)\s*\[(?P<values>.*?)\]\s*')
|
||||
self.dependencies = node['dependency_fields']
|
||||
self.uarch_depends = {'uarch_signals': []}
|
||||
try:
|
||||
if spec is not None:
|
||||
self.uarch_signals = spec['uarch_signals']
|
||||
else:
|
||||
self.uarch_signals = {}
|
||||
except KeyError:
|
||||
self.uarch_signals = {}
|
||||
self.csrname = csrname
|
||||
if spec is not None:
|
||||
self.isa = 'rv32' if '32' in spec['ISA'] else 'rv64'
|
||||
self.create_uarch_depends(self.uarch_signals)
|
||||
|
||||
def check_subval_legal(self, legalstr, value):
|
||||
"""This function checks if a given value satifies the conditions present
|
||||
in a given legal string.
|
||||
|
||||
:param legalstr: This is a string following the warl-legal syntax.
|
||||
:type legalstr: str
|
||||
:param value: The value whose legality to be checked against the
|
||||
warl-legal string
|
||||
:type value: int
|
||||
:return: A list of error strings encountered while performing the
|
||||
checks on a legal string
|
||||
:rtype: list(str)
|
||||
|
||||
The legal string is first broken down into smaller substrings, each of
|
||||
which assigns certain bits a specific value. Each substring should match
|
||||
the following regular-expression: ``\[(.*?)\]\s*(bitmask|in|not in)\s*\[(.*?)\]``
|
||||
|
||||
For each substring, we then extract the indicies of the csr/subfield
|
||||
that are being assigned, the operation used (one of `bitmask`, `in` or
|
||||
`not in`) and values being assigned. Using the indices we extract the
|
||||
relevant sub-value of the input value argument which applies to these
|
||||
indices (we refer to this as subval).
|
||||
|
||||
In case of a ``bitmask`` operation all values of the input are considered
|
||||
legal - since the mask and fixedval will ensure only legal values are
|
||||
set.
|
||||
|
||||
In case of an ``in`` operation, the values list (extracted from the
|
||||
substring) is split into individual elements. Each element can either be
|
||||
a range or a single integer. In case of a range we check if the input
|
||||
subval falls within this range or not. In case of a single integer we
|
||||
perform a direct match. We parse the entire values list and stop as soon
|
||||
as atleast on match is detected.
|
||||
|
||||
In case of a ``not in`` operation, the procedure is the same as above,
|
||||
except we parse through the entire values list to ensure the subval
|
||||
doesn't match any of those values, only then the subval is treated as a
|
||||
legal value.
|
||||
|
||||
"""
|
||||
assigns = self.regex_legal.findall(legalstr)
|
||||
err = []
|
||||
for a in assigns:
|
||||
(indices, op, vals) = a
|
||||
msb = int(indices.split(':')[0], 0)
|
||||
if ':' in indices:
|
||||
lsb = int(indices.split(':')[1], 0)
|
||||
else:
|
||||
# if its a single value, then lsb and msb are the same
|
||||
lsb = msb
|
||||
bitlen = msb - lsb + 1
|
||||
|
||||
if value > self.maxval:
|
||||
err.append(f' for csr "{self.csrname}" the value {hex(value)} is out of bounds')
|
||||
continue
|
||||
|
||||
# extract the value of the bits for which this particular substring
|
||||
# is applicable.
|
||||
subval = (value >> lsb) & ((1 << bitlen)-1)
|
||||
values = vals.split(',')
|
||||
|
||||
# for `in` atleast one of the vals must be a hit. If none is a hit,
|
||||
# then the value is illegal.
|
||||
if op == 'in':
|
||||
atleast_one_pass = False
|
||||
for v in values:
|
||||
base = int(v.split(':')[0], 0)
|
||||
if ':' in v:
|
||||
bound = int(v.split(':')[1], 0)
|
||||
else:
|
||||
bound = base
|
||||
if subval >= base and subval <= bound:
|
||||
atleast_one_pass = True
|
||||
break
|
||||
if not atleast_one_pass:
|
||||
err.append(f' for csr "{self.csrname}" and warl \
|
||||
sub-string "{legalstr}" the value "{hex(value)}" is not legal since it fails the condition \
|
||||
"[{indices}] {op} [{vals}]"')
|
||||
break
|
||||
# for `not in` even a single match will treat the value as illegal.
|
||||
elif op == 'not in':
|
||||
all_pass = True
|
||||
for v in values:
|
||||
base = int(v.split(':')[0], 0)
|
||||
if ':' in v:
|
||||
bound = int(v.split(':')[1], 0)
|
||||
else:
|
||||
bound = base
|
||||
if subval >= base and subval <= bound:
|
||||
all_pass = False
|
||||
if not all_pass:
|
||||
err.append(f' for csr "{self.csrname}" and warl \
|
||||
sub-string "{legalstr}" the value "{value}" is not legal since it fails the condition \
|
||||
"[{indices}] {op} [{vals}]"')
|
||||
break
|
||||
# for bitmask all values are treated as legal.
|
||||
elif op == 'bitmask':
|
||||
continue
|
||||
else:
|
||||
err.append(f' found op:"{op}" in legal string :"{legalstr}" \
|
||||
which is not supported')
|
||||
break
|
||||
|
||||
return err
|
||||
|
||||
def getlegal(self, dependency_vals=[]):
|
||||
'''
|
||||
This function is used to return a legal value for a given set of
|
||||
dependency_vals. If the dependency_vals is empty and self.dependencies
|
||||
is not empty, then the first legal string is picked and the
|
||||
assignment-string substring is dierctly evaluated to get a legal value.
|
||||
|
||||
:param dependency_vals: This is dictionary of csr:value pairs which
|
||||
indicates the current value of csrs/subfields present in the
|
||||
dependency_fields of the warl node.
|
||||
:type dependency_vals: dict
|
||||
|
||||
:return: A single integer value which is considered legal for the csr
|
||||
under the provided dependency_vals arg
|
||||
:rtype: int
|
||||
'''
|
||||
logger.debug(f'Deriving a legal value for csr:{self.csrname}')
|
||||
err = []
|
||||
value = 0
|
||||
index = -1
|
||||
if self.dependencies and dependency_vals:
|
||||
for legalstr in self.node['legal']:
|
||||
index = index + 1
|
||||
depstr = legalstr.split('->')[0]
|
||||
# we replace all boolean operators first to simple parse and the
|
||||
# check if the (in|not in|bitmask) operators are infact legal or
|
||||
# not.
|
||||
raw_depstr = re.sub('\(|\)|and|or','',depstr)
|
||||
|
||||
# implicitly assume it passes - in case of writeval and currval.
|
||||
dep_pass = False
|
||||
for m in self.regex_dep_legal.finditer(raw_depstr):
|
||||
(csrname, indices, op, vals) = m.groups()
|
||||
matchstr = m.group()
|
||||
|
||||
# in case the dependency is on writeval then we
|
||||
# assume the condition is always true.
|
||||
if csrname in ['writeval']:
|
||||
depstr = depstr.replace(matchstr, 'True')
|
||||
continue
|
||||
# in case the dependency is on the current val of the same
|
||||
# csr (before performing the write), then we continue by
|
||||
# replacing the currval string with the csrname::subfield
|
||||
# syntax
|
||||
if csrname == 'currval':
|
||||
if '::' in self.csrname:
|
||||
renamed_csr = self.csrname.split('::')[0]
|
||||
subfield = self.csrname.split('::')[1]
|
||||
else:
|
||||
renamed_csr = self.csrname
|
||||
subfield = ''
|
||||
else:
|
||||
_csrname = re.sub('{\d*}','',csrname)
|
||||
renamed_csr = list(filter(re.compile(f'[a-zA-Z0-9]*[:]*{_csrname}\s*$').match, self.dependencies))[0]
|
||||
if '::' in renamed_csr:
|
||||
subfield = renamed_csr.split('::')[1]
|
||||
else:
|
||||
subfield = ''
|
||||
renamed_csr = renamed_csr.split('::')[0]
|
||||
# if the dependency_vals dict is not empty, then pick the
|
||||
# values of the csrs/subfields from there. Here we expect
|
||||
# the key in the dependency_vals dict to be a subfield
|
||||
# name without the `::` delimiter.
|
||||
if csrname not in dependency_vals:
|
||||
err.append(f'in warl string of {self.csrname}, \
|
||||
the value of dependency field {csrname} not present in dependency_vals')
|
||||
return err, value
|
||||
else:
|
||||
dep_csr_val = dependency_vals[csrname]
|
||||
step_err = self.check_subval_legal(matchstr, dep_csr_val)
|
||||
err = err + step_err
|
||||
step_pass = True if step_err == [] else False
|
||||
depstr = depstr.replace(matchstr, str(step_pass))
|
||||
dep_pass = eval(depstr)
|
||||
if not dep_pass:
|
||||
continue
|
||||
else:
|
||||
break
|
||||
else:
|
||||
index = 0
|
||||
dep_pass = True
|
||||
|
||||
if not dep_pass:
|
||||
err.append(f'Cannot find a single legal string for which dependencies are satisfied')
|
||||
return err, value
|
||||
|
||||
lstr = self.node['legal'][index].split('->')[-1]
|
||||
for assigns in self.regex_legal.findall(lstr):
|
||||
(indices, operation, vals) = assigns
|
||||
|
||||
msb = int(indices.split(':')[0], 0)
|
||||
if ':' in indices:
|
||||
lsb = int(indices.split(':')[1], 0)
|
||||
else:
|
||||
# if its a single value, then lsb and msb are the same
|
||||
lsb = msb
|
||||
bitlen = msb - lsb + 1
|
||||
if operation == 'in':
|
||||
v = random.choice(vals.split(','))
|
||||
base = int(v.split(':')[0], 0)
|
||||
if ':' in v:
|
||||
bound = int(v.split(':')[1], 0)
|
||||
else:
|
||||
bound = base
|
||||
myval = random.randrange(base, bound+1)
|
||||
value = value | (myval << lsb)
|
||||
elif operation == 'not in':
|
||||
exclude_list = []
|
||||
for v in vals.split(','):
|
||||
base = int(v.split(':')[0], 0)
|
||||
if ':' in v:
|
||||
bound = int(v.split(':')[1], 0)
|
||||
else:
|
||||
bound = base
|
||||
exclude_list += list(range(base, bound+1))
|
||||
|
||||
full_list = range(0,2**bitlen)
|
||||
select_list = list(set(full_list) - set(exclude_list))
|
||||
if not select_list:
|
||||
err.append(f'Cannot find a legal value since \
|
||||
{assigns} uses a not-in operation across the entire range')
|
||||
return err,value
|
||||
myval = random.choice(select_list)
|
||||
value = value | (myval << lsb)
|
||||
elif operation == 'bitmask':
|
||||
mask = int(vals.split(',')[0], 0)
|
||||
fixedval = int(vals.split(',')[1], 0)
|
||||
myval = random.randrange(0,2**bitlen)
|
||||
myval = (myval & mask) | (~mask & fixedval)
|
||||
value = (myval << lsb)
|
||||
return err, value
|
||||
|
||||
|
||||
def islegal(self, value, dependency_vals=None):
|
||||
"""This function is used to check if an input value is a legal value for
|
||||
csr for given set of dependency values. The legality is checked against
|
||||
all warl string listed under the `legal` node of the warl dictionary.
|
||||
|
||||
:param value: input integer whose legality needs to be checked for the
|
||||
csr/subfield warl node.
|
||||
:type value: int
|
||||
:param dependency_vals: This is dictionary of csr:value pairs which
|
||||
indicates the current value of csrs/subfields present in the
|
||||
dependency_fields of the warl node.
|
||||
:type dependency_vals: dict
|
||||
|
||||
If the dependency_fields of the warl node is empty, then the single
|
||||
legal string in the legal list, is simply processed by the function
|
||||
:py:func:`check_subval_legal` and result of which is simply returned as
|
||||
is.
|
||||
|
||||
However, if the dependency_fields is not empty, then for each legal
|
||||
string we check if both dependency_vals substring is satisfied and the
|
||||
assignment substring is also satisfied, else an error is generated.
|
||||
|
||||
for the dependency_vals substring the values of the csrs in the
|
||||
dependency_fields if obtained either from the input dependency_vals
|
||||
argument or else the reset-vals of the csr in the isa spec (self.spec)
|
||||
are used. If neither is available, then an error is posted about the
|
||||
same.
|
||||
|
||||
The dependency_vals substring is again split further down to process
|
||||
each condition individually. The checks for the dependency_vals
|
||||
substring include:
|
||||
|
||||
- checking is the csrs in the substring are indeed present in the
|
||||
dependency_fields list of the warl node
|
||||
- if writeval or currval is detected, then that part of the
|
||||
conditions is ignored.
|
||||
|
||||
The dependency_vals substring is treated as a boolean condition. Hence,
|
||||
when when each part of the substring is evaluated, we replace that part
|
||||
of the string with either True or False, and at the end perform an
|
||||
`eval` on the new replaced dependency_vals substring. If this condition
|
||||
evaluates to True, the corresponing assign string also evaluates to
|
||||
True, then the input value is considered legal.
|
||||
|
||||
Things this function does not do:
|
||||
|
||||
- this does not check if the warl strings are valid. It is assumed
|
||||
that they are valid. If not, pass them through the function iserr
|
||||
to check for validity.
|
||||
- in case of dependency_fields being not empty, this function
|
||||
doesn't check if the possible values of the dependency
|
||||
csrs/subfields are indeed legal for them. This causes a nesting
|
||||
problem, which is probably doesn't warrant an immediate solution ??
|
||||
-
|
||||
"""
|
||||
logger.debug(f'---- WARL Value Legality Check: value:{value} csr:{self.csrname} dependency_vals:{dependency_vals}')
|
||||
err = []
|
||||
# if no dependencies then only one legal string is present. Simply use
|
||||
# check_subval_legal function to detect legality.
|
||||
if not self.dependencies:
|
||||
for legalstr in self.node['legal']:
|
||||
err = self.check_subval_legal(legalstr, value)
|
||||
# in case of dependencies there can be multiple legal strings. We split
|
||||
# the legal strings into dependency strings and assign strings. Each
|
||||
# substring needs to be validated to indicate that value is indeed legal
|
||||
# for the current set of dependency vals.
|
||||
else:
|
||||
for legalstr in self.node['legal']:
|
||||
depstr = legalstr.split('->')[0]
|
||||
# we replace all boolean operators first to simple parse and the
|
||||
# check if the (in|not in|bitmask) operators are infact legal or
|
||||
# not.
|
||||
raw_depstr = re.sub('\(|\)|and|or','',depstr)
|
||||
|
||||
# implicitly assume it passes - in case of writeval and currval.
|
||||
dep_pass = True
|
||||
for m in self.regex_dep_legal.finditer(raw_depstr):
|
||||
(csrname, indices, op, vals) = m.groups()
|
||||
matchstr = m.group()
|
||||
|
||||
# in case the dependency is on writeval then we
|
||||
# assume the condition is always true.
|
||||
if csrname in ['writeval']:
|
||||
depstr = depstr.replace(matchstr, 'True')
|
||||
continue
|
||||
# in case the dependency is on the current val of the same
|
||||
# csr (before performing the write), then we continue by
|
||||
# replacing the currval string with the csrname::subfield
|
||||
# syntax
|
||||
if csrname == 'currval':
|
||||
if '::' in self.csrname:
|
||||
renamed_csr = self.csrname.split('::')[0]
|
||||
subfield = self.csrname.split('::')[1]
|
||||
else:
|
||||
renamed_csr = self.csrname
|
||||
subfield = ''
|
||||
else:
|
||||
_csrname = re.sub('{\d*}','',csrname)
|
||||
renamed_csr = list(filter(re.compile(f'[a-zA-Z0-9_]*[:]*{_csrname}\s*$').match, self.dependencies))[0]
|
||||
if '::' in renamed_csr:
|
||||
subfield = renamed_csr.split('::')[1]
|
||||
else:
|
||||
subfield = ''
|
||||
renamed_csr = renamed_csr.split('::')[0]
|
||||
# if the dependency_vals dict is not empty, then pick the
|
||||
# values of the csrs/subfields from there. Here we expect
|
||||
# the key in the dependency_vals dict to be a subfield
|
||||
# name without the `::` delimiter.
|
||||
if dependency_vals is not None:
|
||||
if csrname not in dependency_vals:
|
||||
err.append(f'in warl string of {self.csrname}, \
|
||||
the value of dependency field {csrname} not present in dependency_vals')
|
||||
return err
|
||||
else:
|
||||
dep_csr_val = dependency_vals[csrname]
|
||||
# else we pick the reset-vals from the isa spec (if the isa
|
||||
# spec was provided during contruction of the class). If the
|
||||
# dependency field is a subfield, then the reset-val of the
|
||||
# subfield has to be extracted from the reset-val of the csr
|
||||
elif self.spec is not None:
|
||||
if '{' in csrname:
|
||||
index_val = int(re.findall('{(\d*?)}',csrname)[0],0)
|
||||
logger.debug(f'dependent csr is indexed with val {index_val}')
|
||||
for i in self.spec[renamed_csr][self.isa]['index_list']:
|
||||
logger.debug(f'parsing {i["index_val"]}')
|
||||
if index_val == i['index_val']:
|
||||
dep_csr_val = i['reset-val']
|
||||
break
|
||||
else:
|
||||
if 'uarch_' in renamed_csr:
|
||||
dep_csr_val = self.uarch_signals[renamed_csr]['reset-val']
|
||||
else:
|
||||
dep_csr_val = self.spec[renamed_csr]['reset-val']
|
||||
if subfield != '':
|
||||
if 'uarch_' in renamed_csr:
|
||||
msb = self.uarch_signals[renamed_csr]['subfields'][subfield]['msb']
|
||||
lsb = self.uarch_signals[renamed_csr]['subfields'][subfield]['lsb']
|
||||
else:
|
||||
msb = self.spec[renamed_csr][self.isa][subfield]['msb']
|
||||
lsb = self.spec[renamed_csr][self.isa][subfield]['lsb']
|
||||
bitlen = msb - lsb + 1
|
||||
dep_csr_val = (dep_csr_val >> lsb) & \
|
||||
((1 << bitlen)-1)
|
||||
else:
|
||||
err.append(f'No dependency_vals or spec exists to \
|
||||
check the values of the csrs in the dependency_fields of csr {self.csrname}')
|
||||
return err
|
||||
|
||||
step_err = self.check_subval_legal(matchstr, dep_csr_val)
|
||||
err = err + step_err
|
||||
step_pass = True if step_err == [] else False
|
||||
depstr = depstr.replace(matchstr.strip(), str(step_pass))
|
||||
dep_pass = eval(depstr)
|
||||
|
||||
assignstr = legalstr.split('->')[1]
|
||||
assign_err = self.check_subval_legal(assignstr, value)
|
||||
err = err + assign_err
|
||||
assign_legal = True if assign_err == [] else False
|
||||
# if at any point both dependency strings and the assign strings
|
||||
# pass, then throw away the errors and treat it as a pass.
|
||||
if assign_legal and dep_pass:
|
||||
logger.debug(f' warl legal string "{legalstr}" treats the \
|
||||
input value {value} as legal')
|
||||
err = []
|
||||
break
|
||||
return err
|
||||
|
||||
def create_uarch_depends(self, uarch_signals):
|
||||
'''
|
||||
This function populates the uarch_depends dict with the csr/subfield
|
||||
'''
|
||||
|
||||
csrname = self.csrname
|
||||
reg_lsb = 0
|
||||
if self.f_lsb != 0:
|
||||
reg_msb = self.f_msb - self.f_lsb
|
||||
else:
|
||||
reg_msb = self.f_msb
|
||||
reg_bitlen = reg_msb - reg_lsb + 1
|
||||
for legalstr in self.node['legal']:
|
||||
depstr = legalstr.split('->')[0]
|
||||
raw_depstr = re.sub('\(|\)|and|or|\&\&|\|\|','',depstr)
|
||||
dep_str_matches = self.regex_dep_legal.findall(raw_depstr)
|
||||
|
||||
if '->' in legalstr:
|
||||
dependencies = self.node['dependency_fields']
|
||||
if dependencies != [] and self.spec is not None:
|
||||
for d in dependencies:
|
||||
subfield = ''
|
||||
if '::' in d:
|
||||
depcsrname = d.split('::')[0]
|
||||
subfield = d.split('::')[1]
|
||||
else:
|
||||
depcsrname = d
|
||||
|
||||
# if the depcsrname has the 'uarch_' prefix, then drop that dependency for all checks entirely
|
||||
if depcsrname.startswith('uarch_'):
|
||||
subfield_str = '' if subfield == '' else f'{subfield} field from '
|
||||
logger.warning(f'WARL for csr {csrname} depends on \
|
||||
{subfield_str}uarch csr {depcsrname}. Treating this as a uarch dependency.')
|
||||
if subfield == '':
|
||||
subfield = depcsrname
|
||||
depcsrname = 'uarch_signals'
|
||||
if depcsrname not in self.uarch_depends:
|
||||
self.uarch_depends[depcsrname] = []
|
||||
if subfield != '' and subfield not in self.uarch_depends[depcsrname]:
|
||||
self.uarch_depends[depcsrname].append(subfield)
|
||||
logger.debug(f'uArch dependencies are: {self.uarch_depends}')
|
||||
|
||||
for entry, signode in self.uarch_depends.items():
|
||||
if signode == []:
|
||||
continue
|
||||
else:
|
||||
# grouped uarch signals
|
||||
if entry in uarch_signals:
|
||||
for subfield in signode:
|
||||
if subfield in uarch_signals[entry]['subfields']:
|
||||
logger.debug(f'found csr {csrname} to depend on uArch signal {entry} \
|
||||
for the following subfields: {signode}.')
|
||||
else:
|
||||
logger.error(f'csr {csrname} depends on uArch signal {entry} \
|
||||
for the following subfields: {signode} but the uArch signal is not defined.')
|
||||
# ungrouped uarch signals
|
||||
else:
|
||||
for entry in signode:
|
||||
if entry in uarch_signals:
|
||||
logger.debug(f'found csr {csrname} to depend on uArch signal {entry}.')
|
||||
else:
|
||||
logger.error(f'csr {csrname} depends on uArch signal {entry} \
|
||||
but the uArch signal is not defined.')
|
||||
|
||||
def iserr(self):
|
||||
logger.debug(f'---- Checking for Errors in {self.csrname}')
|
||||
csrname = self.csrname
|
||||
reg_lsb = 0
|
||||
if self.f_lsb != 0:
|
||||
reg_msb = self.f_msb - self.f_lsb
|
||||
else:
|
||||
reg_msb = self.f_msb
|
||||
reg_bitlen = reg_msb - reg_lsb + 1
|
||||
err = []
|
||||
#basic checks
|
||||
#if dependencies is empty, then there should be only one legal string
|
||||
if self.dependencies == [] and len(self.node['legal']) > 1:
|
||||
err.append(f'for In absence of dependencies there should be only \
|
||||
1 legal string, instead found {len(self.node["legal"])}')
|
||||
if err:
|
||||
return err
|
||||
|
||||
# start checking legality of all legal strings
|
||||
for legalstr in self.node['legal']:
|
||||
depstr = legalstr.split('->')[0]
|
||||
raw_depstr = re.sub('\(|\)|and|or|\&\&|\|\|','',depstr)
|
||||
dep_str_matches = self.regex_dep_legal.findall(raw_depstr)
|
||||
|
||||
# if there are no dependencies then "->" should never be used in the
|
||||
# warl legal strings
|
||||
if '->' in legalstr and self.dependencies == []:
|
||||
err.append(f' found "->" in legal string "legalstr" when \
|
||||
dependency_fields is empty.')
|
||||
return err
|
||||
if self.dependencies != [] and not '->' in legalstr:
|
||||
err.append(f' missing "->" in legalstr since dependency_fields \
|
||||
is non empty')
|
||||
return err
|
||||
|
||||
if '->' in legalstr:
|
||||
dependencies = self.node['dependency_fields']
|
||||
if dependencies != [] and self.spec is not None:
|
||||
for d in dependencies:
|
||||
subfield = ''
|
||||
if '::' in d:
|
||||
depcsrname = d.split('::')[0]
|
||||
subfield = d.split('::')[1]
|
||||
else:
|
||||
depcsrname = d
|
||||
|
||||
# if the csr is a uarch dependency and also exists in the spec, throw an error
|
||||
if depcsrname in self.uarch_depends and depcsrname in self.spec:
|
||||
err.append(f' csr {csrname} depends on uarch csr \
|
||||
{depcsrname} which is also present in the spec. This is not allowed.')
|
||||
|
||||
# if the dependency is on writeval or currval of the
|
||||
# same csr, or is a uArch dependency, then no more checks required.
|
||||
if depcsrname not in ['writeval', 'currval'] and depcsrname not in self.uarch_depends and depcsrname not in self.uarch_depends['uarch_signals']:
|
||||
# if the csr doesn't exist then its probably a typo
|
||||
if depcsrname not in self.spec:
|
||||
err.append(f' warl for csr {csrname} depends on csr \
|
||||
{depcsrname} is not a valid csrname as per spec')
|
||||
# if csr exists, but is not accessible, then its a
|
||||
# pointless dependency
|
||||
elif not self.spec[depcsrname][self.isa]['accessible']:
|
||||
err.append(f' warl for csr {csrname} depends on csr \
|
||||
{depcsrname} is not accessible or not implemented in the isa yaml')
|
||||
# if csr exists and is accessible but subfield
|
||||
# doesn't exist, then its another typo
|
||||
elif subfield != '' and subfield not in self.spec[depcsrname][self.isa]:
|
||||
err.append(f' warl for csr {csrname} depends on \
|
||||
subfield {depcsrname}::{subfield} which does not exist as per spec')
|
||||
# if subfield is valid, but is not implemented, then
|
||||
# its another pointless dependency
|
||||
elif subfield !='' and not self.spec[depcsrname][self.isa][subfield]['implemented']:
|
||||
err.append(f' warl for csr {csrname} depends \
|
||||
on subfield {depcsrname}::{subfield} which is not implemented')
|
||||
|
||||
# ensure that all dependency csrs/subfields found in the
|
||||
# strings, are indeed present in the dependency_fields list
|
||||
# of the warl node.
|
||||
for matches in dep_str_matches:
|
||||
(csr, ind, op, val) = matches
|
||||
csr = re.sub('{\d*}','', csr)
|
||||
csr_in_dependencies = list(filter(re.compile(f'[a-zA-Z0-9_]*[:]*{csr}\s*$').match, dependencies))
|
||||
if csr_in_dependencies == []:
|
||||
for entry, subfields in self.uarch_signals.items():
|
||||
if csr == entry:
|
||||
csr_in_dependencies.append(csr)
|
||||
elif csr in subfields['subfields']:
|
||||
csr_in_dependencies.append(f'{csr}::{subfield}')
|
||||
if csr_in_dependencies == []:
|
||||
err.append(f' dependency_vals string "{depstr}" for csr \
|
||||
{csrname} is dependent on field {csr} which is not present in the \
|
||||
dependency_fields list of the node')
|
||||
|
||||
for matches in dep_str_matches:
|
||||
(csr, indices, op, val) = matches
|
||||
# only in and not-in are supported inside dependency
|
||||
# strings. Bitmask do not make sense as a boolean operation.
|
||||
if op not in ['in', 'not in']:
|
||||
err.append(f' the dependency_vals string {depstr} for csr \
|
||||
{csr} uses operation "{op}" which is not supported. Use only "in" and "not in" \
|
||||
operations only')
|
||||
|
||||
msb = int(indices.split(':')[0], 0)
|
||||
if ':' in indices:
|
||||
lsb = int(indices.split(':')[1], 0)
|
||||
else:
|
||||
lsb = msb
|
||||
# for range value strings, indices msb::lsb syntax to be
|
||||
# followed where msb > lsb
|
||||
if msb < lsb:
|
||||
err.append(f'msb < lsb for one of the \
|
||||
dependency_vals in warl string {legalstr} in csr {csrname}')
|
||||
maxval = 2**(msb - lsb + 1 )
|
||||
values = val.split(',')
|
||||
|
||||
# for each range value, check if the base and bound are
|
||||
# correctly ordered and within the possible values of the
|
||||
# csr/subfield
|
||||
for v in values:
|
||||
base = int(v.split(':')[0], 0)
|
||||
if ':' in v:
|
||||
bound = int(v.split(':')[1], 0)
|
||||
else:
|
||||
bound = base
|
||||
if base >= maxval or bound >= maxval:
|
||||
err.append(f'The range values in dependency_vals of warl\
|
||||
string "{legalstr}" for csr {csrname} are out of bounds wrt the indices used \
|
||||
in that string')
|
||||
if base > bound:
|
||||
err.append(f' base > bound for range \
|
||||
values in dependency_vals of the warl string "{legalstr}" for csr {csrname}')
|
||||
|
||||
lstr = legalstr.split('->')[-1]
|
||||
bitcount = reg_bitlen
|
||||
|
||||
assigns = self.regex_legal.findall(lstr)
|
||||
# if there is not match, then something is wrong in the string.
|
||||
if assigns == []:
|
||||
err.append(f' The legal string "{legalstr}" for csr \
|
||||
{csrname} does not follow warl syntax')
|
||||
# split the assignment string and process each individually.
|
||||
for a in assigns:
|
||||
(indices, op, vals) = a
|
||||
|
||||
# msb lsb checks just as before
|
||||
msb = int(indices.split(':')[0], 0)
|
||||
if ':' in indices:
|
||||
lsb = int(indices.split(':')[1], 0)
|
||||
else:
|
||||
lsb = msb
|
||||
if msb < lsb:
|
||||
err.append(f'msb < lsb for one of the \
|
||||
range values in warl string {legalstr} in csr {csrname}')
|
||||
if msb > reg_msb or lsb < reg_lsb:
|
||||
err.append(f' The indices used in warl \
|
||||
string "{legalstr}" of csr {csrname} do not comply with the msb[{reg_msb}] and lsb[{reg_lsb}] values \
|
||||
of the register')
|
||||
|
||||
# we need to ensure that the assignment string eventually
|
||||
# defines the legal value for all the bits (and not just a few).
|
||||
# To check this we use a counter (bitcount) which is initialized
|
||||
# to the size of the register/subfield. And each time a part of
|
||||
# the assignment string is evaluated, we decrease the bitcount
|
||||
# by the size of the assigment. At the end, if the bitcount is
|
||||
# not zero then there is something wrong in the entire
|
||||
# assignment string.
|
||||
bitcount = bitcount - (msb-lsb+1)
|
||||
bitlength = msb - lsb + 1
|
||||
reg_maxval = 2**bitlength
|
||||
maxval = 2**bitlength
|
||||
if op not in ['in', 'not in', 'bitmask']:
|
||||
err.append(f' the warl string {legalstr} for csr \
|
||||
{csr} uses operation "{op}" which is not supported. Use only "in", "bitmask" and "not in" \
|
||||
operations only')
|
||||
if 'bitmask' in op:
|
||||
if len(vals.split(',')) != 2:
|
||||
err.append(f'bitmask syntax is wrong in legal string \
|
||||
{legalstr}')
|
||||
break
|
||||
mask = int(vals.split(',')[0], 0)
|
||||
fixedval = int(vals.split(',')[1], 0)
|
||||
if mask > reg_maxval or fixedval > reg_maxval:
|
||||
err.append(f' The mask and/or fixedval used in \
|
||||
bitmask string "{legalstr}" of csr {csrname} have values exceeding the \
|
||||
maxvalue the csr can take.')
|
||||
else:
|
||||
values = vals.split(',')
|
||||
for v in values:
|
||||
base = int(v.split(':')[0], 0)
|
||||
if ':' in v:
|
||||
bound = int(v.split(':')[1], 0)
|
||||
else:
|
||||
bound = base
|
||||
if base >= maxval or bound >= maxval:
|
||||
err.append(f'The range values in warl \
|
||||
string "{legalstr} for csr {csrname} are out of bounds wrt the indices used \
|
||||
in that string')
|
||||
if base > bound:
|
||||
err.append(f' base > bound for range \
|
||||
values in warl string "{legalstr}" for csr {csrname}')
|
||||
|
||||
if bitcount < 0:
|
||||
err.append(f' warl string "{legalstr}" defines values for bits \
|
||||
outside the size of the register "{reg_bitlen}"')
|
||||
elif bitcount != 0:
|
||||
err.append(f' warl string "{legalstr}" for csr \
|
||||
"{csrname}" either does not define values for all bits or has overlapping ranges \
|
||||
defining the same bits multiple times')
|
||||
|
||||
return err
|
||||
|
16
vendor/riscv/riscv-config/setup.cfg
vendored
Normal file
16
vendor/riscv/riscv-config/setup.cfg
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
[bumpversion]
|
||||
current_version = 3.18.1
|
||||
commit = True
|
||||
tag = True
|
||||
|
||||
[bumpversion:file:riscv_config/__init__.py]
|
||||
search = __version__ = '{current_version}'
|
||||
replace = __version__ = '{new_version}'
|
||||
|
||||
[bdist_wheel]
|
||||
universal = 1
|
||||
|
||||
[flake8]
|
||||
exclude = docs
|
||||
|
||||
[aliases]
|
41
vendor/riscv/riscv-config/setup.py
vendored
Normal file
41
vendor/riscv/riscv-config/setup.py
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
import os
|
||||
import codecs
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
import riscv_config
|
||||
|
||||
# Base directory of package
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
|
||||
def read(*parts):
|
||||
with codecs.open(os.path.join(here, *parts), 'r') as fp:
|
||||
return fp.read()
|
||||
|
||||
|
||||
#Long Description
|
||||
with open("README.rst", "r") as fh:
|
||||
long_description = fh.read()
|
||||
|
||||
setup(name="riscv_config",
|
||||
version=riscv_config.__version__,
|
||||
description="RISC-V Configuration Validator",
|
||||
long_description=long_description,
|
||||
classifiers=[
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"License :: OSI Approved :: BSD License",
|
||||
"Development Status :: 4 - Beta"
|
||||
],
|
||||
url='https://github.com/riscv/riscv-config',
|
||||
author='InCore Semiconductors Pvt. Ltd.',
|
||||
author_email='neelgala@incoresemi.com',
|
||||
license='BSD-3-Clause',
|
||||
packages=find_packages(),
|
||||
install_package_data=True,
|
||||
package_dir={'riscv_config': 'riscv_config/'},
|
||||
package_data={'riscv_config': ['schemas/*']},
|
||||
install_requires=['Cerberus>=1.3.1', 'ruamel.yaml>=0.17.16', 'pyyaml==5.2'],
|
||||
python_requires=">=3.7.0",
|
||||
entry_points={
|
||||
"console_scripts": ["riscv-config=riscv_config.main:main"],
|
||||
})
|
14
vendor/riscv_riscv-config.lock.hjson
vendored
Normal file
14
vendor/riscv_riscv-config.lock.hjson
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// This file is generated by the util/vendor script. Please do not modify it
|
||||
// manually.
|
||||
|
||||
{
|
||||
upstream:
|
||||
{
|
||||
url: https://github.com/riscv/riscv-config.git
|
||||
rev: 3416efeb219b0b743013266c0341697b3580b625
|
||||
}
|
||||
}
|
28
vendor/riscv_riscv-config.vendor.hjson
vendored
Normal file
28
vendor/riscv_riscv-config.vendor.hjson
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2024 Thales DIS France SAS
|
||||
// SPDX-License-Identifier: Apache-2.0.
|
||||
// Original Author: Zbigniew Chamski (Thales)
|
||||
|
||||
{
|
||||
// Name of the project
|
||||
name: "riscv-config",
|
||||
|
||||
// Target directory: relative to the location of this script.
|
||||
target_dir: "riscv/riscv-config",
|
||||
|
||||
// Upstream repository
|
||||
upstream: {
|
||||
// URL
|
||||
url: "https://github.com/riscv/riscv-config.git",
|
||||
// revision
|
||||
rev: "3.18.1",
|
||||
}
|
||||
|
||||
// Patch dir for local changes
|
||||
patch_dir: "patches/riscv/riscv-config",
|
||||
|
||||
// Exclusions from upstream content
|
||||
exclude_from_upstream: [
|
||||
".github",
|
||||
]
|
||||
}
|
Loading…
Add table
Reference in a new issue