Welcome to RISCV-Config

Welcome to RISC-V Configuration Validator documentation.

For information about the changes and additions for releases, please refer to the Revisions documentation.

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

RISCV-Config [Repository]

Overview

The following diagram captures the overall-flow of RISCV-Config.

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 : 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 : 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.

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.

$ pip3 install riscv_config

To update an already installed version of RISCV-CONFIG to the latest version:

$ pip3 install -U riscv_config

To checkout a specific version of riscv_config:

$ 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.

$ 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

$ riscv-config -ispec examples/rv32i_isa.yaml -pspec examples/rv32i_platform.yaml

Executing the above command should display the following on the terminal:

[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

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

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

Vendor

  • Description: A string capturing the vendor name.

  • Examples:

    Vendor: Shakti
    Vendor: Incoresemi
    

Device

  • Description: A string capturing the device name.

  • Examples:

    Device: E-Class
    Device: C-Class
    

ISA

  • Description: Takes input a string representing the ISA supported by the implementation. All extension names (other than Zext) should be mentioned in upper-case. Z extensions should begin with an upper-case ‘Z’ followed by lower-case extension name (without Camel casing)

  • Default: This is a required field to be set by the user. No defaults exist.

  • Constraints:

    • Certain extensions are only valid in certain user-spec version. For, eg. Zifencei is available only in user-spec 2.3 and above.

    • The ISA string must be specified as per the convention mentioned in the specifications(like subsequent Z extensions must be separated with an ‘_’)

  • Examples:

    ISA: RV32IMA
    ISA: RV64IMAFDCZifencei
    

User_Spec_Version

  • Description: Version number of User/Non-priveleged ISA specification as string. Please enclose the version in “” to avoid type mismatches.

  • Default: 2.2

  • Constraints: should be a valid version later than 2.2

  • Examples:

    User_Spec_Version: "2.2"
    User_Spec_Version: "2.3"
    

Privilege_Spec_Version

  • Description: Version number of Priveleged ISA specification as string. Please enclose the version in “” to avoid type mismatches.

  • Default: “1.10”

  • Constraints: should be a valid version later than 1.10

  • Examples:

    Privilege_Spec_Version: "1.10"
    Privilege_Spec_Version: "1.11"
    

hw_data_misaligned_support

  • Description: A boolean value indicating whether hardware support for misaligned load/store requests exists.

  • Default: False

  • Constraints: None

  • Examples:

    hw_data_misaligned_support: True
    hw_data_misaligned_support: False
    

supported_xlen

  • Description: list of supported xlen on the target

  • Default: This is a required field to be set by the user. No defaults exist.

  • Constraints: list should include integers from: 32, 64 and/or 128. XLEN=128 is not fully supported though.

  • Examples:

    supported_xlen : [32]
    supported_xlen : [64, 32]
    supported_xlen : [64]
    

pmp_granularity

  • Description: Granularity of pmps

  • Default: 0

  • Constraints: None

  • Examples:

    pmp_granularity : 2
    pmp_granularity : 4
    

physical_addr_sz

  • Description: size of the physical address

  • Default: This is a required field to be set by the user. No defaults exist.

  • Constraints: cannot exceed 56 bits

  • Examples:

    physical_addr_sz : 32
    

custom_exceptions

  • Description: A dictionary of custom exceptions implemented by the device. Each node in the dictionary contains 3 fields:

    • cause_val: and integer indicating the cause value associated with that exception. Cannot be a reserved cause value.

    • cause_name: a string containing the name of the exception

    • priv_mode: a string containing one-of M, S or U indicating the privilege mode to which the exception is associated with.

  • Default: null dictionary indicating no custom exceptions exist.

  • Constraints: Reserved encodings cannot be used in cause_val

  • Examples:

    custom_exceptions:
      - cause_val: 25
        cause_name: mycustom
        priv_mode: M
      - cause_val: 26
        cause_name: mycustom2
        priv_mode: M
    

custom_interrupts

  • Description: A dictionary of custom interrupts implemented by the device. Each node in the dictionary contains 4 fields:

    • cause_val: and integer indicating the cause value associated with that interrupt. Cannot be a reserved cause value.

    • cause_name: a string containing the name of the interrupt

    • priv_mode: a string containing one-of M, S or U indicating the privilege mode to which the exception is associated with.

    • on_reset_enable: an integer which be 0 or 1, indicating the whether the interrupt is enable on reset or not.

  • Default: null dictionary indicating no custom exceptions exist.

  • Constraints: Reserved encodings cannot be used in cause_val

  • Examples:

    custom_interrupts:
      - cause_val: 25
        cause_name: mycustom
        priv_mode: M
        on_reset_enable: 1
      - cause_val: 26
        cause_name: mycustom2
        priv_mode: S
        on_reset_enable: 0
    

pte_ad_hw_update

  • Description: This is a boolean field indicating that when a virtual page is accessed and the A bit is clear, or is written and the D bit is clear, the implementation sets the corresponding bit(s) in the PTE in the hardware itself and does not raise an exception for this particular scenario. When set to False, a corresponding page-fault exception needs to be raised.

  • Default: False

  • Constraints: Can be set to True only if ‘S’ mode is implemented in the ISA and if stap.mode can be set to one of the virtualization modes.

  • Examples:

    pte_ad_hw_update: False
    pte_ad_hw_update: True
    

mtval_update

  • Description: This field a basically a bitmap. If bit n is set, it indicates that the device will update the mtval CSR with a non-zero value when an exception corresponding to cause n occurs. A value of zero will indicate that the exception n will update the mtval with value 0.

  • Default: 255 (set for exception cause values 0-7)

  • Constraints:

    • reserved bits [10, 11, 16-23, 32-47, >=64] must be zeros always

    • bits corresponding to page-faults can only be set if ‘S’ mode is implemented

    • bits corresponding to guest-page faults can only be set if ‘H’ mode is implemented

  • Examples:

    mtval_update: 0b1110
    

CSR Template

All csrs are defined using a common template. Two variants are available: csrs with subfields and those without

CSRs with sub-fields

<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.
      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.

CSRs without sub-fields

<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.
    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

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:

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:

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.

    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.

    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:

# 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:

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:

    - 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.

  • 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:

    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:

    <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:

    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:

    (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:

    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:

      if ( val < base || val > bound)
          return Flip-MSB of field
      

Examples

# 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

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.

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:

    reset:
      label: reset_vector
    reset:
      label: 0x80000000
    

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:

    nmi:
       label: nmi_vector
    
    nmi:
       address: 0x8000000
    

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:

    mtime:
       implemented: True
       address: 0x458
    

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:

    mtimecmp:
       implemented: True
       address: 0x458
    

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:

TBD: Provide a concrete use-case for the above.

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:

    scause_non_standard:
       implemented: True
       value: [16,17,20]
    

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:

    TBD: Provide a concrete use-case for the above.
    

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:

    zicbo_cache_block_sz :
      implemented: true
      zicbom_sz: 64
      zicboz_sz: 64
    

Debug YAML Spec

supported_xlen

Description: list of supported xlen on the target

Examples:

supported_xlen : [32]
supported_xlen : [64, 32]
supported_xlen : [64]

Constraints:

  • None

Debug_Spec_Version

Description: Version number of Debug specification as string. Please enclose the version in “” to avoid type mismatches.

Examples:

Debug_Spec_Version: "1.0.0"
Debug_Spec_Version: "0.13.2"

Constraints:

  • should be a valid version later than 1.0.0

debug_mode

Description: Boolean value indicating if the debug instructions are accessible.

Examples:

debug_mode: False

parking_loop

Description: Integer value indicating the address of the debug parking loop

Examples:

parking_loop: 0x800

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 node. Following is an instance of the node for reference:

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 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).

  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).

  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)

  4. Similar canonical ordering checks for performed for the Z extension subsets as well (here).

  5. Finally, a series of if based checks are performed on the extension_list to see if any illegal combination exists (here)

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:

