Merge branch 'main' of https://github.com/openhwgroup/cvw into update_ccov

This commit is contained in:
Jordan Carlin 2024-11-29 15:44:19 -08:00
commit c75fffbaba
No known key found for this signature in database
26 changed files with 288 additions and 245 deletions

View File

@ -71,7 +71,8 @@ Then fork and clone the repo, source setup, make the tests and run regression
> This section describes the open source toolchain installation. > This section describes the open source toolchain installation.
### Compatibility ### Compatibility
The current version of the toolchain has been tested on Ubuntu (versions 20.04 LTS, 22.04 LTS, and 24.04 LTS), Debian (versions 11 and 12), Red Hat/Rocky/AlmaLinux (versions 8 and 9), and OpenSUSE (version 15.6). Only the latest minor release of each major version is tested. The current version of the toolchain has been tested on Ubuntu (versions 20.04 LTS, 22.04 LTS, and 24.04 LTS), Debian (versions 11 and 12), Red Hat/Rocky/AlmaLinux (versions 8 and 9),
and SUSE version 15.6. Only the latest minor release of each major version is tested.
> [!WARNING] > [!WARNING]
> - Ubuntu 22.04LTS is incompatible with Synopsys Design Compiler. > - Ubuntu 22.04LTS is incompatible with Synopsys Design Compiler.
@ -135,11 +136,17 @@ export VCS_HOME=.. # Change this for your path to Synopsys VCS
Electronic Design Automation (EDA) tools are vital to implementations of System on Chip architectures as well as validating different designs. Open-source and commercial tools exist for multiple strategies and although the one can spend a lifetime using combinations of different tools, only a small subset of tools is utilized for this text. The tools are chosen because of their ease in access as well as their repeatability for accomplishing many of the tasks utilized to design Wally. It is anticipated that additional tools may be documented later after this is text is published to improve use and access. Electronic Design Automation (EDA) tools are vital to implementations of System on Chip architectures as well as validating different designs. Open-source and commercial tools exist for multiple strategies and although the one can spend a lifetime using combinations of different tools, only a small subset of tools is utilized for this text. The tools are chosen because of their ease in access as well as their repeatability for accomplishing many of the tasks utilized to design Wally. It is anticipated that additional tools may be documented later after this is text is published to improve use and access.
Siemens Questa is the primary tool utilized for simulating and validating Wally. For logic synthesis, you will need Synopsys Design Compiler. Questa and Design Compiler are commercial tools that require an educational or commercial license. Verilator is an open-source Verilog simulator. It is fast and free. Run Wally on the riscv-arch-test suite using Verilator with:
```
regression-wally
```
Running code or functional coverage simulations or lock-step presently require commercial tools. Siemens Questa is the primary tool utilized for simulating and validating Wally. Synopsys VCS also can run regression-wally and lock-step simulation. For logic synthesis, you will need Synopsys Design Compiler. Questa and Design Compiler are commercial tools that require an educational or commercial license.
Note: Some EDA tools utilize `LM_LICENSE_FILE` for their environmental variable to point to their license server. Some operating systems may also utilize `MGLS_LICENSE_FILE` instead, therefore, it is important to read the user manual on the preferred environmental variable required to point to a users license file. Although there are different mechanisms to allow licenses to work, many companies commonly utilize the FlexLM (i.e., Flex-enabled) license server manager that runs off a node locked license. Note: Some EDA tools utilize `LM_LICENSE_FILE` for their environmental variable to point to their license server. Some operating systems may also utilize `MGLS_LICENSE_FILE` instead, therefore, it is important to read the user manual on the preferred environmental variable required to point to a users license file. Although there are different mechanisms to allow licenses to work, many companies commonly utilize the FlexLM (i.e., Flex-enabled) license server manager that runs off a node locked license.
Although most EDA tools are Linux-friendly, they tend to have issues when not installed on recommended OS flavors. Both Red Hat Enterprise Linux and SUSE Linux products typically tend to be recommended for installing commercial-based EDA tools and are recommended for utilizing complex simulation and architecture exploration. Questa can also be installed on Microsoft Windows as well as Mac OS with a Virtual Machine such as Parallels. Although most EDA tools are Linux-friendly, they tend to have issues when not installed on recommended OS flavors. Red Hat Enterprise Linux (and its free Rocky clone) and SUSE Linux products typically tend to be recommended for installing commercial-based EDA tools and are recommended for utilizing complex simulation and architecture exploration.
### Siemens Questa ### Siemens Questa

View File

@ -107,7 +107,7 @@ elif [[ "$ID" == opensuse-leap || "$ID" == sles || "$ID_LIKE" == *suse* ]]; then
exit 1 exit 1
fi fi
else else
printf "${FAIL_COLOR}%s%s%s\n${ENDC}" "The Wally installation script is currently only compatible with Ubuntu, Debian, and Red Hat family " \ printf "${FAIL_COLOR}%s%s%s\n${ENDC}" "The Wally installation script is currently only compatible with Ubuntu, Debian, SUSE, and Red Hat family " \
"(RHEL, Rocky Linux, or AlmaLinux) distros. Your detected distro is $PRETTY_NAME. You may try manually running the " \ "(RHEL, Rocky Linux, or AlmaLinux) distros. Your detected distro is $PRETTY_NAME. You may try manually running the " \
"commands in this script, but it is likely that some will need to be altered." "commands in this script, but it is likely that some will need to be altered."
exit 1 exit 1

View File

@ -147,7 +147,6 @@ localparam WFI_TIMEOUT_BIT = 32'd16;
// Peripheral Physical Addresses // Peripheral Physical Addresses
// Peripheral memory space extends from BASE to BASE+RANGE // Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits // Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
// *** each of these is `PA_BITS wide. is this paramaterizable INSIDE the config file?
localparam logic DTIM_SUPPORTED = 0; localparam logic DTIM_SUPPORTED = 0;
localparam logic [63:0] DTIM_BASE = 64'h80000000; localparam logic [63:0] DTIM_BASE = 64'h80000000;
localparam logic [63:0] DTIM_RANGE = 64'h007FFFFF; localparam logic [63:0] DTIM_RANGE = 64'h007FFFFF;

