Minor tweak to fix vectors not working for fadd.

This commit is contained in:
James E. Stine 2023-06-26 14:25:44 -05:00
parent 1a936882f8
commit 3cfec29cc7

View File

@ -2,7 +2,7 @@
// //
// Written: me@KatherineParry.com, james.stine@okstate.edu // Written: me@KatherineParry.com, james.stine@okstate.edu
// //
// Purpose: Testbench for Testfloat // Purpose: Testbench for UCB Testfloat on Wally
// //
// A component of the Wally configurable RISC-V project. // A component of the Wally configurable RISC-V project.
// //
@ -21,18 +21,21 @@
// either express or implied. See the License for the specific language governing permissions // either express or implied. See the License for the specific language governing permissions
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
//`include "wally-config.vh"
`include "config.vh" `include "config.vh"
`include "tests-fp.vh" `include "tests-fp.vh"
import cvw::*; import cvw::*;
module testbenchfp; module testbenchfp;
// Two parameters TEST, TEST_SIZE used with testfloat.do in sim dir
// to run specific precisions (e.g., quad or all)
parameter TEST="none"; parameter TEST="none";
parameter TEST_SIZE="none"; parameter TEST_SIZE="none";
`include "parameter-defs.vh" `include "parameter-defs.vh"
// FIXME: needs cleaning of unused variables (jes)
string Tests[]; // list of tests to be run string Tests[]; // list of tests to be run
logic [2:0] OpCtrl[]; // list of op controls logic [2:0] OpCtrl[]; // list of op controls
logic [2:0] Unit[]; // list of units being tested logic [2:0] Unit[]; // list of units being tested
@ -61,7 +64,8 @@ module testbenchfp;
logic [P.FMTBITS-1:0] ModFmt; // format - 10 = half, 00 = single, 01 = double, 11 = quad logic [P.FMTBITS-1:0] ModFmt; // format - 10 = half, 00 = single, 01 = double, 11 = quad
logic [P.FLEN-1:0] FpRes, FpCmpRes; // Results from each unit logic [P.FLEN-1:0] FpRes, FpCmpRes; // Results from each unit
logic [P.XLEN-1:0] IntRes, CmpRes; // Results from each unit logic [P.XLEN-1:0] IntRes, CmpRes; // Results from each unit
logic [4:0] FmaFlg, CvtFlg, DivFlg, CmpFlg; // Outputed flags logic [4:0] FmaFlg, CvtFlg, DivFlg; // Outputed flags
logic [4:0] CmpFlg; // Outputed flags
logic AnsNaN, ResNaN, NaNGood; logic AnsNaN, ResNaN, NaNGood;
logic Xs, Ys, Zs; // sign of the inputs logic Xs, Ys, Zs; // sign of the inputs
logic [P.NE-1:0] Xe, Ye, Ze; // exponent of the inputs logic [P.NE-1:0] Xe, Ye, Ze; // exponent of the inputs
@ -114,8 +118,8 @@ module testbenchfp;
logic [P.NE+1:0] QeM; logic [P.NE+1:0] QeM;
logic [P.DIVb:0] QmM; logic [P.DIVb:0] QmM;
logic [P.XLEN-1:0] FIntDivResultM; logic [P.XLEN-1:0] FIntDivResultM;
logic ResMatch; // Check if result matches logic ResMatch; // Check if result match
logic FlagMatch; // Check if flag matches logic FlagMatch; // Check if IEEE flags match
logic CheckNow; // Final check logic CheckNow; // Final check
/////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////
@ -139,6 +143,7 @@ module testbenchfp;
// all - test all of the above // all - test all of the above
initial begin initial begin
// Information displayed for user on what is simulating
$display("\nThe start of simulation..."); $display("\nThe start of simulation...");
$display("This simulation for TEST is %s", TEST); $display("This simulation for TEST is %s", TEST);
$display("This simulation for TEST is of the operand size of %s", TEST_SIZE); $display("This simulation for TEST is of the operand size of %s", TEST_SIZE);
@ -618,7 +623,6 @@ module testbenchfp;
end end
end end
end end
// check if nothing is being tested // check if nothing is being tested
if (Tests.size() == 0) begin if (Tests.size() == 0) begin
$display("TEST %s not supported in this configuration", TEST); $display("TEST %s not supported in this configuration", TEST);
@ -644,7 +648,7 @@ module testbenchfp;
string tt0; string tt0;
tt0 = $psprintf("%s", Tests[TestNum]); tt0 = $psprintf("%s", Tests[TestNum]);
testname = {p, tt0}; testname = {p, tt0};
//$display("Here you are %s", testname); $display("Here you are %s", testname);
$display("\n\nRunning %s vectors ", Tests[TestNum]); $display("\n\nRunning %s vectors ", Tests[TestNum]);
$readmemh(testname, TestVectors); $readmemh(testname, TestVectors);
// set the test index to 0 // set the test index to 0
@ -722,6 +726,7 @@ module testbenchfp;
.Xm, .Ym, .XZero, .YZero, .CmpIntRes(CmpRes), .Xm, .Ym, .XZero, .YZero, .CmpIntRes(CmpRes),
.XNaN, .YNaN, .XSNaN, .YSNaN, .X, .Y, .CmpNV(CmpFlg[4]), .CmpFpRes(FpCmpRes)); .XNaN, .YNaN, .XSNaN, .YSNaN, .X, .Y, .CmpNV(CmpFlg[4]), .CmpFpRes(FpCmpRes));
end end
if (TEST === "div" | TEST === "sqrt" | TEST === "all") begin: fdivsqrt if (TEST === "div" | TEST === "sqrt" | TEST === "all") begin: fdivsqrt
fdivsqrt #(P) fdivsqrt(.clk, .reset, .XsE(Xs), .FmtE(ModFmt), .XmE(Xm), .YmE(Ym), fdivsqrt #(P) fdivsqrt(.clk, .reset, .XsE(Xs), .FmtE(ModFmt), .XmE(Xm), .YmE(Ym),
.XeE(Xe), .YeE(Ye), .SqrtE(OpCtrlVal[0]), .SqrtM(OpCtrlVal[0]), .XeE(Xe), .YeE(Ye), .SqrtE(OpCtrlVal[0]), .SqrtM(OpCtrlVal[0]),
@ -836,13 +841,35 @@ module testbenchfp;
OldFDivBusyE = FDivDoneE; OldFDivBusyE = FDivDoneE;
// For FP division this adds extra clock cycles to make sure the // For FP division this adds extra clock cycles to make sure the
// computation completes. 18 clocks cycles are utilize to handle // computation completes.
// Quad, but this can be changed for each precision to go faster.
always @(posedge clk) begin always @(posedge clk) begin
// Add extra clock cycles in beginning for fdivsqrt to adequate reset state // Add extra clock cycles in beginning for fdivsqrt to adequate reset state
if (~(FDivBusyE|DivStart)|(UnitVal != `DIVUNIT)) begin if (~(FDivBusyE|DivStart)|(UnitVal != `DIVUNIT)) begin
// This allows specific number of clocks to allow each vector
// to complete for division or square root. It is an
// arbitrary value and can be changed, if needed.
case (FmtVal)
// QP
4'b11: begin
repeat (20)
@(posedge clk);
end
// HP
4'b10: begin
repeat (14)
@(posedge clk);
end
// DP
4'b01: begin
repeat (18) repeat (18)
@(posedge clk); @(posedge clk);
end
// SP
4'b00: begin
repeat (16)
@(posedge clk);
end
endcase // case (FmtVal)
if (reset != 1'b1) if (reset != 1'b1)
VectorNum += 1; // increment the vector VectorNum += 1; // increment the vector
end end
@ -850,7 +877,6 @@ module testbenchfp;
// check results on falling edge of clk // check results on falling edge of clk
always @(negedge clk) begin always @(negedge clk) begin
// check if the NaN value is good. IEEE754-2019 sections 6.3 and 6.2.3 specify: // check if the NaN value is good. IEEE754-2019 sections 6.3 and 6.2.3 specify:
// - the sign of the NaN does not matter for the opperations being tested // - the sign of the NaN does not matter for the opperations being tested
// - when 2 or more NaNs are inputed the NaN that is propigated doesn't matter // - when 2 or more NaNs are inputed the NaN that is propigated doesn't matter
@ -935,7 +961,8 @@ module testbenchfp;
// Testfloat outputs 800... for both the largest integer values for both positive and negitive numbers but // Testfloat outputs 800... for both the largest integer values for both positive and negitive numbers but
// the riscv spec specifies 2^31-1 for positive values out of range and NaNs ie 7fff... // the riscv spec specifies 2^31-1 for positive values out of range and NaNs ie 7fff...
else if ((UnitVal === `CVTINTUNIT) & ~(((WriteIntVal&~OpCtrlVal[0]&AnsFlg[4]&Xs&(Res[P.XLEN-1:0] === (P.XLEN)'(0))) | else if ((UnitVal === `CVTINTUNIT) &
~(((WriteIntVal&~OpCtrlVal[0]&AnsFlg[4]&Xs&(Res[P.XLEN-1:0] === (P.XLEN)'(0))) |
(WriteIntVal&OpCtrlVal[0]&AnsFlg[4]&(~Xs|XNaN)&OpCtrlVal[1]&(Res[P.XLEN-1:0] === {1'b0, {P.XLEN-1{1'b1}}})) | (WriteIntVal&OpCtrlVal[0]&AnsFlg[4]&(~Xs|XNaN)&OpCtrlVal[1]&(Res[P.XLEN-1:0] === {1'b0, {P.XLEN-1{1'b1}}})) |
(WriteIntVal&OpCtrlVal[0]&AnsFlg[4]&(~Xs|XNaN)&~OpCtrlVal[1]&(Res[P.XLEN-1:0] === {{P.XLEN-32{1'b0}}, 1'b0, {31{1'b1}}})) | (WriteIntVal&OpCtrlVal[0]&AnsFlg[4]&(~Xs|XNaN)&~OpCtrlVal[1]&(Res[P.XLEN-1:0] === {{P.XLEN-32{1'b0}}, 1'b0, {31{1'b1}}})) |
(~(WriteIntVal&~OpCtrlVal[0]&AnsFlg[4]&Xs&~XNaN)&(Res === Ans | NaNGood | NaNGood === 1'bx))) & (ResFlg === AnsFlg | AnsFlg === 5'bx))) begin (~(WriteIntVal&~OpCtrlVal[0]&AnsFlg[4]&Xs&~XNaN)&(Res === Ans | NaNGood | NaNGood === 1'bx))) & (ResFlg === AnsFlg | AnsFlg === 5'bx))) begin
@ -959,13 +986,11 @@ module testbenchfp;
// increment the rounding mode or loop back to rne // increment the rounding mode or loop back to rne
if (FrmNum < 4) FrmNum += 1; if (FrmNum < 4) FrmNum += 1;
else FrmNum = 0; else FrmNum = 0;
// if no more Tests - finish // if no more Tests - finish
if (Tests[TestNum] === "") begin if (Tests[TestNum] === "") begin
$display("\nAll Tests completed with %d errors\n", errors); $display("\nAll Tests completed with %d errors\n", errors);
$stop; $stop;
end end
$display("Running %s vectors", Tests[TestNum]); $display("Running %s vectors", Tests[TestNum]);
end end
end end
@ -1000,18 +1025,17 @@ module readvectors (
localparam Q_LEN = 32'd128; localparam Q_LEN = 32'd128;
`include "parameter-defs.vh" `include "parameter-defs.vh"
logic XEn, YEn, ZEn; logic XEn;
logic YEn;
logic ZEn;
logic FPUActive; logic FPUActive;
// apply test vectors on rising edge of clk // apply test vectors on rising edge of clk
// Format of vectors Inputs(1/2/3)_AnsFlg // Format of vectors Inputs(1/2/3)_AnsFlg
always @(VectorNum) begin always @(VectorNum) begin
// Initial delay is given to allow vector to work for fdiv
// otherwise it will fail on first vector - fix needed (jes)
DivStart = 1'b0; DivStart = 1'b0;
#20; #1;
AnsFlg = TestVector[4:0]; AnsFlg = TestVector[4:0];
DivStart = 1'b0;
case (Unit) case (Unit)
`FMAUNIT: `FMAUNIT:
case (Fmt) case (Fmt)
@ -1078,6 +1102,7 @@ module readvectors (
if (OpCtrl[0]) if (OpCtrl[0])
case (Fmt) case (Fmt)
2'b11: begin // quad 2'b11: begin // quad
#20;
X = TestVector[8+2*(P.Q_LEN)-1:8+(P.Q_LEN)]; X = TestVector[8+2*(P.Q_LEN)-1:8+(P.Q_LEN)];
Ans = TestVector[8+(P.Q_LEN-1):8]; Ans = TestVector[8+(P.Q_LEN-1):8];
if (~clk) #5; if (~clk) #5;
@ -1085,6 +1110,7 @@ module readvectors (
DivStart = 1'b0; DivStart = 1'b0;
end end
2'b01: if (P.D_SUPPORTED) begin // double 2'b01: if (P.D_SUPPORTED) begin // double
#20;
X = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+2*(P.D_LEN)-1:8+(P.D_LEN)]}; X = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+2*(P.D_LEN)-1:8+(P.D_LEN)]};
Ans = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+(P.D_LEN-1):8]}; Ans = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+(P.D_LEN-1):8]};
if (~clk) #5; if (~clk) #5;
@ -1092,6 +1118,7 @@ module readvectors (
DivStart = 1'b0; DivStart = 1'b0;
end end
2'b00: if (P.S_SUPPORTED) begin // single 2'b00: if (P.S_SUPPORTED) begin // single
#20;
X = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+2*(P.S_LEN)-1:8+1*(P.S_LEN)]}; X = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+2*(P.S_LEN)-1:8+1*(P.S_LEN)]};
Ans = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+(P.S_LEN-1):8]}; Ans = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+(P.S_LEN-1):8]};
if (~clk) #5; if (~clk) #5;
@ -1099,6 +1126,7 @@ module readvectors (
DivStart = 1'b0; DivStart = 1'b0;
end end
2'b10: begin // half 2'b10: begin // half
#20;
X = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+2*(P.H_LEN)-1:8+(P.H_LEN)]}; X = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+2*(P.H_LEN)-1:8+(P.H_LEN)]};
Ans = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+(P.H_LEN-1):8]}; Ans = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+(P.H_LEN-1):8]};
if (~clk) #5; if (~clk) #5;
@ -1109,6 +1137,7 @@ module readvectors (
else else
case (Fmt) case (Fmt)
2'b11: begin // quad 2'b11: begin // quad
#20;
X = TestVector[8+3*(P.Q_LEN)-1:8+2*(P.Q_LEN)]; X = TestVector[8+3*(P.Q_LEN)-1:8+2*(P.Q_LEN)];
Y = TestVector[8+2*(P.Q_LEN)-1:8+(P.Q_LEN)]; Y = TestVector[8+2*(P.Q_LEN)-1:8+(P.Q_LEN)];
Ans = TestVector[8+(P.Q_LEN-1):8]; Ans = TestVector[8+(P.Q_LEN-1):8];
@ -1117,6 +1146,7 @@ module readvectors (
DivStart = 1'b0; DivStart = 1'b0;
end end
2'b01: if (P.D_SUPPORTED) begin // double 2'b01: if (P.D_SUPPORTED) begin // double
#20;
X = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+3*(P.D_LEN)-1:8+2*(P.D_LEN)]}; X = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+3*(P.D_LEN)-1:8+2*(P.D_LEN)]};
Y = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+2*(P.D_LEN)-1:8+(P.D_LEN)]}; Y = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+2*(P.D_LEN)-1:8+(P.D_LEN)]};
Ans = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+(P.D_LEN-1):8]}; Ans = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+(P.D_LEN-1):8]};
@ -1125,6 +1155,7 @@ module readvectors (
DivStart = 1'b0; DivStart = 1'b0;
end end
2'b00: if (P.S_SUPPORTED) begin // single 2'b00: if (P.S_SUPPORTED) begin // single
#20;
X = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+3*(P.S_LEN)-1:8+2*(P.S_LEN)]}; X = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+3*(P.S_LEN)-1:8+2*(P.S_LEN)]};
Y = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+2*(P.S_LEN)-1:8+1*(P.S_LEN)]}; Y = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+2*(P.S_LEN)-1:8+1*(P.S_LEN)]};
Ans = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+(P.S_LEN-1):8]}; Ans = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+(P.S_LEN-1):8]};
@ -1133,6 +1164,7 @@ module readvectors (
DivStart = 1'b0; DivStart = 1'b0;
end end
2'b10: begin // half 2'b10: begin // half
#20;
X = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+3*(P.H_LEN)-1:8+2*(P.H_LEN)]}; X = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+3*(P.H_LEN)-1:8+2*(P.H_LEN)]};
Y = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+2*(P.H_LEN)-1:8+(P.H_LEN)]}; Y = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+2*(P.H_LEN)-1:8+(P.H_LEN)]};
Ans = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+(P.H_LEN-1):8]}; Ans = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+(P.H_LEN-1):8]};
@ -1247,7 +1279,6 @@ module readvectors (
endcase endcase
end end
endcase endcase
`CVTINTUNIT: `CVTINTUNIT:
case (Fmt) case (Fmt)
2'b11: begin // quad 2'b11: begin // quad