(...)
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 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.

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.

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 :

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

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.

schema_yaml['stval']['default_setter'] = sregsetter
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.

The code below shows an example of how the debug spec is added as an argument to the cli parser module:

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 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 : riscv_config.checker.

Details on the checks like s_debug_check() and u_debug_check, that can also be added to SchemaValidator.py are here: riscv_config.schemaValidator.

Modifications in Constants.py

The new schema must be added in the constants.py to detect its path globally across other files.

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.

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)

Code Documentation

riscv_config.checker

riscv_config.checker.add_debug_setters(schema_yaml)[source]

Function to set the default setters for various fields in the debug schema

riscv_config.checker.add_def_setters(schema_yaml)[source]

Function to set the default setters for various fields in the schema

riscv_config.checker.add_reset_setters(schema_yaml)[source]

Function to set the default setters for extension subfields in the misa

riscv_config.checker.check_custom_specs(custom_spec, work_dir, logging=False, no_anchors=False)[source]

Function to perform ensure that the isa and platform specifications confirm to their schemas. The Cerberus module is used to validate that the specifications confirm to their respective schemas.

Parameters
  • isa_spec (str) – The path to the DUT isa specification yaml file.

  • logging (bool) – A boolean to indicate whether log is to be printed.

Raises

ValidationError – It is raised when the specifications violate the schema rules. It also contains the specific errors in each of the fields.

Returns

A tuple with the first entry being the absolute path to normalized isa file and the second being the absolute path to the platform spec file.

riscv_config.checker.check_debug_specs(debug_spec, isa_spec, work_dir, logging=False, no_anchors=False)[source]