View File

@ -147,7 +147,6 @@ localparam WFI_TIMEOUT_BIT = 32'd16;
// Peripheral Physical Addresses // Peripheral Physical Addresses
// Peripheral memory space extends from BASE to BASE+RANGE // Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits // Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
// *** each of these is `PA_BITS wide. is this paramaterizable INSIDE the config file?
localparam logic DTIM_SUPPORTED = 0; localparam logic DTIM_SUPPORTED = 0;
localparam logic [63:0] DTIM_BASE = 64'h80000000; localparam logic [63:0] DTIM_BASE = 64'h80000000;
localparam logic [63:0] DTIM_RANGE = 64'h007FFFFF; localparam logic [63:0] DTIM_RANGE = 64'h007FFFFF;

View File

@ -45,3 +45,4 @@
`include "EndianM_coverage.svh" `include "EndianM_coverage.svh"
`include "EndianS_coverage.svh" `include "EndianS_coverage.svh"
`include "ExceptionsM_coverage.svh" `include "ExceptionsM_coverage.svh"
`include "ExceptionsZc_coverage.svh"

View File

@ -9,7 +9,7 @@
#--showcommands #--showcommands
# Core settings # Core settings
--variant RV32GC # for RV32GC --variant RV32GCK # for RV32GC
--override cpu/priv_version=1.12 --override cpu/priv_version=1.12
--override cpu/user_version=20191213 --override cpu/user_version=20191213
# arch # arch
@ -59,7 +59,7 @@
#--override cpu/instret_undefined=T #--override cpu/instret_undefined=T
#--override cpu/hpmcounter_undefined=T #--override cpu/hpmcounter_undefined=T
## context registers not implemented # context registers not implemented
#--override cpu/scontext_undefined=True #--override cpu/scontext_undefined=True
#--override cpu/mcontext_undefined=True #--override cpu/mcontext_undefined=True
@ -69,9 +69,14 @@
#--override cpu/Zicfilp=F #--override cpu/Zicfilp=F
--override cpu/trigger_num=0 # disable CSRs 7a0-7a8 --override cpu/trigger_num=0 # disable CSRs 7a0-7a8
--override no_pseudo_inst=T # For code coverage, don't produce pseudoinstructions # For code coverage, don't produce pseudoinstructions
--override no_pseudo_inst=T
--override show_c_prefix=T # Show "c." with compressed instructions # Show "c." with compressed instructions
--override show_c_prefix=T
# nonratified mnoise register not implemented
--override cpu/mnoise_undefined=T
# mcause and scause only have 4 lsbs of code and 1 msb of interrupt flag # mcause and scause only have 4 lsbs of code and 1 msb of interrupt flag
#--override cpu/ecode_mask=0x8000000F # for RV32 #--override cpu/ecode_mask=0x8000000F # for RV32
@ -80,7 +85,8 @@
# Debug mode not yet supported # Debug mode not yet supported
--override cpu/debug_mode=none --override cpu/debug_mode=none
# Zkr entropy source and seed register not supported.
--override cpu/Zkr=F
--override cpu/reset_address=0x80000000 --override cpu/reset_address=0x80000000

View File

@ -147,7 +147,6 @@ localparam WFI_TIMEOUT_BIT = 32'd16;
// Peripheral Physical Addresses // Peripheral Physical Addresses
// Peripheral memory space extends from BASE to BASE+RANGE // Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits // Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
// *** each of these is `PA_BITS wide. is this paramaterizable INSIDE the config file?
localparam logic DTIM_SUPPORTED = 1; localparam logic DTIM_SUPPORTED = 1;
localparam logic [63:0] DTIM_BASE = 64'h80000000; localparam logic [63:0] DTIM_BASE = 64'h80000000;
localparam logic [63:0] DTIM_RANGE = 64'h007FFFFF; localparam logic [63:0] DTIM_RANGE = 64'h007FFFFF;

View File

@ -147,7 +147,6 @@ localparam WFI_TIMEOUT_BIT = 32'd16;
// Peripheral Physical Addresses // Peripheral Physical Addresses
// Peripheral memory space extends from BASE to BASE+RANGE // Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits // Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
// *** each of these is `PA_BITS wide. is this paramaterizable INSIDE the config file?
localparam logic DTIM_SUPPORTED = 1; localparam logic DTIM_SUPPORTED = 1;
localparam logic [63:0] DTIM_BASE = 64'h80000000; localparam logic [63:0] DTIM_BASE = 64'h80000000;
localparam logic [63:0] DTIM_RANGE = 64'h007FFFFF; localparam logic [63:0] DTIM_RANGE = 64'h007FFFFF;

View File

@ -147,7 +147,6 @@ localparam WFI_TIMEOUT_BIT = 32'd16;
// Peripheral Physical Addresses // Peripheral Physical Addresses
// Peripheral memory space extends from BASE to BASE+RANGE // Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits // Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
// *** each of these is `PA_BITS wide. is this paramaterizable INSIDE the config file?
localparam logic DTIM_SUPPORTED = 0; localparam logic DTIM_SUPPORTED = 0;
localparam logic [63:0] DTIM_BASE = 64'h80000000; localparam logic [63:0] DTIM_BASE = 64'h80000000;
localparam logic [63:0] DTIM_RANGE = 64'h007FFFFF; localparam logic [63:0] DTIM_RANGE = 64'h007FFFFF;

View File

@ -44,6 +44,7 @@
`include "EndianM_coverage.svh" `include "EndianM_coverage.svh"
`include "EndianS_coverage.svh" `include "EndianS_coverage.svh"
`include "ExceptionsM_coverage.svh" `include "ExceptionsM_coverage.svh"
`include "ExceptionsZc_coverage.svh"
// `include "RV64VM_PMP_coverage.svh" // `include "RV64VM_PMP_coverage.svh"
// `include "RV64CBO_VM_coverage.svh" // `include "RV64CBO_VM_coverage.svh"
// `include "RV64CBO_PMP_coverage.svh" // `include "RV64CBO_PMP_coverage.svh"

