6. Generator Plugins

6.1. AAPG

Automated Assembly Program Generator [AAPG] plugin is based on the tool developed by Team Shakti to generate random RISC-V Assembly programs to test RISC-V cores.

6.1.1. Installation

  1. Install AAPG

    The easiest way to install aapg is to use pip.

    $ pip install aapg
    

    To stay up-to date with the latest developments and fixes you can use the development version.

    $ git clone https://gitlab.com/shaktiproject/tools/aapg
    $ cd aapg
    $ python3 setup.py install
    

    This will install aapg on your path.

  2. Download the pre-built aapg_plugin from river_core_plugins

    The aapg_plugin can be found in the Generator plugins repo in the river_core_plugins repository.

    $ git clone https://github.com/incoresemi/river_core_plugins
    $ cd generator_plugins/aapg_plugin/
    

6.1.2. Configuring the Plugin

A YAML file is placed in the aapg plugin folder with the name aapg_gen_config.yaml.

  • global_config_path -> Path to the plugin directory

  • global_command -> Command to generate files. i.e. aapg gen

  • templates -> Ideally the test yamls for AAPG can be stored in a folder which can be then filtered via the filter option in the config.ini file.

# Preferred name scheme is given as an example
templates:
   rv64imafdc:
      path: templates/chromite

6.1.3. Output from the plugin

The gen hook of the plugin must return a dictionary of the test and their attributes as defined by the Test List Format.

6.1.4. Instance in config.ini

To use AAPG in the config.ini the following template can be followed:

path_to_suite = ~/river_core_plugins/generator_plugins
generator = aapg

[aapg]
# Number of jobs to use to generate the tests
jobs = 8
# Filter for your tests to only use config file whose name matches the regex rv64imafdc_hazards_s
filter = rv64imafdc_hazards_s
seed = random
# number of tests per selected config file
count = 2
# path to any gen_config yaml which can be used by the AAPG plugin as described above.
config_yaml = /scratch/git-repo/incoresemi/river-framework/core-verification/river_core_plugins/generator_plugins/aapg_plugin/aapg_gen_config.yaml

Note

one can maintain multiple *_gen_config.yaml files and simple point to them in the main config.ini to change configurations.

6.2. Testfloat

Testfloat plugin is based on the on the Berkeley TestFloat program, which checks whether an implementation of binary floating-point conforms to the IEEE Standard for Floating-Point Arithmetic. This particular plugin will convert the test-float generated tests into RISC-V assembly test files. This plugin does not generate self-checking tests and thus ignore the golden the value generated by the testfloat_gen tool.

List of RISC-V instructions currently supported are:

  • FADD.[S|D]

  • FSUB.[S|D]

  • F[N]MADD.[S|D]

  • F[N]MSUB.[S|D]

  • FMUL.[S|D]

  • FDIV.[S|D]

  • FSQRT.[S|D]

  • FEQ.[S|D]

  • FLE.[S|D]

  • FLT.[S|D]

  • FCVT.[W|WU|L|LU].[S|D]

  • FCVT.[S|D].[W|WU|L|LU]

  • FCVT.[S|D].[D|S]

6.2.1. Assembly Macros

This plugin converts test-float output to risc-v assembly using assembly macros which can be found in the asm/test.h file. The macros are defined based on the number of operands required for an isntruction:

  • TEST_R_OP: Used for single operand operations like fqsrt, fcvt, etc

  • TEST_RR_OP: Used for ops requiring 2 operands like fadd, feq, etc

  • TEST_RRR_OP: Used for ops requiring 3 operands like fmadd, fmsub, etc

Each macro will first update the rounding mode in frm csr. Then load the operands from the memory section into respective registers, perform the op and read the fflags csr into an integer register.

6.2.2. Pre-requisites

You’ll have to install the above Testfloat (Release 3e) and the Berkeley SoftFloat into a common directory.

  1. Install Berkeley Testfloat

    Download the Testfloat and Softfloat ZIP files.

    $ wget 'http://www.jhauser.us/arithmetic/TestFloat-3e.zip'
    $ wget 'http://www.jhauser.us/arithmetic/SoftFloat-3e.zip'
    
  2. Unzip both the ZIP files

    $ unzip TestFloat-3e.zip
    $ unzip SoftFloat-3e.zip
    
  3. Build the Testfloat and Softfloat utilities.

    #Assuming that your system is a x86-64 system with GCC
    $ cd SoftFloat-3e/build/Linux-x86_64-GCC/
    #Other alternatives are available in build, please check your system configuration before running make
    $ make
    
    #Assuming that your system is a x86-64 system with GCC
    $ cd TestFloat-3e/build/Linux-x86_64-GCC/
    #Other alternatives are available in build, please check your system configuration before running make
    $ make
    

6.2.3. Setting up your plugin

A YAML file is placed in the testfloat plugin folder with the name testfloat_gen_config.yaml.

  • gen_binary_path -> Path to the testfloat_gen command

As for the instructions to be generated using the plugin, one has to follow the below convention to generate files.

# path to where the testfloat_gen path. The following is enough if it exists in your $PATH
gen_binary_path: testfloat_gen

# Essential to start set_* for naming, that's how the plugin detects the name
set_1:
    # Instruction to generate using the plugin
    inst: [fadd.s, fsub.s, fmul.s, fdiv.s]
    # Range of possible values for the destination register
    dest: 0,31
    # Range of possible values for the source register 1
    reg1: 0,31
    # Range of possible values for the source register 2
    reg2: 0,31
    # Rounding mode for the floating point operation. Legal values are: RNE, RTZ, RDN, RUP, RMM
    rounding-mode: [RNE]
    # Needs to be above 46464. this is a testfloat limitation.
    tests_per_instruction: 46464
    # Number of tests generated per instruction per rounding mode combination
    num_tests: 4

