cvw/pipelined/testbench/testbench-fp.sv

1543 lines
86 KiB
Systemverilog
Raw Normal View History

2022-05-19 16:32:30 +00:00
`include "wally-config.vh"
`include "tests-fp.vh"
// steps to run FMA Tests
// 1) create test vectors in riscv-wally/Tests/fp with: ./run-all.sh
// 2) go to riscv-wally/pipelined/testbench/fp/Tests
// 3) run ./sim-fma-batch
//*** drop the any constants in each file and figure out a way to do them without the code
module testbenchfp;
parameter TEST="none";
string Tests[];
logic [2:0] OpCtrl[];
logic [2:0] Unit[];
string FmaRneTests[];
string FmaRuTests[];
string FmaRdTests[];
string FmaRzTests[];
string FmaRnmTests[];
logic [2:0] Frm[4:0] = {3'b100, 3'b010, 3'b011, 3'b001, 3'b000}; // rne, rz, ru, rd, rnm
logic [1:0] Fmt[];
logic [1:0] FmaFmt[];
logic clk=0;
logic [31:0] TestNum=0;
logic [31:0] OpCtrlNum=0;
logic [31:0] errors=0;
logic [31:0] VectorNum=0;
logic [31:0] FrmNum=0;
logic [31:0] FmaNum=0;
logic [`FLEN*4+7:0] TestVectors[46464:0];
logic [`FLEN*4+7:0] FmaRneVectors[6133248:0];
logic [`FLEN*4+7:0] FmaRuVectors[6133248:0];
logic [`FLEN*4+7:0] FmaRdVectors[6133248:0];
logic [`FLEN*4+7:0] FmaRzVectors[6133248:0];
logic [`FLEN*4+7:0] FmaRnmVectors[6133248:0];
logic [1:0] FmaFmtVal, FmtVal;
logic [2:0] UnitVal, OpCtrlVal, FrmVal;
logic NaNGood;
logic ZOrigDenorm, FmaRneZOrigDenorm, FmaRzZOrigDenorm, FmaRuZOrigDenorm, FmaRdZOrigDenorm, FmaRnmZOrigDenorm;
2022-05-19 16:32:30 +00:00
logic FmaRneNaNGood, FmaRzNaNGood, FmaRuNaNGood, FmaRdNaNGood, FmaRnmNaNGood;
logic [`FLEN-1:0] X, Y, Z; // inputs read from TestFloat
logic [`FLEN-1:0] FmaRneX, FmaRneY, FmaRneZ; // inputs read from TestFloat
logic [`FLEN-1:0] FmaRzX, FmaRzY, FmaRzZ; // inputs read from TestFloat
logic [`FLEN-1:0] FmaRuX, FmaRuY, FmaRuZ; // inputs read from TestFloat
logic [`FLEN-1:0] FmaRdX, FmaRdY, FmaRdZ; // inputs read from TestFloat
logic [`FLEN-1:0] FmaRnmX, FmaRnmY, FmaRnmZ; // inputs read from TestFloat
logic [`XLEN-1:0] SrcA; // integer input
logic [`FLEN-1:0] Ans; // result from TestFloat
logic [`FLEN-1:0] FmaRneAns, FmaRzAns, FmaRuAns, FmaRdAns, FmaRnmAns; // flags read form testfloat
logic [`FLEN-1:0] Res;
logic [`FLEN-1:0] FmaRneRes, FmaRzRes, FmaRuRes, FmaRdRes, FmaRnmRes; // result from Units
logic [4:0] AnsFlags; // flags read form testfloat
logic [4:0] FmaRneAnsFlags, FmaRzAnsFlags, FmaRuAnsFlags, FmaRdAnsFlags, FmaRnmAnsFlags; // flags read form testfloat
logic [4:0] ResFlags; // Res's flags
logic [4:0] FmaRneResFlags, FmaRzResFlags, FmaRuResFlags, FmaRdResFlags, FmaRnmResFlags; // flags read form testfloat
logic [2:0] FrmE; // rounding mode
logic [`FPSIZES/3:0] ModFmt, FmaModFmt; // format - 10 = half, 00 = single, 01 = double, 11 = quad
logic [3:0] FpuUnit; // Which unit is being tested
logic [`FLEN-1:0] FMAResM, DivResM, CmpResE, CvtResE, CvtFpResE; // Ress
logic [4:0] FMAFlgM, CvtFpFlgM, DivFlgM, CvtIntFlgM, CmpFlgM; // FMA's outputed flags
logic CmpNVE;
logic ResNaN, FmaRneResNaN, FmaRzResNaN, FmaRuResNaN, FmaRdResNaN, FmaRnmResNaN; // is the outputed result NaN
logic AnsNaN, FmaRneAnsNaN, FmaRzAnsNaN, FmaRuAnsNaN, FmaRdAnsNaN, FmaRnmAnsNaN; // is the correct answer NaN
logic [`NE+1:0] ProdExpE, FmaRneProdExp, FmaRzProdExp, FmaRuProdExp, FmaRdProdExp, FmaRnmProdExp;
logic AddendStickyE, FmaRneAddendSticky, FmaRzAddendSticky, FmaRuAddendSticky, FmaRdAddendSticky, FmaRnmAddendSticky;
logic KillProdE, FmaRneKillProd, FmaRzKillProd, FmaRuKillProd, FmaRdKillProd, FmaRnmKillProd;
logic XSgn, YSgn, ZSgn;
logic FmaRneXSgn, FmaRneYSgn, FmaRneZSgn;
logic FmaRzXSgn, FmaRzYSgn, FmaRzZSgn;
logic FmaRuXSgn, FmaRuYSgn, FmaRuZSgn;
logic FmaRdXSgn, FmaRdYSgn, FmaRdZSgn;
logic FmaRnmXSgn, FmaRnmYSgn, FmaRnmZSgn;
logic [`NE-1:0] XExp, YExp, ZExp;
logic [`NE-1:0] FmaRneXExp, FmaRneYExp, FmaRneZExp;
logic [`NE-1:0] FmaRzXExp, FmaRzYExp, FmaRzZExp;
logic [`NE-1:0] FmaRuXExp, FmaRuYExp, FmaRuZExp;
logic [`NE-1:0] FmaRdXExp, FmaRdYExp, FmaRdZExp;
logic [`NE-1:0] FmaRnmXExp, FmaRnmYExp, FmaRnmZExp;
logic [`NF:0] XMan, YMan, ZMan;
logic [`NF:0] FmaRneXMan, FmaRneYMan, FmaRneZMan;
logic [`NF:0] FmaRzXMan, FmaRzYMan, FmaRzZMan;
logic [`NF:0] FmaRuXMan, FmaRuYMan, FmaRuZMan;
logic [`NF:0] FmaRdXMan, FmaRdYMan, FmaRdZMan;
logic [`NF:0] FmaRnmXMan, FmaRnmYMan, FmaRnmZMan;
logic XNorm;
logic XExpMaxE;
logic XNaN, YNaN, ZNaN;
logic FmaRneXNaN, FmaRneYNaN, FmaRneZNaN;
logic FmaRzXNaN, FmaRzYNaN, FmaRzZNaN;
logic FmaRuXNaN, FmaRuYNaN, FmaRuZNaN;
logic FmaRdXNaN, FmaRdYNaN, FmaRdZNaN;
logic FmaRnmXNaN, FmaRnmYNaN, FmaRnmZNaN;
logic XSNaN, YSNaN, ZSNaN;
logic FmaRneXSNaN, FmaRneYSNaN, FmaRneZSNaN;
logic FmaRzXSNaN, FmaRzYSNaN, FmaRzZSNaN;
logic FmaRuXSNaN, FmaRuYSNaN, FmaRuZSNaN;
logic FmaRdXSNaN, FmaRdYSNaN, FmaRdZSNaN;
logic FmaRnmXSNaN, FmaRnmYSNaN, FmaRnmZSNaN;
logic XDenorm, YDenorm, ZDenorm;
logic FmaRneXDenorm, FmaRneYDenorm, FmaRneZDenorm;
logic FmaRzXDenorm, FmaRzYDenorm, FmaRzZDenorm;
logic FmaRuXDenorm, FmaRuYDenorm, FmaRuZDenorm;
logic FmaRdXDenorm, FmaRdYDenorm, FmaRdZDenorm;
logic FmaRnmXDenorm, FmaRnmYDenorm, FmaRnmZDenorm;
logic XInf, YInf, ZInf;
logic FmaRneXInf, FmaRneYInf, FmaRneZInf;
logic FmaRzXInf, FmaRzYInf, FmaRzZInf;
logic FmaRuXInf, FmaRuYInf, FmaRuZInf;
logic FmaRdXInf, FmaRdYInf, FmaRdZInf;
logic FmaRnmXInf, FmaRnmYInf, FmaRnmZInf;
logic XZero, YZero, ZZero;
logic FmaRneXZero, FmaRneYZero, FmaRneZZero;
logic FmaRzXZero, FmaRzYZero, FmaRzZZero;
logic FmaRuXZero, FmaRuYZero, FmaRuZZero;
logic FmaRdXZero, FmaRdYZero, FmaRdZZero;
logic FmaRnmXZero, FmaRnmYZero, FmaRnmZZero;
logic XExpMax, YExpMax, ZExpMax, Mult;
logic [3*`NF+5:0] SumE, FmaRneSum, FmaRzSum, FmaRuSum, FmaRdSum, FmaRnmSum;
logic InvZE, FmaRneInvZ, FmaRzInvZ, FmaRuInvZ, FmaRdInvZ, FmaRnmInvZ;
logic NegSumE, FmaRneNegSum, FmaRzNegSum, FmaRuNegSum, FmaRdNegSum, FmaRnmNegSum;
logic ZSgnEffE, FmaRneZSgnEff, FmaRzZSgnEff, FmaRuZSgnEff, FmaRdZSgnEff, FmaRnmZSgnEff;
logic PSgnE, FmaRnePSgn, FmaRzPSgn, FmaRuPSgn, FmaRdPSgn, FmaRnmPSgn;
logic [$clog2(3*`NF+7)-1:0] NormCntE, FmaRneNormCnt, FmaRzNormCnt, FmaRuNormCnt, FmaRdNormCnt, FmaRnmNormCnt;
///////////////////////////////////////////////////////////////////////////////////////////////
// ||||||||| |||||||| ||||||| ||||||||| ||||||| |||||||| |||
// ||| ||| ||| ||| ||| ||| |||
// ||| |||||||| ||||||| ||| ||||||| |||||||| |||
// ||| ||| ||| ||| ||| ||| |||
// ||| |||||||| ||||||| ||| ||||||| |||||||| |||||||||
///////////////////////////////////////////////////////////////////////////////////////////////
// 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
initial begin
$display("TEST is %s", TEST);
if (`Q_SUPPORTED) 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};
// 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 (`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};
// 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 (TEST === "cvtfp" | TEST === "all") begin // if the floating-point conversions are being tested
if(`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};
// add the unit being tested and fmt (input format)
for(int i = 0; i<10; i++) begin
Unit = {Unit, `CVTFPUNIT};
Fmt = {Fmt, 2'b11};
end
end
if(`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};
// add the unit being tested and fmt (input format)
for(int i = 0; i<10; i++) begin
Unit = {Unit, `CVTFPUNIT};
Fmt = {Fmt, 2'b11};
end
end
if(`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};
// add the unit being tested and fmt (input format)
for(int i = 0; i<10; i++) begin
Unit = {Unit, `CVTFPUNIT};
Fmt = {Fmt, 2'b11};
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};
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};
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};
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};
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};
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};
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
// add each rounding mode to it's own list of tests
// - fma tests are very long, so run all rounding modes in parallel
FmaRneTests = {FmaRneTests, "f128_mulAdd_rne.tv"};
FmaRzTests = {FmaRzTests, "f128_mulAdd_rz.tv"};
FmaRuTests = {FmaRuTests, "f128_mulAdd_ru.tv"};
FmaRdTests = {FmaRdTests, "f128_mulAdd_rd.tv"};
FmaRnmTests = {FmaRnmTests, "f128_mulAdd_rnm.tv"};
// add the format for the Fma
for(int i = 0; i<5; i++) begin
FmaFmt = {FmaFmt, 2'b11};
end
end
end
if (`D_SUPPORTED) 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};
// 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 (`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};
// 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(`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};
// add the unit being tested and fmt (input format)
for(int i = 0; i<10; i++) begin
Unit = {Unit, `CVTFPUNIT};
Fmt = {Fmt, 2'b01};
end
end
if(`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};
// add the unit being tested and fmt (input format)
for(int i = 0; i<10; i++) begin
Unit = {Unit, `CVTFPUNIT};
Fmt = {Fmt, 2'b01};
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};
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};
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};
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};
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};
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};
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
// add each rounding mode to it's own list of tests
// - fma tests are very long, so run all rounding modes in parallel
FmaRneTests = {FmaRneTests, "f64_mulAdd_rne.tv"};
FmaRzTests = {FmaRzTests, "f64_mulAdd_rz.tv"};
FmaRuTests = {FmaRuTests, "f64_mulAdd_ru.tv"};
FmaRdTests = {FmaRdTests, "f64_mulAdd_rd.tv"};
FmaRnmTests = {FmaRnmTests, "f64_mulAdd_rnm.tv"};
for(int i = 0; i<5; i++) begin
FmaFmt = {FmaFmt, 2'b01};
end
end
end
if (`F_SUPPORTED) 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};
// 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 (`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};
// 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(`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};
// add the unit being tested and fmt (input format)
for(int i = 0; i<10; i++) begin
Unit = {Unit, `CVTFPUNIT};
Fmt = {Fmt, 2'b00};
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};
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};
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};
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};
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};
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};
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
// add each rounding mode to it's own list of tests
// - fma tests are very long, so run all rounding modes in parallel
FmaRneTests = {FmaRneTests, "f32_mulAdd_rne.tv"};
FmaRzTests = {FmaRzTests, "f32_mulAdd_rz.tv"};
FmaRuTests = {FmaRuTests, "f32_mulAdd_ru.tv"};
FmaRdTests = {FmaRdTests, "f32_mulAdd_rd.tv"};
FmaRnmTests = {FmaRnmTests, "f32_mulAdd_rnm.tv"};
for(int i = 0; i<5; i++) begin
FmaFmt = {FmaFmt, 2'b00};
end
end
end
if (`ZFH_SUPPORTED) 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};
// 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 (`XLEN == 64) begin // if 64-bit integers are supported
Tests = {Tests, f16rv64cvtint, f16rv32cvtint};
// 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};
// 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};
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};
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};
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};
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};
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};
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
// add each rounding mode to it's own list of tests
// - fma tests are very long, so run all rounding modes in parallel
FmaRneTests = {FmaRneTests, "f16_mulAdd_rne.tv"};
FmaRzTests = {FmaRzTests, "f16_mulAdd_rz.tv"};
FmaRuTests = {FmaRuTests, "f16_mulAdd_ru.tv"};
FmaRdTests = {FmaRdTests, "f16_mulAdd_rd.tv"};
FmaRnmTests = {FmaRnmTests, "f16_mulAdd_rnm.tv"};
for(int i = 0; i<5; i++) begin
FmaFmt = {FmaFmt, 2'b10};
end
end
end
// check if nothing is being tested
if (Tests.size() == 0 & FmaRneTests.size() == 0 & FmaRuTests.size() == 0 & FmaRdTests.size() == 0 & FmaRzTests.size() == 0 & FmaRnmTests.size() == 0) begin
$display("TEST %s not supported in this configuration", TEST);
$stop;
end
end
///////////////////////////////////////////////////////////////////////////////////////////////
// ||||||||| |||||||| ||||||||| ||||||| ||||||||| |||||||| ||||||| |||||||||
// ||| ||| ||| ||| ||| || || ||| ||| ||| |||
// |||||||| |||||||| ||||||||| || || ||| |||||||| ||||||| |||
// ||| || ||| ||| ||| || || ||| ||| ||| |||
// ||| ||| |||||||| ||| ||| ||||||| ||| |||||||| ||||||| |||
///////////////////////////////////////////////////////////////////////////////////////////////
// Read the first test
initial begin
$display("\n\nRunning %s vectors", Tests[TestNum]);
$readmemh({`PATH, Tests[TestNum]}, TestVectors);
$readmemh({`PATH, FmaRneTests[TestNum]}, FmaRneVectors);
$readmemh({`PATH, FmaRuTests[TestNum]}, FmaRuVectors);
$readmemh({`PATH, FmaRdTests[TestNum]}, FmaRdVectors);
$readmemh({`PATH, FmaRzTests[TestNum]}, FmaRzVectors);
$readmemh({`PATH, FmaRnmTests[TestNum]}, FmaRnmVectors);
// set the test index to 0
TestNum = 0;
end
// set a the signals for all tests
always_comb FmaFmtVal = FmaFmt[FmaNum];
always_comb UnitVal = Unit[TestNum];
always_comb FmtVal = Fmt[TestNum];
always_comb OpCtrlVal = OpCtrl[OpCtrlNum];
always_comb FrmVal = Frm[FrmNum];
assign Mult = OpCtrlVal === 3'b100;
// modify the format signal if only 2 percisions supported
// - 1 for the larger precision
// - 0 for the smaller precision
always_comb begin
if(`FPSIZES/3 === 1) ModFmt = FmtVal;
else ModFmt = FmtVal === `FMT;
if(`FPSIZES/3 === 1) FmaModFmt = FmaFmtVal;
else FmaModFmt = FmaFmtVal === `FMT;
end
// extract the inputs (X, Y, Z, SrcA) and the output (Ans, AnsFlags) from the current test vector
readfmavectors readfmarnevectors (.clk, .Frm(`RNE), .TestVector(FmaRneVectors[VectorNum]), .VectorNum, .Ans(FmaRneAns), .AnsFlags(FmaRneAnsFlags),
.XSgnE(FmaRneXSgn), .YSgnE(FmaRneYSgn), .ZSgnE(FmaRneZSgn), .FmaNum,
.XExpE(FmaRneXExp), .YExpE(FmaRneYExp), .ZExpE(FmaRneZExp),
.XManE(FmaRneXMan), .YManE(FmaRneYMan), .ZManE(FmaRneZMan),
.XNaNE(FmaRneXNaN), .YNaNE(FmaRneYNaN), .ZNaNE(FmaRneZNaN), .ZOrigDenormE(FmaRneZOrigDenorm),
2022-05-19 16:32:30 +00:00
.XSNaNE(FmaRneXSNaN), .YSNaNE(FmaRneYSNaN), .ZSNaNE(FmaRneZSNaN),
.XDenormE(FmaRneXDenorm), .YDenormE(FmaRneYDenorm), .ZDenormE(FmaRneZDenorm),
.XZeroE(FmaRneXZero), .YZeroE(FmaRneYZero), .ZZeroE(FmaRneZZero),
.XInfE(FmaRneXInf), .YInfE(FmaRneYInf), .ZInfE(FmaRneZInf), .FmaModFmt, .FmaFmt(FmaFmtVal),
.X(FmaRneX), .Y(FmaRneY), .Z(FmaRneZ));
readfmavectors readfmarzvectors (.clk, .Frm(`RZ), .TestVector(FmaRzVectors[VectorNum]), .VectorNum, .Ans(FmaRzAns), .AnsFlags(FmaRzAnsFlags),
.XSgnE(FmaRzXSgn), .YSgnE(FmaRzYSgn), .ZSgnE(FmaRzZSgn), .FmaNum, .FmaModFmt,
.XExpE(FmaRzXExp), .YExpE(FmaRzYExp), .ZExpE(FmaRzZExp),
.XManE(FmaRzXMan), .YManE(FmaRzYMan), .ZManE(FmaRzZMan),
.XNaNE(FmaRzXNaN), .YNaNE(FmaRzYNaN), .ZNaNE(FmaRzZNaN), .ZOrigDenormE(FmaRzZOrigDenorm),
2022-05-19 16:32:30 +00:00
.XSNaNE(FmaRzXSNaN), .YSNaNE(FmaRzYSNaN), .ZSNaNE(FmaRzZSNaN),
.XDenormE(FmaRzXDenorm), .YDenormE(FmaRzYDenorm), .ZDenormE(FmaRzZDenorm),
.XZeroE(FmaRzXZero), .YZeroE(FmaRzYZero), .ZZeroE(FmaRzZZero),
.XInfE(FmaRzXInf), .YInfE(FmaRzYInf), .ZInfE(FmaRzZInf), .FmaFmt(FmaFmtVal),
.X(FmaRzX), .Y(FmaRzY), .Z(FmaRzZ));
readfmavectors readfmaruvectors (.clk, .Frm(`RU), .TestVector(FmaRuVectors[VectorNum]), .VectorNum, .Ans(FmaRuAns), .AnsFlags(FmaRuAnsFlags),
.XSgnE(FmaRuXSgn), .YSgnE(FmaRuYSgn), .ZSgnE(FmaRuZSgn), .FmaNum, .FmaModFmt,
.XExpE(FmaRuXExp), .YExpE(FmaRuYExp), .ZExpE(FmaRuZExp),
.XManE(FmaRuXMan), .YManE(FmaRuYMan), .ZManE(FmaRuZMan),
.XNaNE(FmaRuXNaN), .YNaNE(FmaRuYNaN), .ZNaNE(FmaRuZNaN), .ZOrigDenormE(FmaRuZOrigDenorm),
2022-05-19 16:32:30 +00:00
.XSNaNE(FmaRuXSNaN), .YSNaNE(FmaRuYSNaN), .ZSNaNE(FmaRuZSNaN),
.XDenormE(FmaRuXDenorm), .YDenormE(FmaRuYDenorm), .ZDenormE(FmaRuZDenorm),
.XZeroE(FmaRuXZero), .YZeroE(FmaRuYZero), .ZZeroE(FmaRuZZero),
.XInfE(FmaRuXInf), .YInfE(FmaRuYInf), .ZInfE(FmaRuZInf), .FmaFmt(FmaFmtVal),
.X(FmaRuX), .Y(FmaRuY), .Z(FmaRuZ));
readfmavectors readfmardvectors (.clk, .Frm(`RD), .TestVector(FmaRdVectors[VectorNum]), .VectorNum, .Ans(FmaRdAns), .AnsFlags(FmaRdAnsFlags),
.XSgnE(FmaRdXSgn), .YSgnE(FmaRdYSgn), .ZSgnE(FmaRdZSgn), .FmaNum, .FmaModFmt,
.XExpE(FmaRdXExp), .YExpE(FmaRdYExp), .ZExpE(FmaRdZExp),
.XManE(FmaRdXMan), .YManE(FmaRdYMan), .ZManE(FmaRdZMan),
.XNaNE(FmaRdXNaN), .YNaNE(FmaRdYNaN), .ZNaNE(FmaRdZNaN), .ZOrigDenormE(FmaRdZOrigDenorm),
2022-05-19 16:32:30 +00:00
.XSNaNE(FmaRdXSNaN), .YSNaNE(FmaRdYSNaN), .ZSNaNE(FmaRdZSNaN),
.XDenormE(FmaRdXDenorm), .YDenormE(FmaRdYDenorm), .ZDenormE(FmaRdZDenorm),
.XZeroE(FmaRdXZero), .YZeroE(FmaRdYZero), .ZZeroE(FmaRdZZero),
.XInfE(FmaRdXInf), .YInfE(FmaRdYInf), .ZInfE(FmaRdZInf), .FmaFmt(FmaFmtVal),
.X(FmaRdX), .Y(FmaRdY), .Z(FmaRdZ));
readfmavectors readfmarnmvectors (.clk, .Frm(`RNM), .TestVector(FmaRnmVectors[VectorNum]), .VectorNum, .Ans(FmaRnmAns), .AnsFlags(FmaRnmAnsFlags),
.XSgnE(FmaRnmXSgn), .YSgnE(FmaRnmYSgn), .ZSgnE(FmaRnmZSgn), .FmaNum, .FmaModFmt,
.XExpE(FmaRnmXExp), .YExpE(FmaRnmYExp), .ZExpE(FmaRnmZExp),
.XManE(FmaRnmXMan), .YManE(FmaRnmYMan), .ZManE(FmaRnmZMan), .ZOrigDenormE(FmaRnmZOrigDenorm),
2022-05-19 16:32:30 +00:00
.XNaNE(FmaRnmXNaN), .YNaNE(FmaRnmYNaN), .ZNaNE(FmaRnmZNaN),
.XSNaNE(FmaRnmXSNaN), .YSNaNE(FmaRnmYSNaN), .ZSNaNE(FmaRnmZSNaN),
.XDenormE(FmaRnmXDenorm), .YDenormE(FmaRnmYDenorm), .ZDenormE(FmaRnmZDenorm),
.XZeroE(FmaRnmXZero), .YZeroE(FmaRnmYZero), .ZZeroE(FmaRnmZZero),
.XInfE(FmaRnmXInf), .YInfE(FmaRnmYInf), .ZInfE(FmaRnmZInf), .FmaFmt(FmaFmtVal),
.X(FmaRnmX), .Y(FmaRnmY), .Z(FmaRnmZ));
readvectors readvectors (.clk, .Fmt(FmtVal), .ModFmt, .TestVector(TestVectors[VectorNum]), .VectorNum, .Ans(Ans), .AnsFlags(AnsFlags), .SrcA,
.XSgnE(XSgn), .YSgnE(YSgn), .ZSgnE(ZSgn), .Unit (UnitVal),
.XExpE(XExp), .YExpE(YExp), .ZExpE(ZExp), .TestNum, .OpCtrl(OpCtrlVal),
.XManE(XMan), .YManE(YMan), .ZManE(ZMan), .ZOrigDenormE(ZOrigDenorm),
2022-05-19 16:32:30 +00:00
.XNaNE(XNaN), .YNaNE(YNaN), .ZNaNE(ZNaN),
.XSNaNE(XSNaN), .YSNaNE(YSNaN), .ZSNaNE(ZSNaN),
.XDenormE(XDenorm), .YDenormE(YDenorm), .ZDenormE(ZDenorm),
.XZeroE(XZero), .YZeroE(YZero), .ZZeroE(ZZero),
.XInfE(XInf), .YInfE(YInf), .ZInfE(ZInf),.XNormE(XNorm), .XExpMaxE(XExpMax),
.X, .Y, .Z);
///////////////////////////////////////////////////////////////////////////////////////////////
// ||||||| ||| ||| |||||||||
// ||| ||| ||| ||| |||
// ||| ||| ||| ||| |||
// ||| ||| ||| ||| |||
// ||||||| ||||||||| |||
///////////////////////////////////////////////////////////////////////////////////////////////
// instantiate devices under test
// - one fma for each precison
// - all the units for the other tests (including fma for add/sub/mul)
fma1 fma1rne(.XSgnE(FmaRneXSgn), .YSgnE(FmaRneYSgn), .ZSgnE(FmaRneZSgn),
.XExpE(FmaRneXExp), .YExpE(FmaRneYExp), .ZExpE(FmaRneZExp),
.XManE(FmaRneXMan), .YManE(FmaRneYMan), .ZManE(FmaRneZMan),
.XDenormE(FmaRneXDenorm), .YDenormE(FmaRneYDenorm), .ZDenormE(FmaRneZDenorm),
.XZeroE(FmaRneXZero), .YZeroE(FmaRneYZero), .ZZeroE(FmaRneZZero),
.FOpCtrlE(3'b0), .FmtE(FmaModFmt), .SumE(FmaRneSum), .NegSumE(FmaRneNegSum), .InvZE(FmaRneInvZ),
.NormCntE(FmaRneNormCnt), .ZSgnEffE(FmaRneZSgnEff), .PSgnE(FmaRnePSgn),
.ProdExpE(FmaRneProdExp), .AddendStickyE(FmaRneAddendSticky), .KillProdE(FmaRneSumKillProd));
fma2 fma2rne(.XSgnM(FmaRneXSgn), .YSgnM(FmaRneYSgn),
.ZExpM(FmaRneZExp), .ZOrigDenormM(FmaRneZOrigDenorm),
2022-05-19 16:32:30 +00:00
.XManM(FmaRneXMan), .YManM(FmaRneYMan), .ZManM(FmaRneZMan),
.XNaNM(FmaRneXNaN), .YNaNM(FmaRneYNaN), .ZNaNM(FmaRneZNaN),
.XZeroM(FmaRneXZero), .YZeroM(FmaRneYZero), .ZZeroM(FmaRneZZero),
.XInfM(FmaRneXInf), .YInfM(FmaRneYInf), .ZInfM(FmaRneZInf),
.XSNaNM(FmaRneXSNaN), .YSNaNM(FmaRneYSNaN), .ZSNaNM(FmaRneZSNaN),
.KillProdM(FmaRneSumKillProd), .AddendStickyM(FmaRneAddendSticky), .ProdExpM(FmaRneProdExp),
.SumM((FmaRneSum)), .NegSumM(FmaRneNegSum), .InvZM(FmaRneInvZ), .NormCntM(FmaRneNormCnt), .ZSgnEffM(FmaRneZSgnEff),
.PSgnM(FmaRnePSgn), .FmtM(FmaModFmt), .FrmM(`RNE),
.FMAFlgM(FmaRneResFlags), .FMAResM(FmaRneRes), .Mult(1'b0));
fma1 fma1rz(.XSgnE(FmaRzXSgn), .YSgnE(FmaRzYSgn), .ZSgnE(FmaRzZSgn),
.XExpE(FmaRzXExp), .YExpE(FmaRzYExp), .ZExpE(FmaRzZExp),
.XManE(FmaRzXMan), .YManE(FmaRzYMan), .ZManE(FmaRzZMan),
.XDenormE(FmaRzXDenorm), .YDenormE(FmaRzYDenorm), .ZDenormE(FmaRzZDenorm),
.XZeroE(FmaRzXZero), .YZeroE(FmaRzYZero), .ZZeroE(FmaRzZZero),
.FOpCtrlE(3'b0), .FmtE(FmaModFmt), .SumE(FmaRzSum), .NegSumE(FmaRzNegSum), .InvZE(FmaRzInvZ),
.NormCntE(FmaRzNormCnt), .ZSgnEffE(FmaRzZSgnEff), .PSgnE(FmaRzPSgn),
.ProdExpE(FmaRzProdExp), .AddendStickyE(FmaRzAddendSticky), .KillProdE(FmaRzSumKillProd));
fma2 fma2rz(.XSgnM(FmaRzXSgn), .YSgnM(FmaRzYSgn),
.ZExpM(FmaRzZExp), .ZOrigDenormM(FmaRzZOrigDenorm),
2022-05-19 16:32:30 +00:00
.XManM(FmaRzXMan), .YManM(FmaRzYMan), .ZManM(FmaRzZMan),
.XNaNM(FmaRzXNaN), .YNaNM(FmaRzYNaN), .ZNaNM(FmaRzZNaN),
.XZeroM(FmaRzXZero), .YZeroM(FmaRzYZero), .ZZeroM(FmaRzZZero),
.XInfM(FmaRzXInf), .YInfM(FmaRzYInf), .ZInfM(FmaRzZInf),
.XSNaNM(FmaRzXSNaN), .YSNaNM(FmaRzYSNaN), .ZSNaNM(FmaRzZSNaN),
.KillProdM(FmaRzSumKillProd), .AddendStickyM(FmaRzAddendSticky), .ProdExpM(FmaRzProdExp),
.SumM((FmaRzSum)), .NegSumM(FmaRzNegSum), .InvZM(FmaRzInvZ), .NormCntM(FmaRzNormCnt), .ZSgnEffM(FmaRzZSgnEff),
.PSgnM(FmaRzPSgn), .FmtM(FmaModFmt), .FrmM(`RZ),
.FMAFlgM(FmaRzResFlags), .FMAResM(FmaRzRes), .Mult(1'b0));
fma1 fma1ru(.XSgnE(FmaRuXSgn), .YSgnE(FmaRuYSgn), .ZSgnE(FmaRuZSgn),
.XExpE(FmaRuXExp), .YExpE(FmaRuYExp), .ZExpE(FmaRuZExp),
.XManE(FmaRuXMan), .YManE(FmaRuYMan), .ZManE(FmaRuZMan),
.XDenormE(FmaRuXDenorm), .YDenormE(FmaRuYDenorm), .ZDenormE(FmaRuZDenorm),
.XZeroE(FmaRuXZero), .YZeroE(FmaRuYZero), .ZZeroE(FmaRuZZero),
.FOpCtrlE(3'b0), .FmtE(FmaModFmt), .SumE(FmaRuSum), .NegSumE(FmaRuNegSum), .InvZE(FmaRuInvZ),
.NormCntE(FmaRuNormCnt), .ZSgnEffE(FmaRuZSgnEff), .PSgnE(FmaRuPSgn),
.ProdExpE(FmaRuProdExp), .AddendStickyE(FmaRuAddendSticky), .KillProdE(FmaRuSumKillProd));
fma2 fma2ru(.XSgnM(FmaRuXSgn), .YSgnM(FmaRuYSgn),
.ZExpM(FmaRuZExp), .ZOrigDenormM(FmaRuZOrigDenorm),
2022-05-19 16:32:30 +00:00
.XManM(FmaRuXMan), .YManM(FmaRuYMan), .ZManM(FmaRuZMan),
.XNaNM(FmaRuXNaN), .YNaNM(FmaRuYNaN), .ZNaNM(FmaRuZNaN),
.XZeroM(FmaRuXZero), .YZeroM(FmaRuYZero), .ZZeroM(FmaRuZZero),
.XInfM(FmaRuXInf), .YInfM(FmaRuYInf), .ZInfM(FmaRuZInf),
.XSNaNM(FmaRuXSNaN), .YSNaNM(FmaRuYSNaN), .ZSNaNM(FmaRuZSNaN),
.KillProdM(FmaRuSumKillProd), .AddendStickyM(FmaRuAddendSticky), .ProdExpM(FmaRuProdExp),
.SumM((FmaRuSum)), .NegSumM(FmaRuNegSum), .InvZM(FmaRuInvZ), .NormCntM(FmaRuNormCnt), .ZSgnEffM(FmaRuZSgnEff),
.PSgnM(FmaRuPSgn), .FmtM(FmaModFmt), .FrmM(`RU),
.FMAFlgM(FmaRuResFlags), .FMAResM(FmaRuRes), .Mult(1'b0));
fma1 fma1rd(.XSgnE(FmaRdXSgn), .YSgnE(FmaRdYSgn), .ZSgnE(FmaRdZSgn),
.XExpE(FmaRdXExp), .YExpE(FmaRdYExp), .ZExpE(FmaRdZExp),
.XManE(FmaRdXMan), .YManE(FmaRdYMan), .ZManE(FmaRdZMan),
.XDenormE(FmaRdXDenorm), .YDenormE(FmaRdYDenorm), .ZDenormE(FmaRdZDenorm),
.XZeroE(FmaRdXZero), .YZeroE(FmaRdYZero), .ZZeroE(FmaRdZZero),
.FOpCtrlE(3'b0), .FmtE(FmaModFmt), .SumE(FmaRdSum), .NegSumE(FmaRdNegSum), .InvZE(FmaRdInvZ),
.NormCntE(FmaRdNormCnt), .ZSgnEffE(FmaRdZSgnEff), .PSgnE(FmaRdPSgn),
.ProdExpE(FmaRdProdExp), .AddendStickyE(FmaRdAddendSticky), .KillProdE(FmaRdSumKillProd));
fma2 fma2rd(.XSgnM(FmaRdXSgn), .YSgnM(FmaRdYSgn),
.ZExpM(FmaRdZExp), .ZOrigDenormM(FmaRdZOrigDenorm),
2022-05-19 16:32:30 +00:00
.XManM(FmaRdXMan), .YManM(FmaRdYMan), .ZManM(FmaRdZMan),
.XNaNM(FmaRdXNaN), .YNaNM(FmaRdYNaN), .ZNaNM(FmaRdZNaN),
.XZeroM(FmaRdXZero), .YZeroM(FmaRdYZero), .ZZeroM(FmaRdZZero),
.XInfM(FmaRdXInf), .YInfM(FmaRdYInf), .ZInfM(FmaRdZInf),
.XSNaNM(FmaRdXSNaN), .YSNaNM(FmaRdYSNaN), .ZSNaNM(FmaRdZSNaN),
.KillProdM(FmaRdSumKillProd), .AddendStickyM(FmaRdAddendSticky), .ProdExpM(FmaRdProdExp),
.SumM((FmaRdSum)), .NegSumM(FmaRdNegSum), .InvZM(FmaRdInvZ), .NormCntM(FmaRdNormCnt), .ZSgnEffM(FmaRdZSgnEff),
.PSgnM(FmaRdPSgn), .FmtM(FmaModFmt), .FrmM(`RD),
.FMAFlgM(FmaRdResFlags), .FMAResM(FmaRdRes), .Mult(1'b0));
fma1 fma1rnm(.XSgnE(FmaRnmXSgn), .YSgnE(FmaRnmYSgn), .ZSgnE(FmaRnmZSgn),
.XExpE(FmaRnmXExp), .YExpE(FmaRnmYExp), .ZExpE(FmaRnmZExp),
.XManE(FmaRnmXMan), .YManE(FmaRnmYMan), .ZManE(FmaRnmZMan),
.XDenormE(FmaRnmXDenorm), .YDenormE(FmaRnmYDenorm), .ZDenormE(FmaRnmZDenorm),
.XZeroE(FmaRnmXZero), .YZeroE(FmaRnmYZero), .ZZeroE(FmaRnmZZero),
.FOpCtrlE(3'b0), .FmtE(FmaModFmt), .SumE(FmaRnmSum), .NegSumE(FmaRnmNegSum), .InvZE(FmaRnmInvZ),
.NormCntE(FmaRnmNormCnt), .ZSgnEffE(FmaRnmZSgnEff), .PSgnE(FmaRnmPSgn),
.ProdExpE(FmaRnmProdExp), .AddendStickyE(FmaRnmAddendSticky), .KillProdE(FmaRnmSumKillProd));
fma2 fma2rnm(.XSgnM(FmaRnmXSgn), .YSgnM(FmaRnmYSgn),
.ZExpM(FmaRnmZExp), .ZOrigDenormM(FmaRmeZOrigDenorm),
2022-05-19 16:32:30 +00:00
.XManM(FmaRnmXMan), .YManM(FmaRnmYMan), .ZManM(FmaRnmZMan),
.XNaNM(FmaRnmXNaN), .YNaNM(FmaRnmYNaN), .ZNaNM(FmaRnmZNaN),
.XZeroM(FmaRnmXZero), .YZeroM(FmaRnmYZero), .ZZeroM(FmaRnmZZero),
.XInfM(FmaRnmXInf), .YInfM(FmaRnmYInf), .ZInfM(FmaRnmZInf),
.XSNaNM(FmaRnmXSNaN), .YSNaNM(FmaRnmYSNaN), .ZSNaNM(FmaRnmZSNaN),
.KillProdM(FmaRnmSumKillProd), .AddendStickyM(FmaRnmAddendSticky), .ProdExpM(FmaRnmProdExp),
.SumM((FmaRnmSum)), .NegSumM(FmaRnmNegSum), .InvZM(FmaRnmInvZ), .NormCntM(FmaRnmNormCnt), .ZSgnEffM(FmaRnmZSgnEff),
.PSgnM(FmaRnmPSgn), .FmtM(FmaModFmt), .FrmM(`RNM),
.FMAFlgM(FmaRnmResFlags), .FMAResM(FmaRnmRes), .Mult(1'b0));
fma1 fma1(.XSgnE(XSgn), .YSgnE(YSgn), .ZSgnE(ZSgn),
.XExpE(XExp), .YExpE(YExp), .ZExpE(ZExp),
.XManE(XMan), .YManE(YMan), .ZManE(ZMan),
.XDenormE(XDenorm), .YDenormE(YDenorm), .ZDenormE(ZDenorm),
.XZeroE(XZero), .YZeroE(YZero), .ZZeroE(ZZero),
.FOpCtrlE(OpCtrlVal), .FmtE(ModFmt), .SumE, .NegSumE, .InvZE, .NormCntE, .ZSgnEffE, .PSgnE,
2022-05-19 16:32:30 +00:00
.ProdExpE, .AddendStickyE, .KillProdE);
fma2 fma2(.XSgnM(XSgn), .YSgnM(YSgn),
.ZExpM(ZExp), .ZOrigDenormM(ZOrigDenorm),
2022-05-19 16:32:30 +00:00
.XManM(XMan), .YManM(YMan), .ZManM(ZMan),
.XNaNM(XNaN), .YNaNM(YNaN), .ZNaNM(ZNaN),
.XZeroM(XZero), .YZeroM(YZero), .ZZeroM(ZZero),
.XInfM(XInf), .YInfM(YInf), .ZInfM(ZInf),
.XSNaNM(XSNaN), .YSNaNM(YSNaN), .ZSNaNM(ZSNaN),
.KillProdM(KillProdE), .AddendStickyM(AddendStickyE), .ProdExpM(ProdExpE),
.SumM(SumE), .NegSumM(NegSumE), .InvZM(InvZE), .NormCntM(NormCntE), .ZSgnEffM(ZSgnEffE), .PSgnM(PSgnE), .FmtM(ModFmt), .FrmM(FrmVal),
.FMAFlgM, .FMAResM, .Mult);
// fcvtfp fcvtfp (.XExpE(XExp), .XManE(XMan), .XSgnE(XSgn), .XZeroE(XZero), .XDenormE(XDenorm), .XInfE(XInf),
// .XNaNE(XNaN), .XSNaNE(XSNaN), .FrmE(Frmal), .FmtE(ModFmt), .CvtFpResE, .CvtFpFlgE);
// fcmp fcmp (.FmtE(ModFmt), .FOpCtrlE, .XSgnE(XSgn), .YSgnE(YSgn), .XExpE(XExp), .YExpE(YExp),
// .XManE(XMan), .YManE(YMan), .XZeroE(XZero), .YZeroE(YZero),
// .XNaNE(XNaN), .YNaNE(YNaN), .XSNaNE(XSNaN), .YSNaNE(YSNaN), .FSrcXE(X), .FSrcYE(Y), .CmpNVE, .CmpResE);
// fcvtint fcvtint (.XSgnE(XSgn), .XExpE(XExp), .XManE(XMan), .XZeroE(XZero), .XNaNE(XNaN), .XInfE(XInf),
// .XDenormE(XDenorm), .ForwardedSrcAE(SrcA), .FOpCtrlE, .FmtE(ModFmt), .FrmE(Frmal),
// .CvtResE, .CvtFlgE);
// *** integrade divide and squareroot
// fpdiv_pipe fdivsqrt (.op1(DivInput1E), .op2(DivInput2E), .rm(FrmVal[1:0]), .op_type(FOpCtrlQ),
// .reset, .clk(clk), .start(FDivStartE), .P(~FmtQ), .OvEn(1'b1), .UnEn(1'b1),
// .XNaNQ, .YNaNQ, .XInfQ, .YInfQ, .XZeroQ, .YZeroQ, .load_preload,
// .FDivBusyE, .done(FDivSqrtDoneE), .AS_Res(FDivResM), .Flags(FDivFlgM));
// produce clock
always begin
clk = 1; #5; clk = 0; #5;
end
///////////////////////////////////////////////////////////////////////////////////////////////
// ||||| ||| |||||||||| ||||| |||
// ||||||| ||| ||| ||| ||||||| |||
// |||| ||| ||| |||||||||| |||| ||| |||
// |||| ||| ||| ||| ||| |||| ||| |||
// |||| ||| ||| ||| ||| |||| ||| |||
// |||| |||||| ||| ||| |||| ||||||
///////////////////////////////////////////////////////////////////////////////////////////////
//Check if answer is a NaN
always_comb begin
case (FmaFmtVal)
4'b11: begin // quad
FmaRneAnsNaN = &FmaRneAns[`Q_LEN-2:`Q_NF]&(|FmaRneAns[`Q_NF-1:0]);
FmaRneResNaN = &FmaRneRes[`Q_LEN-2:`Q_NF]&(|FmaRneRes[`Q_NF-1:0]);
FmaRzAnsNaN = &FmaRzAns[`Q_LEN-2:`Q_NF]&(|FmaRzAns[`Q_NF-1:0]);
FmaRzResNaN = &FmaRzRes[`Q_LEN-2:`Q_NF]&(|FmaRzRes[`Q_NF-1:0]);
FmaRuAnsNaN = &FmaRuAns[`Q_LEN-2:`Q_NF]&(|FmaRuAns[`Q_NF-1:0]);
FmaRuResNaN = &FmaRuRes[`Q_LEN-2:`Q_NF]&(|FmaRuRes[`Q_NF-1:0]);
FmaRdAnsNaN = &FmaRdAns[`Q_LEN-2:`Q_NF]&(|FmaRdAns[`Q_NF-1:0]);
FmaRdResNaN = &FmaRdRes[`Q_LEN-2:`Q_NF]&(|FmaRdRes[`Q_NF-1:0]);
FmaRnmAnsNaN = &FmaRnmAns[`Q_LEN-2:`Q_NF]&(|FmaRnmAns[`Q_NF-1:0]);
FmaRnmResNaN = &FmaRnmRes[`Q_LEN-2:`Q_NF]&(|FmaRnmRes[`Q_NF-1:0]);
end
4'b01: begin // double
FmaRneAnsNaN = &FmaRneAns[`D_LEN-2:`D_NF]&(|FmaRneAns[`D_NF-1:0]);
FmaRneResNaN = &FmaRneRes[`D_LEN-2:`D_NF]&(|FmaRneRes[`D_NF-1:0]);
FmaRzAnsNaN = &FmaRzAns[`D_LEN-2:`D_NF]&(|FmaRzAns[`D_NF-1:0]);
FmaRzResNaN = &FmaRzRes[`D_LEN-2:`D_NF]&(|FmaRzRes[`D_NF-1:0]);
FmaRuAnsNaN = &FmaRuAns[`D_LEN-2:`D_NF]&(|FmaRuAns[`D_NF-1:0]);
FmaRuResNaN = &FmaRuRes[`D_LEN-2:`D_NF]&(|FmaRuRes[`D_NF-1:0]);
FmaRdAnsNaN = &FmaRdAns[`D_LEN-2:`D_NF]&(|FmaRdAns[`D_NF-1:0]);
FmaRdResNaN = &FmaRdRes[`D_LEN-2:`D_NF]&(|FmaRdRes[`D_NF-1:0]);
FmaRnmAnsNaN = &FmaRnmAns[`D_LEN-2:`D_NF]&(|FmaRnmAns[`D_NF-1:0]);
FmaRnmResNaN = &FmaRnmRes[`D_LEN-2:`D_NF]&(|FmaRnmRes[`D_NF-1:0]);
end
4'b00: begin // single
FmaRneAnsNaN = &FmaRneAns[`S_LEN-2:`S_NF]&(|FmaRneAns[`S_NF-1:0]);
FmaRneResNaN = &FmaRneRes[`S_LEN-2:`S_NF]&(|FmaRneRes[`S_NF-1:0]);
FmaRzAnsNaN = &FmaRzAns[`S_LEN-2:`S_NF]&(|FmaRzAns[`S_NF-1:0]);
FmaRzResNaN = &FmaRzRes[`S_LEN-2:`S_NF]&(|FmaRzRes[`S_NF-1:0]);
FmaRuAnsNaN = &FmaRuAns[`S_LEN-2:`S_NF]&(|FmaRuAns[`S_NF-1:0]);
FmaRuResNaN = &FmaRuRes[`S_LEN-2:`S_NF]&(|FmaRuRes[`S_NF-1:0]);
FmaRdAnsNaN = &FmaRdAns[`S_LEN-2:`S_NF]&(|FmaRdAns[`S_NF-1:0]);
FmaRdResNaN = &FmaRdRes[`S_LEN-2:`S_NF]&(|FmaRdRes[`S_NF-1:0]);
FmaRnmAnsNaN = &FmaRnmAns[`S_LEN-2:`S_NF]&(|FmaRnmAns[`S_NF-1:0]);
FmaRnmResNaN = &FmaRnmRes[`S_LEN-2:`S_NF]&(|FmaRnmRes[`S_NF-1:0]);
end
4'b10: begin // half
FmaRneAnsNaN = &FmaRneAns[`H_LEN-2:`H_NF]&(|FmaRneAns[`H_NF-1:0]);
FmaRneResNaN = &FmaRneRes[`H_LEN-2:`H_NF]&(|FmaRneRes[`H_NF-1:0]);
FmaRzAnsNaN = &FmaRzAns[`H_LEN-2:`H_NF]&(|FmaRzAns[`H_NF-1:0]);
FmaRzResNaN = &FmaRzRes[`H_LEN-2:`H_NF]&(|FmaRzRes[`H_NF-1:0]);
FmaRuAnsNaN = &FmaRuAns[`H_LEN-2:`H_NF]&(|FmaRuAns[`H_NF-1:0]);
FmaRuResNaN = &FmaRuRes[`H_LEN-2:`H_NF]&(|FmaRuRes[`H_NF-1:0]);
FmaRdAnsNaN = &FmaRdAns[`H_LEN-2:`H_NF]&(|FmaRdAns[`H_NF-1:0]);
FmaRdResNaN = &FmaRdRes[`H_LEN-2:`H_NF]&(|FmaRdRes[`H_NF-1:0]);
FmaRnmAnsNaN = &FmaRnmAns[`H_LEN-2:`H_NF]&(|FmaRnmAns[`H_NF-1:0]);
FmaRnmResNaN = &FmaRnmRes[`H_LEN-2:`H_NF]&(|FmaRnmRes[`H_NF-1:0]);
end
endcase
end
always_comb begin //***need for other units???
if(UnitVal === `CVTINTUNIT | UnitVal === `CMPUNIT) begin
AnsNaN = 1'b0;
ResNaN = 1'b0;
end
else begin
case (FmtVal)
4'b11: begin // quad
AnsNaN = &Ans[`FLEN-2:`NF]&(|Ans[`NF-1:0]);
ResNaN = &FMAResM[`FLEN-2:`NF]&(|FMAResM[`NF-1:0]);
end
4'b01: begin // double
AnsNaN = &Ans[`LEN1-2:`NF1]&(|Ans[`NF1-1:0]);
ResNaN = &FMAResM[`LEN1-2:`NF1]&(|FMAResM[`NF1-1:0]);
end
4'b00: begin // single
AnsNaN = &Ans[`LEN2-2:`NF2]&(|Ans[`NF2-1:0]);
ResNaN = &FMAResM[`LEN2-2:`NF2]&(|FMAResM[`NF2-1:0]);
end
4'b10: begin // half
AnsNaN = &Ans[`H_LEN-2:`H_NF]&(|Ans[`H_NF-1:0]);
ResNaN = &FMAResM[`H_LEN-2:`H_NF]&(|FMAResM[`H_NF-1:0]);
end
endcase
end
end
// check results on falling edge of clk
always @(negedge clk) begin
case (UnitVal)
`FMAUNIT: Res = FMAResM;
`DIVUNIT: Res = DivResM;
`CMPUNIT: Res = CmpResE;
`CVTINTUNIT: Res = CvtResE;
`CVTFPUNIT: Res = CvtFpResE;
endcase
case (UnitVal)
`FMAUNIT: ResFlags = FMAFlgM;
`DIVUNIT: ResFlags = DivFlgM;
`CMPUNIT: ResFlags = CmpFlgM;
`CVTINTUNIT: ResFlags = CvtIntFlgM;
`CVTFPUNIT: ResFlags = CvtFpFlgM;
endcase
// check if the NaN value is good. IEEE754-2019 sections 6.3 and 6.2.3 specify:
// - 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
2022-05-19 16:32:30 +00:00
case (FmaFmtVal)
4'b11: FmaRneNaNGood =((FmaRneAnsFlags[4]&(FmaRneRes[`Q_LEN-2:0] === {{`Q_NE+1{1'b1}}, {`Q_NF-1{1'b0}}})) |
(FmaRneXNaN&(FmaRneRes[`Q_LEN-2:0] === {FmaRneX[`Q_LEN-2:`Q_NF],1'b1,FmaRneX[`Q_NF-2:0]})) |
(FmaRneYNaN&(FmaRneRes[`Q_LEN-2:0] === {FmaRneY[`Q_LEN-2:`Q_NF],1'b1,FmaRneY[`Q_NF-2:0]})) |
(FmaRneZNaN&(FmaRneRes[`Q_LEN-2:0] === {FmaRneZ[`Q_LEN-2:`Q_NF],1'b1,FmaRneZ[`Q_NF-2:0]})));
4'b01: FmaRneNaNGood =((FmaRneAnsFlags[4]&(FmaRneRes[`D_LEN-2:0] === {{`D_NE+1{1'b1}}, {`D_NF-1{1'b0}}})) |
(FmaRneXNaN&(FmaRneRes[`D_LEN-2:0] === {FmaRneX[`D_LEN-2:`D_NF],1'b1,FmaRneX[`D_NF-2:0]})) |
(FmaRneYNaN&(FmaRneRes[`D_LEN-2:0] === {FmaRneY[`D_LEN-2:`D_NF],1'b1,FmaRneY[`D_NF-2:0]})) |
(FmaRneZNaN&(FmaRneRes[`D_LEN-2:0] === {FmaRneZ[`D_LEN-2:`D_NF],1'b1,FmaRneZ[`D_NF-2:0]})));
4'b00: FmaRneNaNGood =((FmaRneAnsFlags[4]&(FmaRneRes[`S_LEN-2:0] === {{`S_NE+1{1'b1}}, {`S_NF-1{1'b0}}})) |
(FmaRneXNaN&(FmaRneRes[`S_LEN-2:0] === {FmaRneX[`S_LEN-2:`S_NF],1'b1,FmaRneX[`S_NF-2:0]})) |
(FmaRneYNaN&(FmaRneRes[`S_LEN-2:0] === {FmaRneY[`S_LEN-2:`S_NF],1'b1,FmaRneY[`S_NF-2:0]})) |
(FmaRneZNaN&(FmaRneRes[`S_LEN-2:0] === {FmaRneZ[`S_LEN-2:`S_NF],1'b1,FmaRneZ[`S_NF-2:0]})));
4'b10: FmaRneNaNGood =((FmaRneAnsFlags[4]&(FmaRneRes[`H_LEN-2:0] === {{`H_NE+1{1'b1}}, {`H_NF-1{1'b0}}})) |
(FmaRneXNaN&(FmaRneRes[`H_LEN-2:0] === {FmaRneX[`H_LEN-2:`H_NF],1'b1,FmaRneX[`H_NF-2:0]})) |
(FmaRneYNaN&(FmaRneRes[`H_LEN-2:0] === {FmaRneY[`H_LEN-2:`H_NF],1'b1,FmaRneY[`H_NF-2:0]})) |
(FmaRneZNaN&(FmaRneRes[`H_LEN-2:0] === {FmaRneZ[`H_LEN-2:`H_NF],1'b1,FmaRneZ[`H_NF-2:0]})));
endcase
case (FmaFmtVal)
4'b11: FmaRzNaNGood = ((FmaRzAnsFlags[4]&(FmaRzRes[`Q_LEN-2:0] === {{`Q_NE+1{1'b1}}, {`Q_NF-1{1'b0}}})) |
(FmaRzXNaN&(FmaRzRes[`Q_LEN-2:0] === {FmaRzX[`Q_LEN-2:`Q_NF],1'b1,FmaRzX[`Q_NF-2:0]})) |
(FmaRzYNaN&(FmaRzRes[`Q_LEN-2:0] === {FmaRzY[`Q_LEN-2:`Q_NF],1'b1,FmaRzY[`Q_NF-2:0]})) |
(FmaRzZNaN&(FmaRzRes[`Q_LEN-2:0] === {FmaRzZ[`Q_LEN-2:`Q_NF],1'b1,FmaRzZ[`Q_NF-2:0]})));
4'b01: FmaRzNaNGood = ((FmaRzAnsFlags[4]&(FmaRzRes[`D_LEN-2:0] === {{`D_NE+1{1'b1}}, {`D_NF-1{1'b0}}})) |
(FmaRzXNaN&(FmaRzRes[`D_LEN-2:0] === {FmaRzX[`D_LEN-2:`D_NF],1'b1,FmaRzX[`D_NF-2:0]})) |
(FmaRzYNaN&(FmaRzRes[`D_LEN-2:0] === {FmaRzY[`D_LEN-2:`D_NF],1'b1,FmaRzY[`D_NF-2:0]})) |
(FmaRzZNaN&(FmaRzRes[`D_LEN-2:0] === {FmaRzZ[`D_LEN-2:`D_NF],1'b1,FmaRzZ[`D_NF-2:0]})));
4'b00: FmaRzNaNGood = ((FmaRzAnsFlags[4]&(FmaRzRes[`S_LEN-2:0] === {{`S_NE+1{1'b1}}, {`S_NF-1{1'b0}}})) |
(FmaRzXNaN&(FmaRzRes[`S_LEN-2:0] === {FmaRzX[`S_LEN-2:`S_NF],1'b1,FmaRzX[`S_NF-2:0]})) |
(FmaRzYNaN&(FmaRzRes[`S_LEN-2:0] === {FmaRzY[`S_LEN-2:`S_NF],1'b1,FmaRzY[`S_NF-2:0]})) |
(FmaRzZNaN&(FmaRzRes[`S_LEN-2:0] === {FmaRzZ[`S_LEN-2:`S_NF],1'b1,FmaRzZ[`S_NF-2:0]})));
4'b10: FmaRzNaNGood = ((FmaRzAnsFlags[4]&(FmaRzRes[`H_LEN-2:0] === {{`H_NE+1{1'b1}}, {`H_NF-1{1'b0}}})) |
(FmaRzXNaN&(FmaRzRes[`H_LEN-2:0] === {FmaRzX[`H_LEN-2:`H_NF],1'b1,FmaRzX[`H_NF-2:0]})) |
(FmaRzYNaN&(FmaRzRes[`H_LEN-2:0] === {FmaRzY[`H_LEN-2:`H_NF],1'b1,FmaRzY[`H_NF-2:0]})) |
(FmaRzZNaN&(FmaRzRes[`H_LEN-2:0] === {FmaRzZ[`H_LEN-2:`H_NF],1'b1,FmaRzZ[`H_NF-2:0]})));
endcase
case (FmaFmtVal)
4'b11: FmaRuNaNGood = ((FmaRuAnsFlags[4]&(FmaRuRes[`Q_LEN-2:0] === {{`Q_NE+1{1'b1}}, {`Q_NF-1{1'b0}}})) |
(FmaRuXNaN&(FmaRuRes[`Q_LEN-2:0] === {FmaRuX[`Q_LEN-2:`Q_NF],1'b1,FmaRuX[`Q_NF-2:0]})) |
(FmaRuYNaN&(FmaRuRes[`Q_LEN-2:0] === {FmaRuY[`Q_LEN-2:`Q_NF],1'b1,FmaRuY[`Q_NF-2:0]})) |
(FmaRuZNaN&(FmaRuRes[`Q_LEN-2:0] === {FmaRuZ[`Q_LEN-2:`Q_NF],1'b1,FmaRuZ[`Q_NF-2:0]})));
4'b01: FmaRuNaNGood = ((FmaRuAnsFlags[4]&(FmaRuRes[`D_LEN-2:0] === {{`D_NE+1{1'b1}}, {`D_NF-1{1'b0}}})) |
(FmaRuAnsFlags[4]&(FmaRuRes[`Q_LEN-2:0] === {{`D_NE+1{1'b1}}, {`D_NF{1'b0}}})) |
(FmaRuXNaN&(FmaRuRes[`D_LEN-2:0] === {FmaRuX[`D_LEN-2:`D_NF],1'b1,FmaRuX[`D_NF-2:0]})) |
(FmaRuYNaN&(FmaRuRes[`D_LEN-2:0] === {FmaRuY[`D_LEN-2:`D_NF],1'b1,FmaRuY[`D_NF-2:0]})) |
(FmaRuZNaN&(FmaRuRes[`D_LEN-2:0] === {FmaRuZ[`D_LEN-2:`D_NF],1'b1,FmaRuZ[`D_NF-2:0]})));
4'b00: FmaRuNaNGood = ((FmaRuAnsFlags[4]&(FmaRuRes[`S_LEN-2:0] === {{`S_NE+1{1'b1}}, {`S_NF-1{1'b0}}})) |
(FmaRuXNaN&(FmaRuRes[`S_LEN-2:0] === {FmaRuX[`S_LEN-2:`S_NF],1'b1,FmaRuX[`S_NF-2:0]})) |
(FmaRuYNaN&(FmaRuRes[`S_LEN-2:0] === {FmaRuY[`S_LEN-2:`S_NF],1'b1,FmaRuY[`S_NF-2:0]})) |
(FmaRuZNaN&(FmaRuRes[`S_LEN-2:0] === {FmaRuZ[`S_LEN-2:`S_NF],1'b1,FmaRuZ[`S_NF-2:0]})));
4'b10: FmaRuNaNGood = ((FmaRuAnsFlags[4]&(FmaRuRes[`H_LEN-2:0] === {{`H_NE+1{1'b1}}, {`H_NF-1{1'b0}}})) |
(FmaRuXNaN&(FmaRuRes[`H_LEN-2:0] === {FmaRuX[`H_LEN-2:`H_NF],1'b1,FmaRuX[`H_NF-2:0]})) |
(FmaRuYNaN&(FmaRuRes[`H_LEN-2:0] === {FmaRuY[`H_LEN-2:`H_NF],1'b1,FmaRuY[`H_NF-2:0]})) |
(FmaRuZNaN&(FmaRuRes[`H_LEN-2:0] === {FmaRuZ[`H_LEN-2:`H_NF],1'b1,FmaRuZ[`H_NF-2:0]})));
endcase
case (FmaFmtVal)
4'b11: FmaRdNaNGood = ((FmaRdAnsFlags[4]&(FmaRdRes[`Q_LEN-2:0] === {{`Q_NE+1{1'b1}}, {`Q_NF-1{1'b0}}})) |
(FmaRdXNaN&(FmaRdRes[`Q_LEN-2:0] === {FmaRdX[`Q_LEN-2:`Q_NF],1'b1,FmaRdX[`Q_NF-2:0]})) |
(FmaRdYNaN&(FmaRdRes[`Q_LEN-2:0] === {FmaRdY[`Q_LEN-2:`Q_NF],1'b1,FmaRdY[`Q_NF-2:0]})) |
(FmaRdZNaN&(FmaRdRes[`Q_LEN-2:0] === {FmaRdZ[`Q_LEN-2:`Q_NF],1'b1,FmaRdZ[`Q_NF-2:0]})));
4'b01: FmaRdNaNGood = ((FmaRdAnsFlags[4]&(FmaRdRes[`D_LEN-2:0] === {{`D_NE+1{1'b1}}, {`D_NF-1{1'b0}}})) |
(FmaRdXNaN&(FmaRdRes[`D_LEN-2:0] === {FmaRdX[`D_LEN-2:`D_NF],1'b1,FmaRdX[`D_NF-2:0]})) |
(FmaRdYNaN&(FmaRdRes[`D_LEN-2:0] === {FmaRdY[`D_LEN-2:`D_NF],1'b1,FmaRdY[`D_NF-2:0]})) |
(FmaRdZNaN&(FmaRdRes[`D_LEN-2:0] === {FmaRdZ[`D_LEN-2:`D_NF],1'b1,FmaRdZ[`D_NF-2:0]})));
4'b00: FmaRdNaNGood = ((FmaRdAnsFlags[4]&(FmaRdRes[`S_LEN-2:0] === {{`S_NE+1{1'b1}}, {`S_NF-1{1'b0}}})) |
(FmaRdXNaN&(FmaRdRes[`S_LEN-2:0] === {FmaRdX[`S_LEN-2:`S_NF],1'b1,FmaRdX[`S_NF-2:0]})) |
(FmaRdYNaN&(FmaRdRes[`S_LEN-2:0] === {FmaRdY[`S_LEN-2:`S_NF],1'b1,FmaRdY[`S_NF-2:0]})) |
(FmaRdZNaN&(FmaRdRes[`S_LEN-2:0] === {FmaRdZ[`S_LEN-2:`S_NF],1'b1,FmaRdZ[`S_NF-2:0]})));
4'b10: FmaRdNaNGood = ((FmaRdAnsFlags[4]&(FmaRdRes[`H_LEN-2:0] === {{`H_NE+1{1'b1}}, {`H_NF-1{1'b0}}})) |
(FmaRdXNaN&(FmaRdRes[`H_LEN-2:0] === {FmaRdX[`H_LEN-2:`H_NF],1'b1,FmaRdX[`H_NF-2:0]})) |
(FmaRdYNaN&(FmaRdRes[`H_LEN-2:0] === {FmaRdY[`H_LEN-2:`H_NF],1'b1,FmaRdY[`H_NF-2:0]})) |
(FmaRdZNaN&(FmaRdRes[`H_LEN-2:0] === {FmaRdZ[`H_LEN-2:`H_NF],1'b1,FmaRdZ[`H_NF-2:0]})));
endcase
case (FmaFmtVal)
4'b11: FmaRnmNaNGood =((FmaRnmAnsFlags[4]&(FmaRnmRes[`Q_LEN-2:0] === {{`Q_NE+1{1'b1}}, {`Q_NF-1{1'b0}}})) |
(FmaRnmXNaN&(FmaRnmRes[`Q_LEN-2:0] === {FmaRnmX[`Q_LEN-2:`Q_NF],1'b1,FmaRnmX[`Q_NF-2:0]})) |
(FmaRnmYNaN&(FmaRnmRes[`Q_LEN-2:0] === {FmaRnmY[`Q_LEN-2:`Q_NF],1'b1,FmaRnmY[`Q_NF-2:0]})) |
(FmaRnmZNaN&(FmaRnmRes[`Q_LEN-2:0] === {FmaRnmZ[`Q_LEN-2:`Q_NF],1'b1,FmaRnmZ[`Q_NF-2:0]})));
4'b01: FmaRnmNaNGood =((FmaRnmAnsFlags[4]&(FmaRnmRes[`D_LEN-2:0] === {{`D_NE+1{1'b1}}, {`D_NF-1{1'b0}}})) |
(FmaRnmXNaN&(FmaRnmRes[`D_LEN-2:0] === {FmaRnmX[`D_LEN-2:`D_NF],1'b1,FmaRnmX[`D_NF-2:0]})) |
(FmaRnmYNaN&(FmaRnmRes[`D_LEN-2:0] === {FmaRnmY[`D_LEN-2:`D_NF],1'b1,FmaRnmY[`D_NF-2:0]})) |
(FmaRnmZNaN&(FmaRnmRes[`D_LEN-2:0] === {FmaRnmZ[`D_LEN-2:`D_NF],1'b1,FmaRnmZ[`D_NF-2:0]})));
4'b00: FmaRnmNaNGood =((FmaRnmAnsFlags[4]&(FmaRnmRes[`S_LEN-2:0] === {{`S_NE+1{1'b1}}, {`S_NF-1{1'b0}}})) |
(FmaRnmXNaN&(FmaRnmRes[`S_LEN-2:0] === {FmaRnmX[`S_LEN-2:`S_NF],1'b1,FmaRnmX[`S_NF-2:0]})) |
(FmaRnmYNaN&(FmaRnmRes[`S_LEN-2:0] === {FmaRnmY[`S_LEN-2:`S_NF],1'b1,FmaRnmY[`S_NF-2:0]})) |
(FmaRnmZNaN&(FmaRnmRes[`S_LEN-2:0] === {FmaRnmZ[`S_LEN-2:`S_NF],1'b1,FmaRnmZ[`S_NF-2:0]})));
4'b10: FmaRnmNaNGood =((FmaRnmAnsFlags[4]&(FmaRnmRes[`H_LEN-2:0] === {{`H_NE+1{1'b1}}, {`H_NF-1{1'b0}}})) |
(FmaRnmXNaN&(FmaRnmRes[`H_LEN-2:0] === {FmaRnmX[`H_LEN-2:`H_NF],1'b1,FmaRnmX[`H_NF-2:0]})) |
(FmaRnmYNaN&(FmaRnmRes[`H_LEN-2:0] === {FmaRnmY[`H_LEN-2:`H_NF],1'b1,FmaRnmY[`H_NF-2:0]})) |
(FmaRnmZNaN&(FmaRnmRes[`H_LEN-2:0] === {FmaRnmZ[`H_LEN-2:`H_NF],1'b1,FmaRnmZ[`H_NF-2:0]})));
endcase
if (UnitVal !== `CVTFPUNIT & UnitVal !== `CVTINTUNIT)
case (FmtVal)
4'b11: NaNGood = ((AnsFlags[4]&(Res[`Q_LEN-2:0] === {{`Q_NE+1{1'b1}}, {`Q_NF-1{1'b0}}})) |
(XNaN&(Res[`Q_LEN-2:0] === {X[`Q_LEN-2:`Q_NF],1'b1,X[`Q_NF-2:0]})) |
(YNaN&(Res[`Q_LEN-2:0] === {Y[`Q_LEN-2:`Q_NF],1'b1,Y[`Q_NF-2:0]})) |
(ZNaN&(Res[`Q_LEN-2:0] === {Z[`Q_LEN-2:`Q_NF],1'b1,Z[`Q_NF-2:0]})));
2022-05-19 16:32:30 +00:00
4'b01: NaNGood = ((AnsFlags[4]&(Res[`D_LEN-2:0] === {{`D_NE+1{1'b1}}, {`D_NF-1{1'b0}}})) |
(XNaN&(Res[`D_LEN-2:0] === {X[`D_LEN-2:`D_NF],1'b1,X[`D_NF-2:0]})) |
(YNaN&(Res[`D_LEN-2:0] === {Y[`D_LEN-2:`D_NF],1'b1,Y[`D_NF-2:0]})) |
(ZNaN&(Res[`D_LEN-2:0] === {Z[`D_LEN-2:`D_NF],1'b1,Z[`D_NF-2:0]})));
2022-05-19 16:32:30 +00:00
4'b00: NaNGood = ((AnsFlags[4]&(Res[`S_LEN-2:0] === {{`S_NE+1{1'b1}}, {`S_NF-1{1'b0}}})) |
(XNaN&(Res[`S_LEN-2:0] === {X[`S_LEN-2:`S_NF],1'b1,X[`S_NF-2:0]})) |
(YNaN&(Res[`S_LEN-2:0] === {Y[`S_LEN-2:`S_NF],1'b1,Y[`S_NF-2:0]})) |
(ZNaN&(Res[`S_LEN-2:0] === {Z[`S_LEN-2:`S_NF],1'b1,Z[`S_NF-2:0]})));
2022-05-19 16:32:30 +00:00
4'b10: NaNGood = ((AnsFlags[4]&(Res[`H_LEN-2:0] === {{`H_NE+1{1'b1}}, {`H_NF-1{1'b0}}})) |
(XNaN&(Res[`H_LEN-2:0] === {X[`H_LEN-2:`H_NF],1'b1,X[`H_NF-2:0]})) |
(YNaN&(Res[`H_LEN-2:0] === {Y[`H_LEN-2:`H_NF],1'b1,Y[`H_NF-2:0]})) |
(ZNaN&(Res[`H_LEN-2:0] === {Z[`H_LEN-2:`H_NF],1'b1,Z[`H_NF-2:0]})));
2022-05-19 16:32:30 +00:00
endcase
else if (UnitVal === `CVTFPUNIT) // if converting from floating point to floating point OpCtrl contains the final FP format
case (OpCtrlVal[1:0])
2'b11: NaNGood = ((AnsFlags[4]&(Res[`Q_LEN-2:0] === {{`Q_NE+1{1'b1}}, {`Q_NF-1{1'b0}}})) |
(XNaN&(Res[`Q_LEN-2:0] === {X[`Q_LEN-2:`Q_NF],1'b1,X[`Q_NF-2:0]})) |
(YNaN&(Res[`Q_LEN-2:0] === {Y[`Q_LEN-2:`Q_NF],1'b1,Y[`Q_NF-2:0]})));
2'b01: NaNGood = ((AnsFlags[4]&(Res[`D_LEN-2:0] === {{`D_NE+1{1'b1}}, {`D_NF-1{1'b0}}})) |
(XNaN&(Res[`D_LEN-2:0] === {X[`D_LEN-2:`D_NF],1'b1,X[`D_NF-2:0]})) |
(YNaN&(Res[`D_LEN-2:0] === {Y[`D_LEN-2:`D_NF],1'b1,Y[`D_NF-2:0]})));
2'b00: NaNGood = ((AnsFlags[4]&(Res[`S_LEN-2:0] === {{`S_NE+1{1'b1}}, {`S_NF-1{1'b0}}})) |
(XNaN&(Res[`S_LEN-2:0] === {X[`S_LEN-2:`S_NF],1'b1,X[`S_NF-2:0]})) |
(YNaN&(Res[`S_LEN-2:0] === {Y[`S_LEN-2:`S_NF],1'b1,Y[`S_NF-2:0]})));
2'b10: NaNGood = ((AnsFlags[4]&(Res[`H_LEN-2:0] === {{`H_NE+1{1'b1}}, {`H_NF-1{1'b0}}})) |
(XNaN&(Res[`H_LEN-2:0] === {X[`H_LEN-2:`H_NF],1'b1,X[`H_NF-2:0]})) |
(YNaN&(Res[`H_LEN-2:0] === {Y[`H_LEN-2:`H_NF],1'b1,Y[`H_NF-2:0]})));
endcase
else NaNGood = 1'b0;
///////////////////////////////////////////////////////////////////////////////////////////////
// ||||||| ||| ||| ||||||| ||||||| ||| |||
// ||| ||| ||| ||| ||| ||| |||
// ||| |||||||||| ||||||| ||| ||||||
// ||| ||| ||| ||| ||| ||| |||
// ||||||| ||| ||| ||||||| ||||||| ||| |||
///////////////////////////////////////////////////////////////////////////////////////////////
if(~((Res === Ans | NaNGood | NaNGood === 1'bx) & (ResFlags === AnsFlags | AnsFlags === 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, ResFlags, Ans, AnsFlags);
$stop;
end
if(~((FmaRneRes === FmaRneAns | FmaRneNaNGood | FmaRneNaNGood === 1'bx) & (FmaRneResFlags === FmaRneAnsFlags | FmaRneAnsFlags === 5'bx))) begin
errors += 1;
$display("There is an error in FMA - RNE");
$display("inputs: %h %h %h\n Res: %h %h\n Ans: %h %h", FmaRneX, FmaRneY, FmaRneZ, FmaRneRes, FmaRneResFlags, FmaRneAns, FmaRneAnsFlags);
$stop;
end
if(~((FmaRzRes === FmaRzAns | FmaRzNaNGood | FmaRzNaNGood === 1'bx) & (FmaRzResFlags === FmaRzAnsFlags | FmaRzAnsFlags === 5'bx))) begin
errors += 1;
$display("There is an error in FMA - RZ");
$display("inputs: %h %h %h\n Res: %h %h\n Ans: %h %h", FmaRzX, FmaRzY, FmaRzZ, FmaRzRes, FmaRzResFlags, FmaRzAns, FmaRzAnsFlags);
$stop;
end
if(~((FmaRuRes === FmaRuAns | FmaRuNaNGood | FmaRuNaNGood === 1'bx) & (FmaRuResFlags === FmaRuAnsFlags | FmaRuAnsFlags === 5'bx))) begin
errors += 1;
$display("There is an error in FMA - RU");
$display("inputs: %h %h %h\n Res: %h %h\n Ans: %h %h", FmaRuX, FmaRuY, FmaRuZ, FmaRuRes, FmaRuResFlags, FmaRuAns, FmaRuAnsFlags);
$stop;
end
if(~((FmaRdRes === FmaRdAns | FmaRdNaNGood | FmaRdNaNGood === 1'bx) & (FmaRdResFlags === FmaRdAnsFlags | FmaRdAnsFlags === 5'bx))) begin
errors += 1;
$display("There is an error in FMA - RD");
$display("inputs: %h %h %h\n Res: %h %h\n Ans: %h %h", FmaRdX, FmaRdY, FmaRdZ, FmaRdRes, FmaRdResFlags, FmaRdAns, FmaRdAnsFlags);
$stop;
end
if(~((FmaRnmRes === FmaRnmAns | FmaRnmNaNGood | FmaRnmNaNGood === 1'bx) & (FmaRnmResFlags === FmaRnmAnsFlags | FmaRnmAnsFlags === 5'bx))) begin
errors += 1;
$display("There is an error in FMA - RNM");
$display("inputs: %h %h %h\n Res: %h %h\n Ans: %h %h", FmaRnmX, FmaRnmY, FmaRnmZ, FmaRnmRes, FmaRnmResFlags, FmaRnmAns, FmaRnmAnsFlags);
$stop;
end
VectorNum += 1; // increment test
if (TestVectors[VectorNum][0] === 1'bx &
FmaRneVectors[VectorNum][0] === 1'bx &
FmaRzVectors[VectorNum][0] === 1'bx &
FmaRuVectors[VectorNum][0] === 1'bx &
FmaRdVectors[VectorNum][0] === 1'bx &
FmaRnmVectors[VectorNum][0] === 1'bx) begin // if reached the end of file
if (errors) begin // if there were errors
$display("%s completed with %d Tests and %d errors", Tests[VectorNum], VectorNum, errors);
$stop;
end
TestNum += 1;
// read next files
$readmemh({`PATH, Tests[TestNum]}, TestVectors);
$readmemh({`PATH, FmaRneTests[TestNum]}, FmaRneVectors);
$readmemh({`PATH, FmaRuTests[TestNum]}, FmaRuVectors);
$readmemh({`PATH, FmaRdTests[TestNum]}, FmaRdVectors);
$readmemh({`PATH, FmaRzTests[TestNum]}, FmaRzVectors);
$readmemh({`PATH, FmaRnmTests[TestNum]}, FmaRnmVectors);
FmaNum += 1;
VectorNum = 0;
if(FrmNum === 4) OpCtrlNum += 1;
if(FrmNum < 4) FrmNum += 1;
else FrmNum = 0;
// if no more Tests - finish
if(Tests[TestNum] === "" &
FmaRneTests[TestNum] === "" &
FmaRzTests[TestNum] === "" &
FmaRuTests[TestNum] === "" &
FmaRdTests[TestNum] === "" &
FmaRnmTests[TestNum] === "") begin
$display("\nAll Tests completed with %d errors\n", errors);
$stop;
end
$display("Running %s vectors", Tests[TestNum]);
end
end
endmodule
module readfmavectors (
input logic clk,
input logic [2:0] Frm,
input logic [`FPSIZES/3:0] FmaModFmt,
input logic [1:0] FmaFmt,
input logic [`FLEN*4+7:0] TestVector,
input logic [31:0] VectorNum,
input logic [31:0] FmaNum,
output logic [`FLEN-1:0] Ans,
output logic ZOrigDenormE,
2022-05-19 16:32:30 +00:00
output logic [4:0] AnsFlags,
output logic XSgnE, YSgnE, ZSgnE, // sign bits of XYZ
output logic [`NE-1:0] XExpE, YExpE, ZExpE, // exponents of XYZ (converted to largest supported precision)
output logic [`NF:0] XManE, YManE, ZManE, // mantissas of XYZ (converted to largest supported precision)
output logic XNaNE, YNaNE, ZNaNE, // is XYZ a NaN
output logic XSNaNE, YSNaNE, ZSNaNE, // is XYZ a signaling NaN
output logic XDenormE, YDenormE, ZDenormE, // is XYZ denormalized
output logic XZeroE, YZeroE, ZZeroE, // is XYZ zero
output logic XInfE, YInfE, ZInfE, // is XYZ infinity
output logic [`FLEN-1:0] X, Y, Z
);
logic XNormE, XExpMaxE; // signals the unpacker outputs but isn't used in FMA
// apply test vectors on rising edge of clk
// Format of vectors Inputs(1/2/3)_AnsFlags
always @(posedge clk) begin
#1;
AnsFlags = TestVector[4:0];
case (FmaFmt)
2'b11: begin // quad
X = TestVector[8+4*(`Q_LEN)-1:8+3*(`Q_LEN)];
Y = TestVector[8+3*(`Q_LEN)-1:8+2*(`Q_LEN)];
Z = TestVector[8+2*(`Q_LEN)-1:8+`Q_LEN];
Ans = TestVector[8+(`Q_LEN-1):8];
end
2'b01: begin // double
X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+4*(`D_LEN)-1:8+3*(`D_LEN)]};
Y = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+3*(`D_LEN)-1:8+2*(`D_LEN)]};
Z = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+2*(`D_LEN)-1:8+`D_LEN]};
Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]};
end
2'b00: begin // single
X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+4*(`S_LEN)-1:8+3*(`S_LEN)]};
Y = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+3*(`S_LEN)-1:8+2*(`S_LEN)]};
Z = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+2*(`S_LEN)-1:8+`S_LEN]};
Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]};
end
2'b10: begin // half
X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+4*(`H_LEN)-1:8+3*(`H_LEN)]};
Y = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+3*(`H_LEN)-1:8+2*(`H_LEN)]};
Z = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+2*(`H_LEN)-1:8+`H_LEN]};
Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]};
end
endcase
end
unpack unpack(.X, .Y, .Z, .FmtE(FmaModFmt), .XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE,
.XManE, .YManE, .ZManE, .XNormE, .XNaNE, .YNaNE, .ZNaNE, .XSNaNE, .YSNaNE, .ZSNaNE,
.XDenormE, .YDenormE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE, .XInfE, .YInfE, .ZInfE,
.XExpMaxE, .ZOrigDenormE);
2022-05-19 16:32:30 +00:00
endmodule
module readvectors (
input logic clk,
input logic [`FLEN*4+7:0] TestVector,
input logic [`FPSIZES/3:0] ModFmt,
input logic [1:0] Fmt,
input logic [2:0] Unit,
input logic [31:0] VectorNum,
input logic [31:0] TestNum,
input logic [2:0] OpCtrl,
output logic [`FLEN-1:0] Ans,
output logic [`XLEN-1:0] SrcA,
output logic [4:0] AnsFlags,
output logic XSgnE, YSgnE, ZSgnE, // sign bits of XYZ
output logic [`NE-1:0] XExpE, YExpE, ZExpE, // exponents of XYZ (converted to largest supported precision)
output logic [`NF:0] XManE, YManE, ZManE, // mantissas of XYZ (converted to largest supported precision)
output logic XNaNE, YNaNE, ZNaNE, // is XYZ a NaN
output logic XSNaNE, YSNaNE, ZSNaNE, // is XYZ a signaling NaN
output logic XDenormE, YDenormE, ZDenormE, // is XYZ denormalized
output logic XZeroE, YZeroE, ZZeroE, // is XYZ zero
output logic XInfE, YInfE, ZInfE, // is XYZ infinity
output logic XNormE, XExpMaxE,
output logic ZOrigDenormE,
2022-05-19 16:32:30 +00:00
output logic [`FLEN-1:0] X, Y, Z
);
// apply test vectors on rising edge of clk
// Format of vectors Inputs(1/2/3)_AnsFlags
always @(posedge clk) begin
#1;
AnsFlags = TestVector[4:0];
case (Unit)
`FMAUNIT:
case (Fmt)
2'b11: begin // quad
X = TestVector[8+3*(`Q_LEN)-1:8+2*(`Q_LEN)];
if(OpCtrl === `MUL_OPCTRL) Y = TestVector[8+2*(`Q_LEN)-1:8+(`Q_LEN)]; else Y = {2'b0, {`Q_NE-1{1'b1}}, `Q_NF'h0};
if(OpCtrl === `MUL_OPCTRL) Z = 0; else Z = TestVector[8+2*(`Q_LEN)-1:8+(`Q_LEN)];
Ans = TestVector[8+(`Q_LEN-1):8];
end
2'b01: begin // double
X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+3*(`D_LEN)-1:8+2*(`D_LEN)]};
if(OpCtrl === `MUL_OPCTRL) Y = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+2*(`D_LEN)-1:8+(`D_LEN)]};
else Y = {{`FLEN-`D_LEN{1'b1}}, 2'b0, {`D_NE-1{1'b1}}, `D_NF'h0};
if(OpCtrl === `MUL_OPCTRL) Z = {{`FLEN-`D_LEN{1'b1}}, {`D_LEN{1'b0}}};
else Z = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+2*(`D_LEN)-1:8+(`D_LEN)]};
Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]};
end
2'b00: begin // single
X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+3*(`S_LEN)-1:8+2*(`S_LEN)]};
if(OpCtrl === `MUL_OPCTRL) Y = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+2*(`S_LEN)-1:8+(`S_LEN)]};
else Y = {{`FLEN-`S_LEN{1'b1}}, 2'b0, {`S_NE-1{1'b1}}, `S_NF'h0};
if(OpCtrl === `MUL_OPCTRL) Z = {{`FLEN-`S_LEN{1'b1}}, {`S_LEN{1'b0}}};
else Z = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+2*(`S_LEN)-1:8+(`S_LEN)]};
Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]};
end
2'b10: begin // half
X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+3*(`H_LEN)-1:8+2*(`H_LEN)]};
if(OpCtrl === `MUL_OPCTRL) Y = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+2*(`H_LEN)-1:8+(`H_LEN)]};
else Y = {{`FLEN-`H_LEN{1'b1}}, 2'b0, {`H_NE-1{1'b1}}, `H_NF'h0};
if(OpCtrl === `MUL_OPCTRL) Z = {{`FLEN-`H_LEN{1'b1}}, {`H_LEN{1'b0}}};
else Z = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+2*(`H_LEN)-1:8+(`H_LEN)]};
Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]};
end
endcase
`DIVUNIT:
case (Fmt)
2'b11: begin // quad
X = TestVector[8+3*(`Q_LEN)-1:8+2*(`Q_LEN)];
Y = TestVector[8+2*(`Q_LEN)-1:8+(`Q_LEN)];
Ans = TestVector[8+(`Q_LEN-1):8];
end
2'b01: begin // double
X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+3*(`D_LEN)-1:8+2*(`D_LEN)]};
Y = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+2*(`D_LEN)-1:8+(`D_LEN)]};
Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]};
end
2'b00: begin // single
X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+3*(`S_LEN)-1:8+2*(`S_LEN)]};
Y = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+2*(`S_LEN)-1:8+1*(`S_LEN)]};
Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]};
end
2'b10: begin // half
X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+3*(`H_LEN)-1:8+2*(`H_LEN)]};
Y = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+2*(`H_LEN)-1:8+(`H_LEN)]};
Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]};
end
endcase
`CMPUNIT:
case (Fmt)
2'b11: begin // quad
X = TestVector[8+2*(`Q_LEN)-1:8+(`Q_LEN)];
Y = TestVector[8+(`Q_LEN)-1:9];
Ans = TestVector[8];
end
2'b01: begin // double
X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+2*(`D_LEN)-1:8+(`D_LEN)]};
Y = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN)-1:9]};
Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8]};
end
2'b00: begin // single
X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+2*(`S_LEN)-1:8+(`S_LEN)]};
Y = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN)-1:9]};
Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8]};
end
2'b10: begin // half
X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+3*(`H_LEN)-1:8+(`H_LEN)]};
Y = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN)-1:9]};
Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8]};
end
endcase
`CVTFPUNIT:
case (Fmt)
2'b11: begin // quad
case (OpCtrl[1:0])
2'b11: begin // quad
X = {{`FLEN-`Q_LEN{1'b1}}, TestVector[8+`Q_LEN+`Q_LEN-1:8+(`Q_LEN)]};
Ans = TestVector[8+(`Q_LEN-1):8];
end
2'b01: begin // double
X = {{`FLEN-`Q_LEN{1'b1}}, TestVector[8+`Q_LEN+`D_LEN-1:8+(`D_LEN)]};
Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]};
end
2'b00: begin // single
X = {{`FLEN-`Q_LEN{1'b1}}, TestVector[8+`Q_LEN+`S_LEN-1:8+(`S_LEN)]};
Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]};
end
2'b10: begin // half
X = {{`FLEN-`Q_LEN{1'b1}}, TestVector[8+`Q_LEN+`H_LEN-1:8+(`H_LEN)]};
Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]};
end
endcase
end
2'b01: begin // double
case (OpCtrl[1:0])
2'b11: begin // quad
X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+`D_LEN+`Q_LEN-1:8+(`Q_LEN)]};
Ans = TestVector[8+(`Q_LEN-1):8];
end
2'b01: begin // double
X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+`D_LEN+`D_LEN-1:8+(`D_LEN)]};
Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]};
end
2'b00: begin // single
X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+`D_LEN+`S_LEN-1:8+(`S_LEN)]};
Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]};
end
2'b10: begin // half
X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+`D_LEN+`H_LEN-1:8+(`H_LEN)]};
Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]};
end
endcase
end
2'b00: begin // single
case (OpCtrl[1:0])
2'b11: begin // quad
X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+`S_LEN+`Q_LEN-1:8+(`Q_LEN)]};
Ans = TestVector[8+(`Q_LEN-1):8];
end
2'b01: begin // double
X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+`S_LEN+`D_LEN-1:8+(`D_LEN)]};
Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]};
end
2'b00: begin // single
X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+`S_LEN+`S_LEN-1:8+(`S_LEN)]};
Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]};
end
2'b10: begin // half
X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+`S_LEN+`H_LEN-1:8+(`H_LEN)]};
Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`H_LEN-1):8]};
end
endcase
end
2'b10: begin // half
case (OpCtrl[1:0])
2'b11: begin // quad
X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+`H_LEN+`Q_LEN-1:8+(`Q_LEN)]};
Ans = TestVector[8+(`Q_LEN-1):8];
end
2'b01: begin // double
X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+`H_LEN+`D_LEN-1:8+(`D_LEN)]};
Ans = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+(`D_LEN-1):8]};
end
2'b00: begin // single
X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+`H_LEN+`S_LEN-1:8+(`S_LEN)]};
Ans = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+(`S_LEN-1):8]};
end
2'b10: begin // half
X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+`H_LEN+`H_LEN-1:8+(`H_LEN)]};
Ans = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+(`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}
casex ({OpCtrl[2], OpCtrl[0]})
2'b11: begin // long -> quad
SrcA = TestVector[8+`Q_LEN+`XLEN-1:8+(`Q_LEN)];
Ans = TestVector[8+(`Q_LEN-1):8];
end
2'b01: begin // int -> quad
// correctly sign extend the integer depending on if it's a signed/unsigned test
SrcA = {{`XLEN-32{TestVector[8+`Q_LEN+`XLEN]&~OpCtrl[1]}}, TestVector[8+`Q_LEN+`XLEN-1:8+(`Q_LEN)]};
Ans = TestVector[8+(`Q_LEN-1):8];
end
2'b10: begin // quad -> long
X = {{`FLEN-`Q_LEN{1'b1}}, TestVector[8+`XLEN+`Q_LEN-1:8+(`XLEN)]};
Ans = {TestVector[8+(`XLEN-1):8]};
end
2'b00: begin // double -> long
X = {{`FLEN-`Q_LEN{1'b1}}, TestVector[8+`XLEN+`Q_LEN-1:8+(`XLEN)]};
Ans = {{`XLEN-32{TestVector[8+`XLEN]&~OpCtrl[1]}},TestVector[8+(`XLEN-1):8]};
end
endcase
end
2'b01: begin // double
// {is the integer a long, is the opperation to an integer}
casex ({OpCtrl[2], OpCtrl[0]})
2'b11: begin // long -> double
SrcA = TestVector[8+`D_LEN+`XLEN-1:8+(`D_LEN)];
Ans = TestVector[8+(`D_LEN-1):8];
end
2'b01: begin // int -> double
// correctly sign extend the integer depending on if it's a signed/unsigned test
SrcA = {{`XLEN-32{TestVector[8+`D_LEN+`XLEN]&~OpCtrl[1]}}, TestVector[8+`D_LEN+`XLEN-1:8+(`D_LEN)]};
Ans = TestVector[8+(`D_LEN-1):8];
end
2'b10: begin // double -> long
X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+`XLEN+`D_LEN-1:8+(`XLEN)]};
Ans = {TestVector[8+(`XLEN-1):8]};
end
2'b00: begin // double -> int
X = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+`XLEN+`D_LEN-1:8+(`XLEN)]};
Ans = {{`XLEN-32{TestVector[8+`XLEN]&~OpCtrl[1]}},TestVector[8+(`XLEN-1):8]};
end
endcase
end
2'b00: begin // single
// {is the integer a long, is the opperation to an integer}
casex ({OpCtrl[2], OpCtrl[0]})
2'b11: begin // long -> single
SrcA = TestVector[8+`S_LEN+`XLEN-1:8+(`S_LEN)];
Ans = TestVector[8+(`S_LEN-1):8];
end
2'b01: begin // int -> single
// correctly sign extend the integer depending on if it's a signed/unsigned test
SrcA = {{`XLEN-32{TestVector[8+`S_LEN+`XLEN]&~OpCtrl[1]}}, TestVector[8+`S_LEN+`XLEN-1:8+(`S_LEN)]};
Ans = TestVector[8+(`S_LEN-1):8];
end
2'b10: begin // single -> long
X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+`XLEN+`S_LEN-1:8+(`XLEN)]};
Ans = {TestVector[8+(`XLEN-1):8]};
end
2'b00: begin // single -> int
X = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+`XLEN+`S_LEN-1:8+(`XLEN)]};
Ans = {{`XLEN-32{TestVector[8+`XLEN]&~OpCtrl[1]}},TestVector[8+(`XLEN-1):8]};
end
endcase
end
2'b10: begin // half
// {is the integer a long, is the opperation to an integer}
casex ({OpCtrl[2], OpCtrl[0]})
2'b11: begin // long -> half
SrcA = TestVector[8+`H_LEN+`XLEN-1:8+(`H_LEN)];
Ans = TestVector[8+(`H_LEN-1):8];
end
2'b01: begin // int -> half
// correctly sign extend the integer depending on if it's a signed/unsigned test
SrcA = {{`XLEN-32{TestVector[8+`H_LEN+`XLEN]&~OpCtrl[1]}}, TestVector[8+`H_LEN+`XLEN-1:8+(`H_LEN)]};
Ans = TestVector[8+(`H_LEN-1):8];
end
2'b10: begin // half -> long
X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+`XLEN+`H_LEN-1:8+(`XLEN)]};
Ans = {TestVector[8+(`XLEN-1):8]};
end
2'b00: begin // half -> int
X = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+`XLEN+`H_LEN-1:8+(`XLEN)]};
Ans = {{`XLEN-32{TestVector[8+`XLEN]&~OpCtrl[1]}}, TestVector[8+(`XLEN-1):8]};
end
endcase
end
endcase
endcase
end
unpack unpack(.X, .Y, .Z, .FmtE(ModFmt), .XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE,
.XManE, .YManE, .ZManE, .XNormE, .XNaNE, .YNaNE, .ZNaNE, .XSNaNE, .YSNaNE, .ZSNaNE,
.XDenormE, .YDenormE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE, .XInfE, .YInfE, .ZInfE,
.XExpMaxE, .ZOrigDenormE);
2022-05-19 16:32:30 +00:00
endmodule