View File

@ -73,7 +73,7 @@
# Show "c." with compressed instructions # Show "c." with compressed instructions
--override show_c_prefix=T --override show_c_prefix=T
# nonratified mnosie register not implemented # nonratified mnoise register not implemented
--override cpu/mnoise_undefined=T --override cpu/mnoise_undefined=T
# mcause and scause only have 4 lsbs of code and 1 msb of interrupt flag # mcause and scause only have 4 lsbs of code and 1 msb of interrupt flag
@ -86,8 +86,6 @@
# Zkr entropy source and seed register not supported. # Zkr entropy source and seed register not supported.
--override cpu/Zkr=F --override cpu/Zkr=F
--override cpu/reset_address=0x80000000 --override cpu/reset_address=0x80000000
--override cpu/unaligned=T # Zicclsm (should be true) --override cpu/unaligned=T # Zicclsm (should be true)

View File

@ -147,7 +147,6 @@ localparam WFI_TIMEOUT_BIT = 32'd16;
// Peripheral Physical Addresses // Peripheral Physical Addresses
// Peripheral memory space extends from BASE to BASE+RANGE // Peripheral memory space extends from BASE to BASE+RANGE
// Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits // Range should be a thermometer code with 0's in the upper bits and 1s in the lower bits
// *** each of these is `PA_BITS wide. is this paramaterizable INSIDE the config file?
localparam logic DTIM_SUPPORTED = 1; localparam logic DTIM_SUPPORTED = 1;
localparam logic [63:0] DTIM_BASE = 64'h80000000; localparam logic [63:0] DTIM_BASE = 64'h80000000;
localparam logic [63:0] DTIM_RANGE = 64'h007FFFFF; localparam logic [63:0] DTIM_RANGE = 64'h007FFFFF;

View File