# you can define a new set with new combinations in the same file. Generator will parse through all sets
set_5:
     inst: [fmadd.s]
     dest: 0,9
     reg1: 0,12
     reg2: 0,10
     reg3: 0,10
     rounding-mode: [RUP]
     tests_per_instruction: 6133248 # needs to be above minimum definition required by testfloat
     num_tests: 8

Additionally you will need to define the simulation halt/end condition in an assembly macro RVMODEL_HALT which is located in the asm/model.h file of the plugin folder. An example of the macro for chromite DUT and spike REF is given below:

#define RVMODEL_HALT                    \
   .align 2;                            \
   .option push;                        \
   .option norvc;                       \
   la t6, 1f;                           \
   csrw mtvec, t6;                      \
   fence.i;                             \
   li t6,  0x20000;                     \
   la t5, begin_rvtest_data;            \
   sw t5, 0(t6);                        \
   la t5, begin_rvtest_data+8;          \
   sw t5, 8(t6);                        \
   sw t5,  12(t6);                      \
1:                                      \
  li t1, 1;                             \
  write_tohost:                         \
    sw t1, tohost, t4;                  \
    j write_tohost;                     \
.option pop;

Line-3 updates the mtvec to point to the self-loop required for terminating spike. Lines-4 to 10 are used for terminating the simulation on Chromite.

The user may also change the linker script available at: asm/link.ld as per the model. Note however the entry point for the tests will always be rvtest_entry_point

6.2.4. Output from the plugin

The gen hook of the plugin must return a dictionary of the test and their attributes as defined by the Test List Format.

6.2.5. Instance in config.ini

To use TestFloat in the config.ini the following template can be followed:

path_to_suite = ~/river_core_plugins/generator_plugins
generator = testfloat

[testfloat]
# number of parallel jobs
jobs=8
# seed to use for testfloat_gen command
seed = random
# path to the yaml conforming to the above spec.
config_yaml = /scratch/git-repo/incoresemi/river-framework/core-verification/river_core_plugins/generator_plugins/testfloat_plugin/testfloat_gen_config.yaml

Note

one can maintain multiple *_gen_config.yaml files and simple point to them in the main config.ini to change configurations.

6.3. MicroTESK Random Generator

MicroTESK generator has the RISC-V model developed in nML language and it is used for generation of RISC-V tests from the templates.

# generator setup
$ wget https://forge.ispras.ru/attachments/download/7191/microtesk-riscv-0.1.0-beta-191227.tar.gz
$ tar -xvzf microtesk-riscv-0.1.0-beta-191227.tar.gz
$ cd microtesk-riscv-0.1.0-beta-191227
$ export MICROTESK_HOME=$PWD
$ sudo apt-get install -y openjdk-11-jdk-headless

# compiling the model
$ bash $PWD/bin/compile.sh $PWD/arch/riscv/model/riscv.nml $PWD/arch/riscv/model/mmu/riscv.mmu \
--extension-dir $PWD/arch/riscv/extensions/ --rev-id RV64FULL

the rev-id can be configured to use the different ISA present in $PWD/arch/riscv/revisions.xml
<revision name="RV64FULL">
<includes name="RV64I"/>
<includes name="RV64M"/>
<includes name="RV64A"/>
<includes name="RV64F"/>
<includes name="RV32D"/>
<includes name="RV64D"/>
<includes name="RV64C"/>
<includes name="RV32DC"/>
<includes name="RV32V"/>
<includes name="RV64"/>
<excludes name="MEM_SV32"/>

6.3.1. Opensource generator

It has a configurable model, generator code, some standard example templates.

6.3.2. Config.yaml options

WIP

A YAML file is placed in the microtesk plugin file with the name microtesk_gen_config.yaml.

  • global_home -> Path to the microtesk folder

  • global_config_path -> Path to the template folders in the plugins

  • global_command -> The command to generate the required assembly files. (Usually generate.sh riscv)

  • global_args -> Args to pass to the microtesk generator (Usually –solver z3 –generate)

6.3.3. Output

This plugin will generate a test-list containing all necessary information for the framework to compile and test code.

This can be useful to share test cases across machines. In order to share the tests, one only needs to share the original finals and test-list which contains all necessary information about the tests run.

6.4. RISCOF

RISCOF is a RISC-V architectural test checking tool. This tool hosts a suite of tests which are currently included in the official RISC-V architectural test suites.

This plugin uses the RISCOF tool to filter and select tests that should be run on the DUT. All tests generated generated by this plugin are compliant with the official Test Format Spec.

6.4.1. Installation

  1. Install RISCOF

    The easiest way to install riscof is to use pip.

    $ pip install -U riscof
    

6.4.2. Configuring the Plugin

You will need to create a config.ini as per RISCOF’s specification provided here. Secnodly you will also need to create the relevant plugin files:

  • yaml specs

  • python plugin files

  • model_test.h header files

  • linker file (must be named link.ld)

Please refer to Generate Templates section of RISCOF for more details on how to create the above files.

An example of the above files for chromite can be found in the riscof_plugin directory of the Chromite_verilator plugin

6.4.3. Output from the plugin

The gen hook of the plugin must return a dictionary of the test and their attributes as defined by the Test List Format.

6.4.4. Instance in config.ini

To use RISCV_CTG in the config.ini the following template can be followed:

path_to_suite = ~/river_core_plugins/generator_plugins
generator = riscof

[riscof]
jobs = 8
count = 1
seed = random
# path to the config.ini to be used by riscof.
riscof_config=/scratch/git-repo/incoresemi/river-framework/core-verification/river_core_plugins/dut_plugins/chromite_verilator_plugin/riscof_plugin/config.ini