diff --git a/testbench/testbench_fp.sv b/testbench/testbench_fp.sv index c6b91ad10..8bff47682 100644 --- a/testbench/testbench_fp.sv +++ b/testbench/testbench_fp.sv @@ -3,9 +3,9 @@ // Written: me@KatherineParry.com, james.stine@okstate.edu // // Purpose: Testbench for UCB Testfloat on Wally -// +// // A component of the Wally configurable RISC-V project. -// +// // Copyright (C) 2021 Harvey Mudd College & Oklahoma State University // // SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 @@ -28,1392 +28,1382 @@ import cvw::*; module testbench_fp; - // Two parameters TEST, TEST_SIZE used with testfloat.do in sim dir - // to run specific precisions (e.g., quad or all) - parameter string TEST="none"; // choices are cvtint, cvtfp, cmp, add, sub, mul, div, sqrt, fma; all does not check properly - parameter string TEST_SIZE="all"; + // Two parameters TEST, TEST_SIZE used with testfloat.do in sim dir + // to run specific precisions (e.g., quad or all) + parameter string TEST="none"; // choices are cvtint, cvtfp, cmp, add, sub, mul, div, sqrt, fma; all does not check properly + parameter string TEST_SIZE="all"; `include "parameter-defs.vh" - `ifdef VERILATOR - import "DPI-C" function string getenvval(input string env_name); - string WALLY_DIR = getenvval("WALLY"); - `elsif VCS - import "DPI-C" function string getenv(input string env_name); - string WALLY_DIR = getenv("WALLY"); - `else - string WALLY_DIR = "$WALLY"; - `endif - - string FP_TESTS = {WALLY_DIR, "/tests/fp/vectors"}; - string pp; - if (P.IEEE754) assign pp = {FP_TESTS, "/ieee/"}; - else assign pp = {FP_TESTS, "/riscv/"}; - - parameter MAXVECTORS = 8388610; - - // FIXME: needs cleaning of unused variables (jes) - string Tests[]; // list of tests to be run - logic [2:0] OpCtrl[]; // list of op controls - logic [2:0] Unit[]; // list of units being tested - logic WriteInt[]; // Is being written to integer resgiter - logic [2:0] Frm[4:0] = {3'b100, 3'b010, 3'b011, 3'b001, 3'b000}; // rounding modes: rne-000, rz-001, ru-011, rd-010, rnm-100 - logic [1:0] Fmt[]; // list of formats for the other units - - logic clk=0; - logic [31:0] TestNum=0; // index for the test - logic [31:0] OpCtrlNum=0; // index for OpCtrl - logic [31:0] errors=0; // how many errors - logic [31:0] VectorNum=0; // index for test vector - logic [31:0] FrmNum=0; // index for rounding mode - logic [P.Q_LEN*4+7:0] TestVectors[MAXVECTORS-1:0]; // list of test vectors - - logic [1:0] FmtVal; // value of the current Fmt - logic [2:0] UnitVal, OpCtrlVal, FrmVal; // value of the currnet Unit/OpCtrl/FrmVal - logic WriteIntVal; // value of the current WriteInt - logic [P.Q_LEN-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.Q_LEN-1:0] Ans; // correct answer from TestFloat - logic [P.Q_LEN-1:0] Res; // result from other units - logic [4:0] AnsFlg; // correct flags read from testfloat - logic [4:0] ResFlg, Flg; // Result flags - logic [P.FMTBITS-1:0] ModFmt; // format - 10 = half, 00 = single, 01 = double, 11 = quad - logic [P.FLEN-1:0] FpRes, FpCmpRes; // Results from each unit - logic [P.XLEN-1:0] IntRes, CmpRes; // Results from each unit - logic [P.Q_LEN-1:0] FpResExtended; // FpRes extended to same length as Ans/Res - logic [4:0] FmaFlg, CvtFlg, DivFlg; // Outputed flags - logic [4:0] CmpFlg; // Outputed flags - logic AnsNaN, ResNaN, NaNGood; - logic Xs, Ys, Zs; // sign of the inputs - logic [P.NE-1:0] Xe, Ye, Ze; // exponent of the inputs - logic [P.NF:0] Xm, Ym, Zm; // mantissas of the inputs - logic XNaN, YNaN, ZNaN; // is the input NaN - logic XSNaN, YSNaN, ZSNaN; // is the input a signaling NaN - logic XSubnorm, ZSubnorm; // is the input denormalized - logic XInf, YInf, ZInf; // is the input infinity - logic XZero, YZero, ZZero; // is the input zero - logic XExpMax, YExpMax, ZExpMax; // is the input's exponent all ones - logic [P.CVTLEN-1:0] CvtLzcInE; // input to the Leading Zero Counter (priority encoder) - logic IntZero; - logic CvtResSgnE; - logic [P.NE:0] CvtCalcExpE; // the calculated exponent - logic [P.LOGCVTLEN-1:0] CvtShiftAmtE; // how much to shift by - logic [P.DIVb:0] Quot; - logic CvtResSubnormUfE; - logic DivStart; - logic FDivBusyE; - logic OldFDivBusyE; - logic reset = 1'b0; - logic [$clog2(P.NF+2)-1:0] XZeroCnt, YZeroCnt; - - // in-between FMA signals - logic Mult; - logic Ss; - logic [P.NE+1:0] Pe; - logic [P.NE+1:0] Se; - logic ASticky; - logic KillProd; - logic [$clog2(P.FMALEN+1)-1:0] SCnt; - logic [P.FMALEN-1:0] Sm; - logic InvA; - logic NegSum; - logic As; - logic Ps; - logic DivSticky; - logic DivDone; - logic DivNegSticky; - logic [P.NE+1:0] DivCalcExp; - logic divsqrtop; - - // Missing logic vectors fdivsqrt - logic [2:0] Funct3E; - logic [2:0] Funct3M; - logic FlushE; - logic IFDivStartE; - logic FDivDoneE; - logic [P.NE+1:0] UeM; - logic [P.DIVb:0] UmM; - logic [P.XLEN-1:0] FIntDivResultM; - logic ResMatch; // Check if result match - logic FlagMatch; // Check if IEEE flags match - logic CheckNow; // Final check - logic FMAop; // Is this a FMA operation? - - logic [P.NE-2:0] BiasE; // Bias of exponent - logic [P.LOGFLEN-1:0] NfE; // Number of fractional bits - - // FSM for testing each item per clock - typedef enum logic [2:0] {S0, Start, S2, Done} statetype; - statetype state, nextstate; - - /////////////////////////////////////////////////////////////////////////////////////////////// - - // ||||||||| |||||||| ||||||| ||||||||| ||||||| |||||||| ||| - // ||| ||| ||| ||| ||| ||| ||| - // ||| |||||||| ||||||| ||| ||||||| |||||||| ||| - // ||| ||| ||| ||| ||| ||| ||| - // ||| |||||||| ||||||| ||| ||||||| |||||||| ||||||||| - - /////////////////////////////////////////////////////////////////////////////////////////////// - - // select tests relevent to the specified configuration - // cvtint - test integer conversion unit (fcvtint) - // cvtfp - test floating-point conversion unit (fcvtfp) - // cmp - test comparison unit's LT, LE, EQ opperations (fcmp) - // add - test addition - // sub - test subtraction - // div - test division - // sqrt - test square root - // all - test all of the above < doesn't report errors properly > - - initial begin - // Information displayed for user on what is simulating - // $display("\nThe start of simulation..."); - // $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 - // 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 - OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL}; - 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}; - end - if (P.XLEN == 64) begin // if 64-bit integers are supported add their conversions - Tests = {Tests, f128rv64cvtint}; - // add the op-codes for these tests to the op-code list - OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; - 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}; - end - end - 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}; - // add the op-ctrls (i.e. the format of the result) - OpCtrl = {OpCtrl, 3'b01, 3'b11}; - 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}; - end - for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b01}; - end - end - if (P.F_SUPPORTED) begin // if single precision is supported - // add the 128 <-> 32 bit conversions to the to-be-tested list - Tests = {Tests, f128f32cvt}; - // add the op-ctrls (i.e. the format of the result) - OpCtrl = {OpCtrl, 3'b00, 3'b11}; - 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}; - end - for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b00}; - end - end - if (P.ZFH_SUPPORTED) begin // if half precision is supported - // add the 128 <-> 16 bit conversions to the to-be-tested list - Tests = {Tests, f128f16cvt}; - // add the op-ctrls (i.e. the format of the result) - OpCtrl = {OpCtrl, 3'b10, 3'b11}; - 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}; - end - for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b10}; - end - end - 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}; - WriteInt = {WriteInt, 1'b0, 1'b0, 1'b0}; - for(int i = 0; i<15; i++) begin - Unit = {Unit, `CMPUNIT}; - Fmt = {Fmt, 2'b11}; - end - 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}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b11}; - end - 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}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b11}; - end - 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}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b11}; - end - 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}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `DIVUNIT}; - Fmt = {Fmt, 2'b11}; - end - 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}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `DIVUNIT}; - Fmt = {Fmt, 2'b11}; - end - 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}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b11}; - end - 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 - 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}; - 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}; - end - if (P.XLEN == 64) begin // if 64-bit integers are being supported - Tests = {Tests, f64rv64cvtint}; - // add the op-codes for these tests to the op-code list - OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; - 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}; - end - end - 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}; - // add the op-ctrls (i.e. the format of the result) - OpCtrl = {OpCtrl, 3'b00, 3'b01}; - 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}; - end - for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b00}; - end - end - if (P.ZFH_SUPPORTED) begin // if half precision is supported - // add the 64 <-> 16 bit conversions to the to-be-tested list - Tests = {Tests, f64f16cvt}; - // add the op-ctrls (i.e. the format of the result) - OpCtrl = {OpCtrl, 3'b10, 3'b01}; - 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}; - end - for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b10}; - end - end - 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}; - WriteInt = {WriteInt, 1'b0, 1'b0, 1'b0}; - for(int i = 0; i<15; i++) begin - Unit = {Unit, `CMPUNIT}; - Fmt = {Fmt, 2'b01}; - end - 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}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b01}; - end - 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}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b01}; - end - 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}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b01}; - end - 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}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `DIVUNIT}; - Fmt = {Fmt, 2'b01}; - end - 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}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `DIVUNIT}; - Fmt = {Fmt, 2'b01}; - end - 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}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b01}; - end - 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 - 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}; - 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}; - end - if (P.XLEN == 64) begin // if 64-bit integers are supported - Tests = {Tests, f32rv64cvtint}; - // add the op-codes for these tests to the op-code list - OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; - 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}; - end - end - 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}; - // add the op-ctrls (i.e. the format of the result) - OpCtrl = {OpCtrl, 3'b10, 3'b00}; - 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}; - end - for(int i = 0; i<5; i++) begin - Unit = {Unit, `CVTFPUNIT}; - Fmt = {Fmt, 2'b10}; - end - end - 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}; - WriteInt = {WriteInt, 1'b0, 1'b0, 1'b0}; - for(int i = 0; i<15; i++) begin - Unit = {Unit, `CMPUNIT}; - Fmt = {Fmt, 2'b00}; - end - 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}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b00}; - end - 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}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b00}; - end - 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}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b00}; - end - 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}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `DIVUNIT}; - Fmt = {Fmt, 2'b00}; - end - 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}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `DIVUNIT}; - Fmt = {Fmt, 2'b00}; - end - end - if (TEST === "fma" | TEST === "all") begin // if fma is being tested - Tests = {Tests, f32fma}; - OpCtrl = {OpCtrl, `FMA_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b00}; - end - 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 - 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}; - 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}; - end - if (P.XLEN == 64) begin // if 64-bit integers are supported - Tests = {Tests, f16rv64cvtint}; - // add the op-codes for these tests to the op-code list - OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; - 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}; - end - end - 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}; - WriteInt = {WriteInt, 1'b0, 1'b0, 1'b0}; - for(int i = 0; i<15; i++) begin - Unit = {Unit, `CMPUNIT}; - Fmt = {Fmt, 2'b10}; - end - 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}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b10}; - end - 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}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b10}; - end - 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}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b10}; - end - 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}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `DIVUNIT}; - Fmt = {Fmt, 2'b10}; - end - 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}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `DIVUNIT}; - Fmt = {Fmt, 2'b10}; - end - end - if (TEST === "fma" | TEST === "all") begin // if fma is being tested - Tests = {Tests, f16fma}; - OpCtrl = {OpCtrl, `FMA_OPCTRL}; - WriteInt = {WriteInt, 1'b0}; - for(int i = 0; i<5; i++) begin - Unit = {Unit, `FMAUNIT}; - Fmt = {Fmt, 2'b10}; - end - end - end - // check if nothing is being tested - if (Tests.size() == 0) begin - $display("TEST %s not supported in this configuration", TEST); -`ifdef QUESTA - $stop; // if this is changed to $finish for Questa, wally.do terminates without allowing GUI debug +`ifdef VERILATOR + import "DPI-C" function string getenvval(input string env_name); + string WALLY_DIR = getenvval("WALLY"); +`elsif VCS + import "DPI-C" function string getenv(input string env_name); + string WALLY_DIR = getenv("WALLY"); `else - $finish; + string WALLY_DIR = "$WALLY"; `endif + + string FP_TESTS = {WALLY_DIR, "/tests/fp/vectors"}; + string pp; + if (P.IEEE754) assign pp = {FP_TESTS, "/ieee/"}; + else assign pp = {FP_TESTS, "/riscv/"}; + + parameter MAXVECTORS = 8388610; + + // FIXME: needs cleaning of unused variables (jes) + string Tests[]; // list of tests to be run + logic [2:0] OpCtrl[]; // list of op controls + logic [2:0] Unit[]; // list of units being tested + logic WriteInt[]; // Is being written to integer resgiter + logic [2:0] Frm[4:0] = {3'b100, 3'b010, 3'b011, 3'b001, 3'b000}; // rounding modes: rne-000, rz-001, ru-011, rd-010, rnm-100 + logic [1:0] Fmt[]; // list of formats for the other units + + logic clk=0; + logic [31:0] TestNum=0; // index for the test + logic [31:0] OpCtrlNum=0; // index for OpCtrl + logic [31:0] errors=0; // how many errors + logic [31:0] VectorNum=0; // index for test vector + logic [31:0] FrmNum=0; // index for rounding mode + logic [P.Q_LEN*4+7:0] TestVectors[MAXVECTORS-1:0]; // list of test vectors + + logic [1:0] FmtVal; // value of the current Fmt + logic [2:0] UnitVal, OpCtrlVal, FrmVal; // value of the currnet Unit/OpCtrl/FrmVal + logic WriteIntVal; // value of the current WriteInt + logic [P.Q_LEN-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.Q_LEN-1:0] Ans; // correct answer from TestFloat + logic [P.Q_LEN-1:0] Res; // result from other units + logic [4:0] AnsFlg; // correct flags read from testfloat + logic [4:0] ResFlg, Flg; // Result flags + logic [P.FMTBITS-1:0] ModFmt; // format - 10 = half, 00 = single, 01 = double, 11 = quad + logic [P.FLEN-1:0] FpRes, FpCmpRes; // Results from each unit + logic [P.XLEN-1:0] IntRes, CmpRes; // Results from each unit + logic [P.Q_LEN-1:0] FpResExtended; // FpRes extended to same length as Ans/Res + logic [4:0] FmaFlg, CvtFlg, DivFlg; // Outputed flags + logic [4:0] CmpFlg; // Outputed flags + logic AnsNaN, ResNaN, NaNGood; + logic Xs, Ys, Zs; // sign of the inputs + logic [P.NE-1:0] Xe, Ye, Ze; // exponent of the inputs + logic [P.NF:0] Xm, Ym, Zm; // mantissas of the inputs + logic XNaN, YNaN, ZNaN; // is the input NaN + logic XSNaN, YSNaN, ZSNaN; // is the input a signaling NaN + logic XSubnorm, ZSubnorm; // is the input denormalized + logic XInf, YInf, ZInf; // is the input infinity + logic XZero, YZero, ZZero; // is the input zero + logic XExpMax, YExpMax, ZExpMax; // is the input's exponent all ones + logic [P.CVTLEN-1:0] CvtLzcInE; // input to the Leading Zero Counter (priority encoder) + logic IntZero; + logic CvtResSgnE; + logic [P.NE:0] CvtCalcExpE; // the calculated exponent + logic [P.LOGCVTLEN-1:0] CvtShiftAmtE; // how much to shift by + logic [P.DIVb:0] Quot; + logic CvtResSubnormUfE; + logic DivStart; + logic FDivBusyE; + logic OldFDivBusyE; + logic reset = 1'b0; + logic [$clog2(P.NF+2)-1:0] XZeroCnt, YZeroCnt; + + // in-between FMA signals + logic Mult; + logic Ss; + logic [P.NE+1:0] Pe; + logic [P.NE+1:0] Se; + logic ASticky; + logic KillProd; + logic [$clog2(P.FMALEN+1)-1:0] SCnt; + logic [P.FMALEN-1:0] Sm; + logic InvA; + logic NegSum; + logic As; + logic Ps; + logic DivSticky; + logic DivDone; + logic DivNegSticky; + logic [P.NE+1:0] DivCalcExp; + logic divsqrtop; + + // Missing logic vectors fdivsqrt + logic [2:0] Funct3E; + logic [2:0] Funct3M; + logic FlushE; + logic IFDivStartE; + logic FDivDoneE; + logic [P.NE+1:0] UeM; + logic [P.DIVb:0] UmM; + logic [P.XLEN-1:0] FIntDivResultM; + logic ResMatch; // Check if result match + logic FlagMatch; // Check if IEEE flags match + logic CheckNow; // Final check + logic FMAop; // Is this a FMA operation? + + logic [P.NE-2:0] BiasE; // Bias of exponent + logic [P.LOGFLEN-1:0] NfE; // Number of fractional bits + + // FSM for testing each item per clock + typedef enum logic [2:0] {S0, Start, S2, Done} statetype; + statetype state, nextstate; + + /////////////////////////////////////////////////////////////////////////////////////////////// + + // ||||||||| |||||||| ||||||| ||||||||| ||||||| |||||||| ||| + // ||| ||| ||| ||| ||| ||| ||| + // ||| |||||||| ||||||| ||| ||||||| |||||||| ||| + // ||| ||| ||| ||| ||| ||| ||| + // ||| |||||||| ||||||| ||| ||||||| |||||||| ||||||||| + + /////////////////////////////////////////////////////////////////////////////////////////////// + + // select tests relevent to the specified configuration + // cvtint - test integer conversion unit (fcvtint) + // cvtfp - test floating-point conversion unit (fcvtfp) + // cmp - test comparison unit's LT, LE, EQ opperations (fcmp) + // add - test addition + // sub - test subtraction + // div - test division + // sqrt - test square root + // all - test all of the above < doesn't report errors properly > + + initial begin + // Information displayed for user on what is simulating + // $display("\nThe start of simulation..."); + // $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 + // 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 + OpCtrl = {OpCtrl, `FROM_UI_OPCTRL, `FROM_I_OPCTRL, `TO_UI_OPCTRL, `TO_I_OPCTRL}; + 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}; + end + if (P.XLEN == 64) begin // if 64-bit integers are supported add their conversions + Tests = {Tests, f128rv64cvtint}; + // add the op-codes for these tests to the op-code list + OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; + 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}; + end + end end - end - - /////////////////////////////////////////////////////////////////////////////////////////////// - - // ||||||||| |||||||| ||||||||| ||||||| ||||||||| |||||||| ||||||| ||||||||| - // ||| ||| ||| ||| ||| || || ||| ||| ||| ||| - // |||||||| |||||||| ||||||||| || || ||| |||||||| ||||||| ||| - // ||| || ||| ||| ||| || || ||| ||| ||| ||| - // ||| ||| |||||||| ||| ||| ||||||| ||| |||||||| ||||||| ||| - - /////////////////////////////////////////////////////////////////////////////////////////////// - - // Read the first test - initial begin - string testname; - string tt0; - tt0 = $sformatf("%s", Tests[TestNum]); - testname = {pp, tt0}; - //$display("Here you are %s", testname); - // clear the vectors - for(int i=0; i 64 bit conversions to the to-be-tested list + Tests = {Tests, f128f64cvt}; + // add the op-ctrls (i.e. the format of the result) + OpCtrl = {OpCtrl, 3'b01, 3'b11}; + 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}; + end + for(int i = 0; i<5; i++) begin + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b01}; + end + end + if (P.F_SUPPORTED) begin // if single precision is supported + // add the 128 <-> 32 bit conversions to the to-be-tested list + Tests = {Tests, f128f32cvt}; + // add the op-ctrls (i.e. the format of the result) + OpCtrl = {OpCtrl, 3'b00, 3'b11}; + 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}; + end + for(int i = 0; i<5; i++) begin + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b00}; + end + end + if (P.ZFH_SUPPORTED) begin // if half precision is supported + // add the 128 <-> 16 bit conversions to the to-be-tested list + Tests = {Tests, f128f16cvt}; + // add the op-ctrls (i.e. the format of the result) + OpCtrl = {OpCtrl, 3'b10, 3'b11}; + 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}; + end + for(int i = 0; i<5; i++) begin + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b10}; + end + end end - else if (UnitVal === `CVTFPUNIT) begin - case (OpCtrlVal[1:0]) - 2'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]); - end - 2'b01: begin // double - AnsNaN = &Ans[P.D_LEN-2:P.D_NF]&(|Ans[P.D_NF-1:0]); - ResNaN = &Res[P.D_LEN-2:P.D_NF]&(|Res[P.D_NF-1:0]); - end - 2'b00: begin // single - AnsNaN = &Ans[P.S_LEN-2:P.S_NF]&(|Ans[P.S_NF-1:0]); - ResNaN = &Res[P.S_LEN-2:P.S_NF]&(|Res[P.S_NF-1:0]); - end - 2'b10: begin // half - 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 + 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}; + WriteInt = {WriteInt, 1'b0, 1'b0, 1'b0}; + for(int i = 0; i<15; i++) begin + Unit = {Unit, `CMPUNIT}; + Fmt = {Fmt, 2'b11}; + end end - else begin - case (FmtVal) - 2'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]); - end - 2'b01: begin // double - AnsNaN = &Ans[P.D_LEN-2:P.D_NF]&(|Ans[P.D_NF-1:0]); - ResNaN = &Res[P.D_LEN-2:P.D_NF]&(|Res[P.D_NF-1:0]); - end - 2'b00: begin // single - AnsNaN = &Ans[P.S_LEN-2:P.S_NF]&(|Ans[P.S_NF-1:0]); - ResNaN = &Res[P.S_LEN-2:P.S_NF]&(|Res[P.S_NF-1:0]); - end - 2'b10: begin // half - 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 + 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}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b11}; + end end - end - - always_comb begin - FpResExtended = {{(P.Q_LEN-P.FLEN){1'b1}}, FpRes}; - // select the result to check - case (UnitVal) - `FMAUNIT: Res = FpResExtended; - `DIVUNIT: Res = FpResExtended; - `CMPUNIT: Res = {{(Q_LEN-XLEN){1'b0}}, CmpRes}; - `CVTINTUNIT: if (WriteIntVal) Res = {{(Q_LEN-XLEN){1'b0}}, IntRes}; else Res = FpResExtended; - `CVTFPUNIT: Res = FpResExtended; + 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}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b11}; + end + 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}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b11}; + end + 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}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `DIVUNIT}; + Fmt = {Fmt, 2'b11}; + end + 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}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `DIVUNIT}; + Fmt = {Fmt, 2'b11}; + end + 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}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b11}; + end + 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 + 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}; + 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}; + end + if (P.XLEN == 64) begin // if 64-bit integers are being supported + Tests = {Tests, f64rv64cvtint}; + // add the op-codes for these tests to the op-code list + OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; + 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}; + end + end + 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}; + // add the op-ctrls (i.e. the format of the result) + OpCtrl = {OpCtrl, 3'b00, 3'b01}; + 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}; + end + for(int i = 0; i<5; i++) begin + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b00}; + end + end + if (P.ZFH_SUPPORTED) begin // if half precision is supported + // add the 64 <-> 16 bit conversions to the to-be-tested list + Tests = {Tests, f64f16cvt}; + // add the op-ctrls (i.e. the format of the result) + OpCtrl = {OpCtrl, 3'b10, 3'b01}; + 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}; + end + for(int i = 0; i<5; i++) begin + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b10}; + end + end + 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}; + WriteInt = {WriteInt, 1'b0, 1'b0, 1'b0}; + for(int i = 0; i<15; i++) begin + Unit = {Unit, `CMPUNIT}; + Fmt = {Fmt, 2'b01}; + end + 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}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b01}; + end + 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}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b01}; + end + 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}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b01}; + end + 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}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `DIVUNIT}; + Fmt = {Fmt, 2'b01}; + end + 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}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `DIVUNIT}; + Fmt = {Fmt, 2'b01}; + end + 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}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b01}; + end + 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 + 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}; + 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}; + end + if (P.XLEN == 64) begin // if 64-bit integers are supported + Tests = {Tests, f32rv64cvtint}; + // add the op-codes for these tests to the op-code list + OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; + 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}; + end + end + 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}; + // add the op-ctrls (i.e. the format of the result) + OpCtrl = {OpCtrl, 3'b10, 3'b00}; + 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}; + end + for(int i = 0; i<5; i++) begin + Unit = {Unit, `CVTFPUNIT}; + Fmt = {Fmt, 2'b10}; + end + end + 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}; + WriteInt = {WriteInt, 1'b0, 1'b0, 1'b0}; + for(int i = 0; i<15; i++) begin + Unit = {Unit, `CMPUNIT}; + Fmt = {Fmt, 2'b00}; + end + 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}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b00}; + end + 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}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b00}; + end + 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}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b00}; + end + 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}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `DIVUNIT}; + Fmt = {Fmt, 2'b00}; + end + 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}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `DIVUNIT}; + Fmt = {Fmt, 2'b00}; + end + end + if (TEST === "fma" | TEST === "all") begin // if fma is being tested + Tests = {Tests, f32fma}; + OpCtrl = {OpCtrl, `FMA_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b00}; + end + 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 + 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}; + 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}; + end + if (P.XLEN == 64) begin // if 64-bit integers are supported + Tests = {Tests, f16rv64cvtint}; + // add the op-codes for these tests to the op-code list + OpCtrl = {OpCtrl, `FROM_UL_OPCTRL, `FROM_L_OPCTRL, `TO_UL_OPCTRL, `TO_L_OPCTRL}; + 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}; + end + end + 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}; + WriteInt = {WriteInt, 1'b0, 1'b0, 1'b0}; + for(int i = 0; i<15; i++) begin + Unit = {Unit, `CMPUNIT}; + Fmt = {Fmt, 2'b10}; + end + 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}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b10}; + end + 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}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b10}; + end + 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}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b10}; + end + 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}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `DIVUNIT}; + Fmt = {Fmt, 2'b10}; + end + 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}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `DIVUNIT}; + Fmt = {Fmt, 2'b10}; + end + end + if (TEST === "fma" | TEST === "all") begin // if fma is being tested + Tests = {Tests, f16fma}; + OpCtrl = {OpCtrl, `FMA_OPCTRL}; + WriteInt = {WriteInt, 1'b0}; + for(int i = 0; i<5; i++) begin + Unit = {Unit, `FMAUNIT}; + Fmt = {Fmt, 2'b10}; + end + end + end + // check if nothing is being tested + if (Tests.size() == 0) begin + $display("TEST %s not supported in this configuration", TEST); +`ifdef QUESTA + $stop; // if this is changed to $finish for Questa, wally.do terminates without allowing GUI debug +`else + $finish; +`endif + end + end + + /////////////////////////////////////////////////////////////////////////////////////////////// + + // ||||||||| |||||||| ||||||||| ||||||| ||||||||| |||||||| ||||||| ||||||||| + // ||| ||| ||| ||| ||| || || ||| ||| ||| ||| + // |||||||| |||||||| ||||||||| || || ||| |||||||| ||||||| ||| + // ||| || ||| ||| ||| || || ||| ||| ||| ||| + // ||| ||| |||||||| ||| ||| ||||||| ||| |||||||| ||||||| ||| + + /////////////////////////////////////////////////////////////////////////////////////////////// + + // Read the first test + initial begin + string testname; + string tt0; + tt0 = $sformatf("%s", Tests[TestNum]); + testname = {pp, tt0}; + //$display("Here you are %s", testname); + // clear the vectors + for(int i=0; i quad - X = {P.Q_LEN{1'bx}}; - SrcA = TestVector[8+P.Q_LEN+P.XLEN-1:8+(P.Q_LEN)]; - Ans = TestVector[8+(P.Q_LEN-1):8]; - end - 2'b10: begin // int -> quad - // correctly sign extend the integer depending on if it's a signed/unsigned test - X = {P.Q_LEN{1'bx}}; - SrcA = {{P.XLEN-32{TestVector[8+P.Q_LEN+32-1]}}, TestVector[8+P.Q_LEN+32-1:8+(P.Q_LEN)]}; - Ans = TestVector[8+(P.Q_LEN-1):8]; - end - 2'b01: begin // quad -> long - X = {TestVector[8+P.XLEN+P.Q_LEN-1:8+(P.XLEN)]}; - SrcA = {P.XLEN{1'bx}}; - Ans = {{(P.Q_LEN-64){1'b0}}, TestVector[8+(64-1):8]}; - end - 2'b00: begin // quad -> int - X = {TestVector[8+32+P.Q_LEN-1:8+(32)]}; - SrcA = {P.XLEN{1'bx}}; - Ans = {{(P.Q_LEN-32){TestVector[8+32-1]}},TestVector[8+(32-1):8]}; - end - endcase - end - 2'b01: if (P.D_SUPPORTED) begin // double - // {Int->Fp?, is the integer a long} - casez ({OpCtrl[2:1]}) - 2'b11: begin // long -> double - X = {P.Q_LEN{1'bx}}; - SrcA = TestVector[8+P.D_LEN+P.XLEN-1:8+(P.D_LEN)]; - Ans = {{P.Q_LEN-P.D_LEN{1'b1}}, TestVector[8+(P.D_LEN-1):8]}; - end - 2'b10: begin // int -> double - // correctly sign extend the integer depending on if it's a signed/unsigned test - X = {P.Q_LEN{1'bx}}; - SrcA = {{P.XLEN-32{TestVector[8+P.D_LEN+32-1]}}, TestVector[8+P.D_LEN+32-1:8+(P.D_LEN)]}; - Ans = {{P.Q_LEN-P.D_LEN{1'b1}}, TestVector[8+(P.D_LEN-1):8]}; - end - 2'b01: begin // double -> long - X = {{P.Q_LEN-P.D_LEN{1'b1}}, TestVector[8+P.XLEN+P.D_LEN-1:8+(P.XLEN)]}; - SrcA = {P.XLEN{1'bx}}; - Ans = {{(P.Q_LEN-64){1'b0}}, TestVector[8+(64-1):8]}; - end - 2'b00: begin // double -> int - X = {{P.Q_LEN-P.D_LEN{1'b1}}, TestVector[8+32+P.D_LEN-1:8+(32)]}; - SrcA = {P.XLEN{1'bx}}; - Ans = {{P.Q_LEN-32{TestVector[8+32-1]}},TestVector[8+(32-1):8]}; - end - endcase - end - 2'b00: if (P.F_SUPPORTED) begin // single - // {is the integer a long, is the opperation to an integer} - casez ({OpCtrl[2:1]}) - 2'b11: begin // long -> single - X = {P.Q_LEN{1'bx}}; - SrcA = TestVector[8+P.S_LEN+P.XLEN-1:8+(P.S_LEN)]; - Ans = {{P.Q_LEN-P.S_LEN{1'b1}}, TestVector[8+(P.S_LEN-1):8]}; - end - 2'b10: begin // int -> single - // correctly sign extend the integer depending on if it's a signed/unsigned test - X = {P.Q_LEN{1'bx}}; - SrcA = {{P.XLEN-32{TestVector[8+P.S_LEN+32-1]}}, TestVector[8+P.S_LEN+32-1:8+(P.S_LEN)]}; - Ans = {{P.Q_LEN-P.S_LEN{1'b1}}, TestVector[8+(P.S_LEN-1):8]}; - end - 2'b01: begin // single -> long - X = {{P.Q_LEN-P.S_LEN{1'b1}}, TestVector[8+P.XLEN+P.S_LEN-1:8+(P.XLEN)]}; - SrcA = {P.XLEN{1'bx}}; - Ans = {{(P.Q_LEN-64){1'b0}}, TestVector[8+(64-1):8]}; - end - 2'b00: begin // single -> int - X = {{P.Q_LEN-P.S_LEN{1'b1}}, TestVector[8+32+P.S_LEN-1:8+(32)]}; - SrcA = {P.XLEN{1'bx}}; - Ans = {{(P.Q_LEN-32){TestVector[8+32-1]}},TestVector[8+(32-1):8]}; - end - endcase - end - 2'b10: begin // half - // {is the integer a long, is the opperation to an integer} - casez ({OpCtrl[2:1]}) - 2'b11: begin // long -> half - X = {P.Q_LEN{1'bx}}; - SrcA = TestVector[8+P.H_LEN+P.XLEN-1:8+(P.H_LEN)]; - Ans = {{P.Q_LEN-P.H_LEN{1'b1}}, TestVector[8+(P.H_LEN-1):8]}; - end - 2'b10: begin // int -> half - // correctly sign extend the integer depending on if it's a signed/unsigned test - X = {P.Q_LEN{1'bx}}; - SrcA = {{P.XLEN-32{TestVector[8+P.H_LEN+32-1]}}, TestVector[8+P.H_LEN+32-1:8+(P.H_LEN)]}; - Ans = {{P.Q_LEN-P.H_LEN{1'b1}}, TestVector[8+(P.H_LEN-1):8]}; - end - 2'b01: begin // half -> long - X = {{P.Q_LEN-P.H_LEN{1'b1}}, TestVector[8+P.XLEN+P.H_LEN-1:8+(P.XLEN)]}; - SrcA = {P.XLEN{1'bx}}; - Ans = {{(P.Q_LEN-64){1'b0}}, TestVector[8+(64-1):8]}; - end - 2'b00: begin // half -> int - X = {{P.Q_LEN-P.H_LEN{1'b1}}, TestVector[8+32+P.H_LEN-1:8+(32)]}; - SrcA = {P.XLEN{1'bx}}; - Ans = {{(P.Q_LEN-32){TestVector[8+32-1]}}, TestVector[8+(32-1):8]}; - end - endcase - end - endcase - endcase - end + end + 2'b00: if (P.F_SUPPORTED) begin // single + case (OpCtrl[1:0]) + 2'b11: begin // quad + X = {{P.Q_LEN-P.S_LEN{1'b1}}, TestVector[8+P.S_LEN+P.Q_LEN-1:8+(P.Q_LEN)]}; + Ans = TestVector[8+(P.Q_LEN-1):8]; + end + 2'b01: if (P.D_SUPPORTED) begin // double + X = {{P.Q_LEN-P.S_LEN{1'b1}}, TestVector[8+P.S_LEN+P.D_LEN-1:8+(P.D_LEN)]}; + Ans = {{P.Q_LEN-P.D_LEN{1'b1}}, TestVector[8+(P.D_LEN-1):8]}; + end + 2'b00: begin // single + X = {{P.Q_LEN-P.S_LEN{1'b1}}, TestVector[8+P.S_LEN+P.S_LEN-1:8+(P.S_LEN)]}; + Ans = {{P.Q_LEN-P.S_LEN{1'b1}}, TestVector[8+(P.S_LEN-1):8]}; + end + 2'b10: begin // half + X = {{P.Q_LEN-P.S_LEN{1'b1}}, TestVector[8+P.S_LEN+P.H_LEN-1:8+(P.H_LEN)]}; + Ans = {{P.Q_LEN-P.H_LEN{1'b1}}, TestVector[8+(P.H_LEN-1):8]}; + end + endcase + end + 2'b10: begin // half + case (OpCtrl[1:0]) + 2'b11: begin // quad + X = {{P.Q_LEN-P.H_LEN{1'b1}}, TestVector[8+P.H_LEN+P.Q_LEN-1:8+(P.Q_LEN)]}; + Ans = TestVector[8+(P.Q_LEN-1):8]; + end + 2'b01: if (P.D_SUPPORTED) begin // double + X = {{P.Q_LEN-P.H_LEN{1'b1}}, TestVector[8+P.H_LEN+P.D_LEN-1:8+(P.D_LEN)]}; + Ans = {{P.Q_LEN-P.D_LEN{1'b1}}, TestVector[8+(P.D_LEN-1):8]}; + end + 2'b00: if (P.F_SUPPORTED) begin // single + X = {{P.Q_LEN-P.H_LEN{1'b1}}, TestVector[8+P.H_LEN+P.S_LEN-1:8+(P.S_LEN)]}; + Ans = {{P.Q_LEN-P.S_LEN{1'b1}}, TestVector[8+(P.S_LEN-1):8]}; + end + 2'b10: begin // half + X = {{P.Q_LEN-P.H_LEN{1'b1}}, TestVector[8+P.H_LEN+P.H_LEN-1:8+(P.H_LEN)]}; + Ans = {{P.Q_LEN-P.H_LEN{1'b1}}, TestVector[8+(P.H_LEN-1):8]}; + end + endcase + end + endcase + `CVTINTUNIT: + case (Fmt) + 2'b11: begin // quad + // {is the integer a long, is the opperation to an integer} + casez ({OpCtrl[2:1]}) + 2'b11: begin // long -> quad + X = {P.Q_LEN{1'bx}}; + SrcA = TestVector[8+P.Q_LEN+P.XLEN-1:8+(P.Q_LEN)]; + Ans = TestVector[8+(P.Q_LEN-1):8]; + end + 2'b10: begin // int -> quad + // correctly sign extend the integer depending on if it's a signed/unsigned test + X = {P.Q_LEN{1'bx}}; + SrcA = {{P.XLEN-32{TestVector[8+P.Q_LEN+32-1]}}, TestVector[8+P.Q_LEN+32-1:8+(P.Q_LEN)]}; + Ans = TestVector[8+(P.Q_LEN-1):8]; + end + 2'b01: begin // quad -> long + X = {TestVector[8+P.XLEN+P.Q_LEN-1:8+(P.XLEN)]}; + SrcA = {P.XLEN{1'bx}}; + Ans = {{(P.Q_LEN-64){1'b0}}, TestVector[8+(64-1):8]}; + end + 2'b00: begin // quad -> int + X = {TestVector[8+32+P.Q_LEN-1:8+(32)]}; + SrcA = {P.XLEN{1'bx}}; + Ans = {{(P.Q_LEN-32){TestVector[8+32-1]}},TestVector[8+(32-1):8]}; + end + endcase + end + 2'b01: if (P.D_SUPPORTED) begin // double + // {Int->Fp?, is the integer a long} + casez ({OpCtrl[2:1]}) + 2'b11: begin // long -> double + X = {P.Q_LEN{1'bx}}; + SrcA = TestVector[8+P.D_LEN+P.XLEN-1:8+(P.D_LEN)]; + Ans = {{P.Q_LEN-P.D_LEN{1'b1}}, TestVector[8+(P.D_LEN-1):8]}; + end + 2'b10: begin // int -> double + // correctly sign extend the integer depending on if it's a signed/unsigned test + X = {P.Q_LEN{1'bx}}; + SrcA = {{P.XLEN-32{TestVector[8+P.D_LEN+32-1]}}, TestVector[8+P.D_LEN+32-1:8+(P.D_LEN)]}; + Ans = {{P.Q_LEN-P.D_LEN{1'b1}}, TestVector[8+(P.D_LEN-1):8]}; + end + 2'b01: begin // double -> long + X = {{P.Q_LEN-P.D_LEN{1'b1}}, TestVector[8+P.XLEN+P.D_LEN-1:8+(P.XLEN)]}; + SrcA = {P.XLEN{1'bx}}; + Ans = {{(P.Q_LEN-64){1'b0}}, TestVector[8+(64-1):8]}; + end + 2'b00: begin // double -> int + X = {{P.Q_LEN-P.D_LEN{1'b1}}, TestVector[8+32+P.D_LEN-1:8+(32)]}; + SrcA = {P.XLEN{1'bx}}; + Ans = {{P.Q_LEN-32{TestVector[8+32-1]}},TestVector[8+(32-1):8]}; + end + endcase + end + 2'b00: if (P.F_SUPPORTED) begin // single + // {is the integer a long, is the opperation to an integer} + casez ({OpCtrl[2:1]}) + 2'b11: begin // long -> single + X = {P.Q_LEN{1'bx}}; + SrcA = TestVector[8+P.S_LEN+P.XLEN-1:8+(P.S_LEN)]; + Ans = {{P.Q_LEN-P.S_LEN{1'b1}}, TestVector[8+(P.S_LEN-1):8]}; + end + 2'b10: begin // int -> single + // correctly sign extend the integer depending on if it's a signed/unsigned test + X = {P.Q_LEN{1'bx}}; + SrcA = {{P.XLEN-32{TestVector[8+P.S_LEN+32-1]}}, TestVector[8+P.S_LEN+32-1:8+(P.S_LEN)]}; + Ans = {{P.Q_LEN-P.S_LEN{1'b1}}, TestVector[8+(P.S_LEN-1):8]}; + end + 2'b01: begin // single -> long + X = {{P.Q_LEN-P.S_LEN{1'b1}}, TestVector[8+P.XLEN+P.S_LEN-1:8+(P.XLEN)]}; + SrcA = {P.XLEN{1'bx}}; + Ans = {{(P.Q_LEN-64){1'b0}}, TestVector[8+(64-1):8]}; + end + 2'b00: begin // single -> int + X = {{P.Q_LEN-P.S_LEN{1'b1}}, TestVector[8+32+P.S_LEN-1:8+(32)]}; + SrcA = {P.XLEN{1'bx}}; + Ans = {{(P.Q_LEN-32){TestVector[8+32-1]}},TestVector[8+(32-1):8]}; + end + endcase + end + 2'b10: begin // half + // {is the integer a long, is the opperation to an integer} + casez ({OpCtrl[2:1]}) + 2'b11: begin // long -> half + X = {P.Q_LEN{1'bx}}; + SrcA = TestVector[8+P.H_LEN+P.XLEN-1:8+(P.H_LEN)]; + Ans = {{P.Q_LEN-P.H_LEN{1'b1}}, TestVector[8+(P.H_LEN-1):8]}; + end + 2'b10: begin // int -> half + // correctly sign extend the integer depending on if it's a signed/unsigned test + X = {P.Q_LEN{1'bx}}; + SrcA = {{P.XLEN-32{TestVector[8+P.H_LEN+32-1]}}, TestVector[8+P.H_LEN+32-1:8+(P.H_LEN)]}; + Ans = {{P.Q_LEN-P.H_LEN{1'b1}}, TestVector[8+(P.H_LEN-1):8]}; + end + 2'b01: begin // half -> long + X = {{P.Q_LEN-P.H_LEN{1'b1}}, TestVector[8+P.XLEN+P.H_LEN-1:8+(P.XLEN)]}; + SrcA = {P.XLEN{1'bx}}; + Ans = {{(P.Q_LEN-64){1'b0}}, TestVector[8+(64-1):8]}; + end + 2'b00: begin // half -> int + X = {{P.Q_LEN-P.H_LEN{1'b1}}, TestVector[8+32+P.H_LEN-1:8+(32)]}; + SrcA = {P.XLEN{1'bx}}; + Ans = {{(P.Q_LEN-32){TestVector[8+32-1]}}, TestVector[8+(32-1):8]}; + end + endcase + end + endcase + endcase + end - assign XEn = ~((Unit == `CVTINTUNIT)&OpCtrl[2]); - assign YEn = ~((Unit == `CVTINTUNIT)|(Unit == `CVTFPUNIT)|((Unit == `DIVUNIT)&OpCtrl[0])); - assign ZEn = (Unit == `FMAUNIT); - assign FPUActive = 1'b1; - - unpack #(P) unpack(.X(X[P.FLEN-1:0]), .Y(Y[P.FLEN-1:0]), .Z(Z[P.FLEN-1:0]), .Fmt(ModFmt), .FPUActive, .Xs, .Ys, .Zs, .Xe, .Ye, .Ze, - .Xm, .Ym, .Zm, .XNaN, .YNaN, .ZNaN, .XSNaN, .YSNaN, .ZSNaN, - .XSubnorm, .XZero, .YZero, .ZZero, .XInf, .YInf, .ZInf, - .XEn, .YEn, .ZEn, .XExpMax, .XPostBox, .Bias(BiasE), .Nf(NfE)); + assign XEn = ~((Unit == `CVTINTUNIT)&OpCtrl[2]); + assign YEn = ~((Unit == `CVTINTUNIT)|(Unit == `CVTFPUNIT)|((Unit == `DIVUNIT)&OpCtrl[0])); + assign ZEn = (Unit == `FMAUNIT); + assign FPUActive = 1'b1; + unpack #(P) unpack(.X(X[P.FLEN-1:0]), .Y(Y[P.FLEN-1:0]), .Z(Z[P.FLEN-1:0]), .Fmt(ModFmt), .FPUActive, .Xs, .Ys, .Zs, .Xe, .Ye, .Ze, + .Xm, .Ym, .Zm, .XNaN, .YNaN, .ZNaN, .XSNaN, .YSNaN, .ZSNaN, + .XSubnorm, .XZero, .YZero, .ZZero, .XInf, .YInf, .ZInf, + .XEn, .YEn, .ZEn, .XExpMax, .XPostBox, .Bias(BiasE), .Nf(NfE)); endmodule