@ -237,7 +237,7 @@ __uint128_t parseNum(char *num) {
if (strlen(num) < 8) size = 2; if (strlen(num) < 8) size = 2;
else if (strlen(num) < 16) size = 4; else if (strlen(num) < 16) size = 4;
else if (strlen(num) < 32) size = 8; else if (strlen(num) < 32) size = 8;
else if (strlen(num) < 35) size = 16; // *** will need to increase else if (strlen(num) < 35) size = 16;
else { else {
printf("Error: only half, single, double, or quad precision supported"); printf("Error: only half, single, double, or quad precision supported");
exit(1); exit(1);

View File

@ -153,18 +153,20 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
endcase endcase
7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000) 7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000)
ControlsD = `FCTRLW'b0_1_10_00_000_0_0_0_0_0; // fclass ControlsD = `FCTRLW'b0_1_10_00_000_0_0_0_0_0; // fclass
else if (Funct3D == 3'b000 & Rs2D == 5'b00000) else if (Funct3D == 3'b000 & Rs2D == 5'b00000) begin
ControlsD = `FCTRLW'b0_1_11_00_000_0_0_0_0_0; // fmv.x.w/d/h/q fp to int register if (Fmt[1:0] == 2'b00 | Fmt[1:0] == 2'b10 | (P.XLEN == 64 & Fmt[1:0] == 2'b01))
else if (P.ZFA_SUPPORTED & P.XLEN == 32 & P.D_SUPPORTED & Funct7D[1:0] == 2'b01 & Funct3D == 3'b000 & Rs2D == 5'b00001) ControlsD = `FCTRLW'b0_1_11_00_000_0_0_0_0_0; // fmv.x.w/d/h fp to int register (double only in RV64)
end else if (P.ZFA_SUPPORTED & P.XLEN == 32 & P.D_SUPPORTED & Funct7D[1:0] == 2'b01 & Funct3D == 3'b000 & Rs2D == 5'b00001)
ControlsD = `FCTRLW'b0_1_11_00_000_0_0_0_1_0; // fmvh.x.d (Zfa) ControlsD = `FCTRLW'b0_1_11_00_000_0_0_0_1_0; // fmvh.x.d (Zfa)
// Q not supported in RV64GC // Q not supported in RV64GC
// coverage off // coverage off
else if (P.ZFA_SUPPORTED & P.XLEN == 64 & P.Q_SUPPORTED & Funct7D[1:0] == 2'b11 & Funct3D == 3'b000 & Rs2D == 5'b00001) else if (P.ZFA_SUPPORTED & P.XLEN == 64 & P.Q_SUPPORTED & Funct7D[1:0] == 2'b11 & Funct3D == 3'b000 & Rs2D == 5'b00001)
ControlsD = `FCTRLW'b0_1_11_00_000_0_0_0_1_0; // fmvh.x.q (Zfa) ControlsD = `FCTRLW'b0_1_11_00_000_0_0_0_1_0; // fmvh.x.q (Zfa)
// coverage on // coverage on
7'b11110??: if (Funct3D == 3'b000 & Rs2D == 5'b00000) 7'b11110??: if (Funct3D == 3'b000 & Rs2D == 5'b00000) begin
ControlsD = `FCTRLW'b1_0_00_00_011_0_0_0_0_0; // fmv.w/d/h/q.x int to fp reg if (Fmt[1:0] == 2'b00 | Fmt[1:0] == 2'b10 | (P.XLEN == 64 & Fmt[1:0] == 2'b01))
else if (P.ZFA_SUPPORTED & Funct3D == 3'b000 & Rs2D == 5'b00001) ControlsD = `FCTRLW'b1_0_00_00_011_0_0_0_0_0; // fmv.w/d/h.x int to fp reg (double only in RV64)
end else if (P.ZFA_SUPPORTED & Funct3D == 3'b000 & Rs2D == 5'b00001)
ControlsD = `FCTRLW'b1_0_00_00_111_0_0_0_1_0; // fli (Zfa) ControlsD = `FCTRLW'b1_0_00_00_111_0_0_0_1_0; // fli (Zfa)
7'b0100000: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b00) 7'b0100000: if (Rs2D[4:2] == 3'b000 & SupportedFmt2 & Rs2D[1:0] != 2'b00)
ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0_0_0; // fcvt.s.(d/q/h) ControlsD = `FCTRLW'b1_0_01_00_000_0_0_0_0_0; // fcvt.s.(d/q/h)
@ -196,54 +198,54 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
7'b1101000: case(Rs2D) 7'b1101000: case(Rs2D)
5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0_0; // fcvt.s.w w->s 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0_0; // fcvt.s.w w->s
5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0_0_0; // fcvt.s.wu wu->s 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0_0_0; // fcvt.s.wu wu->s
5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0_0_0; // fcvt.s.l l->s 5'b00010: if (P.XLEN == 64) ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0_0_0; // fcvt.s.l l->s
5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0_0_0; // fcvt.s.lu lu->s 5'b00011: if (P.XLEN == 64) ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0_0_0; // fcvt.s.lu lu->s
endcase endcase
7'b1100000: case(Rs2D) 7'b1100000: case(Rs2D)
5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1_0_0; // fcvt.w.s s->w 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1_0_0; // fcvt.w.s s->w
5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1_0_0; // fcvt.wu.s s->wu 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1_0_0; // fcvt.wu.s s->wu
5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1_0_0; // fcvt.l.s s->l 5'b00010: if (P.XLEN == 64) ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1_0_0; // fcvt.l.s s->l
5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1_0_0; // fcvt.lu.s s->lu 5'b00011: if (P.XLEN == 64) ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1_0_0; // fcvt.lu.s s->lu
endcase endcase
7'b1101001: case(Rs2D) 7'b1101001: case(Rs2D)
5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0_0; // fcvt.d.w w->d 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0_0; // fcvt.d.w w->d
5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0_0_0; // fcvt.d.wu wu->d 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0_0_0; // fcvt.d.wu wu->d
5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0_0_0; // fcvt.d.l l->d 5'b00010: if (P.XLEN == 64) ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0_0_0; // fcvt.d.l l->d
5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0_0_0; // fcvt.d.lu lu->d 5'b00011: if (P.XLEN == 64) ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0_0_0; // fcvt.d.lu lu->d
endcase endcase
7'b1100001: case(Rs2D) 7'b1100001: case(Rs2D)
5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1_0_0; // fcvt.w.d d->w 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1_0_0; // fcvt.w.d d->w
5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1_0_0; // fcvt.wu.d d->wu 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1_0_0; // fcvt.wu.d d->wu
5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1_0_0; // fcvt.l.d d->l 5'b00010: if (P.XLEN == 64) ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1_0_0; // fcvt.l.d d->l
5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1_0_0; // fcvt.lu.d d->lu 5'b00011: if (P.XLEN == 64) ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1_0_0; // fcvt.lu.d d->lu
5'b01000: if (P.ZFA_SUPPORTED & P.D_SUPPORTED & Funct3D == 3'b001) 5'b01000: if (P.ZFA_SUPPORTED & P.D_SUPPORTED & Funct3D == 3'b001)
ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1_1_0; // fcvtmod.w.d (Zfa) ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1_1_0; // fcvtmod.w.d (Zfa)
endcase endcase
7'b1101010: case(Rs2D) 7'b1101010: case(Rs2D)
5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0_0; // fcvt.h.w w->h 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0_0; // fcvt.h.w w->h
5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0_0_0; // fcvt.h.wu wu->h 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0_0_0; // fcvt.h.wu wu->h
5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0_0_0; // fcvt.h.l l->h 5'b00010: if (P.XLEN == 64) ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0_0_0; // fcvt.h.l l->h
5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0_0_0; // fcvt.h.lu lu->h 5'b00011: if (P.XLEN == 64) ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0_0_0; // fcvt.h.lu lu->h
endcase endcase
7'b1100010: case(Rs2D) 7'b1100010: case(Rs2D)
5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1_0_0; // fcvt.w.h h->w 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1_0_0; // fcvt.w.h h->w
5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1_0_0; // fcvt.wu.h h->wu 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1_0_0; // fcvt.wu.h h->wu
5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1_0_0; // fcvt.l.h h->l 5'b00010: if (P.XLEN == 64) ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1_0_0; // fcvt.l.h h->l
5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1_0_0; // fcvt.lu.h h->lu 5'b00011: if (P.XLEN == 64) ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1_0_0; // fcvt.lu.h h->lu
endcase endcase
// Not covered in testing because rv64gc does not support quad precision // Not covered in testing because rv64gc does not support quad precision
// coverage off // coverage off
7'b1101011: case(Rs2D) 7'b1101011: case(Rs2D)
5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0_0; // fcvt.q.w w->q 5'b00000: ControlsD = `FCTRLW'b1_0_01_00_101_0_0_0_0_0; // fcvt.q.w w->q
5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0_0_0; // fcvt.q.wu wu->q 5'b00001: ControlsD = `FCTRLW'b1_0_01_00_100_0_0_0_0_0; // fcvt.q.wu wu->q
5'b00010: ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0_0_0; // fcvt.q.l l->q 5'b00010: if (P.XLEN == 64) ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0_0_0; // fcvt.q.l l->q
5'b00011: ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0_0_0; // fcvt.q.lu lu->q 5'b00011: if (P.XLEN == 64) ControlsD = `FCTRLW'b1_0_01_00_110_0_0_0_0_0; // fcvt.q.lu lu->q
endcase endcase
7'b1100011: case(Rs2D) 7'b1100011: case(Rs2D)
5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1_0_0; // fcvt.w.q q->w 5'b00000: ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1_0_0; // fcvt.w.q q->w
5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1_0_0; // fcvt.wu.q q->wu 5'b00001: ControlsD = `FCTRLW'b0_1_01_00_000_0_0_1_0_0; // fcvt.wu.q q->wu
5'b00010: ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1_0_0; // fcvt.l.q q->l 5'b00010: if (P.XLEN == 64) ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1_0_0; // fcvt.l.q q->l
5'b00011: ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1_0_0; // fcvt.lu.q q->lu 5'b00011: if (P.XLEN == 64) ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1_0_0; // fcvt.lu.q q->lu
endcase endcase
// coverage off // coverage off
// Not covered in testing because rv64gc is not RV64Q or RV32D // Not covered in testing because rv64gc is not RV64Q or RV32D

