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/postproc/specialcase.sv b/src/fpu/postproc/specialcase.sv index c8442595a..b765375d1 100644 --- a/src/fpu/postproc/specialcase.sv +++ b/src/fpu/postproc/specialcase.sv @@ -266,28 +266,34 @@ module specialcase import cvw::*; #(parameter cvw_t P) ( // integer result selection /////////////////////////////////////////////////////////////////////////////////////// + // Causes undefined behavior for invalid: + // 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 + // select the overflow integer res // - negitive infinity and out of range negitive input - // | int | long | - // signed | -2^31 | -2^63 | - // unsigned | 0 | 0 | + // | 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-1 | 2^63-1 | + // signed | -2^31 |-2^63 | // unsigned | 2^32-1 | 2^64-1 | // - // other: 32 bit unsinged res should be sign extended as if it were a signed number + // other: 32 bit unsigned 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}}}; + 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'b0}}; // unsigned negitive + if(Xs&~NaNIn) OfIntRes = {P.XLEN{1'b1}}; // unsigned negitive else OfIntRes = {P.XLEN{1'b1}}; // unsigned positive // select the integer output diff --git a/testbench/testbench-fp.sv b/testbench/testbench-fp.sv index 53001a4bc..e9aeb7ee6 100644 --- a/testbench/testbench-fp.sv +++ b/testbench/testbench-fp.sv @@ -957,23 +957,15 @@ module testbenchfp; $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 + // Check for conversion and comparisons + else if (((UnitVal === `CVTINTUNIT) | (UnitVal === `CMPUNIT)) & + ~(ResMatch & FlagMatch) & (Ans[0] !== 1'bx)) 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 if (TestVectors[VectorNum][0] === 1'bx & Tests[TestNum] !== "") begin // if reached the eof