diff --git a/bin/regression-wally b/bin/regression-wally index c67366ee1..95bf17ae9 100755 --- a/bin/regression-wally +++ b/bin/regression-wally @@ -253,7 +253,8 @@ def run_test_case(config): # print(" run_test_case invoking %s" % cmd) os.system(cmd) if search_log_for_text(config.grepstr, grepfile): - print(f"{bcolors.OKGREEN}%s_%s: Success{bcolors.ENDC}" % (config.variant, config.name)) +# print(f"{bcolors.OKGREEN}%s_%s: Success{bcolors.ENDC}" % (config.variant, config.name)) + print(f"{bcolors.OKGREEN}%s: Success{bcolors.ENDC}" % (config.cmd)) return 0 else: print(f"{bcolors.FAIL}%s_%s: Failures detected in output{bcolors.ENDC}" % (config.variant, config.name)) @@ -280,8 +281,8 @@ buildroot = '--buildroot' in sys.argv if (nightly): nightMode = "--nightly"; -# sims = ["questa", "verilator", "vcs"] - sims = ["verilator"] # *** uncomment to exercise all simulators + sims = [defaultsim] +# sims = ["questa", "verilator", "vcs"] # *** uncomment to exercise all simulators else: nightMode = "" sims = [defaultsim] @@ -314,8 +315,8 @@ else: # run derivative configurations in nightly regression if (nightly): - addTests(derivconfigtests, defaultsim) addTests(tests_buildrootboot, defaultsim) + addTests(derivconfigtests, defaultsim) else: addTests(tests_buildrootshort, defaultsim) diff --git a/src/fpu/fround.sv b/src/fpu/fround.sv index 7c4c9084b..e70e25df8 100644 --- a/src/fpu/fround.sv +++ b/src/fpu/fround.sv @@ -31,11 +31,17 @@ module fround import cvw::*; #(parameter cvw_t P) ( input logic Xs, // input's sign input logic [P.NE-1:0] Xe, // input's exponent input logic [P.NF:0] Xm, // input's fraction - input logic [P.FMTBITS-1:0] Fmt, // the input's precision (11=quad 01=double 00=single 10=half) + input logic XNaN, // X is NaN + input logic XSNaN, // X is Signalling NaN + input logic XZero, // X is Zero + input logic [P.FMTBITS-1:0] Fmt // the input's precision (11=quad 01=double 00=single 10=half) ); + logic [P.NE-2:0] Bias; logic [P.NE-1:0] E; + logic [P.NF:0] Imask, Tmasknonneg, Tmaskneg, Tmask, HotE, HotEP1, Trunc, Rnd; + logic Lnonneg, Lp, Rnonneg, Rp, Tp; ////////////////////////////////////////// // Determine exponent bias according to the format @@ -67,11 +73,13 @@ module fround import cvw::*; #(parameter cvw_t P) ( endcase end +/* + // Unbiased exponent assign E = Xe - Bias; ////////////////////////////////////////// - // Compute LSB, rounding bit and Sticky bit mask (TMask) + // Compute LSB L', rounding bit R' and Sticky bit T' // if (E < 0) // negative exponents round to 0 or 1. // L' = 0 // LSB = 0 // if (E = -1) R' = 1, TMask = 0.1111...111 // if (E = -1) 0.5  X < 1. Round bit is 1 @@ -94,15 +102,71 @@ module fround import cvw::*; #(parameter cvw_t P) ( assign Elt0 = (E < 0); assign Eeqm1 = (E == -1); - assign Rneg = Elt0; - mux2 + // Logic for nonnegative mask and rounding bits + assign Imask = {1'b1, {P.NF{1'b0}}} >>> E; + assign Tmasknonneg = ~(IMask >>> 1'b1); + assign HotE = IMask & !(IMask << 1'b1); + assign HotEP1 = HotE >> 1'b1; + assign Lnonneg = |(Xm & HotE); + assign Rnonneg = |(Xm & HotEP1); + assign Trunc = Xm & Imask; + assign Rnd = Trunc + HotE; - // - // if (E = -1) R' = 1, TMask = 0.1111...111 // if (E = -1) 0.5  X < 1. Round bit is 1 - else R' = 0; TMask = 1.1111...111 // if (E < -1), X < 0.5. Round bit is 0 + // mux and AND-OR logic to select final rounding bits + mux2 #(1) Lmux(Lnonneg, 1'b0, Elt0, Lp); + mux2 #(1) Rmux(Rnonneg, Eeqm1, Elt0, Rp); + assign Tmaskneg = {~Eeqm1, {P.NF{1'b1}}}; // 1.11111 or 0.11111 + mux2 #(P.NF+1) Tmaskmux(Tmasknonneg, Tmaskneg, Elt0, Tmask); + assign T' = |(Xm & Tmask); - mux + /////////////////////////// + // Rounding, flags, special Cases + // Flags = 0 // unless overridden later + // if (X is NaN) + // W = Canonical NaN + // Invalid = (X is signaling NaN) + // else if (E >= Nf or X is +/- 0) + // W = X // is exact; this also handles infinity + // else + // RoundUp = RoundingLogic(Xs, L', R', T', rm) // Table 16.4 + // if (E < 0) // 0 <= X < 1 rounds to 0 or 1 + // if (RoundUp) {Ws, We, Wf} = {Xs, bias, 0} // +/- 1.0 + // else {Ws, We, Wf} = {Xs, 0, 0} // +/- 0 + // else // // X  1 rounds to an integer or overflows to infinity + // if (RoundUp) Rm = RND else Rm = TRUNC // Round up to RND or down to TRUNC + // if (Rm = 2.0) // rounding requires incrementing exponent + // if (Xe = emax) {Ws, We, Wf} = {Xs, 111..11, 0} // overflow to W = Infinity with sign of Xs + // else {Ws, We, Wf} = {Xs, Xe+1, 0} // 1.0 x 2E+1 + // else {Ws, We, Wf} = {Xs, Xe, Rf} // Rounded fraction, retain sign and exponent + // If (FroundNX instruction) Inexact = R' | T' + /////////////////////////// + // Exact logic + assign Exact = (E >= Nf | XZero); // result will be exact; no need to round + + // Rounding logic: determine whether to round up in magnitude + always_comb + case (Rm) // *** make sure this includes dynamic + 3'b000: // RNE + 3'b001: RoundUp = 0; // RZ + 3'b010: // RN + 3'b011: // RU + 3'b101: // RNTA + default: // + endcase + + // output logic + if (XNaN) W = CanonicalNan; // *** + else if (Exact) W = X; + else if (Elt0) + if (RoundUp) W = {Xs, bias, {P.NF}} // *** format conversions + + always_comb + + // Flags + assign Invalid = XSNaN; + assign Inexact = FRoundNX & ~(XNaN | Exact) & (Rp | T'); + */ endmodule diff --git a/testbench/testbench.sv b/testbench/testbench.sv index a92af4a08..37f96f139 100644 --- a/testbench/testbench.sv +++ b/testbench/testbench.sv @@ -350,7 +350,8 @@ module testbench; memfilename = {RISCV_DIR, "/linux-testvectors/ram.bin"}; bootmemfilename = {RISCV_DIR, "/linux-testvectors/bootmem.bin"}; uartoutfilename = {"logs/", TEST, "_uart.out"}; - uartoutfile = $fopen(uartoutfilename, "wb"); + uartoutfile = $fopen(uartoutfilename, "wb"); // delete UART output file + $fclose(uartoutfilename); end else memfilename = {pathname, tests[test], ".elf.memfile"}; if (riscofTest) begin @@ -598,7 +599,9 @@ module testbench; always @(posedge clk) begin if (TEST == "buildroot") begin if (~dut.uncoregen.uncore.uartgen.uart.MEMWb & dut.uncoregen.uncore.uartgen.uart.uartPC.A == 3'b000 & ~dut.uncoregen.uncore.uartgen.uart.uartPC.DLAB) begin + uartoutfile = $fopen(uartoutfilename, "a"); // append characters one at a time so we see a consistent log appearing during the run $fwrite(uartoutfile, "%c", dut.uncoregen.uncore.uartgen.uart.uartPC.Din); + $fclose(uartoutfilename); end end end