View File

@ -119,13 +119,11 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) (
if (P.ZBC_SUPPORTED) if (P.ZBC_SUPPORTED)
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
17'b0110011_0000101_010: BMUControlsD = `BMUCTRLW'b000_0011_0001_1_0_0_0_1_0_0_0_0_0; // clmulr 17'b0110011_0000101_010: BMUControlsD = `BMUCTRLW'b000_0011_0001_1_0_0_0_1_0_0_0_0_0; // clmulr
17'b0110011_0000101_0??: BMUControlsD = `BMUCTRLW'b000_0011_0000_1_0_0_0_1_0_0_0_0_0; // clmul/clmulh 17'b0110011_0000101_0?1: BMUControlsD = `BMUCTRLW'b000_0011_0000_1_0_0_0_1_0_0_0_0_0; // clmul/clmulh
endcase endcase
if (P.ZBKC_SUPPORTED) begin if (P.ZBKC_SUPPORTED) begin
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
17'b0110011_0000101_0??: BMUControlsD = `BMUCTRLW'b000_0011_0000_1_0_0_0_1_0_0_0_0_0; // clmul/clmulh 17'b0110011_0000101_0?1: BMUControlsD = `BMUCTRLW'b000_0011_0000_1_0_0_0_1_0_0_0_0_0; // clmul/clmulh
// 17'b0110011_0000101_001: BMUControlsD = `BMUCTRLW'b000_0011_0000_1_0_0_0_1_0_0_0_0_0; // clmul
// 17'b0110011_0000101_011: BMUControlsD = `BMUCTRLW'b000_0011_0001_1_0_0_0_1_0_0_0_0_0; // clmulh
endcase endcase
end end
@ -153,10 +151,17 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) (
end end
if (P.ZBB_SUPPORTED | P.ZBS_SUPPORTED) // rv32i/64i shift instructions need BMU ALUSelect when BMU shifter is used if (P.ZBB_SUPPORTED | P.ZBS_SUPPORTED) // rv32i/64i shift instructions need BMU ALUSelect when BMU shifter is used
casez({OpD, Funct7D, Funct3D}) casez({OpD, Funct7D, Funct3D})
17'b0110011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_0_0_0_1_0_0_0_0_0; // sra, srl, sll // variable shifts don't encode shift amount in funct7
17'b0010011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_1_0_0_1_0_0_0_0_0; // srai, srli, slli 17'b0110011_0000000_001: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_0_0_0_1_0_0_0_0_0; // sll
17'b0111011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_0_1_0_1_0_0_0_0_0; // sraw, srlw, sllw 17'b0110011_0?00000_101: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_0_0_0_1_0_0_0_0_0; // sra, srl
17'b0011011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_1_1_0_1_0_0_0_0_0; // sraiw, srliw, slliw // Immediate Shifts by more than 32 (Funct7[0]) are only supported in RV64
17'b0010011_000000?_001: if (P.XLEN == 64 | !Funct7D[0]) BMUControlsD = `BMUCTRLW'b001_0000_0000_1_1_0_0_1_0_0_0_0_0; // slli
17'b0010011_0?0000?_101: if (P.XLEN == 64 | !Funct7D[0]) BMUControlsD = `BMUCTRLW'b001_0000_0000_1_1_0_0_1_0_0_0_0_0; // srai, srli
// w-type shifts only supported in RV64 and must have Funct7[0] = 0 because the shift amount is < 32
17'b0111011_0000000_001: if (P.XLEN == 64) BMUControlsD = `BMUCTRLW'b001_0000_0000_1_0_1_0_1_0_0_0_0_0; // sllw
17'b0111011_0?00000_101: if (P.XLEN == 64) BMUControlsD = `BMUCTRLW'b001_0000_0000_1_0_1_0_1_0_0_0_0_0; // sraw, srlw
17'b0011011_0000000_001: if (P.XLEN == 64) BMUControlsD = `BMUCTRLW'b001_0000_0000_1_1_1_0_1_0_0_0_0_0; // slliw
17'b0011011_0?00000_101: if (P.XLEN == 64) BMUControlsD = `BMUCTRLW'b001_0000_0000_1_1_1_0_1_0_0_0_0_0; // sraiw, srliw
endcase endcase
if (P.ZBKB_SUPPORTED) begin // ZBKB Bitmanip if (P.ZBKB_SUPPORTED) begin // ZBKB Bitmanip

View File

@ -181,8 +181,8 @@ module controller import cvw::*; #(parameter cvw_t P) (
assign Funct7ZeroD = (Funct7D == 7'b0000000); // most R-type instructions assign Funct7ZeroD = (Funct7D == 7'b0000000); // most R-type instructions
assign Funct7b5D = (Funct7D == 7'b0100000); // srai, sub assign Funct7b5D = (Funct7D == 7'b0100000); // srai, sub
assign FunctCZeroD = (Funct3D == 3'b101 | Funct3D == 3'b111) & (Funct7D == 7'b0000111) & P.ZICOND_SUPPORTED; // czero.eqz or czero.nez assign FunctCZeroD = (Funct3D == 3'b101 | Funct3D == 3'b111) & (Funct7D == 7'b0000111) & P.ZICOND_SUPPORTED; // czero.eqz or czero.nez
assign Funct7ShiftZeroD = (P.XLEN==64) ? (Funct7D[6:1] == 6'b000000) : Funct7ZeroD; assign Funct7ShiftZeroD = (P.XLEN==64 & ~OpD[3]) ? (Funct7D[6:1] == 6'b000000) : Funct7ZeroD; // 64-bit logical shifts allowed on XLEN=64, non-W
assign Funct7Shiftb5D = (P.XLEN==64) ? (Funct7D[6:1] == 6'b010000) : Funct7b5D; assign Funct7Shiftb5D = (P.XLEN==64 & ~OpD[3]) ? (Funct7D[6:1] == 6'b010000) : Funct7b5D; // 64-bit arithmetic shifts allowed on XLEN=64, non-W
assign IShiftD = (Funct3D == 3'b001 & Funct7ShiftZeroD) | (Funct3D == 3'b101 & (Funct7ShiftZeroD | Funct7Shiftb5D)); // slli, srli, srai, or w forms assign IShiftD = (Funct3D == 3'b001 & Funct7ShiftZeroD) | (Funct3D == 3'b101 & (Funct7ShiftZeroD | Funct7Shiftb5D)); // slli, srli, srai, or w forms
assign INoShiftD = ((Funct3D != 3'b001) & (Funct3D != 3'b101)); assign INoShiftD = ((Funct3D != 3'b001) & (Funct3D != 3'b101));
assign IFunctD = IShiftD | INoShiftD; assign IFunctD = IShiftD | INoShiftD;
@ -300,7 +300,6 @@ module controller import cvw::*; #(parameter cvw_t P) (
// Squash control signals if coming from an illegal compressed instruction // Squash control signals if coming from an illegal compressed instruction
// On RV32E, can't write to upper 16 registers. Checking reads to upper 16 is more costly so disregard them. // On RV32E, can't write to upper 16 registers. Checking reads to upper 16 is more costly so disregard them.
assign IllegalERegAdrD = P.E_SUPPORTED & P.ZICSR_SUPPORTED & ControlsD[`CTRLW-1] & InstrD[11]; assign IllegalERegAdrD = P.E_SUPPORTED & P.ZICSR_SUPPORTED & ControlsD[`CTRLW-1] & InstrD[11];
//assign IllegalBaseInstrD = 1'b0;
assign {BaseRegWriteD, PreImmSrcD, ALUSrcAD, BaseALUSrcBD, MemRWD, assign {BaseRegWriteD, PreImmSrcD, ALUSrcAD, BaseALUSrcBD, MemRWD,
ResultSrcD, BranchD, ALUOpD, JumpD, ALUResultSrcD, BaseW64D, CSRReadD, ResultSrcD, BranchD, ALUOpD, JumpD, ALUResultSrcD, BaseW64D, CSRReadD,
PrivilegedD, FenceXD, MDUD, AtomicD, CMOD, unused} = IllegalIEUFPUInstrD ? `CTRLW'b0 : ControlsD; PrivilegedD, FenceXD, MDUD, AtomicD, CMOD, unused} = IllegalIEUFPUInstrD ? `CTRLW'b0 : ControlsD;

View File

@ -59,7 +59,7 @@ module privdec import cvw::*; #(parameter cvw_t P) (
// svinval instructions // svinval instructions
// any svinval instruction is treated as sfence.vma on Wally // any svinval instruction is treated as sfence.vma on Wally
assign sinvalvmaM = (InstrM[31:25] == 7'b0001001); assign sinvalvmaM = (InstrM[31:25] == 7'b0001011);
assign sfencewinvalM = (InstrM[31:20] == 12'b000110000000) & rs1zeroM; assign sfencewinvalM = (InstrM[31:20] == 12'b000110000000) & rs1zeroM;
assign sfenceinvalirM = (InstrM[31:20] == 12'b000110000001) & rs1zeroM; assign sfenceinvalirM = (InstrM[31:20] == 12'b000110000001) & rs1zeroM;
assign invalM = P.SVINVAL_SUPPORTED & (sinvalvmaM | sfencewinvalM | sfenceinvalirM); assign invalM = P.SVINVAL_SUPPORTED & (sinvalvmaM | sfencewinvalM | sfenceinvalirM);

View File

@ -70,7 +70,7 @@ module FunctionName import cvw::*; #(parameter cvw_t P) (
begin begin
if ( pc == 0 ) begin if ( pc == 0 ) begin
// *** want to keep the old value for mid and minval // want to keep the old value for mid and minval
mid = 0; mid = 0;
return; return;
end end

View File

@ -219,6 +219,10 @@ module instrNameDecTB(
else if (imm == 258) name = "SRET"; else if (imm == 258) name = "SRET";
else if (imm == 770) name = "MRET"; else if (imm == 770) name = "MRET";
else if (funct7 == 9) name = "SFENCE.VMA"; else if (funct7 == 9) name = "SFENCE.VMA";
else if (funct7 == 11) name = "SINVAL.VMA";
else if (funct7 == 12 & rs2 == 0) name = "SFENCE.W.INVAL";
else if (funct7 == 12 & rs2 == 1) name = "SFENCE.INVAL.IR";
else if (imm == 259) name = "WFI";
else if (imm == 261) name = "WFI"; else if (imm == 261) name = "WFI";
else name = "ILLEGAL"; else name = "ILLEGAL";
10'b1110011_001: name = "CSRRW"; 10'b1110011_001: name = "CSRRW";

View File

@ -39,7 +39,7 @@ module ramxdetector #(parameter XLEN, LLEN) (
/* verilator lint_off WIDTHXZEXPAND */ /* verilator lint_off WIDTHXZEXPAND */
if (MemReadM & ~LSULoadAccessFaultM & (ReadDataM === 'bx)) begin if (MemReadM & ~LSULoadAccessFaultM & (ReadDataM === 'bx)) begin
/* verilator lint_on WIDTHXZEXPAND */ /* verilator lint_on WIDTHXZEXPAND */
$display("WARNING: Attempting to read from unitialized RAM. Processor may go haywire if it uses x value. But this is normal in WALLY-mmu tests."); $display("WARNING: Attempting to read from unitialized RAM. Processor may go haywire if it uses x value. But this is normal in WALLY-mmu and ExceptionInstr tests.");
$display(" PCM = %x InstrM = %x (%s), IEUAdrM = %x", PCM, InstrM, InstrMName, IEUAdrM); $display(" PCM = %x InstrM = %x (%s), IEUAdrM = %x", PCM, InstrM, InstrMName, IEUAdrM);
//$stop; //$stop;
end end

View File

@ -95,11 +95,19 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi);
assign FlushW = testbench.dut.core.FlushW; assign FlushW = testbench.dut.core.FlushW;
assign TrapM = testbench.dut.core.TrapM; assign TrapM = testbench.dut.core.TrapM;
assign HaltM = testbench.DCacheFlushStart; assign HaltM = testbench.DCacheFlushStart;
if (P.ZICSR_SUPPORTED) begin
assign PrivilegeModeW = testbench.dut.core.priv.priv.privmode.PrivilegeModeW; assign PrivilegeModeW = testbench.dut.core.priv.priv.privmode.PrivilegeModeW;
assign STATUS_SXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_SXL; assign STATUS_SXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_SXL;
assign STATUS_UXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_UXL; assign STATUS_UXL = testbench.dut.core.priv.priv.csr.csrsr.STATUS_UXL;
assign wfiM = testbench.dut.core.priv.priv.wfiM; assign wfiM = testbench.dut.core.priv.priv.wfiM;
assign InterruptM = testbench.dut.core.priv.priv.InterruptM; assign InterruptM = testbench.dut.core.priv.priv.InterruptM;
end else begin
assign PrivilegeModeW = 2'b11;
assign STATUS_SXL = 0;
assign STATUS_UXL = 0;
assign wfiM = 0;
assign InterruptM = 0;
end
//For VM Verification //For VM Verification
assign VAdrIM = testbench.dut.core.ifu.immu.immu.tlb.tlb.VAdr; assign VAdrIM = testbench.dut.core.ifu.immu.immu.tlb.tlb.VAdr;
@ -116,6 +124,7 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi);
logic valid; logic valid;
if (P.ZICSR_SUPPORTED) begin
always_comb begin always_comb begin
// Since we are detected the CSR change by comparing the old value we need to // Since we are detected the CSR change by comparing the old value we need to
// ensure the CSR is detected when the pipeline's Writeback stage is not // ensure the CSR is detected when the pipeline's Writeback stage is not
@ -292,6 +301,9 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi);
end end
end end
end end
end else begin
// no CSRArray
end
genvar index; genvar index;
assign rf[0] = 0; assign rf[0] = 0;
@ -307,11 +319,18 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi);
rf_wb[rf_a3] <= 1'b1; rf_wb[rf_a3] <= 1'b1;
end end
for(index = 0; index < NUMREGS; index += 1) if (P.F_SUPPORTED) begin
assign frf[index] = testbench.dut.core.fpu.fpu.fregfile.rf[index];
assign frf_a4 = testbench.dut.core.fpu.fpu.fregfile.a4; assign frf_a4 = testbench.dut.core.fpu.fpu.fregfile.a4;
assign frf_we4 = testbench.dut.core.fpu.fpu.fregfile.we4; assign frf_we4 = testbench.dut.core.fpu.fpu.fregfile.we4;
for(index = 0; index < NUMREGS; index += 1)
assign frf[index] = testbench.dut.core.fpu.fpu.fregfile.rf[index];
end else begin
assign frf_a4 = '0;
assign frf_we4 = 0;
for(index = 0; index < NUMREGS; index += 1)
assign frf[index] = '0;
end
always_comb begin always_comb begin
frf_wb <= 0; frf_wb <= 0;