Function to perform ensure that the isa and debug specifications confirm to their schemas. The Cerberus module is used to validate that the specifications confirm to their respective schemas.

Parameters
  • debug_spec – The path to the DUT debug specification yaml file.

  • isa_spec (str) – The path to the DUT isa specification yaml file.

  • logging (bool) – A boolean to indicate whether log is to be printed.

Raises

ValidationError – It is raised when the specifications violate the schema rules. It also contains the specific errors in each of the fields.

Returns

A tuple with the first entry being the absolute path to normalized isa file and the second being the absolute path to the platform spec file.

riscv_config.checker.check_isa_specs(isa_spec, work_dir, logging=False, no_anchors=False)[source]

Function to perform ensure that the isa and platform specifications confirm to their schemas. The Cerberus module is used to validate that the specifications confirm to their respective schemas.

Parameters
  • isa_spec (str) – The path to the DUT isa specification yaml file.

  • logging (bool) – A boolean to indicate whether log is to be printed.

Raises

ValidationError – It is raised when the specifications violate the schema rules. It also contains the specific errors in each of the fields.

Returns

A tuple with the first entry being the absolute path to normalized isa file and the second being the absolute path to the platform spec file.

riscv_config.checker.check_mhpm(spec, logging=False)[source]

Check if the mhpmcounters and corresponding mhpmevents are implemented and of the same size as the source

riscv_config.checker.check_pmp(spec, logging=False)[source]

Check if the pmp csrs are implemented correctly as per spec. The following checks are performed:

  • the number of accessible pmpaddr csrs must be 0, 16 or 64

  • the number of implemented pmpcfg csrs must be 0, 16 or 64

  • the pmpaddr and pmpcfgs must be implemented implemented from the lowest numbered indices and be contiguous

  • the number of accessible pmpaddr csrs and the implemented pmpcfg csrs must be the same

  • for each accesible pmpaddr csr the corresponding pmpcfg csr must be implemented

  • reset values of the accessible pmpaddr csrs must be coherent with the pmp_granularity field.

riscv_config.checker.check_reset_fill_fields(spec, logging=False)[source]

The check_reset_fill_fields function fills the field node with the names of the sub-fields of the register and then checks whether the reset-value of the register is a legal value. To do so, it iterates over all the subfields and extracts the corresponding field value from the reset-value. Then it checks the legality of the value according to the given field description. If the fields is implemented i.e accessible in both 64 bit and 32 bit modes, the 64 bit mode is given preference.

riscv_config.checker.check_shadows(spec, logging=False)[source]

Check if the shadowed fields are implemented and of the same size as the source

riscv_config.checker.check_supervisor(spec, logging=False)[source]

this function includes several supervisor related checks:

  • check if pte_ad_hw_update is True, then satp.mode should be able to take one of the possible virtualization modes

riscv_config.checker.delegset()[source]

Function to set “implemented” value for mideleg regisrer.

riscv_config.checker.fsset()[source]

Function to set defaults based on presence of ‘F’ extension.

riscv_config.checker.groupc(test_list)[source]

Generator function to squash consecutive numbers for wpri bits.

riscv_config.checker.hregset()[source]

Function to set defaults based on presence of ‘H’ extension.

riscv_config.checker.hregseth()[source]

Function to set defaults based on presence of ‘H’ extension.

riscv_config.checker.hset()[source]

Function to set defaults based on presence of ‘U’ extension.

riscv_config.checker.nregset()[source]

Function to set defaults based on presence of ‘N’ extension.

riscv_config.checker.nuset()[source]

Function to check and set defaults for all fields which are dependent on the presence of ‘U’ extension and ‘N’ extension.

riscv_config.checker.reset()[source]

Function to set defaults to reset val of misa based on presence of ISA extensions.

riscv_config.checker.reset_vsstatus()[source]

Function to set defaults to reset val of mstatus based on the xlen and S, U extensions

riscv_config.checker.resetsu()[source]

Function to set defaults to reset val of mstatus based on the xlen and S, U extensions

riscv_config.checker.sregset()[source]

Function to set defaults based on presence of ‘S’ extension.

riscv_config.checker.sregseth()[source]

Function to set defaults based on presence of ‘S’ extension.

riscv_config.checker.sset()[source]

Function to set defaults based on presence of ‘S’ extension.

riscv_config.checker.trim(foo)[source]

Function to trim the dictionary. Any node with implemented field set to false is trimmed of all the other nodes.

Parameters

foo (dict) – The dictionary to be trimmed.

Returns

The trimmed dictionary.

riscv_config.checker.twset()[source]

Function to check and set value for tw field in misa.

riscv_config.checker.uregset()[source]

Function to set defaults based on presence of ‘U’ extension.

riscv_config.checker.uregseth()[source]

Function to set defaults based on presence of ‘U’ extension.

