From 738bbf6479f025c975c82e223d1a7b67094532b4 Mon Sep 17 00:00:00 2001 From: Katherine Parry Date: Thu, 19 May 2022 16:32:30 +0000 Subject: [PATCH] Added fp tests - doesnpass yet --- addins/riscv-arch-test | 2 +- pipelined/config/rv64fp/wally-config.vh | 5 +- pipelined/regression/fp.do | 52 + pipelined/regression/sim-fp | 11 + pipelined/regression/sim-fp-batch | 10 + pipelined/regression/wave-fpu.do | 102 ++ pipelined/src/fpu/fcvtfp.sv | 2 +- pipelined/src/fpu/fcvtint.sv | 2 +- pipelined/src/fpu/fpu.sv | 4 +- pipelined/src/fpu/unpack.sv | 9 +- pipelined/testbench/testbench-fp.sv | 1538 +++++++++++++++++++++++ pipelined/testbench/tests-fp.vh | 587 +++++++++ 12 files changed, 2312 insertions(+), 12 deletions(-) create mode 100644 pipelined/regression/fp.do create mode 100755 pipelined/regression/sim-fp create mode 100755 pipelined/regression/sim-fp-batch create mode 100644 pipelined/regression/wave-fpu.do create mode 100644 pipelined/testbench/testbench-fp.sv create mode 100644 pipelined/testbench/tests-fp.vh diff --git a/addins/riscv-arch-test b/addins/riscv-arch-test index 307c77b26..be67c99bd 160000 --- a/addins/riscv-arch-test +++ b/addins/riscv-arch-test @@ -1 +1 @@ -Subproject commit 307c77b26e070ae85ffea665ad9b642b40e33c86 +Subproject commit be67c99bd461742aa1c100bcc0732657faae2230 diff --git a/pipelined/config/rv64fp/wally-config.vh b/pipelined/config/rv64fp/wally-config.vh index c6f80d497..36cda4d91 100644 --- a/pipelined/config/rv64fp/wally-config.vh +++ b/pipelined/config/rv64fp/wally-config.vh @@ -38,12 +38,13 @@ `define IEEE754 1 // MISA RISC-V configuration per specification -`define MISA (32'h00000104 | 1 << 5 | 0 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0 ) +//16 - quad 3 - double 5 - single +`define MISA (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 16 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0 ) `define ZICSR_SUPPORTED 1 `define ZIFENCEI_SUPPORTED 1 `define COUNTERS 32 `define ZICOUNTERS_SUPPORTED 1 -`define ZFH_SUPPORTED 0 +`define ZFH_SUPPORTED 1 /// Microarchitectural Features `define UARCH_PIPELINED 1 diff --git a/pipelined/regression/fp.do b/pipelined/regression/fp.do new file mode 100644 index 000000000..208118fc6 --- /dev/null +++ b/pipelined/regression/fp.do @@ -0,0 +1,52 @@ +# wally-pipelined.do +# +# Modification by Oklahoma State University & Harvey Mudd College +# Use with Testbench +# James Stine, 2008; David Harris 2021 +# Go Cowboys!!!!!! +# +# Takes 1:10 to run RV64IC tests using gui + +# run with vsim -do "do wally-pipelined.do rv64ic riscvarchtest-64m" + +# Use this wally-pipelined.do file to run this example. +# Either bring up ModelSim and type the following at the "ModelSim>" prompt: +# do wally-pipelined.do +# or, to run from a shell, type the following at the shell prompt: +# vsim -do wally-pipelined.do -c +# (omit the "-c" to see the GUI while running from the shell) + +onbreak {resume} + +# create library +if [file exists work] { + vdel -all +} +vlib work + +# compile source files +# suppress spurious warnngs about +# "Extra checking for conflicts with always_comb done at vopt time" +# because vsim will run vopt + +# start and run simulation +# remove +acc flag for faster sim during regressions if there is no need to access internal signals +# $num = the added words after the call +vlog +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-fp.sv ../src/fpu/*.sv -suppress 2583,7063,8607,2697 + +vsim -voptargs=+acc work.testbenchfp -G TEST=$2 + +view wave +#-- display input and output signals as hexidecimal values +#do ./wave-dos/peripheral-waves.do +#add log -recursive /* +#do wave.do deal with when ready + +do wave-fpu.do + +#-- Run the Simulation +#run 3600 +run -all +noview testbench-fp.sv +view wave + diff --git a/pipelined/regression/sim-fp b/pipelined/regression/sim-fp new file mode 100755 index 000000000..1d6425425 --- /dev/null +++ b/pipelined/regression/sim-fp @@ -0,0 +1,11 @@ + +# 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 everything + +vsim -do "do fp.do rv64fp mul" diff --git a/pipelined/regression/sim-fp-batch b/pipelined/regression/sim-fp-batch new file mode 100755 index 000000000..7e2c6a341 --- /dev/null +++ b/pipelined/regression/sim-fp-batch @@ -0,0 +1,10 @@ +# 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 everything + +vsim -c -do "do fp.do rv64fp fma" \ No newline at end of file diff --git a/pipelined/regression/wave-fpu.do b/pipelined/regression/wave-fpu.do new file mode 100644 index 000000000..d2ea6d486 --- /dev/null +++ b/pipelined/regression/wave-fpu.do @@ -0,0 +1,102 @@ + +add wave -noupdate /testbenchfp/clk +add wave -noupdate -radix decimal /testbenchfp/VectorNum +add wave -group Other -noupdate /testbenchfp/FrmNum +add wave -group Other -noupdate /testbenchfp/X +add wave -group Other -noupdate /testbenchfp/Y +add wave -group Other -noupdate /testbenchfp/Z +add wave -group Other -noupdate /testbenchfp/Res +add wave -group Other -noupdate /testbenchfp/Ans + +add wave -group Rne -noupdate /testbenchfp/FmaRneX +add wave -group Rne -noupdate /testbenchfp/FmaRneY +add wave -group Rne -noupdate /testbenchfp/FmaRneZ +add wave -group Rne -noupdate /testbenchfp/FmaRneRes +add wave -group Rne -noupdate /testbenchfp/FmaRneAns +add wave -group Rz -noupdate /testbenchfp/FmaRzX +add wave -group Rz -noupdate /testbenchfp/FmaRzY +add wave -group Rz -noupdate /testbenchfp/FmaRzZ +add wave -group Rz -noupdate /testbenchfp/FmaRzRes +add wave -group Rz -noupdate /testbenchfp/FmaRzAns +add wave -group Ru -noupdate /testbenchfp/FmaRuX +add wave -group Ru -noupdate /testbenchfp/FmaRuY +add wave -group Ru -noupdate /testbenchfp/FmaRuZ +add wave -group Ru -noupdate /testbenchfp/FmaRuRes +add wave -group Ru -noupdate /testbenchfp/FmaRuAns +add wave -group Rd -noupdate /testbenchfp/FmaRdX +add wave -group Rd -noupdate /testbenchfp/FmaRdY +add wave -group Rd -noupdate /testbenchfp/FmaRdZ +add wave -group Rd -noupdate /testbenchfp/FmaRdRes +add wave -group Rd -noupdate /testbenchfp/FmaRdAns +add wave -group Rnm -noupdate /testbenchfp/FmaRnmX +add wave -group Rnm -noupdate /testbenchfp/FmaRnmY +add wave -group Rnm -noupdate /testbenchfp/FmaRnmZ +add wave -group Rnm -noupdate /testbenchfp/FmaRnmRes +add wave -group Rnm -noupdate /testbenchfp/FmaRnmAns +add wave -group AllSignals -noupdate /* +add wave -group AllSignals -noupdate /testbenchfp/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rne/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rne/expadd/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rne/mult/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rne/align/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rne/sign/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rne/add/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rne/loa/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rne/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rne/normalize/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rne/fmaround/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rne/resultsign/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rne/fmaflags/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rne/resultselect/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rz/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rz/expadd/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rz/mult/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rz/align/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rz/sign/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rz/add/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rz/loa/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rz/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rz/normalize/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rz/fmaround/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rz/resultsign/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rz/fmaflags/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rz/resultselect/* +add wave -group AllSignals -noupdate /testbenchfp/fma1ru/* +add wave -group AllSignals -noupdate /testbenchfp/fma1ru/expadd/* +add wave -group AllSignals -noupdate /testbenchfp/fma1ru/mult/* +add wave -group AllSignals -noupdate /testbenchfp/fma1ru/align/* +add wave -group AllSignals -noupdate /testbenchfp/fma1ru/sign/* +add wave -group AllSignals -noupdate /testbenchfp/fma1ru/add/* +add wave -group AllSignals -noupdate /testbenchfp/fma1ru/loa/* +add wave -group AllSignals -noupdate /testbenchfp/fma2ru/* +add wave -group AllSignals -noupdate /testbenchfp/fma2ru/normalize/* +add wave -group AllSignals -noupdate /testbenchfp/fma2ru/fmaround/* +add wave -group AllSignals -noupdate /testbenchfp/fma2ru/resultsign/* +add wave -group AllSignals -noupdate /testbenchfp/fma2ru/fmaflags/* +add wave -group AllSignals -noupdate /testbenchfp/fma2ru/resultselect/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rd/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rd/expadd/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rd/mult/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rd/align/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rd/sign/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rd/add/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rd/loa/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rd/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rd/normalize/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rd/fmaround/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rd/resultsign/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rd/fmaflags/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rd/resultselect/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rnm/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rnm/expadd/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rnm/mult/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rnm/align/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rnm/sign/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rnm/add/* +add wave -group AllSignals -noupdate /testbenchfp/fma1rnm/loa/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rnm/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rnm/normalize/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rnm/fmaround/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rnm/resultsign/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rnm/fmaflags/* +add wave -group AllSignals -noupdate /testbenchfp/fma2rnm/resultselect/* \ No newline at end of file diff --git a/pipelined/src/fpu/fcvtfp.sv b/pipelined/src/fpu/fcvtfp.sv index fb8e1ad9a..f43d15661 100644 --- a/pipelined/src/fpu/fcvtfp.sv +++ b/pipelined/src/fpu/fcvtfp.sv @@ -1,6 +1,6 @@ `include "wally-config.vh" -module cvtfp ( +module fcvtfp ( input logic [10:0] XExpE, // input's exponent input logic [52:0] XManE, // input's mantissa input logic XSgnE, // input's sign diff --git a/pipelined/src/fpu/fcvtint.sv b/pipelined/src/fpu/fcvtint.sv index 6a6686993..97007d660 100644 --- a/pipelined/src/fpu/fcvtint.sv +++ b/pipelined/src/fpu/fcvtint.sv @@ -2,7 +2,7 @@ `include "wally-config.vh" // `include "../../config/rv64icfd/wally-config.vh" // `define XLEN 64 -module fcvt ( +module fcvtint ( input logic XSgnE, // X's sign input logic [10:0] XExpE, // X's exponent input logic [52:0] XManE, // X's fraction diff --git a/pipelined/src/fpu/fpu.sv b/pipelined/src/fpu/fpu.sv index 9a78a36b2..7b05b33f2 100755 --- a/pipelined/src/fpu/fpu.sv +++ b/pipelined/src/fpu/fpu.sv @@ -213,12 +213,12 @@ module fpu ( .FDivBusyE, .done(FDivSqrtDoneE), .AS_Result(FDivResM), .Flags(FDivFlgM)); // other FP execution units - cvtfp cvtfp (.XExpE, .XManE, .XSgnE, .XZeroE, .XDenormE, .XInfE, .XNaNE, .XSNaNE, .FrmE, .FmtE, .CvtFpResE, .CvtFpFlgE); + fcvtfp fcvtfp (.XExpE, .XManE, .XSgnE, .XZeroE, .XDenormE, .XInfE, .XNaNE, .XSNaNE, .FrmE, .FmtE, .CvtFpResE, .CvtFpFlgE); fcmp fcmp (.FmtE, .FOpCtrlE, .XSgnE, .YSgnE, .XExpE, .YExpE, .XManE, .YManE, .XZeroE, .YZeroE, .XNaNE, .YNaNE, .XSNaNE, .YSNaNE, .FSrcXE, .FSrcYE, .CmpNVE, .CmpResE); fsgn fsgn (.SgnOpCodeE(FOpCtrlE[1:0]), .XSgnE, .YSgnE, .FSrcXE, .FmtE, .SgnResE); fclassify fclassify (.XSgnE, .XDenormE, .XZeroE, .XNaNE, .XInfE, .XNormE, .XSNaNE, .ClassResE); - fcvt fcvt (.XSgnE, .XExpE, .XManE, .XZeroE, .XNaNE, .XInfE, .XDenormE, .ForwardedSrcAE, .FOpCtrlE, .FmtE, .FrmE, + fcvtint fcvtint (.XSgnE, .XExpE, .XManE, .XZeroE, .XNaNE, .XInfE, .XDenormE, .ForwardedSrcAE, .FOpCtrlE, .FmtE, .FrmE, .CvtResE, .CvtFlgE); // data to be stored in memory - to IEU diff --git a/pipelined/src/fpu/unpack.sv b/pipelined/src/fpu/unpack.sv index 1c0589e10..a1d96b8b9 100644 --- a/pipelined/src/fpu/unpack.sv +++ b/pipelined/src/fpu/unpack.sv @@ -2,7 +2,7 @@ module unpack ( input logic [`FLEN-1:0] X, Y, Z, // inputs from register file - input logic [`FPSIZES/3:0] FmtE, // format signal 00 - single 10 - double 11 - quad 10 - half + input logic [`FPSIZES/3:0] FmtE, // format signal 00 - single 01 - double 11 - quad 10 - half 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) @@ -50,7 +50,6 @@ module unpack ( end else if (`FPSIZES == 2) begin // if there are 2 floating point formats supported - //***need better names for these constants // largest format | smaller format //---------------------------------- @@ -339,9 +338,9 @@ module unpack ( ZExpE = {ZLen1[`D_LEN-2], {`Q_NE-`D_NE{~ZLen1[`D_LEN-2]&~ZExpZero|ZExpMaxE}}, ZLen1[`D_LEN-3:`D_NF]}; // extract the fraction and add the nessesary trailing zeros - XFracE = {XLen1[`D_NE-1:0], (`Q_NF-`D_NE)'(0)}; - YFracE = {YLen1[`D_NE-1:0], (`Q_NF-`D_NE)'(0)}; - ZFracE = {ZLen1[`D_NE-1:0], (`Q_NF-`D_NE)'(0)}; + XFracE = {XLen1[`D_NF-1:0], (`Q_NF-`D_NF)'(0)}; + YFracE = {YLen1[`D_NF-1:0], (`Q_NF-`D_NF)'(0)}; + ZFracE = {ZLen1[`D_NF-1:0], (`Q_NF-`D_NF)'(0)}; // is the exponent non-zero XExpNonzero = |XLen1[`D_LEN-2:`D_NE]; diff --git a/pipelined/testbench/testbench-fp.sv b/pipelined/testbench/testbench-fp.sv new file mode 100644 index 000000000..42aa7312b --- /dev/null +++ b/pipelined/testbench/testbench-fp.sv @@ -0,0 +1,1538 @@ + +`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 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), + .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), + .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), + .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), + .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), + .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), + .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), + .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), + .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), + .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), + .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), + .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(3'b0), .FmtE(ModFmt), .SumE, .NegSumE, .InvZE, .NormCntE, .ZSgnEffE, .PSgnE, + .ProdExpE, .AddendStickyE, .KillProdE); + fma2 fma2(.XSgnM(XSgn), .YSgnM(YSgn), + .ZExpM(ZExp), + .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 + + 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]}))); + 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]}))); + 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]}))); + 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]}))); + 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 [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); +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 [`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)]; + Y = TestVector[8+2*(`Q_LEN)-1:8+(`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)]}; + Y = {{`FLEN-`D_LEN{1'b1}}, TestVector[8+2*(`D_LEN)-1:8+(`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)]}; + Y = {{`FLEN-`S_LEN{1'b1}}, TestVector[8+2*(`S_LEN)-1:8+1*(`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)]}; + Y = {{`FLEN-`H_LEN{1'b1}}, TestVector[8+2*(`H_LEN)-1:8+(`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); +endmodule \ No newline at end of file diff --git a/pipelined/testbench/tests-fp.vh b/pipelined/testbench/tests-fp.vh new file mode 100644 index 000000000..d285454bb --- /dev/null +++ b/pipelined/testbench/tests-fp.vh @@ -0,0 +1,587 @@ +/////////////////////////////////////////// +// tests.vh +// +// Written: David_Harris@hmc.edu 7 October 2021 +// Modified: +// +// Purpose: List of tests to apply +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + + +`define PATH "../../tests/fp/vectors/" +`define ADD_OPCTRL 3'b110 +`define MUL_OPCTRL 3'b100 +`define SUB_OPCTRL 3'b111 +`define FADD_OPCTRL 3'b000 +`define DIV_OPCTRL 3'b000 +`define SQRT_OPCTRL 3'b001 +`define LE_OPCTRL 3'b011 +`define LT_OPCTRL 3'b001 +`define EQ_OPCTRL 3'b010 +`define TO_UI_OPCTRL 3'b011 +`define TO_I_OPCTRL 3'b001 +`define TO_UL_OPCTRL 3'b111 +`define TO_L_OPCTRL 3'b101 +`define FROM_UI_OPCTRL 3'b010 +`define FROM_I_OPCTRL 3'b000 +`define FROM_UL_OPCTRL 3'b110 +`define FROM_L_OPCTRL 3'b100 +`define RNE 3'b000 +`define RZ 3'b001 +`define RU 3'b011 +`define RD 3'b010 +`define RNM 3'b100 +`define FMAUNIT 0 +`define DIVUNIT 1 +`define CVTINTUNIT 2 +`define CVTFPUNIT 3 +`define CMPUNIT 4 + +string f16rv32cvtint[] = '{ + "f16_to_i32_rne.tv", + "f16_to_i32_rz.tv", + "f16_to_i32_ru.tv", + "f16_to_i32_rd.tv", + "f16_to_i32_rnm.tv", + "f16_to_ui32_rne.tv", + "f16_to_ui32_rz.tv", + "f16_to_ui32_ru.tv", + "f16_to_ui32_rd.tv", + "f16_to_ui32_rnm.tv", + "ui32_to_f16_rne.tv", + "ui32_to_f16_rz.tv", + "ui32_to_f16_ru.tv", + "ui32_to_f16_rd.tv", + "ui32_to_f16_rnm.tv", + "i32_to_f16_rne.tv", + "i32_to_f16_rz.tv", + "i32_to_f16_ru.tv", + "i32_to_f16_rd.tv", + "i32_to_f16_rnm.tv" +}; + +string f16rv64cvtint[] = '{ + "f16_to_ui64_rne.tv", + "f16_to_ui64_rz.tv", + "f16_to_ui64_ru.tv", + "f16_to_ui64_rd.tv", + "f16_to_ui64_rnm.tv", + "f16_to_i64_rne.tv", + "f16_to_i64_rz.tv", + "f16_to_i64_ru.tv", + "f16_to_i64_rd.tv", + "f16_to_i64_rnm.tv", + "ui64_to_f16_rne.tv", + "ui64_to_f16_rz.tv", + "ui64_to_f16_ru.tv", + "ui64_to_f16_rd.tv", + "ui64_to_f16_rnm.tv", + "i64_to_f16_rne.tv", + "i64_to_f16_rz.tv", + "i64_to_f16_ru.tv", + "i64_to_f16_rd.tv", + "i64_to_f16_rnm.tv" +}; + +string f32rv32cvtint[] = '{ + "ui32_to_f32_rne.tv", + "ui32_to_f32_rz.tv", + "ui32_to_f32_ru.tv", + "ui32_to_f32_rd.tv", + "ui32_to_f32_rnm.tv", + "i32_to_f32_rne.tv", + "i32_to_f32_rz.tv", + "i32_to_f32_ru.tv", + "i32_to_f32_rd.tv", + "i32_to_f32_rnm.tv", + "f32_to_ui32_rne.tv", + "f32_to_ui32_rz.tv", + "f32_to_ui32_ru.tv", + "f32_to_ui32_rd.tv", + "f32_to_ui32_rnm.tv", + "f32_to_i32_rne.tv", + "f32_to_i32_rz.tv", + "f32_to_i32_ru.tv", + "f32_to_i32_rd.tv", + "f32_to_i32_rnm.tv" +}; + +string f32rv64cvtint[] = '{ + "ui64_to_f32_rne.tv", + "ui64_to_f32_rz.tv", + "ui64_to_f32_ru.tv", + "ui64_to_f32_rd.tv", + "ui64_to_f32_rnm.tv", + "i64_to_f32_rne.tv", + "i64_to_f32_rz.tv", + "i64_to_f32_ru.tv", + "i64_to_f32_rd.tv", + "i64_to_f32_rnm.tv", + "f32_to_ui64_rne.tv", + "f32_to_ui64_rz.tv", + "f32_to_ui64_ru.tv", + "f32_to_ui64_rd.tv", + "f32_to_ui64_rnm.tv", + "f32_to_i64_rne.tv", + "f32_to_i64_rz.tv", + "f32_to_i64_ru.tv", + "f32_to_i64_rd.tv", + "f32_to_i64_rnm.tv" +}; + + +string f64rv32cvtint[] = '{ + "ui32_to_f64_rne.tv", + "ui32_to_f64_rz.tv", + "ui32_to_f64_ru.tv", + "ui32_to_f64_rd.tv", + "ui32_to_f64_rnm.tv", + "i32_to_f64_rne.tv", + "i32_to_f64_rz.tv", + "i32_to_f64_ru.tv", + "i32_to_f64_rd.tv", + "i32_to_f64_rnm.tv", + "f64_to_ui32_rne.tv", + "f64_to_ui32_rz.tv", + "f64_to_ui32_ru.tv", + "f64_to_ui32_rd.tv", + "f64_to_ui32_rnm.tv", + "f64_to_i32_rne.tv", + "f64_to_i32_rz.tv", + "f64_to_i32_ru.tv", + "f64_to_i32_rd.tv", + "f64_to_i32_rnm.tv" +}; + +string f64rv64cvtint[] = '{ + "ui64_to_f64_rne.tv", + "ui64_to_f64_rz.tv", + "ui64_to_f64_ru.tv", + "ui64_to_f64_rd.tv", + "ui64_to_f64_rnm.tv", + "i64_to_f64_rne.tv", + "i64_to_f64_rz.tv", + "i64_to_f64_ru.tv", + "i64_to_f64_rd.tv", + "i64_to_f64_rnm.tv", + "f64_to_ui64_rne.tv", + "f64_to_ui64_rz.tv", + "f64_to_ui64_ru.tv", + "f64_to_ui64_rd.tv", + "f64_to_ui64_rnm.tv", + "f64_to_i64_rne.tv", + "f64_to_i64_rz.tv", + "f64_to_i64_ru.tv", + "f64_to_i64_rd.tv", + "f64_to_i64_rnm.tv" +}; + +string f128rv64cvtint[] = '{ + "ui64_to_f128_rne.tv", + "ui64_to_f128_rz.tv", + "ui64_to_f128_ru.tv", + "ui64_to_f128_rd.tv", + "ui64_to_f128_rnm.tv", + "i64_to_f128_rne.tv", + "i64_to_f128_rz.tv", + "i64_to_f128_ru.tv", + "i64_to_f128_rd.tv", + "i64_to_f128_rnm.tv", + "f128_to_ui64_rne.tv", + "f128_to_ui64_rz.tv", + "f128_to_ui64_ru.tv", + "f128_to_ui64_rd.tv", + "f128_to_ui64_rnm.tv", + "f128_to_i64_rne.tv", + "f128_to_i64_rz.tv", + "f128_to_i64_ru.tv", + "f128_to_i64_rd.tv", + "f128_to_i64_rnm.tv" +}; + +string f128rv32cvtint[] = '{ + "ui32_to_f128_rne.tv", + "ui32_to_f128_rz.tv", + "ui32_to_f128_ru.tv", + "ui32_to_f128_rd.tv", + "ui32_to_f128_rnm.tv", + "i32_to_f128_rne.tv", + "i32_to_f128_rz.tv", + "i32_to_f128_ru.tv", + "i32_to_f128_rd.tv", + "i32_to_f128_rnm.tv", + "f128_to_ui32_rne.tv", + "f128_to_ui32_rz.tv", + "f128_to_ui32_ru.tv", + "f128_to_ui32_rd.tv", + "f128_to_ui32_rnm.tv", + "f128_to_i32_rne.tv", + "f128_to_i32_rz.tv", + "f128_to_i32_ru.tv", + "f128_to_i32_rd.tv", + "f128_to_i32_rnm.tv" +}; + + +string f32f16cvt[] = '{ + "f32_to_f16_rne.tv", + "f32_to_f16_rz.tv", + "f32_to_f16_ru.tv", + "f32_to_f16_rd.tv", + "f32_to_f16_rnm.tv", + "f16_to_f32_rne.tv", + "f16_to_f32_rz.tv", + "f16_to_f32_ru.tv", + "f16_to_f32_rd.tv", + "f16_to_f32_rnm.tv" +}; + +string f64f16cvt[] = '{ + "f64_to_f16_rne.tv", + "f64_to_f16_rz.tv", + "f64_to_f16_ru.tv", + "f64_to_f16_rd.tv", + "f64_to_f16_rnm.tv", + "f16_to_f64_rne.tv", + "f16_to_f64_rz.tv", + "f16_to_f64_ru.tv", + "f16_to_f64_rd.tv", + "f16_to_f64_rnm.tv" +}; + +string f128f16cvt[] = '{ + "f128_to_f16_rne.tv", + "f128_to_f16_rz.tv", + "f128_to_f16_ru.tv", + "f128_to_f16_rd.tv", + "f128_to_f16_rnm.tv", + "f16_to_f128_rne.tv", + "f16_to_f128_rz.tv", + "f16_to_f128_ru.tv", + "f16_to_f128_rd.tv", + "f16_to_f128_rnm.tv" +}; + +string f64f32cvt[] = '{ + "f64_to_f32_rne.tv", + "f64_to_f32_rz.tv", + "f64_to_f32_ru.tv", + "f64_to_f32_rd.tv", + "f64_to_f32_rnm.tv", + "f32_to_f64_rne.tv", + "f32_to_f64_rz.tv", + "f32_to_f64_ru.tv", + "f32_to_f64_rd.tv", + "f32_to_f64_rnm.tv" +}; + + +string f128f32cvt[] = '{ + "f128_to_f32_rne.tv", + "f128_to_f32_rz.tv", + "f128_to_f32_ru.tv", + "f128_to_f32_rd.tv", + "f128_to_f32_rnm.tv", + "f32_to_f128_rne.tv", + "f32_to_f128_rz.tv", + "f32_to_f128_ru.tv", + "f32_to_f128_rd.tv", + "f32_to_f128_rnm.tv" +}; + + +string f128f64cvt[] = '{ + "f64_to_f128_rne.tv", + "f64_to_f128_rz.tv", + "f64_to_f128_ru.tv", + "f64_to_f128_rd.tv", + "f64_to_f128_rnm.tv", + "f128_to_f64_rne.tv", + "f128_to_f64_rz.tv", + "f128_to_f64_ru.tv", + "f128_to_f64_rd.tv", + "f128_to_f64_rnm.tv" +}; + +string f16add[] = '{ + "f16_add_rne.tv", + "f16_add_rz.tv", + "f16_add_ru.tv", + "f16_add_rd.tv", + "f16_add_rnm.tv" +}; + +string f32add[] = '{ + "f32_add_rne.tv", + "f32_add_rz.tv", + "f32_add_ru.tv", + "f32_add_rd.tv", + "f32_add_rnm.tv" +}; + +string f64add[] = '{ + "f64_add_rne.tv", + "f64_add_rz.tv", + "f64_add_ru.tv", + "f64_add_rd.tv", + "f64_add_rnm.tv" +}; + +string f128add[] = '{ + "f128_add_rne.tv", + "f128_add_rz.tv", + "f128_add_ru.tv", + "f128_add_rd.tv", + "f128_add_rnm.tv" +}; + +string f16sub[] = '{ + "f16_sub_rne.tv", + "f16_sub_rz.tv", + "f16_sub_ru.tv", + "f16_sub_rd.tv", + "f16_sub_rnm.tv" +}; + +string f32sub[] = '{ + "f32_sub_rne.tv", + "f32_sub_rz.tv", + "f32_sub_ru.tv", + "f32_sub_rd.tv", + "f32_sub_rnm.tv" +}; + +string f64sub[] = '{ + "f64_sub_rne.tv", + "f64_sub_rz.tv", + "f64_sub_ru.tv", + "f64_sub_rd.tv", + "f64_sub_rnm.tv" +}; + +string f128sub[] = '{ + "f128_sub_rne.tv", + "f128_sub_rz.tv", + "f128_sub_ru.tv", + "f128_sub_rd.tv", + "f128_sub_rnm.tv" +}; + +string f16mul[] = '{ + "f16_mul_rne.tv", + "f16_mul_rz.tv", + "f16_mul_ru.tv", + "f16_mul_rd.tv", + "f16_mul_rnm.tv" +}; + +string f32mul[] = '{ + "f32_mul_rne.tv", + "f32_mul_rz.tv", + "f32_mul_ru.tv", + "f32_mul_rd.tv", + "f32_mul_rnm.tv" +}; + +string f64mul[] = '{ + "f64_mul_rne.tv", + "f64_mul_rz.tv", + "f64_mul_ru.tv", + "f64_mul_rd.tv", + "f64_mul_rnm.tv" +}; + +string f128mul[] = '{ + "f128_mul_rne.tv", + "f128_mul_rz.tv", + "f128_mul_ru.tv", + "f128_mul_rd.tv", + "f128_mul_rnm.tv" +}; + +string f16div[] = '{ + "f16_div_rne.tv", + "f16_div_rz.tv", + "f16_div_ru.tv", + "f16_div_rd.tv", + "f16_div_rnm.tv" +}; + +string f32div[] = '{ + "f32_div_rne.tv", + "f32_div_rz.tv", + "f32_div_ru.tv", + "f32_div_rd.tv", + "f32_div_rnm.tv" +}; + +string f64div[] = '{ + "f64_div_rne.tv", + "f64_div_rz.tv", + "f64_div_ru.tv", + "f64_div_rd.tv", + "f64_div_rnm.tv" +}; + +string f128div[] = '{ + "f128_div_rne.tv", + "f128_div_rz.tv", + "f128_div_ru.tv", + "f128_div_rd.tv", + "f128_div_rnm.tv" +}; + +string f16sqrt[] = '{ + "f16_sqrt_rne.tv", + "f16_sqrt_rz.tv", + "f16_sqrt_ru.tv", + "f16_sqrt_rd.tv", + "f16_sqrt_rnm.tv" +}; + +string f32sqrt[] = '{ + "f32_sqrt_rne.tv", + "f32_sqrt_rz.tv", + "f32_sqrt_ru.tv", + "f32_sqrt_rd.tv", + "f32_sqrt_rnm.tv" +}; + +string f64sqrt[] = '{ + "f64_sqrt_rne.tv", + "f64_sqrt_rz.tv", + "f64_sqrt_ru.tv", + "f64_sqrt_rd.tv", + "f64_sqrt_rnm.tv" +}; + +string f128sqrt[] = '{ + "f128_sqrt_rne.tv", + "f128_sqrt_rz.tv", + "f128_sqrt_ru.tv", + "f128_sqrt_rd.tv", + "f128_sqrt_rnm.tv" +}; + +string f16cmp[] = '{ + "f16_eq_rne.tv", + "f16_eq_rz.tv", + "f16_eq_ru.tv", + "f16_eq_rd.tv", + "f16_eq_rnm.tv", + "f16_le_rne.tv", + "f16_le_rz.tv", + "f16_le_ru.tv", + "f16_le_rd.tv", + "f16_le_rnm.tv", + "f16_lt_rne.tv", + "f16_lt_rz.tv", + "f16_lt_ru.tv", + "f16_lt_rd.tv", + "f16_lt_rnm.tv" +}; + +string f32cmp[] = '{ + "f32_eq_rne.tv", + "f32_eq_rz.tv", + "f32_eq_ru.tv", + "f32_eq_rd.tv", + "f32_eq_rnm.tv", + "f32_le_rne.tv", + "f32_le_rz.tv", + "f32_le_ru.tv", + "f32_le_rd.tv", + "f32_le_rnm.tv", + "f32_lt_rne.tv", + "f32_lt_rz.tv", + "f32_lt_ru.tv", + "f32_lt_rd.tv", + "f32_lt_rnm.tv" +}; + +string f64cmp[] = '{ + "f64_eq_rne.tv", + "f64_eq_rz.tv", + "f64_eq_ru.tv", + "f64_eq_rd.tv", + "f64_eq_rnm.tv", + "f64_le_rne.tv", + "f64_le_rz.tv", + "f64_le_ru.tv", + "f64_le_rd.tv", + "f64_le_rnm.tv", + "f64_lt_rne.tv", + "f64_lt_rz.tv", + "f64_lt_ru.tv", + "f64_lt_rd.tv", + "f64_lt_rnm.tv" +}; + +string f128cmp[] = '{ + "f128_eq_rne.tv", + "f128_eq_rz.tv", + "f128_eq_ru.tv", + "f128_eq_rd.tv", + "f128_eq_rnm.tv", + "f128_le_rne.tv", + "f128_le_rz.tv", + "f128_le_ru.tv", + "f128_le_rd.tv", + "f128_le_rnm.tv", + "f128_lt_rne.tv", + "f128_lt_rz.tv", + "f128_lt_ru.tv", + "f128_lt_rd.tv", + "f128_lt_rnm.tv" +}; + +string f16fma[] = '{ + "f16_mulAdd_rne.tv", + "f16_mulAdd_rz.tv", + "f16_mulAdd_ru.tv", + "f16_mulAdd_rd.tv", + "f16_mulAdd_rnm.tv" +}; + +string f32fma[] = '{ + "f32_mulAdd_rne.tv", + "f32_mulAdd_rz.tv", + "f32_mulAdd_ru.tv", + "f32_mulAdd_rd.tv", + "f32_mulAdd_rnm.tv" +}; + +string f64fma[] = '{ + "f64_mulAdd_rne.tv", + "f64_mulAdd_rz.tv", + "f64_mulAdd_ru.tv", + "f64_mulAdd_rd.tv", + "f64_mulAdd_rnm.tv" +}; + +string f128fma[] = '{ + "f128_mulAdd_rne.tv", + "f128_mulAdd_rz.tv", + "f128_mulAdd_ru.tv", + "f128_mulAdd_rd.tv", + "f128_mulAdd_rnm.tv" +}; + + +