From 9343c2296ee2961928413c538231e68426c2854e Mon Sep 17 00:00:00 2001 From: Kevin Kim Date: Sat, 8 Jul 2023 20:42:16 -0700 Subject: [PATCH] testbench now compiles with basic infrastructure to do int64rem test on drsu --- testbench/testbench-fp.sv | 483 ++++++++++-------- testbench/tests-fp.vh | 8 + .../extract_arch_vectors.py | 24 +- .../extract_arch_vectors_v2.py | 294 +++++++++++ 4 files changed, 572 insertions(+), 237 deletions(-) create mode 100755 tests/fp/combined_IF_vectors/extract_arch_vectors_v2.py diff --git a/testbench/testbench-fp.sv b/testbench/testbench-fp.sv index a0993b6da..dd0774b3b 100644 --- a/testbench/testbench-fp.sv +++ b/testbench/testbench-fp.sv @@ -56,7 +56,8 @@ module testbenchfp; logic WriteIntVal; // value of the current WriteInt logic [P.FLEN-1:0] X, Y, Z; // inputs read from TestFloat logic [P.FLEN-1:0] XPostBox; // inputs read from TestFloat - logic [P.XLEN-1:0] SrcA; // integer input + logic [P.XLEN-1:0] SrcA, SrcB; // integer input + logic W64; // is W64 instruction logic [P.FLEN-1:0] Ans; // correct answer from TestFloat logic [P.FLEN-1:0] Res; // result from other units logic [4:0] AnsFlg; // correct flags read from testfloat @@ -84,6 +85,7 @@ module testbenchfp; logic [P.DIVb:0] Quot; logic CvtResSubnormUfE; logic DivStart; + logic IDivStart; logic FDivBusyE; logic OldFDivBusyE; logic reset = 1'b0; @@ -118,11 +120,13 @@ module testbenchfp; logic [P.NE+1:0] QeM; logic [P.DIVb:0] QmM; logic [P.XLEN-1:0] FIntDivResultM; + logic IntDivE; logic ResMatch; // Check if result match logic FlagMatch; // Check if IEEE flags match logic CheckNow; // Final check logic FMAop; // Is this a FMA operation? + flop #(3) funct3reg(.clk, .d(Funct3E), .q(Funct3M)); /////////////////////////////////////////////////////////////////////////////////////////////// // ||||||||| |||||||| ||||||| ||||||||| ||||||| |||||||| ||| @@ -149,7 +153,7 @@ module testbenchfp; $display("This simulation for TEST is %s", TEST); $display("This simulation for TEST is of the operand size of %s", TEST_SIZE); if (P.Q_SUPPORTED & (TEST_SIZE == "QP" | TEST_SIZE == "all")) begin // if Quad percision is supported - if (TEST === "cvtint" | TEST === "all") begin // if testing integer conversion + if (TEST === "cvtint" | TEST === "all") begin // if testing integer conversion // add the 128-bit cvtint tests to the to-be-tested list Tests = {Tests, f128rv32cvtint}; // add the op-codes for these tests to the op-code list @@ -167,13 +171,13 @@ module testbenchfp; WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; // add what unit is used and the fmt to their lists (one for each test) for(int i = 0; i<20; i++) begin - Unit = {Unit, `CVTINTUNIT}; - Fmt = {Fmt, 2'b11}; + Unit = {Unit, `CVTINTUNIT}; + Fmt = {Fmt, 2'b11}; end end - end - // if the floating-point conversions are being tested - if (TEST === "cvtfp" | TEST === "all") begin + end + // if the floating-point conversions are being tested + if (TEST === "cvtfp" | TEST === "all") begin if (P.D_SUPPORTED) begin // if double precision is supported // add the 128 <-> 64 bit conversions to the to-be-tested list Tests = {Tests, f128f64cvt}; @@ -182,12 +186,12 @@ module testbenchfp; WriteInt = {WriteInt, 1'b0, 1'b0}; // add the unit being tested and fmt (input format) for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b11}; + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b11}; end for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b01}; + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b01}; end end if (P.F_SUPPORTED) begin // if single precision is supported @@ -198,12 +202,12 @@ module testbenchfp; WriteInt = {WriteInt, 1'b0, 1'b0}; // add the unit being tested and fmt (input format) for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b11}; + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b11}; end for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b00}; + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b00}; end end if (P.ZFH_SUPPORTED) begin // if half precision is supported @@ -214,16 +218,16 @@ module testbenchfp; WriteInt = {WriteInt, 1'b0, 1'b0}; // add the unit being tested and fmt (input format) for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b11}; + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b11}; end for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b10}; + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b10}; end end - end - if (TEST === "cmp" | TEST === "all") begin// if comparisons are being tested + end + if (TEST === "cmp" | TEST === "all") begin// if comparisons are being tested // add the compare tests/op-ctrls/unit/fmt Tests = {Tests, f128cmp}; OpCtrl = {OpCtrl, `EQ_OPCTRL, `LE_OPCTRL, `LT_OPCTRL}; @@ -232,8 +236,8 @@ module testbenchfp; Unit = {Unit, `CMPUNIT}; Fmt = {Fmt, 2'b11}; end - end - if (TEST === "add" | TEST === "all") begin // if addition is being tested + end + if (TEST === "add" | TEST === "all") begin // if addition is being tested // add the addition tests/op-ctrls/unit/fmt Tests = {Tests, f128add}; OpCtrl = {OpCtrl, `ADD_OPCTRL}; @@ -242,8 +246,8 @@ module testbenchfp; Unit = {Unit, `FMAUNIT}; Fmt = {Fmt, 2'b11}; end - end - if (TEST === "sub" | TEST === "all") begin // if subtraction is being tested + end + if (TEST === "sub" | TEST === "all") begin // if subtraction is being tested // add the subtraction tests/op-ctrls/unit/fmt Tests = {Tests, f128sub}; OpCtrl = {OpCtrl, `SUB_OPCTRL}; @@ -252,8 +256,8 @@ module testbenchfp; Unit = {Unit, `FMAUNIT}; Fmt = {Fmt, 2'b11}; end - end - if (TEST === "mul" | TEST === "all") begin // if multiplication is being tested + end + if (TEST === "mul" | TEST === "all") begin // if multiplication is being tested // add the multiply tests/op-ctrls/unit/fmt Tests = {Tests, f128mul}; OpCtrl = {OpCtrl, `MUL_OPCTRL}; @@ -262,8 +266,8 @@ module testbenchfp; Unit = {Unit, `FMAUNIT}; Fmt = {Fmt, 2'b11}; end - end - if (TEST === "div" | TEST === "all") begin // if division is being tested + end + if (TEST === "div" | TEST === "all") begin // if division is being tested // add the divide tests/op-ctrls/unit/fmt Tests = {Tests, f128div}; OpCtrl = {OpCtrl, `DIV_OPCTRL}; @@ -272,8 +276,8 @@ module testbenchfp; Unit = {Unit, `DIVUNIT}; Fmt = {Fmt, 2'b11}; end - end - if (TEST === "sqrt" | TEST === "all") begin // if square-root is being tested + end + if (TEST === "sqrt" | TEST === "all") begin // if square-root is being tested // add the square-root tests/op-ctrls/unit/fmt Tests = {Tests, f128sqrt}; OpCtrl = {OpCtrl, `SQRT_OPCTRL}; @@ -282,8 +286,8 @@ module testbenchfp; Unit = {Unit, `DIVUNIT}; Fmt = {Fmt, 2'b11}; end - end - if (TEST === "fma" | TEST === "all") begin // if fused-mutliply-add is being tested + end + if (TEST === "fma" | TEST === "all") begin // if fused-mutliply-add is being tested Tests = {Tests, f128fma}; OpCtrl = {OpCtrl, `FMA_OPCTRL}; WriteInt = {WriteInt, 1'b0}; @@ -291,7 +295,7 @@ module testbenchfp; Unit = {Unit, `FMAUNIT}; Fmt = {Fmt, 2'b11}; end - end + end if (TEST === "divremsqrt") begin // if unified div sqrt is being tested Tests = {Tests, f128div, f128sqrt}; OpCtrl = {OpCtrl, `DIV_OPCTRL, `SQRT_OPCTRL}; @@ -303,7 +307,7 @@ module testbenchfp; end end if (P.D_SUPPORTED & (TEST_SIZE == "DP" | TEST_SIZE == "all")) begin // if double precision is supported - if (TEST === "cvtint" | TEST === "all") begin // if integer conversion is being tested + if (TEST === "cvtint" | TEST === "all") begin // if integer conversion is being tested Tests = {Tests, f64rv32cvtint}; // add the op-codes for these tests to the op-code list OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL}; @@ -320,12 +324,12 @@ module testbenchfp; WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; // add what unit is used and the fmt to their lists (one for each test) for(int i = 0; i<20; i++) begin - Unit = {Unit, `CVTINTUNIT}; - Fmt = {Fmt, 2'b01}; + Unit = {Unit, `CVTINTUNIT}; + Fmt = {Fmt, 2'b01}; end end - end - if (TEST === "cvtfp" | TEST === "all") begin // if floating point conversions are being tested + end + if (TEST === "cvtfp" | TEST === "all") begin // if floating point conversions are being tested if (P.F_SUPPORTED) begin // if single precision is supported // add the 64 <-> 32 bit conversions to the to-be-tested list Tests = {Tests, f64f32cvt}; @@ -334,12 +338,12 @@ module testbenchfp; WriteInt = {WriteInt, 1'b0, 1'b0}; // add the unit being tested and fmt (input format) for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b01}; + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b01}; end for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b00}; + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b00}; end end if (P.ZFH_SUPPORTED) begin // if half precision is supported @@ -350,16 +354,16 @@ module testbenchfp; WriteInt = {WriteInt, 1'b0, 1'b0}; // add the unit being tested and fmt (input format) for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b01}; + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b01}; end for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b10}; + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b10}; end end - end - if (TEST === "cmp" | TEST === "all") begin // if comparisions are being tested + end + if (TEST === "cmp" | TEST === "all") begin // if comparisions are being tested // add the correct tests/op-ctrls/unit/fmt to their lists Tests = {Tests, f64cmp}; OpCtrl = {OpCtrl, `EQ_OPCTRL, `LE_OPCTRL, `LT_OPCTRL}; @@ -368,8 +372,8 @@ module testbenchfp; Unit = {Unit, `CMPUNIT}; Fmt = {Fmt, 2'b01}; end - end - if (TEST === "add" | TEST === "all") begin // if addition is being tested + end + if (TEST === "add" | TEST === "all") begin // if addition is being tested // add the correct tests/op-ctrls/unit/fmt to their lists Tests = {Tests, f64add}; OpCtrl = {OpCtrl, `ADD_OPCTRL}; @@ -378,8 +382,8 @@ module testbenchfp; Unit = {Unit, `FMAUNIT}; Fmt = {Fmt, 2'b01}; end - end - if (TEST === "sub" | TEST === "all") begin // if subtration is being tested + end + if (TEST === "sub" | TEST === "all") begin // if subtration is being tested // add the correct tests/op-ctrls/unit/fmt to their lists Tests = {Tests, f64sub}; OpCtrl = {OpCtrl, `SUB_OPCTRL}; @@ -388,8 +392,8 @@ module testbenchfp; Unit = {Unit, `FMAUNIT}; Fmt = {Fmt, 2'b01}; end - end - if (TEST === "mul" | TEST === "all") begin // if multiplication is being tested + end + if (TEST === "mul" | TEST === "all") begin // if multiplication is being tested // add the correct tests/op-ctrls/unit/fmt to their lists Tests = {Tests, f64mul}; OpCtrl = {OpCtrl, `MUL_OPCTRL}; @@ -398,8 +402,8 @@ module testbenchfp; Unit = {Unit, `FMAUNIT}; Fmt = {Fmt, 2'b01}; end - end - if (TEST === "div" | TEST === "all") begin // if division is being tested + end + if (TEST === "div" | TEST === "all") begin // if division is being tested // add the correct tests/op-ctrls/unit/fmt to their lists Tests = {Tests, f64div}; OpCtrl = {OpCtrl, `DIV_OPCTRL}; @@ -408,8 +412,8 @@ module testbenchfp; Unit = {Unit, `DIVUNIT}; Fmt = {Fmt, 2'b01}; end - end - if (TEST === "sqrt" | TEST === "all") begin // if square-root is being tessted + end + if (TEST === "sqrt" | TEST === "all") begin // if square-root is being tessted // add the correct tests/op-ctrls/unit/fmt to their lists Tests = {Tests, f64sqrt}; OpCtrl = {OpCtrl, `SQRT_OPCTRL}; @@ -418,8 +422,8 @@ module testbenchfp; Unit = {Unit, `DIVUNIT}; Fmt = {Fmt, 2'b01}; end - end - if (TEST === "fma" | TEST === "all") begin // if the fused multiply add is being tested + end + if (TEST === "fma" | TEST === "all") begin // if the fused multiply add is being tested Tests = {Tests, f64fma}; OpCtrl = {OpCtrl, `FMA_OPCTRL}; WriteInt = {WriteInt, 1'b0}; @@ -427,7 +431,7 @@ module testbenchfp; Unit = {Unit, `FMAUNIT}; Fmt = {Fmt, 2'b01}; end - end + end if (TEST === "divremsqrt") begin // if unified div sqrt is being tested Tests = {Tests, f64div, f64sqrt}; OpCtrl = {OpCtrl, `DIV_OPCTRL, `SQRT_OPCTRL}; @@ -439,7 +443,7 @@ module testbenchfp; end end if (P.F_SUPPORTED & (TEST_SIZE == "SP" | TEST_SIZE == "all")) begin // if single precision being supported - if (TEST === "cvtint"| TEST === "all") begin // if integer conversion is being tested + if (TEST === "cvtint"| TEST === "all") begin // if integer conversion is being tested Tests = {Tests, f32rv32cvtint}; // add the op-codes for these tests to the op-code list OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL}; @@ -456,12 +460,12 @@ module testbenchfp; WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; // add what unit is used and the fmt to their lists (one for each test) for(int i = 0; i<20; i++) begin - Unit = {Unit, `CVTINTUNIT}; - Fmt = {Fmt, 2'b00}; + Unit = {Unit, `CVTINTUNIT}; + Fmt = {Fmt, 2'b00}; end end - end - if (TEST === "cvtfp" | TEST === "all") begin // if floating point conversion is being tested + end + if (TEST === "cvtfp" | TEST === "all") begin // if floating point conversion is being tested if (P.ZFH_SUPPORTED) begin // add the 32 <-> 16 bit conversions to the to-be-tested list Tests = {Tests, f32f16cvt}; @@ -470,16 +474,16 @@ module testbenchfp; WriteInt = {WriteInt, 1'b0, 1'b0}; // add the unit being tested and fmt (input format) for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b00}; + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b00}; end for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b10}; + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b10}; end end - end - if (TEST === "cmp" | TEST === "all") begin // if comparision is being tested + end + if (TEST === "cmp" | TEST === "all") begin // if comparision is being tested // add the correct tests/op-ctrls/unit/fmt to their lists Tests = {Tests, f32cmp}; OpCtrl = {OpCtrl, `EQ_OPCTRL, `LE_OPCTRL, `LT_OPCTRL}; @@ -488,8 +492,8 @@ module testbenchfp; Unit = {Unit, `CMPUNIT}; Fmt = {Fmt, 2'b00}; end - end - if (TEST === "add" | TEST === "all") begin // if addition is being tested + end + if (TEST === "add" | TEST === "all") begin // if addition is being tested // add the correct tests/op-ctrls/unit/fmt to their lists Tests = {Tests, f32add}; OpCtrl = {OpCtrl, `ADD_OPCTRL}; @@ -498,8 +502,8 @@ module testbenchfp; Unit = {Unit, `FMAUNIT}; Fmt = {Fmt, 2'b00}; end - end - if (TEST === "sub" | TEST === "all") begin // if subtration is being tested + end + if (TEST === "sub" | TEST === "all") begin // if subtration is being tested // add the correct tests/op-ctrls/unit/fmt to their lists Tests = {Tests, f32sub}; OpCtrl = {OpCtrl, `SUB_OPCTRL}; @@ -508,8 +512,8 @@ module testbenchfp; Unit = {Unit, `FMAUNIT}; Fmt = {Fmt, 2'b00}; end - end - if (TEST === "mul" | TEST === "all") begin // if multiply is being tested + end + if (TEST === "mul" | TEST === "all") begin // if multiply is being tested // add the correct tests/op-ctrls/unit/fmt to their lists Tests = {Tests, f32mul}; OpCtrl = {OpCtrl, `MUL_OPCTRL}; @@ -518,8 +522,8 @@ module testbenchfp; Unit = {Unit, `FMAUNIT}; Fmt = {Fmt, 2'b00}; end - end - if (TEST === "div" | TEST === "all") begin // if division is being tested + end + if (TEST === "div" | TEST === "all") begin // if division is being tested // add the correct tests/op-ctrls/unit/fmt to their lists Tests = {Tests, f32div}; OpCtrl = {OpCtrl, `DIV_OPCTRL}; @@ -528,8 +532,8 @@ module testbenchfp; Unit = {Unit, `DIVUNIT}; Fmt = {Fmt, 2'b00}; end - end - if (TEST === "sqrt" | TEST === "all") begin // if sqrt is being tested + end + if (TEST === "sqrt" | TEST === "all") begin // if sqrt is being tested // add the correct tests/op-ctrls/unit/fmt to their lists Tests = {Tests, f32sqrt}; OpCtrl = {OpCtrl, `SQRT_OPCTRL}; @@ -538,8 +542,8 @@ module testbenchfp; Unit = {Unit, `DIVUNIT}; Fmt = {Fmt, 2'b00}; end - end - if (TEST === "fma" | TEST === "all") begin // if fma is being tested + end + if (TEST === "fma" | TEST === "all") begin // if fma is being tested Tests = {Tests, f32fma}; OpCtrl = {OpCtrl, `FMA_OPCTRL}; WriteInt = {WriteInt, 1'b0}; @@ -547,7 +551,7 @@ module testbenchfp; Unit = {Unit, `FMAUNIT}; Fmt = {Fmt, 2'b00}; end - end + end if (TEST === "divremsqrt") begin // if unified div sqrt is being tested Tests = {Tests, f32div, f32sqrt}; OpCtrl = {OpCtrl, `DIV_OPCTRL, `SQRT_OPCTRL}; @@ -559,7 +563,7 @@ module testbenchfp; end end if (P.ZFH_SUPPORTED & (TEST_SIZE == "HP" | TEST_SIZE == "all")) begin // if half precision supported - if (TEST === "cvtint" | TEST === "all") begin // if in conversions are being tested + if (TEST === "cvtint" | TEST === "all") begin // if in conversions are being tested Tests = {Tests, f16rv32cvtint}; // add the op-codes for these tests to the op-code list OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL}; @@ -576,12 +580,12 @@ module testbenchfp; WriteInt = {WriteInt, 1'b0, 1'b0, 1'b1, 1'b1}; // add what unit is used and the fmt to their lists (one for each test) for(int i = 0; i<20; i++) begin - Unit = {Unit, `CVTINTUNIT}; - Fmt = {Fmt, 2'b10}; + Unit = {Unit, `CVTINTUNIT}; + Fmt = {Fmt, 2'b10}; end end - end - if (TEST === "cmp" | TEST === "all") begin // if comparisions are being tested + end + if (TEST === "cmp" | TEST === "all") begin // if comparisions are being tested // add the correct tests/op-ctrls/unit/fmt to their lists Tests = {Tests, f16cmp}; OpCtrl = {OpCtrl, `EQ_OPCTRL, `LE_OPCTRL, `LT_OPCTRL}; @@ -590,8 +594,8 @@ module testbenchfp; Unit = {Unit, `CMPUNIT}; Fmt = {Fmt, 2'b10}; end - end - if (TEST === "add" | TEST === "all") begin // if addition is being tested + end + if (TEST === "add" | TEST === "all") begin // if addition is being tested // add the correct tests/op-ctrls/unit/fmt to their lists Tests = {Tests, f16add}; OpCtrl = {OpCtrl, `ADD_OPCTRL}; @@ -600,8 +604,8 @@ module testbenchfp; Unit = {Unit, `FMAUNIT}; Fmt = {Fmt, 2'b10}; end - end - if (TEST === "sub" | TEST === "all") begin // if subtraction is being tested + end + if (TEST === "sub" | TEST === "all") begin // if subtraction is being tested // add the correct tests/op-ctrls/unit/fmt to their lists Tests = {Tests, f16sub}; OpCtrl = {OpCtrl, `SUB_OPCTRL}; @@ -610,8 +614,8 @@ module testbenchfp; Unit = {Unit, `FMAUNIT}; Fmt = {Fmt, 2'b10}; end - end - if (TEST === "mul" | TEST === "all") begin // if multiplication is being tested + end + if (TEST === "mul" | TEST === "all") begin // if multiplication is being tested // add the correct tests/op-ctrls/unit/fmt to their lists Tests = {Tests, f16mul}; OpCtrl = {OpCtrl, `MUL_OPCTRL}; @@ -620,8 +624,8 @@ module testbenchfp; Unit = {Unit, `FMAUNIT}; Fmt = {Fmt, 2'b10}; end - end - if (TEST === "div" | TEST === "all") begin // if division is being tested + end + if (TEST === "div" | TEST === "all") begin // if division is being tested // add the correct tests/op-ctrls/unit/fmt to their lists Tests = {Tests, f16div}; OpCtrl = {OpCtrl, `DIV_OPCTRL}; @@ -630,8 +634,8 @@ module testbenchfp; Unit = {Unit, `DIVUNIT}; Fmt = {Fmt, 2'b10}; end - end - if (TEST === "sqrt" | TEST === "all") begin // if sqrt is being tested + end + if (TEST === "sqrt" | TEST === "all") begin // if sqrt is being tested // add the correct tests/op-ctrls/unit/fmt to their lists Tests = {Tests, f16sqrt}; OpCtrl = {OpCtrl, `SQRT_OPCTRL}; @@ -640,8 +644,8 @@ module testbenchfp; Unit = {Unit, `DIVUNIT}; Fmt = {Fmt, 2'b10}; end - end - if (TEST === "fma" | TEST === "all") begin // if fma is being tested + end + if (TEST === "fma" | TEST === "all") begin // if fma is being tested Tests = {Tests, f16fma}; OpCtrl = {OpCtrl, `FMA_OPCTRL}; WriteInt = {WriteInt, 1'b0}; @@ -649,7 +653,7 @@ module testbenchfp; Unit = {Unit, `FMAUNIT}; Fmt = {Fmt, 2'b10}; end - end + end if (TEST === "divremsqrt") begin // if unified div sqrt is being tested Tests = {Tests, f16div, f16sqrt}; OpCtrl = {OpCtrl, `DIV_OPCTRL, `SQRT_OPCTRL}; @@ -660,12 +664,12 @@ module testbenchfp; end end if (TEST === "divremsqrttest") begin // if unified div sqrt is being tested - Tests = {Tests, f128sqrt}; + Tests = {Tests, f64sqrt}; OpCtrl = {OpCtrl, `SQRT_OPCTRL}; WriteInt = {WriteInt, 1'b0}; for(int i = 0; i<5; i++) begin Unit = {Unit, `DIVUNIT}; - Fmt = {Fmt, 2'b11}; + Fmt = {Fmt, 2'b01}; end end if (TEST === "customdiv") begin // if unified div sqrt is being tested @@ -682,11 +686,19 @@ module testbenchfp; Unit = {Unit, `DIVUNIT}; Fmt = {Fmt, 2'b10}; end + if (TEST === "intdiv") begin // if unified div sqrt is being tested + Tests = {Tests, intdiv}; + OpCtrl = {OpCtrl, `INTREM_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + Unit = {Unit, `INTDIVUNIT}; + Fmt = {Fmt, 2'b10}; end + end + // check if nothing is being tested if (Tests.size() == 0) begin - $display("TEST %s not supported in this configuration", TEST); - $stop; + $display("TEST %s not supported in this configuration", TEST); + $stop; end end @@ -732,10 +744,10 @@ module testbenchfp; // extract the inputs (X, Y, Z, SrcA) and the output (Ans, AnsFlg) from the current test vector readvectors #(P) readvectors (.clk, .Fmt(FmtVal), .ModFmt, .TestVector(TestVectors[VectorNum]), - .VectorNum, .Ans(Ans), .AnsFlg(AnsFlg), .SrcA, + .VectorNum, .Ans(Ans), .AnsFlg(AnsFlg), .SrcA, .SrcB, .Xs, .Ys, .Zs, .Unit(UnitVal), - .Xe, .Ye, .Ze, .TestNum, .OpCtrl(OpCtrlVal), - .Xm, .Ym, .Zm, .DivStart, + .Xe, .Ye, .Ze, .TestNum, .OpCtrl(OpCtrlVal), .Funct3E, + .Xm, .Ym, .Zm, .DivStart, .IDivStart, .IntDivE, .XNaN, .YNaN, .ZNaN, .XSNaN, .YSNaN, .ZSNaN, .XSubnorm, .ZSubnorm, @@ -756,29 +768,29 @@ module testbenchfp; // instantiate devices under test if (TEST === "fma"| TEST === "mul" | TEST === "add" | TEST === "sub" | TEST === "all") begin : fma fma #(P) fma(.Xs(Xs), .Ys(Ys), .Zs(Zs), - .Xe(Xe), .Ye(Ye), .Ze(Ze), - .Xm(Xm), .Ym(Ym), .Zm(Zm), - .XZero, .YZero, .ZZero, .Ss, .Se, - .OpCtrl(OpCtrlVal), .Sm, .InvA, .SCnt, .As, .Ps, - .ASticky); + .Xe(Xe), .Ye(Ye), .Ze(Ze), + .Xm(Xm), .Ym(Ym), .Zm(Zm), + .XZero, .YZero, .ZZero, .Ss, .Se, + .OpCtrl(OpCtrlVal), .Sm, .InvA, .SCnt, .As, .Ps, + .ASticky); end /*postprocess #(P) postprocess(.Xs(Xs), .Ys(Ys), .PostProcSel(UnitVal[1:0]), - .OpCtrl(OpCtrlVal), .DivQm(Quot), .DivQe(DivCalcExp), - .Xm(Xm), .Ym(Ym), .Zm(Zm), .CvtCe(CvtCalcExpE), .DivSticky(DivSticky), .FmaSs(Ss), - .XNaN(XNaN), .YNaN(YNaN), .ZNaN(ZNaN), .CvtResSubnormUf(CvtResSubnormUfE), - .XZero(XZero), .YZero(YZero), .CvtShiftAmt(CvtShiftAmtE), - .XInf(XInf), .YInf(YInf), .ZInf(ZInf), .CvtCs(CvtResSgnE), .ToInt(WriteIntVal), - .XSNaN(XSNaN), .YSNaN(YSNaN), .ZSNaN(ZSNaN), .CvtLzcIn(CvtLzcInE), .IntZero, - .FmaASticky(ASticky), .FmaSe(Se), - .FmaSm(Sm), .FmaSCnt(SCnt), .FmaAs(As), .FmaPs(Ps), .Fmt(ModFmt), .Frm(FrmVal), - .PostProcFlg(Flg), .PostProcRes(FpRes), .FCvtIntRes(IntRes));*/ + .OpCtrl(OpCtrlVal), .DivQm(Quot), .DivQe(DivCalcExp), + .Xm(Xm), .Ym(Ym), .Zm(Zm), .CvtCe(CvtCalcExpE), .DivSticky(DivSticky), .FmaSs(Ss), + .XNaN(XNaN), .YNaN(YNaN), .ZNaN(ZNaN), .CvtResSubnormUf(CvtResSubnormUfE), + .XZero(XZero), .YZero(YZero), .CvtShiftAmt(CvtShiftAmtE), + .XInf(XInf), .YInf(YInf), .ZInf(ZInf), .CvtCs(CvtResSgnE), .ToInt(WriteIntVal), + .XSNaN(XSNaN), .YSNaN(YSNaN), .ZSNaN(ZSNaN), .CvtLzcIn(CvtLzcInE), .IntZero, + .FmaASticky(ASticky), .FmaSe(Se), + .FmaSm(Sm), .FmaSCnt(SCnt), .FmaAs(As), .FmaPs(Ps), .Fmt(ModFmt), .Frm(FrmVal), + .PostProcFlg(Flg), .PostProcRes(FpRes), .FCvtIntRes(IntRes));*/ if (TEST === "cvtfp" | TEST === "cvtint" | TEST === "all") begin : fcvt - fcvt #(P) fcvt (.Xs(Xs), .Xe(Xe), .Xm(Xm), .Int(SrcA), .ToInt(WriteIntVal), - .XZero(XZero), .OpCtrl(OpCtrlVal), .IntZero, - .Fmt(ModFmt), .Ce(CvtCalcExpE), .ShiftAmt(CvtShiftAmtE), - .ResSubnormUf(CvtResSubnormUfE), .Cs(CvtResSgnE), .LzcIn(CvtLzcInE)); + fcvt #(P) fcvt (.Xs(Xs), .Xe(Xe), .Xm(Xm), .Int(SrcA), .ToInt(WriteIntVal), + .XZero(XZero), .OpCtrl(OpCtrlVal), .IntZero, + .Fmt(ModFmt), .Ce(CvtCalcExpE), .ShiftAmt(CvtShiftAmtE), + .ResSubnormUf(CvtResSubnormUfE), .Cs(CvtResSgnE), .LzcIn(CvtLzcInE)); end if (TEST === "cmp" | TEST === "all") begin: fcmp @@ -789,29 +801,29 @@ module testbenchfp; if (TEST === "div" | TEST === "sqrt" | TEST === "all"| TEST === "custom" | TEST ==="customdivcorrect") begin: fdivsqrt fdivsqrt #(P) fdivsqrt(.clk, .reset, .XsE(Xs), .FmtE(ModFmt), .XmE(Xm), .YmE(Ym), - .XeE(Xe), .YeE(Ye), .SqrtE(OpCtrlVal[0]), .SqrtM(OpCtrlVal[0]), - .XInfE(XInf), .YInfE(YInf), .XZeroE(XZero), .YZeroE(YZero), - .XNaNE(XNaN), .YNaNE(YNaN), - .FDivStartE(DivStart), .IDivStartE(1'b0), .W64E(1'b0), - .StallM(1'b0), .DivStickyM(DivSticky), .FDivBusyE, .QeM(DivCalcExp), - .QmM(Quot), - .FlushE(1'b0), .ForwardedSrcAE('0), .ForwardedSrcBE('0), .Funct3M(Funct3M), - .Funct3E(Funct3E), .IntDivE(1'b0), .FIntDivResultM(FIntDivResultM), - .FDivDoneE(FDivDoneE), .IFDivStartE(IFDivStartE)); + .XeE(Xe), .YeE(Ye), .SqrtE(OpCtrlVal[0]), .SqrtM(OpCtrlVal[0]), + .XInfE(XInf), .YInfE(YInf), .XZeroE(XZero), .YZeroE(YZero), + .XNaNE(XNaN), .YNaNE(YNaN), + .FDivStartE(DivStart), .IDivStartE(1'b0), .W64E(1'b0), + .StallM(1'b0), .DivStickyM(DivSticky), .FDivBusyE, .QeM(DivCalcExp), + .QmM(Quot), + .FlushE(1'b0), .ForwardedSrcAE('0), .ForwardedSrcBE('0), .Funct3M(Funct3M), + .Funct3E(Funct3E), .IntDivE(1'b0), .FIntDivResultM(FIntDivResultM), + .FDivDoneE(FDivDoneE), .IFDivStartE(IFDivStartE)); end - if (TEST === "divremsqrt" | TEST === "divremsqrttest" | TEST === "customdiv") begin: divremsqrt + if (TEST === "divremsqrt" | TEST === "divremsqrttest" | TEST === "customdiv" | TEST === "intdiv") begin: divremsqrt drsu #(P) drsu(.clk, .reset, .XsE(Xs), .YsE(Ys), .FmtE(ModFmt), .XmE(Xm), .YmE(Ym), - .XeE(Xe), .YeE(Ye), .SqrtE(OpCtrlVal[0]), .SqrtM(OpCtrlVal[0]), + .XeE(Xe), .YeE(Ye), .SqrtE(OpCtrlVal[0]), .SqrtM(OpCtrlVal[0]), .XInfE(XInf), .YInfE(YInf), .XZeroE(XZero), .YZeroE(YZero), .PostProcSel(UnitVal[1:0]), - .XNaNE(XNaN), .YNaNE(YNaN), + .XNaNE(XNaN), .YNaNE(YNaN), .OpCtrl(OpCtrlVal), .XSNaNE(XSNaN), .YSNaNE(YSNaN), .Frm(FrmVal), - .FDivStartE(DivStart), .IDivStartE(1'b0), .W64E(1'b0), + .FDivStartE(DivStart), .IDivStartE(IDivStart), .W64E(1'b0), .StallM(1'b0), .FDivBusyE, - .FlushE(1'b0), .ForwardedSrcAE('0), .ForwardedSrcBE('0), .Funct3M(Funct3M), - .Funct3E(Funct3E), .IntDivE(1'b0), + .FlushE(1'b0), .ForwardedSrcAE(SrcA), .ForwardedSrcBE(SrcB), .Funct3M(Funct3M), + .Funct3E(Funct3E), .IntDivE(IntDivE), .FDivDoneE(FDivDoneE), .IFDivStartE(IFDivStartE), .FResM(FpRes), .FIntDivResultM(IntRes), .FlgM(Flg)); end else begin: postprocess @@ -840,8 +852,8 @@ module testbenchfp; // the IDLE state. initial begin - #0 reset = 1'b1; - #25 reset = 1'b0; + #0 reset = 1'b1; + #25 reset = 1'b0; end /////////////////////////////////////////////////////////////////////////////////////////////// @@ -858,12 +870,12 @@ module testbenchfp; // Check if the correct answer and result is a NaN always_comb begin if (UnitVal === `CVTINTUNIT | UnitVal === `CMPUNIT | (UnitVal === `DIVREMSQRTUNIT && WriteIntVal == 1'b1)) begin - // an integer output can't be a NaN - AnsNaN = 1'b0; - ResNaN = 1'b0; + // an integer output can't be a NaN + AnsNaN = 1'b0; + ResNaN = 1'b0; end else if (UnitVal === `CVTFPUNIT) begin - case (OpCtrlVal[1:0]) + case (OpCtrlVal[1:0]) 4'b11: begin // quad AnsNaN = &Ans[P.Q_LEN-2:P.NF]&(|Ans[P.Q_NF-1:0]); ResNaN = &Res[P.Q_LEN-2:P.NF]&(|Res[P.Q_NF-1:0]); @@ -880,10 +892,10 @@ module testbenchfp; AnsNaN = &Ans[P.H_LEN-2:P.H_NF]&(|Ans[P.H_NF-1:0]); ResNaN = &Res[P.H_LEN-2:P.H_NF]&(|Res[P.H_NF-1:0]); end - endcase + endcase end else begin - case (FmtVal) + case (FmtVal) 4'b11: begin // quad AnsNaN = &Ans[P.Q_LEN-2:P.Q_NF]&(|Ans[P.Q_NF-1:0]); ResNaN = &Res[P.Q_LEN-2:P.Q_NF]&(|Res[P.Q_NF-1:0]); @@ -900,27 +912,29 @@ module testbenchfp; AnsNaN = &Ans[P.H_LEN-2:P.H_NF]&(|Ans[P.H_NF-1:0]); ResNaN = &Res[P.H_LEN-2:P.H_NF]&(|Res[P.H_NF-1:0]); end - endcase + endcase end end always_comb begin // select the result to check case (UnitVal) - `FMAUNIT: Res = FpRes; - `DIVUNIT: Res = FpRes; - `CMPUNIT: Res = CmpRes; - `CVTINTUNIT: if (WriteIntVal) Res = IntRes; else Res = FpRes; - `CVTFPUNIT: Res = FpRes; + `FMAUNIT: Res = FpRes; + `DIVUNIT: Res = FpRes; + `CMPUNIT: Res = CmpRes; + `CVTINTUNIT: if (WriteIntVal) Res = IntRes; else Res = FpRes; + `CVTFPUNIT: Res = FpRes; + `INTDIVUNIT: Res = IntRes; endcase // select the flag to check case (UnitVal) - `FMAUNIT: ResFlg = Flg; - `DIVUNIT: ResFlg = Flg; - `CMPUNIT: ResFlg = CmpFlg; - `CVTINTUNIT: ResFlg = Flg; - `CVTFPUNIT: ResFlg = Flg; + `FMAUNIT: ResFlg = Flg; + `DIVUNIT: ResFlg = Flg; + `CMPUNIT: ResFlg = CmpFlg; + `CVTINTUNIT: ResFlg = Flg; + `CVTFPUNIT: ResFlg = Flg; + `INTDIVUNIT: ResFlg = Flg; endcase end @@ -932,33 +946,33 @@ module testbenchfp; always @(posedge clk) begin // Add extra clock cycles in beginning for fdivsqrt to adequate reset state if (~(FDivBusyE|DivStart)|(UnitVal != `DIVUNIT)) begin - // This allows specific number of clocks to allow each vector - // to complete for division or square root. It is an - // arbitrary value and can be changed, if needed. - case (FmtVal) - // QP - 4'b11: begin - repeat (20) - @(posedge clk); - end - // HP - 4'b10: begin - repeat (14) - @(posedge clk); - end - // DP - 4'b01: begin - repeat (18) - @(posedge clk); - end - // SP - 4'b00: begin - repeat (16) - @(posedge clk); - end - endcase // case (FmtVal) - if (reset != 1'b1) - VectorNum += 1; // increment the vector + // This allows specific number of clocks to allow each vector + // to complete for division or square root. It is an + // arbitrary value and can be changed, if needed. + case (FmtVal) + // QP + 4'b11: begin + repeat (20) + @(posedge clk); + end + // HP + 4'b10: begin + repeat (14) + @(posedge clk); + end + // DP + 4'b01: begin + repeat (18) + @(posedge clk); + end + // SP + 4'b00: begin + repeat (16) + @(posedge clk); + end + endcase // case (FmtVal) + if (reset != 1'b1) + VectorNum += 1; // increment the vector end end @@ -968,7 +982,7 @@ 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) + case (FmtVal) 4'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]})) | @@ -989,9 +1003,9 @@ module testbenchfp; (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 + endcase else if (UnitVal === `CVTFPUNIT) // if converting from floating point to floating point OpCtrl contains the final FP format - case (OpCtrlVal[1:0]) + 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])) | @@ -1012,7 +1026,7 @@ module testbenchfp; (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 + endcase else NaNGood = 1'b0; // integers can't be NaNs @@ -1030,7 +1044,7 @@ module testbenchfp; // 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 divsqrtop = (OpCtrlVal == `SQRT_OPCTRL) | (OpCtrlVal == `DIV_OPCTRL) | (OpCtrlVal == `INTREM_OPCTRL); assign FMAop = (OpCtrlVal == `FMAUNIT); assign DivDone = OldFDivBusyE & ~FDivBusyE; @@ -1041,10 +1055,10 @@ module testbenchfp; fd = $fopen("fperr.out","a"); $fwrite(fd, "%h_%h_%h_%2h\n",X,Y,Ans,AnsFlg); $fclose(fd); - 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); + errors += 1; + $display("\nError in %s", Tests[TestNum]); + $display("TestNum %d OpCtrl %d", TestNum, OpCtrl[TestNum]); + $display("inputs: %h %h %h\nSrcA: %h\n SrcB: %h\n Res: %h %h\n Expected: %h %h", X, Y, Z, SrcA, SrcB, Res, ResFlg, Ans, AnsFlg); end // TestFloat sets the result to all 1's when there is an invalid result, however in @@ -1054,36 +1068,36 @@ module testbenchfp; // 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) & - ~(((WriteIntVal&~OpCtrlVal[0]&AnsFlg[4]&Xs&(Res[P.XLEN-1:0] === (P.XLEN)'(0))) | - (WriteIntVal&OpCtrlVal[0]&AnsFlg[4]&(~Xs|XNaN)&OpCtrlVal[1]&(Res[P.XLEN-1:0] === {1'b0, {P.XLEN-1{1'b1}}})) | - (WriteIntVal&OpCtrlVal[0]&AnsFlg[4]&(~Xs|XNaN)&~OpCtrlVal[1]&(Res[P.XLEN-1:0] === {{P.XLEN-32{1'b0}}, 1'b0, {31{1'b1}}})) | - (~(WriteIntVal&~OpCtrlVal[0]&AnsFlg[4]&Xs&~XNaN)&(Res === Ans | NaNGood | NaNGood === 1'bx))) & (ResFlg === AnsFlg | AnsFlg === 5'bx))) begin - errors += 1; - $display("There is an error in %s", Tests[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; + ~(((WriteIntVal&~OpCtrlVal[0]&AnsFlg[4]&Xs&(Res[P.XLEN-1:0] === (P.XLEN)'(0))) | + (WriteIntVal&OpCtrlVal[0]&AnsFlg[4]&(~Xs|XNaN)&OpCtrlVal[1]&(Res[P.XLEN-1:0] === {1'b0, {P.XLEN-1{1'b1}}})) | + (WriteIntVal&OpCtrlVal[0]&AnsFlg[4]&(~Xs|XNaN)&~OpCtrlVal[1]&(Res[P.XLEN-1:0] === {{P.XLEN-32{1'b0}}, 1'b0, {31{1'b1}}})) | + (~(WriteIntVal&~OpCtrlVal[0]&AnsFlg[4]&Xs&~XNaN)&(Res === Ans | NaNGood | NaNGood === 1'bx))) & (ResFlg === AnsFlg | AnsFlg === 5'bx))) begin + errors += 1; + $display("There is an error in %s", Tests[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 - // increment the test - TestNum += 1; - // clear the vectors - for(int i=0; i<6133248; i++) TestVectors[i] = {P.FLEN*4+8{1'bx}}; - // read next files - $readmemh({`PATH, Tests[TestNum]}, TestVectors); - // set the vector index back to 0 - VectorNum = 0; - // incemet the operation if all the rounding modes have been tested - if (FrmNum === 4) OpCtrlNum += 1; - // increment the rounding mode or loop back to rne - if (FrmNum < 4) FrmNum += 1; - else FrmNum = 0; - // if no more Tests - finish - if (Tests[TestNum] === "") begin + // increment the test + TestNum += 1; + // clear the vectors + for(int i=0; i<6133248; i++) TestVectors[i] = {P.FLEN*4+8{1'bx}}; + // read next files + $readmemh({`PATH, Tests[TestNum]}, TestVectors); + // set the vector index back to 0 + VectorNum = 0; + // incemet the operation if all the rounding modes have been tested + if (FrmNum === 4) OpCtrlNum += 1; + // increment the rounding mode or loop back to rne + if (FrmNum < 4) FrmNum += 1; + else FrmNum = 0; + // if no more Tests - finish + if (Tests[TestNum] === "") begin $display("\nAll Tests completed with %d errors\n", errors); $stop; - end - $display("Running %s vectors", Tests[TestNum]); + end + $display("Running %s vectors", Tests[TestNum]); end end endmodule @@ -1100,6 +1114,7 @@ module readvectors ( input logic [2:0] OpCtrl, output logic [P.FLEN-1:0] Ans, output logic [P.XLEN-1:0] SrcA, + output logic [P.XLEN-1:0] SrcB, output logic [4:0] AnsFlg, output logic Xs, Ys, Zs, // sign bits of XYZ output logic [P.NE-1:0] Xe, Ye, Ze, // exponents of XYZ (converted to largest supported precision) @@ -1111,6 +1126,9 @@ module readvectors ( output logic XInf, YInf, ZInf, // is XYZ infinity output logic XExpMax, output logic DivStart, + output logic IDivStart, + output logic IntDivE, + output logic [2:0] Funct3E, output logic [P.FLEN-1:0] X, Y, Z, XPostBox ); @@ -1265,6 +1283,21 @@ module readvectors ( DivStart = 1'b0; end endcase + `INTDIVUNIT: begin + #20; + X = {P.FLEN{1'bx}}; + SrcA = TestVector[2*(P.Q_LEN)+P.D_LEN-1:2*(P.Q_LEN)]; + SrcB = TestVector[(P.Q_LEN)+P.D_LEN-1:P.Q_LEN]; + Ans = TestVector[P.D_LEN-1:0]; + if (~clk) #5; + IDivStart = 1'b1; + IntDivE = 1'b1; + Funct3E = 3'b110; + #10 // one clk cycle + IDivStart = 1'b0; + IntDivE = 1'b0; + end + `CMPUNIT: case (Fmt) 2'b11: begin // quad @@ -1491,4 +1524,4 @@ module readvectors ( .Xm, .Ym, .Zm, .XNaN, .YNaN, .ZNaN, .XSNaN, .YSNaN, .ZSNaN, .XSubnorm, .XZero, .YZero, .ZZero, .XInf, .YInf, .ZInf, .XEn, .YEn, .ZEn, .XExpMax, .XPostBox); -endmodule +endmodule \ No newline at end of file diff --git a/testbench/tests-fp.vh b/testbench/tests-fp.vh index 500a65d4b..6924ab65c 100644 --- a/testbench/tests-fp.vh +++ b/testbench/tests-fp.vh @@ -42,6 +42,10 @@ `define FROM_I_OPCTRL 3'b101 `define FROM_UL_OPCTRL 3'b110 `define FROM_L_OPCTRL 3'b111 +`define INTREMU_OPCTRL 3'b000 +`define INTREM_OPCTRL 3'b110 +`define INTDIV_OPCTRL 3'b010 +`define INTDIVU_OPCTRL 3'b011 `define RNE 3'b000 `define RZ 3'b001 `define RU 3'b011 @@ -53,6 +57,7 @@ `define CVTFPUNIT 4 `define CMPUNIT 3 `define DIVREMSQRTUNIT 5 +`define INTDIVUNIT 6 string f16rv32cvtint[] = '{ "ui32_to_f16_rne.tv", @@ -589,5 +594,8 @@ string customdivcorrect[] = '{ "f16_custom.tv" }; +string intdiv[] = '{ + "f16_kevin.tv" +}; diff --git a/tests/fp/combined_IF_vectors/extract_arch_vectors.py b/tests/fp/combined_IF_vectors/extract_arch_vectors.py index 12669bc58..8baa0939b 100755 --- a/tests/fp/combined_IF_vectors/extract_arch_vectors.py +++ b/tests/fp/combined_IF_vectors/extract_arch_vectors.py @@ -272,22 +272,22 @@ def create_vectors(my_config): src_file2.close() config_list = [ -Config(32, "M", "div", "div-", 0), +Config(32, "M", "div", "div-", 4), Config(32, "F", "fdiv", "fdiv", 1), Config(32, "F", "fsqrt", "fsqrt", 2), -Config(32, "M", "rem", "rem-", 3), -Config(32, "M", "divu", "divu-", 4), -Config(32, "M", "remu", "remu-", 5), -Config(64, "M", "div", "div-", 0), +Config(32, "M", "rem", "rem-", 6), +Config(32, "M", "divu", "divu-", 5), +Config(32, "M", "remu", "remu-", 7), +Config(64, "M", "div", "div-", 4), Config(64, "F", "fdiv", "fdiv", 1), Config(64, "F", "fsqrt", "fsqrt", 2), -Config(64, "M", "rem", "rem-", 3), -Config(64, "M", "divu", "divu-", 4), -Config(64, "M", "remu", "remu-", 5), -Config(64, "M", "divw", "divw-", 6), -Config(64, "M", "divuw", "divuw-", 7), -Config(64, "M", "remw", "remw-", 8), -Config(64, "M", "remuw", "remuw-", 9) +Config(64, "M", "rem", "rem-", 6), +Config(64, "M", "divu", "divu-", 5), +Config(64, "M", "remu", "remu-", 7), +Config(64, "M", "divw", "divw-", 4), +Config(64, "M", "divuw", "divuw-", 5), +Config(64, "M", "remw", "remw-", 6), +Config(64, "M", "remuw", "remuw-", 7) ] for c in config_list: diff --git a/tests/fp/combined_IF_vectors/extract_arch_vectors_v2.py b/tests/fp/combined_IF_vectors/extract_arch_vectors_v2.py new file mode 100755 index 000000000..6fe63d0c7 --- /dev/null +++ b/tests/fp/combined_IF_vectors/extract_arch_vectors_v2.py @@ -0,0 +1,294 @@ +#! /usr/bin/python3 + +# author: Alessandro Maiuolo, Kevin Kim +# contact: amaiuolo@g.hmc.edu, kekim@hmc.edu +# date created: 3-29-2023 + +# extract all arch test vectors +import os +wally = os.popen('echo $WALLY').read().strip() + +def ext_bits(my_string): + target_len = 32 # we want 128 bits, div by 4 bc hex notation + zeroes_to_add = target_len - len(my_string) + return zeroes_to_add*"0" + my_string + +def twos_comp(b, x): + if b == 32: + return hex(0x100000000 - int(x,16))[2:] + elif b == 64: + return hex(0x10000000000000000 - int(x,16))[2:] + else: + return "UNEXPECTED_BITSIZE" + +def unpack_rf(packed): + bin_u = bin(int(packed, 16))[2:].zfill(8) # translate to binary + flags = hex(int(bin_u[3:],2))[2:].zfill(2) + rounding_mode = hex(int(bin_u[:3],2))[2:] + return flags, rounding_mode + +# rounding mode dictionary +round_dict = { + "rne":"0", + "rnm":"4", + "ru":"3", + "rz":"1", + "rd":"2", + "dyn":"7" +} + +# fcsr dictionary +fcsr_dict = { + "0":"rne", + "128":"rnm", + "96":"ru", + "32":"rz", + "64":"rd", + "224":"dyn" +} + +print("creating arch test vectors") + +class Config: + def __init__(self, bits, letter, op, filt, op_code): + self.bits = bits + self.letter = letter + self.op = op + self.filt = filt + self.op_code = op_code + +def create_vectors(my_config): + suite_folder_num = my_config.bits + if my_config.bits == 64 and my_config.letter == "F": suite_folder_num = 32 + source_dir1 = "{}/addins/riscv-arch-test/riscv-test-suite/rv{}i_m/{}/src/".format(wally, suite_folder_num, my_config.letter) + source_dir2 = "{}/tests/riscof/work/riscv-arch-test/rv{}i_m/{}/src/".format(wally, my_config.bits, my_config.letter) + dest_dir = "{}/tests/fp/combined_IF_vectors/IF_vectors/".format(wally) + all_vectors1 = os.listdir(source_dir1) + + filt_vectors1 = [v for v in all_vectors1 if my_config.filt in v] + # print(filt_vectors1) + filt_vectors2 = [v + "/ref/Reference-sail_c_simulator.signature" for v in all_vectors1 if my_config.filt in v] + + # iterate through all vectors + for i in range(len(filt_vectors1)): + vector1 = filt_vectors1[i] + vector2 = filt_vectors2[i] + operation = my_config.op_code + rounding_mode = "X" + flags = "XX" + # use name to create our new tv + dest_file = open("{}cvw_{}_{}.tv".format(dest_dir, my_config.bits, vector1[:-2]), 'w') + # open vectors + src_file1 = open(source_dir1 + vector1,'r') + src_file2 = open(source_dir2 + vector2,'r') + # for each test in the vector + reading = True + src_file2.readline() #skip first bc junk + # print(my_config.bits, my_config.letter) + if my_config.letter == "F" and my_config.bits == 64: + reading = True + # print("trigger 64F") + #skip first 2 lines bc junk + src_file2.readline() + while reading: + # get answer and flags from Ref...signature + # answers are before deadbeef (first line of 4) + # flags are after deadbeef (third line of 4) + answer = src_file2.readline().strip() + deadbeef = src_file2.readline().strip() + # print(answer) + if not (answer == "e7d4b281" and deadbeef == "6f5ca309"): # if there is still stuff to read + # get flags + packed = src_file2.readline().strip()[6:] + flags, rounding_mode = unpack_rf(packed) + # skip 00000000 buffer + src_file2.readline() + + # parse through .S file + detected = False + done = False + op1val = "0" + op2val = "0" + while not (detected or done): + # print("det1") + line = src_file1.readline() + # print(line) + if "op1val" in line: + # print("det2") + # parse line + op1val = line.split("op1val")[1].split("x")[1].split(";")[0] + if my_config.op != "fsqrt": # sqrt doesn't have two input vals + op2val = line.split("op2val")[1].split("x")[1].strip() + if op2val[-1] == ";": op2val = op2val[:-1] # remove ; if it's there + else: + op2val = 32*"X" + # go to next test in vector + detected = True + elif "RVTEST_CODE_END" in line: + done = True + # put it all together + if not done: + translation = "{}_{}_{}".format(ext_bits(op1val), ext_bits(op2val), ext_bits(answer.strip())) + dest_file.write(translation + "\n") + else: + # print("read false") + reading = False + elif my_config.letter == "M" and my_config.bits == 64: + reading = True + #skip first 2 lines bc junk + src_file2.readline() + while reading: + # print("trigger 64M") + # get answer from Ref...signature + # answers span two lines and are reversed + answer2 = src_file2.readline().strip() + answer1 = src_file2.readline().strip() + answer = answer1 + answer2 + #print(answer1,answer2) + if not (answer2 == "e7d4b281" and answer1 == "6f5ca309"): # if there is still stuff to read + # parse through .S file + detected = False + done = False + op1val = "0" + op2val = "0" + while not (detected or done): + # print("det1") + line = src_file1.readline() + # print(line) + if "op1val" in line: + # print("det2") + # parse line + op1val = line.split("op1val")[1].split("x")[1].split(";")[0] + if "-" in line.split("op1val")[1].split("x")[0]: # neg sign handling + op1val = twos_comp(my_config.bits, op1val) + if my_config.op != "fsqrt": # sqrt doesn't have two input vals, unnec here but keeping for later + op2val = line.split("op2val")[1].split("x")[1].strip() + if op2val[-1] == ";": op2val = op2val[:-1] # remove ; if it's there + if "-" in line.split("op2val")[1].split("x")[0]: # neg sign handling + op2val = twos_comp(my_config.bits, op2val) + # go to next test in vector + detected = True + elif "RVTEST_CODE_END" in line: + done = True + # ints don't have flags + flags = "XX" + # put it all together + if not done: + translation = "{}_{}_{}".format(ext_bits(op1val), ext_bits(op2val), ext_bits(answer.strip())) + dest_file.write(translation + "\n") + else: + # print("read false") + reading = False + elif my_config.letter == "M" and my_config.bits == 32: + reading = True + while reading: + # print("trigger 64M") + # get answer from Ref...signature + # answers span two lines and are reversed + answer = src_file2.readline().strip() + print(f"Answer: {answer}") + #print(answer1,answer2) + if not (answer == "6f5ca309"): # if there is still stuff to read + # parse through .S file + detected = False + done = False + op1val = "0" + op2val = "0" + while not (detected or done): + # print("det1") + line = src_file1.readline() + # print(line) + if "op1val" in line: + # print("det2") + # parse line + op1val = line.split("op1val")[1].split("x")[1].split(";")[0] + if "-" in line.split("op1val")[1].split("x")[0]: # neg sign handling + op1val = twos_comp(my_config.bits, op1val) + if my_config.op != "fsqrt": # sqrt doesn't have two input vals, unnec here but keeping for later + op2val = line.split("op2val")[1].split("x")[1].strip() + if op2val[-1] == ";": op2val = op2val[:-1] # remove ; if it's there + if "-" in line.split("op2val")[1].split("x")[0]: # neg sign handling + op2val = twos_comp(my_config.bits, op2val) + # go to next test in vector + detected = True + elif "RVTEST_CODE_END" in line: + done = True + # ints don't have flags + flags = "XX" + # put it all together + if not done: + translation = "{}_{}_{}".format(ext_bits(op1val), ext_bits(op2val), ext_bits(answer.strip())) + dest_file.write(translation + "\n") + else: + # print("read false") + reading = False + else: + while reading: + # get answer and flags from Ref...signature + answer = src_file2.readline() + print(answer) + packed = src_file2.readline()[6:] + print("Packed: ", packed) + if len(packed.strip())>0: # if there is still stuff to read + # print("packed") + # parse through .S file + detected = False + done = False + op1val = "0" + op2val = "0" + while not (detected or done): + # print("det1") + line = src_file1.readline() + # print(line) + if "op1val" in line: + # print("det2") + # parse line + op1val = line.split("op1val")[1].split("x")[1].split(";")[0] + if "-" in line.split("op1val")[1].split("x")[0]: # neg sign handling + op1val = twos_comp(my_config.bits, op1val) + if my_config.op != "fsqrt": # sqrt doesn't have two input vals + op2val = line.split("op2val")[1].split("x")[1].strip() + if op2val[-1] == ";": op2val = op2val[:-1] # remove ; if it's there + if "-" in line.split("op2val")[1].split("x")[0]: # neg sign handling + op2val = twos_comp(my_config.bits, op2val) + # go to next test in vector + detected = True + elif "RVTEST_CODE_END" in line: + done = True + # rounding mode for float + if not done and (my_config.op == "fsqrt" or my_config.op == "fdiv"): + flags, rounding_mode = unpack_rf(packed) + + # put it all together + if not done: + translation = "{}_{}_{}".format(ext_bits(op1val), ext_bits(op2val), ext_bits(answer.strip())) + dest_file.write(translation + "\n") + else: + # print("read false") + reading = False + # print("out") + dest_file.close() + src_file1.close() + src_file2.close() + +config_list = [ +Config(32, "M", "div", "div-", 4), +Config(32, "F", "fdiv", "fdiv", 1), +Config(32, "F", "fsqrt", "fsqrt", 2), +Config(32, "M", "rem", "rem-", 6), +Config(32, "M", "divu", "divu-", 5), +Config(32, "M", "remu", "remu-", 7), +Config(64, "M", "div", "div-", 4), +Config(64, "F", "fdiv", "fdiv", 1), +Config(64, "F", "fsqrt", "fsqrt", 2), +Config(64, "M", "rem", "rem-", 6), +Config(64, "M", "divu", "divu-", 5), +Config(64, "M", "remu", "remu-", 7), +Config(64, "M", "divw", "divw-", 4), +Config(64, "M", "divuw", "divuw-", 5), +Config(64, "M", "remw", "remw-", 6), +Config(64, "M", "remuw", "remuw-", 7) +] + +for c in config_list: + create_vectors(c) \ No newline at end of file