/////////////////////////////////////////// // // 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 // // Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file // except in compliance with the License, or, at your option, the Apache License version 2.0. You // may obtain a copy of the License at // // https://solderpad.org/licenses/SHL-2.1/ // // Unless required by applicable law or agreed to in writing, any work distributed under the // License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, // either express or implied. See the License for the specific language governing permissions // and limitations under the License. //////////////////////////////////////////////////////////////////////////////////////////////// `include "config.vh" `include "tests_fp.vh" 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"; `include "parameter-defs.vh" 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, 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 `else $finish; `endif end end /////////////////////////////////////////////////////////////////////////////////////////////// // ||||||||| |||||||| ||||||||| ||||||| ||||||||| |||||||| ||||||| ||||||||| // ||| ||| ||| ||| ||| || || ||| ||| ||| ||| // |||||||| |||||||| ||||||||| || || ||| |||||||| ||||||| ||| // ||| || ||| ||| ||| || || ||| ||| ||| ||| // ||| ||| |||||||| ||| ||| ||||||| ||| |||||||| ||||||| ||| /////////////////////////////////////////////////////////////////////////////////////////////// // Read the first test initial begin static string pp = `PATH; 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 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