diff --git a/README.md b/README.md index 70d74eb52..0f560f63a 100644 --- a/README.md +++ b/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 diff --git a/bin/wally-distro-check.sh b/bin/wally-distro-check.sh index c7a540c34..7a519478a 100755 --- a/bin/wally-distro-check.sh +++ b/bin/wally-distro-check.sh @@ -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 diff --git a/config/rv32e/config.vh b/config/rv32e/config.vh index 4ec0123d1..db0838550 100644 --- a/config/rv32e/config.vh +++ b/config/rv32e/config.vh @@ -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; diff --git a/config/rv32gc/config.vh b/config/rv32gc/config.vh index c861759d9..af2032937 100644 --- a/config/rv32gc/config.vh +++ b/config/rv32gc/config.vh @@ -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; diff --git a/config/rv32gc/coverage.svh b/config/rv32gc/coverage.svh index 0403b7e4b..90593e0f5 100644 --- a/config/rv32gc/coverage.svh +++ b/config/rv32gc/coverage.svh @@ -44,4 +44,5 @@ `include "EndianU_coverage.svh" `include "EndianM_coverage.svh" `include "EndianS_coverage.svh" -`include "ExceptionsM_coverage.svh" \ No newline at end of file +`include "ExceptionsM_coverage.svh" +`include "ExceptionsZc_coverage.svh" diff --git a/config/rv32gc/imperas.ic b/config/rv32gc/imperas.ic index 2ba3c1280..0c3f2e2ea 100644 --- a/config/rv32gc/imperas.ic +++ b/config/rv32gc/imperas.ic @@ -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 diff --git a/config/rv32i/config.vh b/config/rv32i/config.vh index 01818afc2..ede534f0b 100644 --- a/config/rv32i/config.vh +++ b/config/rv32i/config.vh @@ -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; diff --git a/config/rv32imc/config.vh b/config/rv32imc/config.vh index 05a8fd242..e9f986a07 100644 --- a/config/rv32imc/config.vh +++ b/config/rv32imc/config.vh @@ -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; diff --git a/config/rv64gc/config.vh b/config/rv64gc/config.vh index b8ed8dc47..4f833178a 100644 --- a/config/rv64gc/config.vh +++ b/config/rv64gc/config.vh @@ -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; diff --git a/config/rv64gc/coverage.svh b/config/rv64gc/coverage.svh index e7c574020..6aba1ac9a 100644 --- a/config/rv64gc/coverage.svh +++ b/config/rv64gc/coverage.svh @@ -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" diff --git a/config/rv64gc/imperas.ic b/config/rv64gc/imperas.ic index 9ba14f2f0..19a7515a5 100644 --- a/config/rv64gc/imperas.ic +++ b/config/rv64gc/imperas.ic @@ -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) diff --git a/config/rv64i/config.vh b/config/rv64i/config.vh index 94360877f..3a8bae1bc 100644 --- a/config/rv64i/config.vh +++ b/config/rv64i/config.vh @@ -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; diff --git a/examples/fp/fpcalc/fpcalc.c b/examples/fp/fpcalc/fpcalc.c index 16dcce225..e4638a64b 100644 --- a/examples/fp/fpcalc/fpcalc.c +++ b/examples/fp/fpcalc/fpcalc.c @@ -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); diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index d04fc45fa..2b8dbc411 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -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 diff --git a/src/ieu/bmu/bmuctrl.sv b/src/ieu/bmu/bmuctrl.sv index d4a8afe23..fe781e78b 100644 --- a/src/ieu/bmu/bmuctrl.sv +++ b/src/ieu/bmu/bmuctrl.sv @@ -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 diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv index 19f96c98d..75dbf2b6a 100644 --- a/src/ieu/controller.sv +++ b/src/ieu/controller.sv @@ -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; diff --git a/src/privileged/privdec.sv b/src/privileged/privdec.sv index 6321413d4..99380e63f 100644 --- a/src/privileged/privdec.sv +++ b/src/privileged/privdec.sv @@ -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); diff --git a/testbench/common/functionName.sv b/testbench/common/functionName.sv index 5a14c84a4..2d257ce32 100644 --- a/testbench/common/functionName.sv +++ b/testbench/common/functionName.sv @@ -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 diff --git a/testbench/common/instrNameDecTB.sv b/testbench/common/instrNameDecTB.sv index 80f6ed607..ae970513f 100644 --- a/testbench/common/instrNameDecTB.sv +++ b/testbench/common/instrNameDecTB.sv @@ -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"; diff --git a/testbench/common/ramxdetector.sv b/testbench/common/ramxdetector.sv index c600cff8c..fac34fb43 100644 --- a/testbench/common/ramxdetector.sv +++ b/testbench/common/ramxdetector.sv @@ -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 diff --git a/testbench/common/wallyTracer.sv b/testbench/common/wallyTracer.sv index a32417737..51f0d302a 100644 --- a/testbench/common/wallyTracer.sv +++ b/testbench/common/wallyTracer.sv @@ -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