mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Merge branch 'main' of https://github.com/openhwgroup/cvw into update_ccov
This commit is contained in:
commit
c75fffbaba
13
README.md
13
README.md
@ -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.
|
||||
|
||||
### 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]
|
||||
> - 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.
|
||||
|
||||
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 user’s 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
|
||||
|
||||
|
@ -107,7 +107,7 @@ elif [[ "$ID" == opensuse-leap || "$ID" == sles || "$ID_LIKE" == *suse* ]]; then
|
||||
exit 1
|
||||
fi
|
||||
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 " \
|
||||
"commands in this script, but it is likely that some will need to be altered."
|
||||
exit 1
|
||||
|
@ -147,7 +147,6 @@ localparam WFI_TIMEOUT_BIT = 32'd16;
|
||||
// Peripheral Physical Addresses
|
||||
// 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
|
||||
// *** each of these is `PA_BITS wide. is this paramaterizable INSIDE the config file?
|
||||
localparam logic DTIM_SUPPORTED = 0;
|
||||
localparam logic [63:0] DTIM_BASE = 64'h80000000;
|
||||
localparam logic [63:0] DTIM_RANGE = 64'h007FFFFF;
|
||||
|
@ -147,7 +147,6 @@ localparam WFI_TIMEOUT_BIT = 32'd16;
|
||||
// Peripheral Physical Addresses
|
||||
// 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
|
||||
// *** each of these is `PA_BITS wide. is this paramaterizable INSIDE the config file?
|
||||
localparam logic DTIM_SUPPORTED = 0;
|
||||
localparam logic [63:0] DTIM_BASE = 64'h80000000;
|
||||
localparam logic [63:0] DTIM_RANGE = 64'h007FFFFF;
|
||||
|
@ -44,4 +44,5 @@
|
||||
`include "EndianU_coverage.svh"
|
||||
`include "EndianM_coverage.svh"
|
||||
`include "EndianS_coverage.svh"
|
||||
`include "ExceptionsM_coverage.svh"
|
||||
`include "ExceptionsM_coverage.svh"
|
||||
`include "ExceptionsZc_coverage.svh"
|
||||
|
@ -9,7 +9,7 @@
|
||||
#--showcommands
|
||||
|
||||
# Core settings
|
||||
--variant RV32GC # for RV32GC
|
||||
--variant RV32GCK # for RV32GC
|
||||
--override cpu/priv_version=1.12
|
||||
--override cpu/user_version=20191213
|
||||
# arch
|
||||
@ -59,7 +59,7 @@
|
||||
#--override cpu/instret_undefined=T
|
||||
#--override cpu/hpmcounter_undefined=T
|
||||
|
||||
## context registers not implemented
|
||||
# context registers not implemented
|
||||
#--override cpu/scontext_undefined=True
|
||||
#--override cpu/mcontext_undefined=True
|
||||
|
||||
@ -69,9 +69,14 @@
|
||||
#--override cpu/Zicfilp=F
|
||||
--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
|
||||
#--override cpu/ecode_mask=0x8000000F # for RV32
|
||||
@ -80,7 +85,8 @@
|
||||
# Debug mode not yet supported
|
||||
--override cpu/debug_mode=none
|
||||
|
||||
|
||||
# Zkr entropy source and seed register not supported.
|
||||
--override cpu/Zkr=F
|
||||
|
||||
--override cpu/reset_address=0x80000000
|
||||
|
||||
|
@ -147,7 +147,6 @@ localparam WFI_TIMEOUT_BIT = 32'd16;
|
||||
// Peripheral Physical Addresses
|
||||
// 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
|
||||
// *** each of these is `PA_BITS wide. is this paramaterizable INSIDE the config file?
|
||||
localparam logic DTIM_SUPPORTED = 1;
|
||||
localparam logic [63:0] DTIM_BASE = 64'h80000000;
|
||||
localparam logic [63:0] DTIM_RANGE = 64'h007FFFFF;
|
||||
|
@ -147,7 +147,6 @@ localparam WFI_TIMEOUT_BIT = 32'd16;
|
||||
// Peripheral Physical Addresses
|
||||
// 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
|
||||
// *** each of these is `PA_BITS wide. is this paramaterizable INSIDE the config file?
|
||||
localparam logic DTIM_SUPPORTED = 1;
|
||||
localparam logic [63:0] DTIM_BASE = 64'h80000000;
|
||||
localparam logic [63:0] DTIM_RANGE = 64'h007FFFFF;
|
||||
|
@ -147,7 +147,6 @@ localparam WFI_TIMEOUT_BIT = 32'd16;
|
||||
// Peripheral Physical Addresses
|
||||
// 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
|
||||
// *** each of these is `PA_BITS wide. is this paramaterizable INSIDE the config file?
|
||||
localparam logic DTIM_SUPPORTED = 0;
|
||||
localparam logic [63:0] DTIM_BASE = 64'h80000000;
|
||||
localparam logic [63:0] DTIM_RANGE = 64'h007FFFFF;
|
||||
|
@ -44,6 +44,7 @@
|
||||
`include "EndianM_coverage.svh"
|
||||
`include "EndianS_coverage.svh"
|
||||
`include "ExceptionsM_coverage.svh"
|
||||
`include "ExceptionsZc_coverage.svh"
|
||||
// `include "RV64VM_PMP_coverage.svh"
|
||||
// `include "RV64CBO_VM_coverage.svh"
|
||||
// `include "RV64CBO_PMP_coverage.svh"
|
||||
|
@ -73,7 +73,7 @@
|
||||
# Show "c." with compressed instructions
|
||||
--override show_c_prefix=T
|
||||
|
||||
# nonratified mnosie register not implemented
|
||||
# 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
|
||||
@ -86,8 +86,6 @@
|
||||
# Zkr entropy source and seed register not supported.
|
||||
--override cpu/Zkr=F
|
||||
|
||||
|
||||
|
||||
--override cpu/reset_address=0x80000000
|
||||
|
||||
--override cpu/unaligned=T # Zicclsm (should be true)
|
||||
|
@ -147,7 +147,6 @@ localparam WFI_TIMEOUT_BIT = 32'd16;
|
||||
// Peripheral Physical Addresses
|
||||
// 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
|
||||
// *** each of these is `PA_BITS wide. is this paramaterizable INSIDE the config file?
|
||||
localparam logic DTIM_SUPPORTED = 1;
|
||||
localparam logic [63:0] DTIM_BASE = 64'h80000000;
|
||||
localparam logic [63:0] DTIM_RANGE = 64'h007FFFFF;
|
||||
|
@ -237,7 +237,7 @@ __uint128_t parseNum(char *num) {
|
||||
if (strlen(num) < 8) size = 2;
|
||||
else if (strlen(num) < 16) size = 4;
|
||||
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 {
|
||||
printf("Error: only half, single, double, or quad precision supported");
|
||||
exit(1);
|
||||
|
@ -153,18 +153,20 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
||||
endcase
|
||||
7'b11100??: if (Funct3D == 3'b001 & Rs2D == 5'b00000)
|
||||
ControlsD = `FCTRLW'b0_1_10_00_000_0_0_0_0_0; // fclass
|
||||
else if (Funct3D == 3'b000 & Rs2D == 5'b00000)
|
||||
ControlsD = `FCTRLW'b0_1_11_00_000_0_0_0_0_0; // fmv.x.w/d/h/q fp to int register
|
||||
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)
|
||||
else if (Funct3D == 3'b000 & Rs2D == 5'b00000) begin
|
||||
if (Fmt[1:0] == 2'b00 | Fmt[1:0] == 2'b10 | (P.XLEN == 64 & Fmt[1:0] == 2'b01))
|
||||
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)
|
||||
// Q not supported in RV64GC
|
||||
// coverage off
|
||||
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
|
||||
7'b11110??: if (Funct3D == 3'b000 & Rs2D == 5'b00000)
|
||||
ControlsD = `FCTRLW'b1_0_00_00_011_0_0_0_0_0; // fmv.w/d/h/q.x int to fp reg
|
||||
else if (P.ZFA_SUPPORTED & Funct3D == 3'b000 & Rs2D == 5'b00001)
|
||||
7'b11110??: if (Funct3D == 3'b000 & Rs2D == 5'b00000) begin
|
||||
if (Fmt[1:0] == 2'b00 | Fmt[1:0] == 2'b10 | (P.XLEN == 64 & Fmt[1:0] == 2'b01))
|
||||
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)
|
||||
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)
|
||||
@ -196,54 +198,54 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
|
||||
7'b1101000: case(Rs2D)
|
||||
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'b00010: 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'b00010: if (P.XLEN == 64) ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0_0_0; // fcvt.s.l l->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
|
||||
7'b1100000: case(Rs2D)
|
||||
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'b00010: 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'b00010: if (P.XLEN == 64) ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1_0_0; // fcvt.l.s s->l
|
||||
5'b00011: if (P.XLEN == 64) ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1_0_0; // fcvt.lu.s s->lu
|
||||
endcase
|
||||
7'b1101001: case(Rs2D)
|
||||
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'b00010: 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'b00010: if (P.XLEN == 64) ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0_0_0; // fcvt.d.l l->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
|
||||
7'b1100001: case(Rs2D)
|
||||
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'b00010: 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'b00010: if (P.XLEN == 64) ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1_0_0; // fcvt.l.d d->l
|
||||
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)
|
||||
ControlsD = `FCTRLW'b0_1_01_00_001_0_0_1_1_0; // fcvtmod.w.d (Zfa)
|
||||
endcase
|
||||
7'b1101010: case(Rs2D)
|
||||
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'b00010: 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'b00010: if (P.XLEN == 64) ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0_0_0; // fcvt.h.l l->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
|
||||
7'b1100010: case(Rs2D)
|
||||
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'b00010: 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'b00010: if (P.XLEN == 64) ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1_0_0; // fcvt.l.h h->l
|
||||
5'b00011: if (P.XLEN == 64) ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1_0_0; // fcvt.lu.h h->lu
|
||||
endcase
|
||||
// Not covered in testing because rv64gc does not support quad precision
|
||||
// coverage off
|
||||
7'b1101011: case(Rs2D)
|
||||
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'b00010: 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'b00010: if (P.XLEN == 64) ControlsD = `FCTRLW'b1_0_01_00_111_0_0_0_0_0; // fcvt.q.l l->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
|
||||
7'b1100011: case(Rs2D)
|
||||
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'b00010: 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'b00010: if (P.XLEN == 64) ControlsD = `FCTRLW'b0_1_01_00_011_0_0_1_0_0; // fcvt.l.q q->l
|
||||
5'b00011: if (P.XLEN == 64) ControlsD = `FCTRLW'b0_1_01_00_010_0_0_1_0_0; // fcvt.lu.q q->lu
|
||||
endcase
|
||||
// coverage off
|
||||
// Not covered in testing because rv64gc is not RV64Q or RV32D
|
||||
|
@ -119,13 +119,11 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) (
|
||||
if (P.ZBC_SUPPORTED)
|
||||
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_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
|
||||
if (P.ZBKC_SUPPORTED) begin
|
||||
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_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
|
||||
17'b0110011_0000101_0?1: BMUControlsD = `BMUCTRLW'b000_0011_0000_1_0_0_0_1_0_0_0_0_0; // clmul/clmulh
|
||||
endcase
|
||||
end
|
||||
|
||||
@ -153,10 +151,17 @@ module bmuctrl import cvw::*; #(parameter cvw_t P) (
|
||||
end
|
||||
if (P.ZBB_SUPPORTED | P.ZBS_SUPPORTED) // rv32i/64i shift instructions need BMU ALUSelect when BMU shifter is used
|
||||
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
|
||||
17'b0010011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_1_0_0_1_0_0_0_0_0; // srai, srli, slli
|
||||
17'b0111011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_0_1_0_1_0_0_0_0_0; // sraw, srlw, sllw
|
||||
17'b0011011_0?0000?_?01: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_1_1_0_1_0_0_0_0_0; // sraiw, srliw, slliw
|
||||
// variable shifts don't encode shift amount in funct7
|
||||
17'b0110011_0000000_001: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_0_0_0_1_0_0_0_0_0; // sll
|
||||
17'b0110011_0?00000_101: BMUControlsD = `BMUCTRLW'b001_0000_0000_1_0_0_0_1_0_0_0_0_0; // sra, srl
|
||||
// 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
|
||||
|
||||
if (P.ZBKB_SUPPORTED) begin // ZBKB Bitmanip
|
||||
|
@ -181,8 +181,8 @@ module controller import cvw::*; #(parameter cvw_t P) (
|
||||
assign Funct7ZeroD = (Funct7D == 7'b0000000); // most R-type instructions
|
||||
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 Funct7ShiftZeroD = (P.XLEN==64) ? (Funct7D[6:1] == 6'b000000) : Funct7ZeroD;
|
||||
assign Funct7Shiftb5D = (P.XLEN==64) ? (Funct7D[6:1] == 6'b010000) : Funct7b5D;
|
||||
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 & ~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 INoShiftD = ((Funct3D != 3'b001) & (Funct3D != 3'b101));
|
||||
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
|
||||
// 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 IllegalBaseInstrD = 1'b0;
|
||||
assign {BaseRegWriteD, PreImmSrcD, ALUSrcAD, BaseALUSrcBD, MemRWD,
|
||||
ResultSrcD, BranchD, ALUOpD, JumpD, ALUResultSrcD, BaseW64D, CSRReadD,
|
||||
PrivilegedD, FenceXD, MDUD, AtomicD, CMOD, unused} = IllegalIEUFPUInstrD ? `CTRLW'b0 : ControlsD;
|
||||
|
@ -59,7 +59,7 @@ module privdec import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
// svinval instructions
|
||||
// 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 sfenceinvalirM = (InstrM[31:20] == 12'b000110000001) & rs1zeroM;
|
||||
assign invalM = P.SVINVAL_SUPPORTED & (sinvalvmaM | sfencewinvalM | sfenceinvalirM);
|
||||
|
@ -70,7 +70,7 @@ module FunctionName import cvw::*; #(parameter cvw_t P) (
|
||||
|
||||
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;
|
||||
return;
|
||||
end
|
||||
|
@ -219,6 +219,10 @@ module instrNameDecTB(
|
||||
else if (imm == 258) name = "SRET";
|
||||
else if (imm == 770) name = "MRET";
|
||||
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 name = "ILLEGAL";
|
||||
10'b1110011_001: name = "CSRRW";
|
||||
|
@ -39,7 +39,7 @@ module ramxdetector #(parameter XLEN, LLEN) (
|
||||
/* verilator lint_off WIDTHXZEXPAND */
|
||||
if (MemReadM & ~LSULoadAccessFaultM & (ReadDataM === 'bx)) begin
|
||||
/* 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);
|
||||
//$stop;
|
||||
end
|
||||
|
@ -95,11 +95,19 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi);
|
||||
assign FlushW = testbench.dut.core.FlushW;
|
||||
assign TrapM = testbench.dut.core.TrapM;
|
||||
assign HaltM = testbench.DCacheFlushStart;
|
||||
assign PrivilegeModeW = testbench.dut.core.priv.priv.privmode.PrivilegeModeW;
|
||||
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 wfiM = testbench.dut.core.priv.priv.wfiM;
|
||||
assign InterruptM = testbench.dut.core.priv.priv.InterruptM;
|
||||
if (P.ZICSR_SUPPORTED) begin
|
||||
assign PrivilegeModeW = testbench.dut.core.priv.priv.privmode.PrivilegeModeW;
|
||||
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 wfiM = testbench.dut.core.priv.priv.wfiM;
|
||||
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
|
||||
assign VAdrIM = testbench.dut.core.ifu.immu.immu.tlb.tlb.VAdr;
|
||||
@ -116,181 +124,185 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi);
|
||||
|
||||
logic valid;
|
||||
|
||||
always_comb begin
|
||||
// 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
|
||||
// stalled. If it is stalled we want CSRArray to hold the old value.
|
||||
if(valid) begin
|
||||
// PMPCFG CSRs (space is 0-15 3a0 - 3af)
|
||||
localparam inc = P.XLEN == 32 ? 4 : 8;
|
||||
int i, i4, i8, csrid;
|
||||
logic [P.XLEN-1:0] pmp;
|
||||
if (P.ZICSR_SUPPORTED) begin
|
||||
always_comb begin
|
||||
// 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
|
||||
// stalled. If it is stalled we want CSRArray to hold the old value.
|
||||
if(valid) begin
|
||||
// PMPCFG CSRs (space is 0-15 3a0 - 3af)
|
||||
localparam inc = P.XLEN == 32 ? 4 : 8;
|
||||
int i, i4, i8, csrid;
|
||||
logic [P.XLEN-1:0] pmp;
|
||||
|
||||
for (i=0; i<P.PMP_ENTRIES; i+=inc) begin
|
||||
i4 = i / 4;
|
||||
i8 = (i / inc) * inc;
|
||||
csrid = 12'h3A0 + i4;
|
||||
pmp = 0;
|
||||
pmp |= testbench.dut.core.priv.priv.csr.csrm.PMPCFG_ARRAY_REGW[i8+0] << 0;
|
||||
pmp |= testbench.dut.core.priv.priv.csr.csrm.PMPCFG_ARRAY_REGW[i8+1] << 8;
|
||||
pmp |= testbench.dut.core.priv.priv.csr.csrm.PMPCFG_ARRAY_REGW[i8+2] << 16;
|
||||
pmp |= testbench.dut.core.priv.priv.csr.csrm.PMPCFG_ARRAY_REGW[i8+3] << 24;
|
||||
pmp |= testbench.dut.core.priv.priv.csr.csrm.PMPCFG_ARRAY_REGW[i8+4] << 32;
|
||||
pmp |= testbench.dut.core.priv.priv.csr.csrm.PMPCFG_ARRAY_REGW[i8+5] << 40;
|
||||
pmp |= testbench.dut.core.priv.priv.csr.csrm.PMPCFG_ARRAY_REGW[i8+6] << 48;
|
||||
pmp |= testbench.dut.core.priv.priv.csr.csrm.PMPCFG_ARRAY_REGW[i8+7] << 56;
|
||||
for (i=0; i<P.PMP_ENTRIES; i+=inc) begin
|
||||
i4 = i / 4;
|
||||
i8 = (i / inc) * inc;
|
||||
csrid = 12'h3A0 + i4;
|
||||
pmp = 0;
|
||||
pmp |= testbench.dut.core.priv.priv.csr.csrm.PMPCFG_ARRAY_REGW[i8+0] << 0;
|
||||
pmp |= testbench.dut.core.priv.priv.csr.csrm.PMPCFG_ARRAY_REGW[i8+1] << 8;
|
||||
pmp |= testbench.dut.core.priv.priv.csr.csrm.PMPCFG_ARRAY_REGW[i8+2] << 16;
|
||||
pmp |= testbench.dut.core.priv.priv.csr.csrm.PMPCFG_ARRAY_REGW[i8+3] << 24;
|
||||
pmp |= testbench.dut.core.priv.priv.csr.csrm.PMPCFG_ARRAY_REGW[i8+4] << 32;
|
||||
pmp |= testbench.dut.core.priv.priv.csr.csrm.PMPCFG_ARRAY_REGW[i8+5] << 40;
|
||||
pmp |= testbench.dut.core.priv.priv.csr.csrm.PMPCFG_ARRAY_REGW[i8+6] << 48;
|
||||
pmp |= testbench.dut.core.priv.priv.csr.csrm.PMPCFG_ARRAY_REGW[i8+7] << 56;
|
||||
|
||||
CSRArray[csrid] = pmp;
|
||||
end
|
||||
|
||||
// PMPADDR CSRs (space is 0-63 3b0 - 3ef)
|
||||
for (i=0; i<P.PMP_ENTRIES; i++) begin
|
||||
csrid = 12'h3B0 + i;;
|
||||
pmp = testbench.dut.core.priv.priv.csr.csrm.PMPADDR_ARRAY_REGW[i];
|
||||
CSRArray[csrid] = pmp;
|
||||
end
|
||||
|
||||
// M-mode trap CSRs
|
||||
CSRArray[12'h300] = testbench.dut.core.priv.priv.csr.csrm.MSTATUS_REGW;
|
||||
CSRArray[12'h302] = testbench.dut.core.priv.priv.csr.csrm.MEDELEG_REGW;
|
||||
CSRArray[12'h303] = testbench.dut.core.priv.priv.csr.csrm.MIDELEG_REGW;
|
||||
CSRArray[12'h304] = testbench.dut.core.priv.priv.csr.csrm.MIE_REGW;
|
||||
CSRArray[12'h305] = testbench.dut.core.priv.priv.csr.csrm.MTVEC_REGW;
|
||||
CSRArray[12'h340] = testbench.dut.core.priv.priv.csr.csrm.MSCRATCH_REGW;
|
||||
CSRArray[12'h341] = testbench.dut.core.priv.priv.csr.csrm.MEPC_REGW;
|
||||
CSRArray[12'h342] = testbench.dut.core.priv.priv.csr.csrm.MCAUSE_REGW;
|
||||
CSRArray[12'h343] = testbench.dut.core.priv.priv.csr.csrm.MTVAL_REGW;
|
||||
CSRArray[12'h344] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW;
|
||||
|
||||
CSRArray[csrid] = pmp;
|
||||
end
|
||||
// S-mode trap CSRs
|
||||
CSRArray[12'h100] = testbench.dut.core.priv.priv.csr.csrs.csrs.SSTATUS_REGW;
|
||||
CSRArray[12'h104] = testbench.dut.core.priv.priv.csr.csrm.MIE_REGW & 12'h222;
|
||||
CSRArray[12'h105] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVEC_REGW;
|
||||
CSRArray[12'h140] = testbench.dut.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW;
|
||||
CSRArray[12'h141] = testbench.dut.core.priv.priv.csr.csrs.csrs.SEPC_REGW;
|
||||
CSRArray[12'h142] = testbench.dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW;
|
||||
CSRArray[12'h143] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW;
|
||||
CSRArray[12'h144] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & testbench.dut.core.priv.priv.csr.csrm.MIDELEG_REGW;
|
||||
|
||||
// PMPADDR CSRs (space is 0-63 3b0 - 3ef)
|
||||
for (i=0; i<P.PMP_ENTRIES; i++) begin
|
||||
csrid = 12'h3B0 + i;;
|
||||
pmp = testbench.dut.core.priv.priv.csr.csrm.PMPADDR_ARRAY_REGW[i];
|
||||
CSRArray[csrid] = pmp;
|
||||
end
|
||||
// Virtual Memory CSRs
|
||||
CSRArray[12'h180] = testbench.dut.core.priv.priv.csr.csrs.csrs.SATP_REGW;
|
||||
|
||||
// M-mode trap CSRs
|
||||
CSRArray[12'h300] = testbench.dut.core.priv.priv.csr.csrm.MSTATUS_REGW;
|
||||
CSRArray[12'h302] = testbench.dut.core.priv.priv.csr.csrm.MEDELEG_REGW;
|
||||
CSRArray[12'h303] = testbench.dut.core.priv.priv.csr.csrm.MIDELEG_REGW;
|
||||
CSRArray[12'h304] = testbench.dut.core.priv.priv.csr.csrm.MIE_REGW;
|
||||
CSRArray[12'h305] = testbench.dut.core.priv.priv.csr.csrm.MTVEC_REGW;
|
||||
CSRArray[12'h340] = testbench.dut.core.priv.priv.csr.csrm.MSCRATCH_REGW;
|
||||
CSRArray[12'h341] = testbench.dut.core.priv.priv.csr.csrm.MEPC_REGW;
|
||||
CSRArray[12'h342] = testbench.dut.core.priv.priv.csr.csrm.MCAUSE_REGW;
|
||||
CSRArray[12'h343] = testbench.dut.core.priv.priv.csr.csrm.MTVAL_REGW;
|
||||
CSRArray[12'h344] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW;
|
||||
|
||||
// S-mode trap CSRs
|
||||
CSRArray[12'h100] = testbench.dut.core.priv.priv.csr.csrs.csrs.SSTATUS_REGW;
|
||||
CSRArray[12'h104] = testbench.dut.core.priv.priv.csr.csrm.MIE_REGW & 12'h222;
|
||||
CSRArray[12'h105] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVEC_REGW;
|
||||
CSRArray[12'h140] = testbench.dut.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW;
|
||||
CSRArray[12'h141] = testbench.dut.core.priv.priv.csr.csrs.csrs.SEPC_REGW;
|
||||
CSRArray[12'h142] = testbench.dut.core.priv.priv.csr.csrs.csrs.SCAUSE_REGW;
|
||||
CSRArray[12'h143] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW;
|
||||
CSRArray[12'h144] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW & 12'h222 & testbench.dut.core.priv.priv.csr.csrm.MIDELEG_REGW;
|
||||
// Floating-Point CSRs
|
||||
CSRArray[12'h001] = testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW;
|
||||
CSRArray[12'h002] = testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW;
|
||||
CSRArray[12'h003] = {testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW, testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW};
|
||||
|
||||
// Virtual Memory CSRs
|
||||
CSRArray[12'h180] = testbench.dut.core.priv.priv.csr.csrs.csrs.SATP_REGW;
|
||||
// Counters / Performance Monitoring CSRs
|
||||
CSRArray[12'h306] = testbench.dut.core.priv.priv.csr.csrm.MCOUNTEREN_REGW;
|
||||
CSRArray[12'h106] = testbench.dut.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW;
|
||||
CSRArray[12'h320] = testbench.dut.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW;
|
||||
// mhpmevent3-31 not connected (232-33F)
|
||||
CSRArray[12'hB00] = testbench.dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; // MCYCLE
|
||||
CSRArray[12'hB02] = testbench.dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; // MINSTRET
|
||||
// mhpmcounter3-31 not connected (B03-B1F)
|
||||
// cycle, time, instret not connected (C00-C02)
|
||||
// hpmcounter3-31 not connected (C03-C1F)
|
||||
|
||||
// Floating-Point CSRs
|
||||
CSRArray[12'h001] = testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW;
|
||||
CSRArray[12'h002] = testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW;
|
||||
CSRArray[12'h003] = {testbench.dut.core.priv.priv.csr.csru.csru.FRM_REGW, testbench.dut.core.priv.priv.csr.csru.csru.FFLAGS_REGW};
|
||||
// Machine Information Registers and Configuration CSRs
|
||||
CSRArray[12'h301] = testbench.dut.core.priv.priv.csr.csrm.MISA_REGW;
|
||||
CSRArray[12'h30A] = testbench.dut.core.priv.priv.csr.csrm.MENVCFG_REGW;
|
||||
CSRArray[12'h10A] = testbench.dut.core.priv.priv.csr.csrs.csrs.SENVCFG_REGW;
|
||||
CSRArray[12'h747] = 0; // mseccfg
|
||||
CSRArray[12'hF11] = 0; //mvendorid
|
||||
CSRArray[12'hF12] = 0; // marchid
|
||||
CSRArray[12'hF13] = {{P.XLEN-12{1'b0}}, 12'h100}; // mimpid
|
||||
CSRArray[12'hF14] = testbench.dut.core.priv.priv.csr.csrm.MHARTID_REGW;
|
||||
CSRArray[12'hF15] = 0; //mconfigptr
|
||||
|
||||
// Counters / Performance Monitoring CSRs
|
||||
CSRArray[12'h306] = testbench.dut.core.priv.priv.csr.csrm.MCOUNTEREN_REGW;
|
||||
CSRArray[12'h106] = testbench.dut.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW;
|
||||
CSRArray[12'h320] = testbench.dut.core.priv.priv.csr.csrm.MCOUNTINHIBIT_REGW;
|
||||
// mhpmevent3-31 not connected (232-33F)
|
||||
CSRArray[12'hB00] = testbench.dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[0]; // MCYCLE
|
||||
CSRArray[12'hB02] = testbench.dut.core.priv.priv.csr.counters.counters.HPMCOUNTER_REGW[2]; // MINSTRET
|
||||
// mhpmcounter3-31 not connected (B03-B1F)
|
||||
// cycle, time, instret not connected (C00-C02)
|
||||
// hpmcounter3-31 not connected (C03-C1F)
|
||||
// Sstc CSRs
|
||||
CSRArray[12'h14D] = testbench.dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW[P.XLEN-1:0];
|
||||
|
||||
// Zkr CSRs
|
||||
// seed not connected (015)
|
||||
|
||||
// Machine Information Registers and Configuration CSRs
|
||||
CSRArray[12'h301] = testbench.dut.core.priv.priv.csr.csrm.MISA_REGW;
|
||||
CSRArray[12'h30A] = testbench.dut.core.priv.priv.csr.csrm.MENVCFG_REGW;
|
||||
CSRArray[12'h10A] = testbench.dut.core.priv.priv.csr.csrs.csrs.SENVCFG_REGW;
|
||||
CSRArray[12'h747] = 0; // mseccfg
|
||||
CSRArray[12'hF11] = 0; //mvendorid
|
||||
CSRArray[12'hF12] = 0; // marchid
|
||||
CSRArray[12'hF13] = {{P.XLEN-12{1'b0}}, 12'h100}; // mimpid
|
||||
CSRArray[12'hF14] = testbench.dut.core.priv.priv.csr.csrm.MHARTID_REGW;
|
||||
CSRArray[12'hF15] = 0; //mconfigptr
|
||||
// extra CSRs for RV32
|
||||
if (P.XLEN == 32) begin
|
||||
CSRArray[12'h310] = testbench.dut.core.priv.priv.csr.csrsr.MSTATUSH_REGW;
|
||||
CSRArray[12'h31A] = testbench.dut.core.priv.priv.csr.csrm.MENVCFGH_REGW;
|
||||
CSRArray[12'h757] = 0; // mseccfgh
|
||||
CSRArray[12'h15D] = testbench.dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW[63:32];
|
||||
end
|
||||
end else begin // hold the old value if the pipeline is stalled.
|
||||
// PMP CFG 3A0 to 3AF
|
||||
int csrid;
|
||||
for(csrid='h3A0; csrid<='h3AF; csrid++)
|
||||
CSRArray[csrid] = CSRArrayOld[csrid];
|
||||
|
||||
// PMP ADDR 3B0 to 3EF
|
||||
for(csrid='h3B0; csrid<='h3EF; csrid++)
|
||||
CSRArray[csrid] = CSRArrayOld[csrid];
|
||||
|
||||
// Sstc CSRs
|
||||
CSRArray[12'h14D] = testbench.dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW[P.XLEN-1:0];
|
||||
|
||||
// Zkr CSRs
|
||||
// seed not connected (015)
|
||||
// M-mode trap CSRs
|
||||
CSRArray[12'h300] = CSRArrayOld[12'h300];
|
||||
CSRArray[12'h302] = CSRArrayOld[12'h302];
|
||||
CSRArray[12'h303] = CSRArrayOld[12'h303];
|
||||
CSRArray[12'h304] = CSRArrayOld[12'h304];
|
||||
CSRArray[12'h305] = CSRArrayOld[12'h305];
|
||||
CSRArray[12'h340] = CSRArrayOld[12'h340];
|
||||
CSRArray[12'h341] = CSRArrayOld[12'h341];
|
||||
CSRArray[12'h342] = CSRArrayOld[12'h342];
|
||||
CSRArray[12'h343] = CSRArrayOld[12'h343];
|
||||
CSRArray[12'h344] = CSRArrayOld[12'h344];
|
||||
|
||||
// extra CSRs for RV32
|
||||
if (P.XLEN == 32) begin
|
||||
CSRArray[12'h310] = testbench.dut.core.priv.priv.csr.csrsr.MSTATUSH_REGW;
|
||||
CSRArray[12'h31A] = testbench.dut.core.priv.priv.csr.csrm.MENVCFGH_REGW;
|
||||
CSRArray[12'h757] = 0; // mseccfgh
|
||||
CSRArray[12'h15D] = testbench.dut.core.priv.priv.csr.csrs.csrs.STIMECMP_REGW[63:32];
|
||||
end
|
||||
end else begin // hold the old value if the pipeline is stalled.
|
||||
// PMP CFG 3A0 to 3AF
|
||||
int csrid;
|
||||
for(csrid='h3A0; csrid<='h3AF; csrid++)
|
||||
CSRArray[csrid] = CSRArrayOld[csrid];
|
||||
|
||||
// PMP ADDR 3B0 to 3EF
|
||||
for(csrid='h3B0; csrid<='h3EF; csrid++)
|
||||
CSRArray[csrid] = CSRArrayOld[csrid];
|
||||
// S-mode trap CSRs
|
||||
CSRArray[12'h100] = CSRArrayOld[12'h100];
|
||||
CSRArray[12'h104] = CSRArrayOld[12'h104];
|
||||
CSRArray[12'h105] = CSRArrayOld[12'h105];
|
||||
CSRArray[12'h140] = CSRArrayOld[12'h140];
|
||||
CSRArray[12'h141] = CSRArrayOld[12'h141];
|
||||
CSRArray[12'h142] = CSRArrayOld[12'h142];
|
||||
CSRArray[12'h143] = CSRArrayOld[12'h143];
|
||||
CSRArray[12'h144] = CSRArrayOld[12'h144];
|
||||
|
||||
// M-mode trap CSRs
|
||||
CSRArray[12'h300] = CSRArrayOld[12'h300];
|
||||
CSRArray[12'h302] = CSRArrayOld[12'h302];
|
||||
CSRArray[12'h303] = CSRArrayOld[12'h303];
|
||||
CSRArray[12'h304] = CSRArrayOld[12'h304];
|
||||
CSRArray[12'h305] = CSRArrayOld[12'h305];
|
||||
CSRArray[12'h340] = CSRArrayOld[12'h340];
|
||||
CSRArray[12'h341] = CSRArrayOld[12'h341];
|
||||
CSRArray[12'h342] = CSRArrayOld[12'h342];
|
||||
CSRArray[12'h343] = CSRArrayOld[12'h343];
|
||||
CSRArray[12'h344] = CSRArrayOld[12'h344];
|
||||
// Virtual Memory CSRs
|
||||
CSRArray[12'h180] = CSRArrayOld[12'h180] ;
|
||||
|
||||
// S-mode trap CSRs
|
||||
CSRArray[12'h100] = CSRArrayOld[12'h100];
|
||||
CSRArray[12'h104] = CSRArrayOld[12'h104];
|
||||
CSRArray[12'h105] = CSRArrayOld[12'h105];
|
||||
CSRArray[12'h140] = CSRArrayOld[12'h140];
|
||||
CSRArray[12'h141] = CSRArrayOld[12'h141];
|
||||
CSRArray[12'h142] = CSRArrayOld[12'h142];
|
||||
CSRArray[12'h143] = CSRArrayOld[12'h143];
|
||||
CSRArray[12'h144] = CSRArrayOld[12'h144];
|
||||
// Floating-Point CSRs
|
||||
CSRArray[12'h001] = CSRArrayOld[12'h001];
|
||||
CSRArray[12'h002] = CSRArrayOld[12'h002];
|
||||
CSRArray[12'h003] = CSRArrayOld[12'h003];
|
||||
|
||||
// Virtual Memory CSRs
|
||||
CSRArray[12'h180] = CSRArrayOld[12'h180] ;
|
||||
// Counters / Performance Monitoring CSRs
|
||||
CSRArray[12'h306] = CSRArrayOld[12'h306];
|
||||
CSRArray[12'h106] = CSRArrayOld[12'h106];
|
||||
CSRArray[12'h320] = CSRArrayOld[12'h320];
|
||||
// mhpmevent3-31 not connected (232-33F)
|
||||
CSRArray[12'hB00] = CSRArrayOld[12'hB00];
|
||||
CSRArray[12'hB02] = CSRArrayOld[12'hB02];
|
||||
// mhpmcounter3-31 not connected (B03-B1F)
|
||||
// cycle, time, instret not connected (C00-C02)
|
||||
// hpmcounter3-31 not connected (C03-C1F)
|
||||
|
||||
// Floating-Point CSRs
|
||||
CSRArray[12'h001] = CSRArrayOld[12'h001];
|
||||
CSRArray[12'h002] = CSRArrayOld[12'h002];
|
||||
CSRArray[12'h003] = CSRArrayOld[12'h003];
|
||||
// Machine Information Registers and Configuration CSRs
|
||||
CSRArray[12'h301] = CSRArrayOld[12'h301];
|
||||
CSRArray[12'h30A] = CSRArrayOld[12'h30A];
|
||||
CSRArray[12'h10A] = CSRArrayOld[12'h10A];
|
||||
CSRArray[12'h747] = CSRArrayOld[12'h747];
|
||||
CSRArray[12'hF11] = CSRArrayOld[12'hF11];
|
||||
CSRArray[12'hF12] = CSRArrayOld[12'hF12];
|
||||
CSRArray[12'hF13] = CSRArrayOld[12'hF13];
|
||||
CSRArray[12'hF14] = CSRArrayOld[12'hF14];
|
||||
CSRArray[12'hF15] = CSRArrayOld[12'hF15];
|
||||
|
||||
// Counters / Performance Monitoring CSRs
|
||||
CSRArray[12'h306] = CSRArrayOld[12'h306];
|
||||
CSRArray[12'h106] = CSRArrayOld[12'h106];
|
||||
CSRArray[12'h320] = CSRArrayOld[12'h320];
|
||||
// mhpmevent3-31 not connected (232-33F)
|
||||
CSRArray[12'hB00] = CSRArrayOld[12'hB00];
|
||||
CSRArray[12'hB02] = CSRArrayOld[12'hB02];
|
||||
// mhpmcounter3-31 not connected (B03-B1F)
|
||||
// cycle, time, instret not connected (C00-C02)
|
||||
// hpmcounter3-31 not connected (C03-C1F)
|
||||
// Sstc CSRs
|
||||
CSRArray[12'h14D] = CSRArrayOld[12'h14D];
|
||||
|
||||
// Zkr CSRs
|
||||
// seed not connected (015)
|
||||
|
||||
// Machine Information Registers and Configuration CSRs
|
||||
CSRArray[12'h301] = CSRArrayOld[12'h301];
|
||||
CSRArray[12'h30A] = CSRArrayOld[12'h30A];
|
||||
CSRArray[12'h10A] = CSRArrayOld[12'h10A];
|
||||
CSRArray[12'h747] = CSRArrayOld[12'h747];
|
||||
CSRArray[12'hF11] = CSRArrayOld[12'hF11];
|
||||
CSRArray[12'hF12] = CSRArrayOld[12'hF12];
|
||||
CSRArray[12'hF13] = CSRArrayOld[12'hF13];
|
||||
CSRArray[12'hF14] = CSRArrayOld[12'hF14];
|
||||
CSRArray[12'hF15] = CSRArrayOld[12'hF15];
|
||||
|
||||
// Sstc CSRs
|
||||
CSRArray[12'h14D] = CSRArrayOld[12'h14D];
|
||||
|
||||
// Zkr CSRs
|
||||
// seed not connected (015)
|
||||
|
||||
// extra CSRs for RV32
|
||||
if (P.XLEN == 32) begin
|
||||
CSRArray[12'h310] = CSRArrayOld[12'h310];
|
||||
CSRArray[12'h31A] = CSRArrayOld[12'h31A];
|
||||
CSRArray[12'h757] = CSRArrayOld[12'h757];
|
||||
CSRArray[12'h15D] = CSRArrayOld[12'h15D];
|
||||
end
|
||||
end
|
||||
// extra CSRs for RV32
|
||||
if (P.XLEN == 32) begin
|
||||
CSRArray[12'h310] = CSRArrayOld[12'h310];
|
||||
CSRArray[12'h31A] = CSRArrayOld[12'h31A];
|
||||
CSRArray[12'h757] = CSRArrayOld[12'h757];
|
||||
CSRArray[12'h15D] = CSRArrayOld[12'h15D];
|
||||
end
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
// no CSRArray
|
||||
end
|
||||
|
||||
genvar index;
|
||||
@ -307,11 +319,18 @@ module wallyTracer import cvw::*; #(parameter cvw_t P) (rvviTrace rvvi);
|
||||
rf_wb[rf_a3] <= 1'b1;
|
||||
end
|
||||
|
||||
for(index = 0; index < NUMREGS; index += 1)
|
||||
assign frf[index] = testbench.dut.core.fpu.fpu.fregfile.rf[index];
|
||||
if (P.F_SUPPORTED) begin
|
||||
assign frf_a4 = testbench.dut.core.fpu.fpu.fregfile.a4;
|
||||
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
|
||||
|
||||
assign frf_a4 = testbench.dut.core.fpu.fpu.fregfile.a4;
|
||||
assign frf_we4 = testbench.dut.core.fpu.fpu.fregfile.we4;
|
||||
|
||||
always_comb begin
|
||||
frf_wb <= 0;
|
||||
|
@ -866,12 +866,14 @@ end
|
||||
|
||||
end
|
||||
|
||||
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[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[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]));
|
||||
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[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[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[5]) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[5]));
|
||||
end
|
||||
|
||||
final begin
|
||||
void'(rvviRefShutdown());
|
||||
|
@ -1,4 +1,13 @@
|
||||
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 read from pmpcfg1 with illegal instruction
|
||||
00000bad
|
||||
|
@ -117,7 +117,7 @@ cause_store_acc:
|
||||
ret
|
||||
|
||||
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
|
||||
ret
|
||||
|
||||
@ -319,7 +319,7 @@ end_trap_triggers:
|
||||
.align 6
|
||||
trap_handler_\MODE\():
|
||||
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
|
||||
// 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.
|
||||
@ -337,7 +337,7 @@ trap_handler_\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.
|
||||
// *** 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
|
||||
// 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
|
||||
|
||||
.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:
|
||||
// value read out from ADDR
|
||||
// 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
|
||||
// 0xB: test called from M mode
|
||||
// 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
|
||||
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
|
||||
// Fault outputs:
|
||||
// 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 t4, \VAL
|
||||
csrw \CSR\(), t4
|
||||
|
@ -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.
|
||||
|
||||
# *** 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
|
||||
|
||||
# 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
|
||||
|
||||
# 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 menvcfgh 0x111
|
||||
# WRITE_READ_CSR mseccfgh 0x111
|
||||
WRITE_READ_CSR mstatush 0x111
|
||||
WRITE_READ_CSR menvcfgh 0x111
|
||||
WRITE_READ_CSR mseccfgh 0x111
|
||||
WRITE_READ_CSR pmpcfg1 0x111
|
||||
WRITE_READ_CSR pmpcfg3 0x111
|
||||
WRITE_READ_CSR mcycleh 0x111
|
||||
|
@ -66,7 +66,7 @@ test_cases:
|
||||
# ---------------------------------------------------------------------------------------------
|
||||
|
||||
# =========== 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 |
|
||||
# | ROM | 0x1000 | Any | YES | NO | YES | YES | NO | NO |
|
||||
|
Loading…
Reference in New Issue
Block a user