diff --git a/examples/fp/softfloat_demo/softfloat_demo2.c b/examples/fp/softfloat_demo/softfloat_demo2.c new file mode 100644 index 000000000..d0582724c --- /dev/null +++ b/examples/fp/softfloat_demo/softfloat_demo2.c @@ -0,0 +1,77 @@ +// +// softfloat_div.c +// james.stine@okstate.edu 12 April 2023 +// +// Demonstrate using SoftFloat to compute 754 fp divide, then print results +// (adapted from original C built by David Harris) +// + +#include +#include +#include "softfloat.h" +#include "softfloat_types.h" +typedef union sp { + uint32_t v; + unsigned short x[2]; + float f; +} sp; + +void printF32 (char *msg, float32_t f) { + sp conv; + int i, j; + conv.v = f.v; // use union to convert between hexadecimal and floating-point views + printf("%s: ", msg); // print out nicely + printf("0x%04x_%04x = %1.15g\n", (conv.v >> 16),(conv.v & 0xFFFF), conv.f); +} + +void printFlags(void) { + int NX = softfloat_exceptionFlags % 2; + int UF = (softfloat_exceptionFlags >> 1) % 2; + int OF = (softfloat_exceptionFlags >> 2) % 2; + int DZ = (softfloat_exceptionFlags >> 3) % 2; + int NV = (softfloat_exceptionFlags >> 4) % 2; + printf ("Flags: Inexact %d Underflow %d Overflow %d DivideZero %d Invalid %d\n", + NX, UF, OF, DZ, NV); +} + +void softfloatInit(void) { + // RNE: softfloat_round_near_even + // RZ: softfloat_round_minMag + // RU: softfloat_round_max + // RD: softfloat_round_min + // RM: softfloat_round_near_maxMag + softfloat_roundingMode = softfloat_round_near_even; + softfloat_exceptionFlags = 0; // clear exceptions + softfloat_detectTininess = softfloat_tininess_afterRounding; // RISC-V behavior for tininess +} + +int main() { + + // float32_t is typedef in SoftFloat + float32_t x, y, r1, r2; + sp convx, convy; + + // Choose two random values + convx.f = 1.30308703073; + convy.f = 1.903038030370; + // Convert to SoftFloat format + x.v = (convx.x[1] << 16) + convx.x[0]; + y.v = (convy.x[1] << 16) + convy.x[0]; + + printf("Example using SoftFloat\n"); + + softfloatInit(); + r1 = f32_div(x, y); + printf("-------\n"); + printF32("X", x); + printF32("Y", y); + printF32("result = X/Y", r1); + printFlags(); + + r2 = f32_sqrt(x); + printf("-------\n"); + printF32("X", x); + printF32("result = sqrt(X)", r2); + printFlags(); + +} diff --git a/sim/imperas.ic b/sim/imperas.ic index 2c1225760..d561b22f2 100644 --- a/sim/imperas.ic +++ b/sim/imperas.ic @@ -30,8 +30,8 @@ --override cpu/ignore_non_leaf_DAU=1 --override cpu/wfi_is_nop=T --override cpu/misa_Extensions_mask=0x0 -#--override cpu/updatePTEA=T -#--override cpu/updatePTED=T +--override cpu/updatePTEA=T +--override cpu/updatePTED=T --override cpu/Sstc=T # THIS NEEDS FIXING to 16 diff --git a/sim/testfloat.do b/sim/testfloat.do index c6573a07e..b2fb2e1dc 100644 --- a/sim/testfloat.do +++ b/sim/testfloat.do @@ -29,19 +29,17 @@ vlog +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-fp.sv vsim -voptargs=+acc work.testbenchfp -G TEST=$2 -#-- display input and output signals as hexidecimal values -if {$3 == "wave"} { +# Determine if nowave argument is provided +# this removes any output to a wlf or wave window to reduce +# disk space. +if {($argc > 2) && ($3 eq "nowave")} { + puts "No wave output is selected" +} else { puts "wave output is selected" view wave add log -recursive /* - do wave-fpu.do -} elseif {$3 == "nowave"} { - puts "No wave output is selected" -} else { - puts "Error with third argument" - exit 2 -} - + do wave-fpu.do +} #-- Run the Simulation run -all diff --git a/src/fpu/fdivsqrt/fdivsqrtfsm.sv b/src/fpu/fdivsqrt/fdivsqrtfsm.sv index da13813fe..4cfede605 100644 --- a/src/fpu/fdivsqrt/fdivsqrtfsm.sv +++ b/src/fpu/fdivsqrt/fdivsqrtfsm.sv @@ -110,7 +110,7 @@ module fdivsqrtfsm( always_ff @(posedge clk) begin if (reset | FlushE) begin state <= #1 IDLE; - end else if (IFDivStartE) begin + end else if ((state == IDLE) & IFDivStartE) begin step <= cycles; if (SpecialCaseE) state <= #1 DONE; else state <= #1 BUSY; diff --git a/src/fpu/fdivsqrt/fdivsqrtiter.sv b/src/fpu/fdivsqrt/fdivsqrtiter.sv index d1cf24354..7de120eda 100644 --- a/src/fpu/fdivsqrt/fdivsqrtiter.sv +++ b/src/fpu/fdivsqrt/fdivsqrtiter.sv @@ -79,8 +79,8 @@ module fdivsqrtiter( assign initUM = {~SqrtE, {(`DIVb){1'b0}}}; mux2 #(`DIVb+1) Umux(UNext[`DIVCOPIES-1], initU, IFDivStartE, UMux); mux2 #(`DIVb+1) UMmux(UMNext[`DIVCOPIES-1], initUM, IFDivStartE, UMMux); - flopen #(`DIVb+1) UReg(clk, IFDivStartE|FDivBusyE, UMux, U[0]); - flopen #(`DIVb+1) UMReg(clk, IFDivStartE|FDivBusyE, UMMux, UM[0]); + flopen #(`DIVb+1) UReg(clk, FDivBusyE, UMux, U[0]); + flopen #(`DIVb+1) UMReg(clk, FDivBusyE, UMMux, UM[0]); // C register/initialization mux // Initialize C to -1 for sqrt and -R for division @@ -93,7 +93,7 @@ module fdivsqrtiter( assign initC = {initCUpper, {`DIVb{1'b0}}}; mux2 #(`DIVb+2) cmux(C[`DIVCOPIES], initC, IFDivStartE, NextC); - flopen #(`DIVb+2) creg(clk, IFDivStartE|FDivBusyE, NextC, C[0]); + flopen #(`DIVb+2) creg(clk, FDivBusyE, NextC, C[0]); // Divisior register flopen #(`DIVb) dreg(clk, IFDivStartE, DPreproc, D); diff --git a/testbench/tests.vh b/testbench/tests.vh index f47c89793..55cf464fa 100644 --- a/testbench/tests.vh +++ b/testbench/tests.vh @@ -1907,8 +1907,10 @@ string arch64zbs[] = '{ "rv64i_m/privilege/src/WALLY-mie-01.S", "rv64i_m/privilege/src/WALLY-minfo-01.S", "rv64i_m/privilege/src/WALLY-misa-01.S", - "rv64i_m/privilege/src/WALLY-mmu-sv39-01.S", - "rv64i_m/privilege/src/WALLY-mmu-sv48-01.S", +// "rv64i_m/privilege/src/WALLY-mmu-sv39-01.S", // run this if SVADU_SUPPORTED = 0 +// "rv64i_m/privilege/src/WALLY-mmu-sv48-01.S", // run this if SVADU_SUPPORTED = 0 + "rv64i_m/privilege/src/WALLY-mmu-sv39-svadu-01.S", // run this if SVADU_SUPPORTED = 1 + "rv64i_m/privilege/src/WALLY-mmu-sv48-svadu-01.S", // run this if SVADU_SUPPORTED = 1 "rv64i_m/privilege/src/WALLY-mtvec-01.S", "rv64i_m/privilege/src/WALLY-pma-01.S", "rv64i_m/privilege/src/WALLY-pmp-01.S", @@ -1996,7 +1998,8 @@ string arch64zbs[] = '{ "rv32i_m/privilege/src/WALLY-mie-01.S", "rv32i_m/privilege/src/WALLY-minfo-01.S", "rv32i_m/privilege/src/WALLY-misa-01.S", - "rv32i_m/privilege/src/WALLY-mmu-sv32-01.S", +// "rv32i_m/privilege/src/WALLY-mmu-sv32-01.S", + "rv32i_m/privilege/src/WALLY-mmu-sv32-svadu-01.S", "rv32i_m/privilege/src/WALLY-mtvec-01.S", "rv32i_m/privilege/src/WALLY-pma-01.S", "rv32i_m/privilege/src/WALLY-pmp-01.S",