diff --git a/bin/wally-tool-chain-install.sh b/bin/wally-tool-chain-install.sh index f690bfac1..7ccb1a138 100755 --- a/bin/wally-tool-chain-install.sh +++ b/bin/wally-tool-chain-install.sh @@ -137,6 +137,27 @@ sudo make install # package manager. Sail has so many dependencies that it can be difficult to install. # This script works for Ubuntu. +# Alex Solomatnikov found these commands worked to build Sail for Centos 8 on 1/12/24 +#sudo su - +#dnf install ocaml.x86_64 +#pip3 install z3-solver +#wget https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh +#sh install.sh +#opam init +#exit +#ocaml -version +#opam switch create 5.1.0 +#eval $(opam config env) +#git clone --recurse-submodules git@github.com:riscv/sail-riscv.git +#cd sail-riscv +#make +#ARCH=RV32 make +#ARCH=RV64 make +#git log -1 +#cp -p c_emulator/riscv_sim_RV* /tools/sail-riscv/d7a3d8012fd579f40e53a29569141d72dd5e0c32/bin/. + + +# This was an earlier attemp to prepare to install Sail on RedHat 8 # Do these commands only for RedHat / Rocky 8 to build from source. #cd $RISCV #git clone https://github.com/Z3Prover/z3.git diff --git a/docs/Dockerfile b/docs/Dockerfile index cdc3dbcfc..b06f9ad67 100755 --- a/docs/Dockerfile +++ b/docs/Dockerfile @@ -30,7 +30,7 @@ FROM debian RUN apt update # INSTALL -RUN apt install -y git gawk make texinfo bison flex build-essential python libz-dev libexpat-dev autoconf device-tree-compiler ninja-build libpixman-1-dev build-essential ncurses-base ncurses-bin libncurses5-dev dialog curl wget ftp libgmp-dev python3-pip pkg-config libglib2.0-dev opam build-essential z3 pkg-config zlib1g-dev verilator cpio bc vim emacs gedit nano +RUN apt install -y git gawk make texinfo bison flex build-essential python3 libz-dev libexpat-dev autoconf device-tree-compiler ninja-build libpixman-1-dev build-essential ncurses-base ncurses-bin libncurses5-dev dialog curl wget ftp libgmp-dev python3-pip pkg-config libglib2.0-dev opam build-essential z3 pkg-config zlib1g-dev verilator cpio bc vim emacs gedit nano RUN pip3 install chardet==3.0.4 RUN pip3 install urllib3==1.22 diff --git a/examples/fp/softfloat_demo/Makefile b/examples/fp/softfloat_demo/Makefile index cc98d0cfb..373d131ca 100644 --- a/examples/fp/softfloat_demo/Makefile +++ b/examples/fp/softfloat_demo/Makefile @@ -6,7 +6,7 @@ LFLAGS = -L. # Link against the riscv-isa-sim version of SoftFloat rather than # the regular version to get RISC-V NaN behavior #IFLAGS = -I$(RISCV)/riscv-isa-sim/softfloat -#LIBS = $(RISCV)/riscv-isa-sim/build/libsoftfloat.a +#LIBS = $(RISCV)/riscv-isa-sim/build/libsoftfloat.a -lm -lquadmath IFLAGS = -I../../../addins/SoftFloat-3e/source/include/ LIBS = ../../../addins/SoftFloat-3e/build/Linux-x86_64-GCC/softfloat.a -lm -lquadmath SRCS = $(wildcard *.c) diff --git a/examples/fp/softfloat_demo/softfloat_demoDP.c b/examples/fp/softfloat_demo/softfloat_demoDP.c index 50b3d0b53..b46103eed 100644 --- a/examples/fp/softfloat_demo/softfloat_demoDP.c +++ b/examples/fp/softfloat_demo/softfloat_demoDP.c @@ -38,16 +38,19 @@ void printF64 (char *msg, float64_t d) { int i, j; conv.v = d.v; // use union to convert between hexadecimal and floating-point views printf("%s: ", msg); // print out nicely - printf("0x%08x_%08x = %g\n", (conv.v >> 32),(conv.v & 0xFFFFFFFF), conv.d); + printf("0x%08lx_%08lx = %g\n", (conv.v >> 32),(conv.v & 0xFFFFFFFF), conv.d); } void printF128 (char *msg, float128_t q) { qp conv; int i, j; + char buf[64]; conv.v[0] = q.v[0]; // use union to convert between hexadecimal and floating-point views conv.v[1] = q.v[1]; // use union to convert between hexadecimal and floating-point views printf("%s: ", msg); // print out nicely - printf("0x%016" PRIx64 "_%016" PRIx64 " = %1.15Qe\n", q.v[1], q.v[0], conv.q); + //printf("0x%016" PRIx64 "_%016" PRIx64 " = %1.15Qe\n", q.v[1], q.v[0], conv.q); + quadmath_snprintf (buf, sizeof buf, "%1.15Qe", conv.q); + printf("0x%016" PRIx64 "_%016" PRIx64 " = %s\n", q.v[1], q.v[0], buf); } void printFlags(void) { diff --git a/examples/fp/softfloat_demo/softfloat_demoQP.c b/examples/fp/softfloat_demo/softfloat_demoQP.c index 03f0e5edb..0f97d3bf6 100644 --- a/examples/fp/softfloat_demo/softfloat_demoQP.c +++ b/examples/fp/softfloat_demo/softfloat_demoQP.c @@ -38,16 +38,23 @@ void printF64 (char *msg, float64_t d) { int i, j; conv.v = d.v; // use union to convert between hexadecimal and floating-point views printf("%s: ", msg); // print out nicely - printf("0x%08x_%08x = %g\n", (conv.v >> 32),(conv.v & 0xFFFFFFFF), conv.d); + printf("0x%08lx_%08lx = %g\n", (conv.v >> 32),(conv.v & 0xFFFFFFFF), conv.d); } void printF128 (char *msg, float128_t q) { qp conv; int i, j; + char buf[64]; conv.v[0] = q.v[0]; // use union to convert between hexadecimal and floating-point views conv.v[1] = q.v[1]; // use union to convert between hexadecimal and floating-point views printf("%s: ", msg); // print out nicely - printf("0x%016" PRIx64 "_%016" PRIx64 " = %1.15Qe\n", q.v[1], q.v[0], conv.q); + + // Some compilers can understand %Q for printf on quad precision instead of the + // API call of quadmath_snprintf + // printf("0x%016" PRIx64 "_%016" PRIx64 " = %1.15Qe\n", q.v[1], q.v[0], conv.q); + quadmath_snprintf (buf, sizeof buf, "%1.15Qe", conv.q); + printf("0x%016" PRIx64 "_%016" PRIx64 " = %s\n", q.v[1], q.v[0], buf); + } void printFlags(void) { @@ -74,6 +81,8 @@ int main() { float128_t x, y, z; float128_t r; + uint32_t u, v, w; + int32_t a, b, c; x.v[1] = 0xBFFF988ECE97DFEB; x.v[0] = 0xC3BBA082445B4836; diff --git a/examples/fp/softfloat_demo/softfloat_demoSP.c b/examples/fp/softfloat_demo/softfloat_demoSP.c index 55c5ef991..bbc39438e 100644 --- a/examples/fp/softfloat_demo/softfloat_demoSP.c +++ b/examples/fp/softfloat_demo/softfloat_demoSP.c @@ -38,16 +38,19 @@ void printF64 (char *msg, float64_t d) { int i, j; conv.v = d.v; // use union to convert between hexadecimal and floating-point views printf("%s: ", msg); // print out nicely - printf("0x%08x_%08x = %g\n", (conv.v >> 32),(conv.v & 0xFFFFFFFF), conv.d); + printf("0x%08lx_%08lx = %g\n", (conv.v >> 32),(conv.v & 0xFFFFFFFF), conv.d); } void printF128 (char *msg, float128_t q) { qp conv; int i, j; + char buf[64]; conv.v[0] = q.v[0]; // use union to convert between hexadecimal and floating-point views conv.v[1] = q.v[1]; // use union to convert between hexadecimal and floating-point views printf("%s: ", msg); // print out nicely - printf("0x%016" PRIx64 "_%016" PRIx64 " = %1.15Qe\n", q.v[1], q.v[0], conv.q); + //printf("0x%016" PRIx64 "_%016" PRIx64 " = %1.15Qe\n", q.v[1], q.v[0], conv.q); + quadmath_snprintf (buf, sizeof buf, "%1.15Qe", conv.q); + printf("0x%016" PRIx64 "_%016" PRIx64 " = %s\n", q.v[1], q.v[0], buf); } void printFlags(void) { diff --git a/setup.csh b/setup.csh index 0508c36d0..82728f57c 100755 --- a/setup.csh +++ b/setup.csh @@ -46,4 +46,7 @@ extend PATH /usr/local/bin/verilator # Change this for your path to Verilator #set path = ($RISCV/imperas-riscv-tests/riscv-ovpsim-plus/bin/Linux64 $path) #setenv LD_LIBRARY_PATH $RISCV/imperas_riscv_tests/riscv-ovpsim-plus/bin/Linux64:$LD_LIBRARY_PATH # remove if no imperas +# Verilator needs a larger stack to simulate CORE-V Wally +limit stacksize unlimited + echo "setup done" diff --git a/src/fpu/fclassify.sv b/src/fpu/fclassify.sv index 1a8f0fc19..bfc7a53dd 100644 --- a/src/fpu/fclassify.sv +++ b/src/fpu/fclassify.sv @@ -37,7 +37,7 @@ module fclassify import cvw::*; #(parameter cvw_t P) ( ); logic PInf, PZero, PNorm, PSubnorm; // is the input a positive infinity/zero/normal/subnormal - logic NInf, NZero, NNorm, NSubnorm; // is the input a negitive infinity/zero/normal/subnormal + logic NInf, NZero, NNorm, NSubnorm; // is the input a negative infinity/zero/normal/subnormal logic XNorm; // is the input normal // determine the sub categories diff --git a/src/fpu/fctrl.sv b/src/fpu/fctrl.sv index a9e187205..3d1a7bedd 100755 --- a/src/fpu/fctrl.sv +++ b/src/fpu/fctrl.sv @@ -215,7 +215,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) ( // rounding modes: // 000 - round to nearest, ties to even // 001 - round twords 0 - round to min magnitude - // 010 - round down - round twords negitive infinity + // 010 - round down - round twords negative infinity // 011 - round up - round twords positive infinity // 100 - round to nearest, ties to max magnitude - round to nearest, ties away from zero // 111 - dynamic - choose FRM_REGW as rounding mode diff --git a/src/fpu/fcvt.sv b/src/fpu/fcvt.sv index 86321ae2f..d396fee95 100644 --- a/src/fpu/fcvt.sv +++ b/src/fpu/fcvt.sv @@ -80,7 +80,7 @@ module fcvt import cvw::*; #(parameter cvw_t P) ( /////////////////////////////////////////////////////////////////////////// // negation /////////////////////////////////////////////////////////////////////////// - // 1) negate the input if the input is a negitive singed integer + // 1) negate the input if the input is a negative singed integer // 2) trim the input to the proper size (kill the 32 most significant zeroes if needed) assign PosInt = Cs ? -Int : Int; @@ -182,7 +182,7 @@ module fcvt import cvw::*; #(parameter cvw_t P) ( assign Ce = {1'b0, OldExp} - (P.NE+1)'(P.BIAS) - {{P.NE-P.LOGCVTLEN+1{1'b0}}, (LeadingZeros)} + {2'b0, NewBias}; // find if the result is dnormal or underflows - // - if Calculated expoenent is 0 or negitive (and the input/result is not exactaly 0) + // - if Calculated expoenent is 0 or negative (and the input/result is not exactaly 0) // - can't underflow an integer to Fp conversion assign ResSubnormUf = (~|Ce | Ce[P.NE])&~XZero&~IntToFp; @@ -190,7 +190,7 @@ module fcvt import cvw::*; #(parameter cvw_t P) ( // shifter /////////////////////////////////////////////////////////////////////////// - // kill the shift if it's negitive + // kill the shift if it's negative // select the amount to shift by // fp -> int: // - shift left by CalcExp - essentially shifting until the unbiased exponent = 0 diff --git a/src/fpu/fma/fmaadd.sv b/src/fpu/fma/fmaadd.sv index 3d7dbbd81..98ff21491 100644 --- a/src/fpu/fma/fmaadd.sv +++ b/src/fpu/fma/fmaadd.sv @@ -42,8 +42,8 @@ module fmaadd import cvw::*; #(parameter cvw_t P) ( output logic [3*P.NF+3:0] Sm // the positive sum ); - logic [3*P.NF+3:0] PreSum, NegPreSum; // possibly negitive sum - logic NegSum; // was the sum negitive + logic [3*P.NF+3:0] PreSum, NegPreSum; // possibly negative sum + logic NegSum; // was the sum negative /////////////////////////////////////////////////////////////////////////////// // Addition @@ -54,8 +54,8 @@ module fmaadd import cvw::*; #(parameter cvw_t P) ( // Kill the product if the product is too small to effect the addition (determined in fma1.sv) assign PmKilled = {2*P.NF+2{~KillProd}}&Pm; // Do the addition - // - calculate a positive and negitive sum in parallel - // if there was a small negitive number killed in the alignment stage one needs to be subtracted from the sum + // - calculate a positive and negative sum in parallel + // if there was a small negative number killed in the alignment stage one needs to be subtracted from the sum // prod - addend where some of the addend is put into the sticky bit then don't add +1 from negation // ie ~(InvA&ASticky&~KillProd)&InvA = (~ASticky|KillProd)&InvA // addend - prod where product is killed (and not exactly zero) then don't add +1 from negation @@ -66,10 +66,10 @@ module fmaadd import cvw::*; #(parameter cvw_t P) ( // Choose the positive sum and accompanying LZA result. assign Sm = NegSum ? NegPreSum : PreSum; - // is the result negitive - // if p - z is the Sum negitive + // is the result negative + // if p - z is the Sum negative // if -p + z is the Sum positive - // if -p - z then the Sum is negitive + // if -p - z then the Sum is negative assign Ss = NegSum^Ps; assign Se = KillProd ? {2'b0, Ze} : Pe; endmodule diff --git a/src/fpu/fma/fmaalign.sv b/src/fpu/fma/fmaalign.sv index f9bddb9e3..efc4a4c5f 100644 --- a/src/fpu/fma/fmaalign.sv +++ b/src/fpu/fma/fmaalign.sv @@ -45,7 +45,7 @@ module fmaalign import cvw::*; #(parameter cvw_t P) ( /////////////////////////////////////////////////////////////////////////////// // determine the shift count for alignment - // - negitive means Z is larger, so shift Z left + // - negative means Z is larger, so shift Z left // - positive means the product is larger, so shift Z right // This could have been done using Pe, but ACnt is on the critical path so we replicate logic for speed assign ACnt = {2'b0, Xe} + {2'b0, Ye} - {2'b0, (P.NE)'(P.BIAS)} + (P.NE+2)'(P.NF+2) - {2'b0, Ze}; diff --git a/src/fpu/postproc/divshiftcalc.sv b/src/fpu/postproc/divshiftcalc.sv index 380f8f5e6..9e5de7173 100644 --- a/src/fpu/postproc/divshiftcalc.sv +++ b/src/fpu/postproc/divshiftcalc.sv @@ -36,7 +36,7 @@ module divshiftcalc import cvw::*; #(parameter cvw_t P) ( ); logic [P.LOGNORMSHIFTSZ-1:0] NormShift; // normalized result shift amount - logic [P.LOGNORMSHIFTSZ-1:0] DivSubnormShiftAmt; // subnormal result shift amount (killed if negitive) + logic [P.LOGNORMSHIFTSZ-1:0] DivSubnormShiftAmt; // subnormal result shift amount (killed if negative) logic [P.NE+1:0] DivSubnormShift; // subnormal result shift amount // is the result subnormal @@ -62,7 +62,7 @@ module divshiftcalc import cvw::*; #(parameter cvw_t P) ( // shift one more if the it's a minimally redundent radix 4 - one entire cycle needed for integer bit assign NormShift = (P.LOGNORMSHIFTSZ)'(P.NF); - // if the shift amount is negitive then don't shift (keep sticky bit) + // if the shift amount is negative then don't shift (keep sticky bit) // need to multiply the early termination shift by LOGR*DIVCOPIES = left shift of log2(LOGR*DIVCOPIES) assign DivSubnormShiftAmt = DivSubnormShiftPos ? DivSubnormShift[P.LOGNORMSHIFTSZ-1:0] : '0; assign DivShiftAmt = DivResSubnorm ? DivSubnormShiftAmt : NormShift; diff --git a/src/fpu/postproc/flags.sv b/src/fpu/postproc/flags.sv index 4a525bb0d..98ed0a34d 100644 --- a/src/fpu/postproc/flags.sv +++ b/src/fpu/postproc/flags.sv @@ -47,7 +47,7 @@ module flags import cvw::*; #(parameter cvw_t P) ( input logic Int64, // convert to 64 bit integer input logic Signed, // convert to a signed integer input logic [P.NE:0] CvtCe, // the calculated expoent - Cvt - input logic [1:0] CvtNegResMsbs, // the negitive integer result's most significant bits + input logic [1:0] CvtNegResMsbs, // the negative integer result's most significant bits // divsqrt input logic DivOp, // conversion opperation? input logic Sqrt, // Sqrt? @@ -122,7 +122,7 @@ module flags import cvw::*; #(parameter cvw_t P) ( // calulate overflow flag: // if the result is greater than or equal to the max exponent(not taking into account sign) - // | and the exponent isn't negitive + // | and the exponent isn't negative // | | if the input isnt infinity or NaN // | | | assign Overflow = ResExpGteMax & ~FullRe[P.NE+1]&~(InfIn|NaNIn|DivByZero); @@ -132,7 +132,7 @@ module flags import cvw::*; #(parameter cvw_t P) ( /////////////////////////////////////////////////////////////////////////////// // calculate underflow flag: detecting tininess after rounding - // the exponent is negitive + // the exponent is negative // | the result is subnormal // | | the result is normal and rounded from a Subnorm // | | | and if given an unbounded exponent the result does not round @@ -170,7 +170,7 @@ module flags import cvw::*; #(parameter cvw_t P) ( // invalid flag for integer result // if the input is NaN or infinity // | if the integer res overflows (out of range) - // | | if the input was negitive but ouputing to a unsigned number + // | | if the input was negative but ouputing to a unsigned number // | | | the res doesn't round to zero // | | | | or the res rounds up out of bounds // | | | | and the res didn't underflow diff --git a/src/fpu/postproc/resultsign.sv b/src/fpu/postproc/resultsign.sv index 9701cb7a6..0dd22c1f4 100644 --- a/src/fpu/postproc/resultsign.sv +++ b/src/fpu/postproc/resultsign.sv @@ -47,7 +47,7 @@ module resultsign( // determine the sign for a result of 0 // The IEEE754-2019 standard specifies: - // - the sign of an exact zero sum (with operands of diffrent signs) should be positive unless rounding toward negitive infinity + // - the sign of an exact zero sum (with operands of diffrent signs) should be positive unless rounding toward negative infinity // - when the exact result of an FMA opperation is non-zero, but is zero due to rounding, use the sign of the exact result // - if x = +0 or -0 then x+x=x and x-(-x)=x // - the sign of a product is the exclisive or or the opperand's signs @@ -63,10 +63,10 @@ module resultsign( assign Zeros = (FmaPs^FmaAs)&~(Round|Guard|Sticky)&~Mult ? Frm[1:0] == 2'b10 : FmaPs; // determine the sign of an infinity result - // is the result negitive - // if p - z is the Sum negitive + // is the result negative + // if p - z is the Sum negative // if -p + z is the Sum positive - // if -p - z then the Sum is negitive + // if -p - z then the Sum is negative assign Infs = ZInf ? FmaAs : FmaPs; // select the result sign diff --git a/src/fpu/postproc/specialcase.sv b/src/fpu/postproc/specialcase.sv index c8442595a..677ccce16 100644 --- a/src/fpu/postproc/specialcase.sv +++ b/src/fpu/postproc/specialcase.sv @@ -266,8 +266,32 @@ module specialcase import cvw::*; #(parameter cvw_t P) ( // integer result selection /////////////////////////////////////////////////////////////////////////////////////// + // Causes undefined behavior for invalid: + + // Invalid cases are different for IEEE 754 vs. RISC-V. For RISC-V, typical results are used + // unsigned: if invalid (e.g., negative fp to unsigned int, result should overflow and + // overflows to the maximum value + // signed: if invalid, result should overflow to maximum negative value + // but is undefined and used for information only + // Note: The IEEE 754 result comes from values in TestFloat for x86_64 + + // IEEE 754 // select the overflow integer res - // - negitive infinity and out of range negitive input + // - negative infinity and out of range negative input + // | int | long | + // signed | -2^31 | -2^63 | + // unsigned | 2^32-1 | 2^64-1 | + // + // - positive infinity and out of range positive input and NaNs + // | int | long | + // signed | -2^31 |-2^63 | + // unsigned | 2^32-1 | 2^64-1 | + // + // other: 32 bit unsigned res should be sign extended as if it were a signed number + + // RISC-V + // select the overflow integer res + // - negative infinity and out of range negative input // | int | long | // signed | -2^31 | -2^63 | // unsigned | 0 | 0 | @@ -278,22 +302,38 @@ module specialcase import cvw::*; #(parameter cvw_t P) ( // unsigned | 2^32-1 | 2^64-1 | // // other: 32 bit unsinged res should be sign extended as if it were a signed number - always_comb - if(Signed) - if(Xs&~NaNIn) // signed negitive - if(Int64) OfIntRes = {1'b1, {P.XLEN-1{1'b0}}}; - else OfIntRes = {{P.XLEN-32{1'b1}}, 1'b1, {31{1'b0}}}; - else // signed positive - if(Int64) OfIntRes = {1'b0, {P.XLEN-1{1'b1}}}; - else OfIntRes = {{P.XLEN-32{1'b0}}, 1'b0, {31{1'b1}}}; - else - if(Xs&~NaNIn) OfIntRes = {P.XLEN{1'b0}}; // unsigned negitive - else OfIntRes = {P.XLEN{1'b1}}; // unsigned positive + + if(P.IEEE754) begin + always_comb + if(Signed) + if(Xs&~NaNIn) // signed negative + if(Int64) OfIntRes = {1'b1, {P.XLEN-1{1'b0}}}; + else OfIntRes = {{P.XLEN-32{1'b1}}, 1'b1, {31{1'b0}}}; + else // signed positive + if(Int64) OfIntRes = {1'b1, {P.XLEN-1{1'b0}}}; + else OfIntRes = {{P.XLEN-32{1'b1}}, 1'b1, {31{1'b0}}}; + else + if(Xs&~NaNIn) OfIntRes = {P.XLEN{1'b1}}; // unsigned negative + else OfIntRes = {P.XLEN{1'b1}}; // unsigned positive + end else begin + always_comb + if(Signed) + if(Xs&~NaNIn) // signed negative + if(Int64) OfIntRes = {1'b1, {P.XLEN-1{1'b0}}}; + else OfIntRes = {{P.XLEN-32{1'b1}}, 1'b1, {31{1'b0}}}; + else // signed positive + if(Int64) OfIntRes = {1'b0, {P.XLEN-1{1'b1}}}; + else OfIntRes = {{P.XLEN-32{1'b0}}, 1'b0, {31{1'b1}}}; + else + if(Xs&~NaNIn) OfIntRes = {P.XLEN{1'b0}}; // unsigned negative + else OfIntRes = {P.XLEN{1'b1}}; // unsigned positive + end + // select the integer output // - if the input is invalid (out of bounds NaN or Inf) then output overflow res // - if the input underflows - // - if rounding and signed opperation and negitive input, output -1 + // - if rounding and signed opperation and negative input, output -1 // - otherwise output a rounded 0 // - otherwise output the normal res (trmined and sign extended if nessisary) always_comb diff --git a/src/ieu/alu.sv b/src/ieu/alu.sv index b13c3a65c..4c296fda2 100644 --- a/src/ieu/alu.sv +++ b/src/ieu/alu.sv @@ -101,11 +101,16 @@ module alu import cvw::*; #(parameter cvw_t P) ( // Zicond block if (P.ZICOND_SUPPORTED) begin: zicond - logic BZero, KillB; + logic BZero; + assign BZero = (B == 0); // check if rs2 = 0 // Create a signal that is 0 when czero.* instruction should clear result // If B = 0 for czero.eqz or if B != 0 for czero.nez - assign KillB = BZero & CZero[0] | ~BZero & CZero[1]; - assign ZeroCondMaskInvB = |CZero ? {P.XLEN{~KillB}} : CondMaskInvB; // extend to full width + always_comb + case (CZero) + 2'b01: ZeroCondMaskInvB = {P.XLEN{~BZero}}; // czero.eqz: kill if B = 0 + 2'b10: ZeroCondMaskInvB = {P.XLEN{BZero}}; // czero.nez: kill if B != 0 + default: ZeroCondMaskInvB = CondMaskInvB; // otherwise normal behavior + endcase end else assign ZeroCondMaskInvB = CondMaskInvB; // no masking if Zicond is not supported endmodule diff --git a/src/ifu/decompress.sv b/src/ifu/decompress.sv index 5c4395a12..50617d3c5 100644 --- a/src/ifu/decompress.sv +++ b/src/ifu/decompress.sv @@ -165,14 +165,14 @@ module decompress import cvw::*; #(parameter cvw_t P) ( InstrD = {7'b0000000, rs2p, rds1p, 3'b110, rds1p, 7'b0110011}; // c.or else // if (instr16[6:5] == 2'b11) InstrD = {7'b0000000, rs2p, rds1p, 3'b111, rds1p, 7'b0110011}; // c.and - else if (instr16[12:10] == 3'b111) begin + else begin // (instr16[12:10] == 3'b111) if (instr16[6:5] == 2'b00 & P.XLEN > 32) InstrD = {7'b0100000, rs2p, rds1p, 3'b000, rds1p, 7'b0111011}; // c.subw else if (instr16[6:5] == 2'b01 & P.XLEN > 32) InstrD = {7'b0000000, rs2p, rds1p, 3'b000, rds1p, 7'b0111011}; // c.addw else if (instr16[6:2] == 5'b11000 & P.ZCB_SUPPORTED) InstrD = {12'b000011111111, rds1p, 3'b111, rds1p, 7'b0010011}; // c.zext.b = andi rd, rs1, 255 - else if (instr16[6:2] == 5'b10101 & P.ZCB_SUPPORTED) + else if (instr16[6:2] == 5'b11001 & P.ZCB_SUPPORTED) InstrD = {12'b011000000100, rds1p, 3'b001, rds1p, 7'b0010011}; // c.sext.b else if (instr16[6:2] == 5'b11010 & P.ZCB_SUPPORTED) InstrD = {7'b0000100, 5'b00000, rds1p, 3'b100, rds1p, 3'b011, P.XLEN > 32, 3'b011}; // c.zext.h @@ -188,9 +188,9 @@ module decompress import cvw::*; #(parameter cvw_t P) ( IllegalCompInstrD = 1; InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap end - end else begin // illegal instruction + /** end else begin // illegal instruction IllegalCompInstrD = 1; - InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap + InstrD = {16'b0, instr16}; // preserve instruction for mtval on trap **/ end 5'b01101: InstrD = {immCJ, 5'b00000, 7'b1101111}; // c.j 5'b01110: InstrD = {immCB[11:5], 5'b00000, rs1p, 3'b000, immCB[4:0], 7'b1100011}; // c.beqz diff --git a/src/privileged/csrs.sv b/src/privileged/csrs.sv index da8ab48bf..e107fc0f7 100644 --- a/src/privileged/csrs.sv +++ b/src/privileged/csrs.sv @@ -160,9 +160,9 @@ module csrs import cvw::*; #(parameter cvw_t P) ( CSRSReadValM = 0; IllegalCSRSAccessM = 1; end - STIMECMPH: if (STCE) + STIMECMPH: if (STCE & P.XLEN == 32) // not supported for RV64 CSRSReadValM = {{(P.XLEN-32){1'b0}}, STIMECMP_REGW[63:32]}; - else begin // not supported for RV64 + else begin CSRSReadValM = 0; IllegalCSRSAccessM = 1; end diff --git a/testbench/testbench-fp.sv b/testbench/testbench-fp.sv index 53001a4bc..ce10c2be2 100644 --- a/testbench/testbench-fp.sv +++ b/testbench/testbench-fp.sv @@ -882,98 +882,88 @@ module testbenchfp; // - the sign of the NaN does not matter for the opperations being tested // - when 2 or more NaNs are inputed the NaN that is propigated doesn't matter if (UnitVal !== `CVTFPUNIT & UnitVal !== `CVTINTUNIT) - case (FmtVal) - 2'b11: NaNGood = (((P.IEEE754==0)&AnsNaN&(Res === {1'b0, {P.Q_NE+1{1'b1}}, {P.Q_NF-1{1'b0}}})) | - (AnsFlg[4]&(Res[P.Q_LEN-2:0] === {{P.Q_NE+1{1'b1}}, {P.Q_NF-1{1'b0}}})) | - (XNaN&(Res[P.Q_LEN-2:0] === {X[P.Q_LEN-2:P.Q_NF],1'b1,X[P.Q_NF-2:0]})) | - (YNaN&(Res[P.Q_LEN-2:0] === {Y[P.Q_LEN-2:P.Q_NF],1'b1,Y[P.Q_NF-2:0]})) | - (ZNaN&(Res[P.Q_LEN-2:0] === {Z[P.Q_LEN-2:P.Q_NF],1'b1,Z[P.Q_NF-2:0]}))); - 2'b01: NaNGood = (((P.IEEE754==0)&AnsNaN&(Res[P.D_LEN-1:0] === {1'b0, {P.D_NE+1{1'b1}}, {P.D_NF-1{1'b0}}})) | - (AnsFlg[4]&(Res[P.D_LEN-2:0] === {{P.D_NE+1{1'b1}}, {P.D_NF-1{1'b0}}})) | - (XNaN&(Res[P.D_LEN-2:0] === {X[P.D_LEN-2:P.D_NF],1'b1,X[P.D_NF-2:0]})) | - (YNaN&(Res[P.D_LEN-2:0] === {Y[P.D_LEN-2:P.D_NF],1'b1,Y[P.D_NF-2:0]})) | - (ZNaN&(Res[P.D_LEN-2:0] === {Z[P.D_LEN-2:P.D_NF],1'b1,Z[P.D_NF-2:0]}))); - 2'b00: NaNGood = (((P.IEEE754==0)&AnsNaN&(Res[P.S_LEN-1:0] === {1'b0, {P.S_NE+1{1'b1}}, {P.S_NF-1{1'b0}}})) | - (AnsFlg[4]&(Res[P.S_LEN-2:0] === {{P.S_NE+1{1'b1}}, {P.S_NF-1{1'b0}}})) | - (XNaN&(Res[P.S_LEN-2:0] === {X[P.S_LEN-2:P.S_NF],1'b1,X[P.S_NF-2:0]})) | - (YNaN&(Res[P.S_LEN-2:0] === {Y[P.S_LEN-2:P.S_NF],1'b1,Y[P.S_NF-2:0]})) | - (ZNaN&(Res[P.S_LEN-2:0] === {Z[P.S_LEN-2:P.S_NF],1'b1,Z[P.S_NF-2:0]}))); - 2'b10: NaNGood = (((P.IEEE754==0)&AnsNaN&(Res[P.H_LEN-1:0] === {1'b0, {P.H_NE+1{1'b1}}, {P.H_NF-1{1'b0}}})) | - (AnsFlg[4]&(Res[P.H_LEN-2:0] === {{P.H_NE+1{1'b1}}, {P.H_NF-1{1'b0}}})) | - (XNaN&(Res[P.H_LEN-2:0] === {X[P.H_LEN-2:P.H_NF],1'b1,X[P.H_NF-2:0]})) | - (YNaN&(Res[P.H_LEN-2:0] === {Y[P.H_LEN-2:P.H_NF],1'b1,Y[P.H_NF-2:0]})) | - (ZNaN&(Res[P.H_LEN-2:0] === {Z[P.H_LEN-2:P.H_NF],1'b1,Z[P.H_NF-2:0]}))); - endcase - else if (UnitVal === `CVTFPUNIT) // if converting from floating point to floating point OpCtrl contains the final FP format - case (OpCtrlVal[1:0]) - 2'b11: NaNGood = (((P.IEEE754==0)&AnsNaN&(Res === {1'b0, {P.Q_NE+1{1'b1}}, {P.Q_NF-1{1'b0}}})) | - (AnsFlg[4]&(Res[P.Q_LEN-2:0] === {{P.Q_NE+1{1'b1}}, {P.Q_NF-1{1'b0}}})) | - (AnsNaN&(Res[P.Q_LEN-2:0] === Ans[P.Q_LEN-2:0])) | - (XNaN&(Res[P.Q_LEN-2:0] === {X[P.Q_LEN-2:P.Q_NF],1'b1,X[P.Q_NF-2:0]})) | - (YNaN&(Res[P.Q_LEN-2:0] === {Y[P.Q_LEN-2:P.Q_NF],1'b1,Y[P.Q_NF-2:0]}))); - 2'b01: NaNGood = (((P.IEEE754==0)&AnsNaN&(Res[P.D_LEN-1:0] === {1'b0, {P.D_NE+1{1'b1}}, {P.D_NF-1{1'b0}}})) | - (AnsFlg[4]&(Res[P.D_LEN-2:0] === {{P.D_NE+1{1'b1}}, {P.D_NF-1{1'b0}}})) | - (AnsNaN&(Res[P.D_LEN-2:0] === Ans[P.D_LEN-2:0])) | - (XNaN&(Res[P.D_LEN-2:0] === {X[P.D_LEN-2:P.D_NF],1'b1,X[P.D_NF-2:0]})) | - (YNaN&(Res[P.D_LEN-2:0] === {Y[P.D_LEN-2:P.D_NF],1'b1,Y[P.D_NF-2:0]}))); - 2'b00: NaNGood = (((P.IEEE754==0)&AnsNaN&(Res[P.S_LEN-1:0] === {1'b0, {P.S_NE+1{1'b1}}, {P.S_NF-1{1'b0}}})) | - (AnsFlg[4]&(Res[P.S_LEN-2:0] === {{P.S_NE+1{1'b1}}, {P.S_NF-1{1'b0}}})) | - (AnsNaN&(Res[P.S_LEN-2:0] === Ans[P.S_LEN-2:0])) | - (XNaN&(Res[P.S_LEN-2:0] === {X[P.S_LEN-2:P.S_NF],1'b1,X[P.S_NF-2:0]})) | - (YNaN&(Res[P.S_LEN-2:0] === {Y[P.S_LEN-2:P.S_NF],1'b1,Y[P.S_NF-2:0]}))); - 2'b10: NaNGood = (((P.IEEE754==0)&AnsNaN&(Res[P.H_LEN-1:0] === {1'b0, {P.H_NE+1{1'b1}}, {P.H_NF-1{1'b0}}})) | - (AnsFlg[4]&(Res[P.H_LEN-2:0] === {{P.H_NE+1{1'b1}}, {P.H_NF-1{1'b0}}})) | - (AnsNaN&(Res[P.H_LEN-2:0] === Ans[P.H_LEN-2:0])) | - (XNaN&(Res[P.H_LEN-2:0] === {X[P.H_LEN-2:P.H_NF],1'b1,X[P.H_NF-2:0]})) | - (YNaN&(Res[P.H_LEN-2:0] === {Y[P.H_LEN-2:P.H_NF],1'b1,Y[P.H_NF-2:0]}))); - endcase - else NaNGood = 1'b0; // integers can't be NaNs + case (FmtVal) + 2'b11: NaNGood = (((P.IEEE754==0)&AnsNaN&(Res === {1'b0, {P.Q_NE+1{1'b1}}, {P.Q_NF-1{1'b0}}})) | + (AnsFlg[4]&(Res[P.Q_LEN-2:0] === {{P.Q_NE+1{1'b1}}, {P.Q_NF-1{1'b0}}})) | + (XNaN&(Res[P.Q_LEN-2:0] === {X[P.Q_LEN-2:P.Q_NF],1'b1,X[P.Q_NF-2:0]})) | + (YNaN&(Res[P.Q_LEN-2:0] === {Y[P.Q_LEN-2:P.Q_NF],1'b1,Y[P.Q_NF-2:0]})) | + (ZNaN&(Res[P.Q_LEN-2:0] === {Z[P.Q_LEN-2:P.Q_NF],1'b1,Z[P.Q_NF-2:0]}))); + 2'b01: NaNGood = (((P.IEEE754==0)&AnsNaN&(Res[P.D_LEN-1:0] === {1'b0, {P.D_NE+1{1'b1}}, {P.D_NF-1{1'b0}}})) | + (AnsFlg[4]&(Res[P.D_LEN-2:0] === {{P.D_NE+1{1'b1}}, {P.D_NF-1{1'b0}}})) | + (XNaN&(Res[P.D_LEN-2:0] === {X[P.D_LEN-2:P.D_NF],1'b1,X[P.D_NF-2:0]})) | + (YNaN&(Res[P.D_LEN-2:0] === {Y[P.D_LEN-2:P.D_NF],1'b1,Y[P.D_NF-2:0]})) | + (ZNaN&(Res[P.D_LEN-2:0] === {Z[P.D_LEN-2:P.D_NF],1'b1,Z[P.D_NF-2:0]}))); + 2'b00: NaNGood = (((P.IEEE754==0)&AnsNaN&(Res[P.S_LEN-1:0] === {1'b0, {P.S_NE+1{1'b1}}, {P.S_NF-1{1'b0}}})) | + (AnsFlg[4]&(Res[P.S_LEN-2:0] === {{P.S_NE+1{1'b1}}, {P.S_NF-1{1'b0}}})) | + (XNaN&(Res[P.S_LEN-2:0] === {X[P.S_LEN-2:P.S_NF],1'b1,X[P.S_NF-2:0]})) | + (YNaN&(Res[P.S_LEN-2:0] === {Y[P.S_LEN-2:P.S_NF],1'b1,Y[P.S_NF-2:0]})) | + (ZNaN&(Res[P.S_LEN-2:0] === {Z[P.S_LEN-2:P.S_NF],1'b1,Z[P.S_NF-2:0]}))); + 2'b10: NaNGood = (((P.IEEE754==0)&AnsNaN&(Res[P.H_LEN-1:0] === {1'b0, {P.H_NE+1{1'b1}}, {P.H_NF-1{1'b0}}})) | + (AnsFlg[4]&(Res[P.H_LEN-2:0] === {{P.H_NE+1{1'b1}}, {P.H_NF-1{1'b0}}})) | + (XNaN&(Res[P.H_LEN-2:0] === {X[P.H_LEN-2:P.H_NF],1'b1,X[P.H_NF-2:0]})) | + (YNaN&(Res[P.H_LEN-2:0] === {Y[P.H_LEN-2:P.H_NF],1'b1,Y[P.H_NF-2:0]})) | + (ZNaN&(Res[P.H_LEN-2:0] === {Z[P.H_LEN-2:P.H_NF],1'b1,Z[P.H_NF-2:0]}))); + endcase + else if (UnitVal === `CVTFPUNIT) // if converting from floating point to floating point OpCtrl contains the final FP format + case (OpCtrlVal[1:0]) + 2'b11: NaNGood = (((P.IEEE754==0)&AnsNaN&(Res === {1'b0, {P.Q_NE+1{1'b1}}, {P.Q_NF-1{1'b0}}})) | + (AnsFlg[4]&(Res[P.Q_LEN-2:0] === {{P.Q_NE+1{1'b1}}, {P.Q_NF-1{1'b0}}})) | + (AnsNaN&(Res[P.Q_LEN-2:0] === Ans[P.Q_LEN-2:0])) | + (XNaN&(Res[P.Q_LEN-2:0] === {X[P.Q_LEN-2:P.Q_NF],1'b1,X[P.Q_NF-2:0]})) | + (YNaN&(Res[P.Q_LEN-2:0] === {Y[P.Q_LEN-2:P.Q_NF],1'b1,Y[P.Q_NF-2:0]}))); + 2'b01: NaNGood = (((P.IEEE754==0)&AnsNaN&(Res[P.D_LEN-1:0] === {1'b0, {P.D_NE+1{1'b1}}, {P.D_NF-1{1'b0}}})) | + (AnsFlg[4]&(Res[P.D_LEN-2:0] === {{P.D_NE+1{1'b1}}, {P.D_NF-1{1'b0}}})) | + (AnsNaN&(Res[P.D_LEN-2:0] === Ans[P.D_LEN-2:0])) | + (XNaN&(Res[P.D_LEN-2:0] === {X[P.D_LEN-2:P.D_NF],1'b1,X[P.D_NF-2:0]})) | + (YNaN&(Res[P.D_LEN-2:0] === {Y[P.D_LEN-2:P.D_NF],1'b1,Y[P.D_NF-2:0]}))); + 2'b00: NaNGood = (((P.IEEE754==0)&AnsNaN&(Res[P.S_LEN-1:0] === {1'b0, {P.S_NE+1{1'b1}}, {P.S_NF-1{1'b0}}})) | + (AnsFlg[4]&(Res[P.S_LEN-2:0] === {{P.S_NE+1{1'b1}}, {P.S_NF-1{1'b0}}})) | + (AnsNaN&(Res[P.S_LEN-2:0] === Ans[P.S_LEN-2:0])) | + (XNaN&(Res[P.S_LEN-2:0] === {X[P.S_LEN-2:P.S_NF],1'b1,X[P.S_NF-2:0]})) | + (YNaN&(Res[P.S_LEN-2:0] === {Y[P.S_LEN-2:P.S_NF],1'b1,Y[P.S_NF-2:0]}))); + 2'b10: NaNGood = (((P.IEEE754==0)&AnsNaN&(Res[P.H_LEN-1:0] === {1'b0, {P.H_NE+1{1'b1}}, {P.H_NF-1{1'b0}}})) | + (AnsFlg[4]&(Res[P.H_LEN-2:0] === {{P.H_NE+1{1'b1}}, {P.H_NF-1{1'b0}}})) | + (AnsNaN&(Res[P.H_LEN-2:0] === Ans[P.H_LEN-2:0])) | + (XNaN&(Res[P.H_LEN-2:0] === {X[P.H_LEN-2:P.H_NF],1'b1,X[P.H_NF-2:0]})) | + (YNaN&(Res[P.H_LEN-2:0] === {Y[P.H_LEN-2:P.H_NF],1'b1,Y[P.H_NF-2:0]}))); + endcase + else NaNGood = 1'b0; // integers can't be NaNs - - /////////////////////////////////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////////////////////////////////// - // ||||||| ||| ||| ||||||| ||||||| ||| ||| - // ||| ||| ||| ||| ||| ||| ||| - // ||| |||||||||| ||||||| ||| |||||| - // ||| ||| ||| ||| ||| ||| ||| - // ||||||| ||| ||| ||||||| ||||||| ||| ||| + // ||||||| ||| ||| ||||||| ||||||| ||| ||| + // ||| ||| ||| ||| ||| ||| ||| + // ||| |||||||||| ||||||| ||| |||||| + // ||| ||| ||| ||| ||| ||| ||| + // ||||||| ||| ||| ||||||| ||||||| ||| ||| - /////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////// - // check if result is correct - // wait till the division result is done or one extra cylcle for early termination (to simulate the EM pipline stage) - assign ResMatch = ((Res === Ans) | NaNGood | (NaNGood === 1'bx)); - assign FlagMatch = ((ResFlg === AnsFlg) | (AnsFlg === 5'bx)); - assign divsqrtop = (OpCtrlVal == `SQRT_OPCTRL) | (OpCtrlVal == `DIV_OPCTRL); - assign FMAop = (OpCtrlVal == `FMAUNIT); - assign DivDone = OldFDivBusyE & ~FDivBusyE; + // check if result is correct + // wait till the division result is done or one extra cylcle for early termination (to simulate the EM pipline stage) + assign ResMatch = ((Res === Ans) | NaNGood | (NaNGood === 1'bx)); + assign FlagMatch = ((ResFlg === AnsFlg) | (AnsFlg === 5'bx)); + assign divsqrtop = (OpCtrlVal == `SQRT_OPCTRL) | (OpCtrlVal == `DIV_OPCTRL); + assign FMAop = (OpCtrlVal == `FMAUNIT); + assign DivDone = OldFDivBusyE & ~FDivBusyE; - // Maybe change OpCtrl but for now just look at TEST for fma test - assign CheckNow = ((DivDone | ~divsqrtop) | (TEST == "add" | TEST == "fma" | TEST == "sub")) & (UnitVal !== `CVTINTUNIT) & (UnitVal !== `CMPUNIT); - if (~(ResMatch & FlagMatch) & CheckNow) begin - errors += 1; - $display("\nError in %s", Tests[TestNum]); - $display("TestNum %d OpCtrl %d", TestNum, OpCtrl[TestNum]); - $display("inputs: %h %h %h\nSrcA: %h\n Res: %h %h\n Expected: %h %h", X, Y, Z, SrcA, Res, ResFlg, Ans, AnsFlg); - $stop; - end - - // TestFloat sets the result to all 1's when there is an invalid result, however in - // http://www.jhauser.us/arithmetic/TestFloat-3/doc/TestFloat-general.html it says - // for an unsigned integer result 0 is also okay - - // TestFloat outputs 800... for both the largest integer values for both positive and negitive numbers but - // the riscv spec specifies 2^31-1 for positive values out of range and NaNs ie 7fff... - else if ( ((UnitVal === `CVTINTUNIT) | (UnitVal === `CMPUNIT)) & ~FlagMatch ) begin - // ResMatch & FlagMatch checks the result again. It is checked within the - // test again to avoid issues related when the values change tests (e.g., f16_eq_rne -> f16_eq_rz) - if (~(ResMatch & FlagMatch)) begin - errors += 1; - $display("\nError in %s", Tests[TestNum]); - $display("TestNum %d OpCtrl %d", TestNum, OpCtrl[TestNum]); - $display("inputs: %h %h %h\nSrcA: %h\n Res: %h %h\n Ans: %h %h", X, Y, Z, SrcA, Res, ResFlg, Ans, AnsFlg); - $stop; - end + // Maybe change OpCtrl but for now just look at TEST for fma test + assign CheckNow = ((DivDone | ~divsqrtop) | (TEST == "add" | TEST == "fma" | TEST == "sub")) & (UnitVal !== `CVTINTUNIT) & (UnitVal !== `CMPUNIT); + if (~(ResMatch & FlagMatch) & CheckNow) begin + errors += 1; + $display("\nError in %s", Tests[TestNum]); + $display("TestNum %d OpCtrl %d", TestNum, OpCtrl[TestNum]); + $display("inputs: %h %h %h\nSrcA: %h\n Res: %h %h\n Expected: %h %h", X, Y, Z, SrcA, Res, ResFlg, Ans, AnsFlg); + $stop; + end else if (((UnitVal === `CVTINTUNIT) | (UnitVal === `CMPUNIT)) & + ~(ResMatch & FlagMatch) & (Ans[0] !== 1'bx)) begin // Check for conversion and comparisons + errors += 1; + $display("\nError in %s", Tests[TestNum]); + $display("TestNum %d OpCtrl %d", TestNum, OpCtrl[TestNum]); + $display("inputs: %h %h %h\nSrcA: %h\n Res: %h %h\n Ans: %h %h", X, Y, Z, SrcA, Res, ResFlg, Ans, AnsFlg); + $stop; + end end if (TestVectors[VectorNum][0] === 1'bx & Tests[TestNum] !== "") begin // if reached the eof diff --git a/tests/coverage/ifu.S b/tests/coverage/ifu.S index cc24b50b0..f387774bf 100644 --- a/tests/coverage/ifu.S +++ b/tests/coverage/ifu.S @@ -40,12 +40,40 @@ main: .hword 0x2002 // c.fldsp fs0, 0 .hword 0xA002 // c.fsdsp fs0, 0 .hword 0x9C41 // line 134 Illegal compressed instruction + + # Zcb coverage tests # could restore assembly language versions when GCC supports Zcb -# c.lbu s1, 0(s0) // exercise c.lbu mv s0, sp + #c.lbu s1, 0(s0) // exercise c.lbu .hword 0x8004 // c.lbu s1, 0(s0) + #c.lh s1, 0(s0) // exercise c.lh + .hword 0x8444 // c.lh s1, 0(s0) + #c.lhu s1, 0(s0) // exercise c.lhu + .hword 0x8404 // c.lhu s1, 0(s0) + #c.sb s1, 0(s0) // exercise c.sb + .hword 0x8804 // c.sb s1, 0(s0) + #c.sh s1, 0(s0) // exercise c.sh + .hword 0x8C04 // c.sh s1, 0(s0) + + .hword 0x8C44 // Illegal compressed instruction with op = 00, Instr[15:10] = 100011, Instr[6] = 1 and 0's everywhere else. Line 119 illegal instruction + .hword 0x9C00 // Illegal compressed instruction with op = 00, Instr[15:10] = 100111, and 0's everywhere else. Line 119 illegal instruction + + li s0, 0xFF + # c.zext.b s0 // exercise c.zext.b + .hword 0x9C61 // c.zext.b s0 + # c.sext.b s0 // exercise c.sext.b + .hword 0x9C65 // c.sext.b s0 + # c.zext.h s0 // exercise c.zext.h + .hword 0x9C69 // c.zext.h s0 + # c.sext.h s0 // exercise c.sext.h + .hword 0x9C6D // c.sext.h s0 + # c.zext.w s0 // exercise c.zext.w + .hword 0x9C71 // c.zext.w s0 + # c.not s0 // exercise c.not + .hword 0x9C75 // c.not s0 + + .hword 0x9C7D // Reserved instruction from line 187 with op = 01, Instr[15:10] = 100111, Instr[6:5] = 11, and 0's everywhere else - //.hword 0x9C01 //# Illegal compressed instruction with op = 01, instr[15:10] = 100111, and 0's everywhere else diff --git a/tests/coverage/tlbmisc.S b/tests/coverage/tlbmisc.S index 5475d7e6e..67971dd06 100644 --- a/tests/coverage/tlbmisc.S +++ b/tests/coverage/tlbmisc.S @@ -40,6 +40,10 @@ main: sw t5, 0(t0) fence.i + # Test not being able to write illegal SATP mode + li t5, 0xA000000000080010 + csrw satp, t5 + # Page table root address at 0x80010000; SV48 li t5, 0x9000000000080010 csrw satp, t5