riscv_config.checker.uset()[source]

Function to set defaults based on presence of ‘U’ extension.

riscv_config.schemaValidator

class riscv_config.schemaValidator.schemaValidator(*args, **kwargs)[source]

Custom validator for schema having the custom rules necessary for implementation and checks.

__init__(*args, **kwargs)[source]

The arguments will be treated as with this signature:

__init__(self, schema=None, ignore_none_values=False,

allow_unknown=False, require_all=False, purge_unknown=False, purge_readonly=False, error_handler=errors.BasicErrorHandler)

_check_with_cannot_be_false_rv32(field, value)[source]

Functions ensures that the field cannot be False in rv32 mode

_check_with_cannot_be_false_rv64(field, value)[source]

Functions ensures that the field cannot be False in rv64 mode

_check_with_capture_isa_specifics(field, value)[source]

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.

_check_with_max_length(field, value)[source]

Function to check whether the given value is less than the maximum value that can be stored(2^xlen-1).

_check_with_max_length32(field, value)[source]

Function to check whether the given value is less than the maximum value that can be stored(2^xlen-1).

_check_with_mtval_update(field, value)[source]

Function to check if the mtval_update bitmap adhered to the required restrictions.

_check_with_s_debug_check(field, value)[source]

Function ensures that the ro_constant is hardwired to zero when S is present in the ISA string Used mainly for debug schema

_check_with_s_exists(field, value)[source]

Function to check that the value can be true only when ‘S’ mode exists in the ISA string

_check_with_u_debug_check(field, value)[source]

Function ensures that the ro_constant is hardwired to zero when U is present in the ISA string Used mainly for debug schema

_check_with_xcause_check(field, value)[source]

Function to verify the inputs for mcause.

_check_with_xtveccheck(field, value)[source]

Function to check whether the inputs in range type in mtvec are valid.

Utils

class riscv_config.utils.ColoredFormatter(*args, **kwargs)[source]

Class to create a log output which is colored based on level.

__init__(*args, **kwargs)[source]

Initialize the formatter with specified format strings.

Initialize the formatter either with the specified format string, or a default as described above. Allow for specialized date formatting with the optional datefmt argument. If datefmt is omitted, you get an ISO8601-like (or RFC 3339-like) format.

Use a style parameter of ‘%’, ‘{‘ or ‘$’ to specify that you want to use one of %-formatting, str.format() ({}) formatting or string.Template formatting in your format string.

Changed in version 3.2: Added the style parameter.

format(record)[source]

Format the specified record as text.

The record’s attribute dictionary is used as the operand to a string formatting operation which yields the returned string. Before formatting the dictionary, a couple of preparatory steps are carried out. The message attribute of the record is computed using LogRecord.getMessage(). If the formatting string uses the time (as determined by a call to usesTime(), formatTime() is called to format the event time. If there is exception information, it is formatted using formatException() and appended to the message.

class riscv_config.utils.SortingHelpFormatter(prog, indent_increment=2, max_help_position=24, width=None)[source]
riscv_config.utils.setup_logging(log_level)[source]

Setup logging

Verbosity decided on user input

Parameters

log_level (str) – User defined log level

WARL

class riscv_config.warl.warl_class(node, csrname, f_msb, f_lsb, spec=None)[source]

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:

warl:
   dependency_fields: [list]
   legal: [list of warl-string]
   wr_illegal: [list of warl-string]
Parameters
  • node (dict) – This input is the dict adhering to the above syntax.

  • csrname (str) – 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.

  • f_msb (int) – the max msb location of the csr or subfield.

  • f_lsb (int) – the min lsb location of the csr or subfield.

  • spec (dict) – 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.

__init__(node, csrname, f_msb, f_lsb, spec=None)[source]

Constructor Method

__weakref__

list of weak references to the object (if defined)

This function checks if a given value satifies the conditions present in a given legal string.

Parameters
  • legalstr (str) – This is a string following the warl-legal syntax.

  • value (int) – The value whose legality to be checked against the warl-legal string

Returns

A list of error strings encountered while performing the checks on a legal string

Return type

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.

getlegal(dependency_vals=[])[source]

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.

Parameters

dependency_vals (dict) – This is dictionary of csr:value pairs which indicates the current value of csrs/subfields present in the dependency_fields of the warl node.

Returns

A single integer value which is considered legal for the csr under the provided dependency_vals arg

Return type

int

islegal(value, dependency_vals=None)[source]

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.

Parameters
  • value (int) – input integer whose legality needs to be checked for the csr/subfield warl node.

  • dependency_vals (dict) – This is dictionary of csr:value pairs which indicates the current value of csrs/subfields present in the dependency_fields of the warl node.

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 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 ??

Changelog

This project adheres to Semantic Versioning.

[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 isaspecs 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.

Indices and tables