View File

@ -866,12 +866,14 @@ end
end end
if (P.ZICSR_SUPPORTED) begin
always @(dut.core.priv.priv.csr.csri.MIP_REGW[7]) void'(rvvi.net_push("MTimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[7])); always @(dut.core.priv.priv.csr.csri.MIP_REGW[7]) void'(rvvi.net_push("MTimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[7]));
always @(dut.core.priv.priv.csr.csri.MIP_REGW[11]) void'(rvvi.net_push("MExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[11])); always @(dut.core.priv.priv.csr.csri.MIP_REGW[11]) void'(rvvi.net_push("MExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[11]));
always @(dut.core.priv.priv.csr.csri.MIP_REGW[9]) void'(rvvi.net_push("SExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[9])); always @(dut.core.priv.priv.csr.csri.MIP_REGW[9]) void'(rvvi.net_push("SExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[9]));
always @(dut.core.priv.priv.csr.csri.MIP_REGW[3]) void'(rvvi.net_push("MSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[3])); always @(dut.core.priv.priv.csr.csri.MIP_REGW[3]) void'(rvvi.net_push("MSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[3]));
always @(dut.core.priv.priv.csr.csri.MIP_REGW[1]) void'(rvvi.net_push("SSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[1])); always @(dut.core.priv.priv.csr.csri.MIP_REGW[1]) void'(rvvi.net_push("SSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[1]));
always @(dut.core.priv.priv.csr.csri.MIP_REGW[5]) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[5])); always @(dut.core.priv.priv.csr.csri.MIP_REGW[5]) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[5]));
end
final begin final begin
void'(rvviRefShutdown()); void'(rvviRefShutdown());

View File

@ -1,4 +1,13 @@
0000000b # Test 5.2.3.6: ecall from going to S mode from M mode 0000000b # Test 5.2.3.6: ecall from going to S mode from M mode
00000002 # S mode write to mstatush with illegal instruction
00000002 # S mode read from mstatush with illegal instruction
00000bad
00000002 # S mode write to menvcfgh with illegal instruction
00000002 # S mode read from menvcfgh with illegal instruction
00000bad
00000002 # S mode write to mseccfgh with illegal instruction
00000002 # S mode read from mseccfgh with illegal instruction
00000bad
00000002 # S mode write to pmpcfg1 with illegal instruction 00000002 # S mode write to pmpcfg1 with illegal instruction
00000002 # S mode read from pmpcfg1 with illegal instruction 00000002 # S mode read from pmpcfg1 with illegal instruction
00000bad 00000bad

View File

@ -117,7 +117,7 @@ cause_store_acc:
ret ret
cause_ecall: cause_ecall:
// *** ASSUMES you have already gone to the mode you need to call this from. // ASSUMES you have already gone to the mode you need to call this from.
ecall ecall
ret ret
@ -319,7 +319,7 @@ end_trap_triggers:
.align 6 .align 6
trap_handler_\MODE\(): trap_handler_\MODE\():
j trap_unvectored_\MODE\() // for the unvectored implimentation: jump past this table of addresses into the actual handler j trap_unvectored_\MODE\() // for the unvectored implimentation: jump past this table of addresses into the actual handler
// *** ASSUMES that a cause value of 0 for an interrupt is unimplemented // ASSUMES that a cause value of 0 for an interrupt is unimplemented
// otherwise, a vectored interrupt handler should jump to trap_handler_\MODE\() + 4 * Interrupt cause code // otherwise, a vectored interrupt handler should jump to trap_handler_\MODE\() + 4 * Interrupt cause code
// No matter the value of VECTORED, exceptions (not interrupts) are handled in an unvecotred way // No matter the value of VECTORED, exceptions (not interrupts) are handled in an unvecotred way
j s_soft_vector_\MODE\() // 1: instruction access fault // the zero spot is taken up by the instruction to skip this table. j s_soft_vector_\MODE\() // 1: instruction access fault // the zero spot is taken up by the instruction to skip this table.
@ -337,7 +337,7 @@ trap_handler_\MODE\():
trap_unvectored_\MODE\(): trap_unvectored_\MODE\():
csrrw sp, \MODE\()scratch, sp // swap sp and scratch so we can use the scratch stack in the trap hanler without messing up sp's value or the stack itself. csrrw sp, \MODE\()scratch, sp // swap sp and scratch so we can use the scratch stack in the trap hanler without messing up sp's value or the stack itself.
// *** NOTE: this means that nested traps will be screwed up but they shouldn't happen in any of these tests // NOTE: this means that nested traps will be screwed up but they shouldn't happen in any of these tests
trap_stack_saved_\MODE\(): // jump here after handling vectored interupt since we already switch sp and scratch there trap_stack_saved_\MODE\(): // jump here after handling vectored interupt since we already switch sp and scratch there
// save registers on stack before using // save registers on stack before using
@ -707,7 +707,7 @@ trap_handler_end_\MODE\(): // place to jump to so we can skip the trap handler a
.endm .endm
.macro READ32 ADDR .macro READ32 ADDR
// Attempt read at ADDR. Write the value read out to the output *** Consider adding specific test for reading a non known value // Attempt read at ADDR. Write the value read out to the output. Consider adding specific test for reading a non known value
// Success outputs: // Success outputs:
// value read out from ADDR // value read out from ADDR
// Fault outputs: // Fault outputs:
@ -751,7 +751,6 @@ trap_handler_end_\MODE\(): // place to jump to so we can skip the trap handler a
// 0x9: test called from S mode // 0x9: test called from S mode
// 0xB: test called from M mode // 0xB: test called from M mode
// they generally do not fault or cause issues as long as these modes are enabled // they generally do not fault or cause issues as long as these modes are enabled
// *** add functionality to check if modes are enabled before jumping? maybe cause a fault if not?
.macro GOTO_M_MODE RETURN_VPN=0x0 RETURN_PAGETYPE=0x0 .macro GOTO_M_MODE RETURN_VPN=0x0 RETURN_PAGETYPE=0x0
li a0, 2 // determine trap handler behavior (go to machine mode) li a0, 2 // determine trap handler behavior (go to machine mode)
@ -807,7 +806,7 @@ trap_handler_end_\MODE\(): // place to jump to so we can skip the trap handler a
// value read back out from CSR after writing // value read back out from CSR after writing
// Fault outputs: // Fault outputs:
// The previous CSR value before write attempt // The previous CSR value before write attempt
// *** Most likely 0x2, the mcause for illegal instruction if we don't have write or read access // Most likely 0x2, the mcause for illegal instruction if we don't have write or read access
li t5, 0xbad // load bad value to be overwritten by csrr li t5, 0xbad // load bad value to be overwritten by csrr
li t4, \VAL li t4, \VAL
csrw \CSR\(), t4 csrw \CSR\(), t4

View File

@ -32,18 +32,15 @@ TRAP_HANDLER m
# Test 5.2.3.6: Test that all the machine mode CSR's are innaccessible for reads and writes in S mode. # Test 5.2.3.6: Test that all the machine mode CSR's are innaccessible for reads and writes in S mode.
# *** several of these appear not to be implemented in the assembler?
# I get "assembler messages: error: unkown CSR" with many of them.
GOTO_S_MODE 0x0, 0x0 GOTO_S_MODE 0x0, 0x0
# Attempt to write 0x111 to each of these CSRs and read the value back # Attempt to write 0x111 to each of these CSRs and read the value back
# should result in an illegal instruction for the write and read, respectively # should result in an illegal instruction for the write and read, respectively
# High-bit versions storing the upper 32 bits of some CSRs for RV32 # High-bit versions storing the upper 32 bits of some CSRs for RV32
# WRITE_READ_CSR mstatush 0x111 # *** these appear not to be implemented in GCC WRITE_READ_CSR mstatush 0x111
# WRITE_READ_CSR menvcfgh 0x111 WRITE_READ_CSR menvcfgh 0x111
# WRITE_READ_CSR mseccfgh 0x111 WRITE_READ_CSR mseccfgh 0x111
WRITE_READ_CSR pmpcfg1 0x111 WRITE_READ_CSR pmpcfg1 0x111
WRITE_READ_CSR pmpcfg3 0x111 WRITE_READ_CSR pmpcfg3 0x111
WRITE_READ_CSR mcycleh 0x111 WRITE_READ_CSR mcycleh 0x111

View File

@ -66,7 +66,7 @@ test_cases:
# --------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------
# =========== test 12.3.2.1 PMAs: Memory Access Size, Type protection test =========== # =========== test 12.3.2.1 PMAs: Memory Access Size, Type protection test ===========
# Tests memory load, store, and execute permissions based on table 12.3 in the *** riscv book, copied below # Tests memory load, store, and execute permissions
# | Region | Base Address | Read widths | R | W | X | Cacheable | Idempotent | Atomic | # | Region | Base Address | Read widths | R | W | X | Cacheable | Idempotent | Atomic |
# | ROM | 0x1000 | Any | YES | NO | YES | YES | NO | NO | # | ROM | 0x1000 | Any | YES | NO | YES | YES | NO | NO |