mirror of
https://github.com/openhwgroup/cvw.git
synced 2025-04-22 21:08:08 -04:00
Merge branch 'main' of https://github.com/openhwgroup/cvw into dev
This commit is contained in:
commit
35cd4e1d6c
1 changed files with 92 additions and 112 deletions
|
@ -83,7 +83,7 @@ module testbenchfp;
|
|||
logic [P.LOGCVTLEN-1:0] CvtShiftAmtE; // how much to shift by
|
||||
logic [P.DIVb:0] Quot;
|
||||
logic CvtResSubnormUfE;
|
||||
logic DivStart;
|
||||
logic DivStart=0;
|
||||
logic FDivBusyE;
|
||||
logic OldFDivBusyE;
|
||||
logic reset = 1'b0;
|
||||
|
@ -120,7 +120,11 @@ module testbenchfp;
|
|||
logic ResMatch; // Check if result match
|
||||
logic FlagMatch; // Check if IEEE flags match
|
||||
logic CheckNow; // Final check
|
||||
logic FMAop; // Is this a FMA operation?
|
||||
logic FMAop; // Is this a FMA operation?
|
||||
|
||||
// FSM for testing each item per clock
|
||||
typedef enum logic [2:0] {S0, Start, S2, Done} statetype;
|
||||
statetype state, nextstate;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -676,7 +680,7 @@ module testbenchfp;
|
|||
.VectorNum, .Ans(Ans), .AnsFlg(AnsFlg), .SrcA,
|
||||
.Xs, .Ys, .Zs, .Unit(UnitVal),
|
||||
.Xe, .Ye, .Ze, .TestNum, .OpCtrl(OpCtrlVal),
|
||||
.Xm, .Ym, .Zm, .DivStart,
|
||||
.Xm, .Ym, .Zm,
|
||||
.XNaN, .YNaN, .ZNaN,
|
||||
.XSNaN, .YSNaN, .ZSNaN,
|
||||
.XSubnorm, .ZSubnorm,
|
||||
|
@ -748,16 +752,6 @@ module testbenchfp;
|
|||
clk = 1; #5; clk = 0; #5;
|
||||
end
|
||||
|
||||
// Provide reset for divsqrt to reset state to IDLE
|
||||
// Previous version did not initiate a divide due to missing state
|
||||
// information. This starts the FSM by putting the fdivsqrt into
|
||||
// the IDLE state.
|
||||
initial
|
||||
begin
|
||||
#0 reset = 1'b1;
|
||||
#25 reset = 1'b0;
|
||||
end
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ||||| ||| |||||||||| ||||| |||
|
||||
|
@ -835,45 +829,64 @@ module testbenchfp;
|
|||
`CMPUNIT: ResFlg = CmpFlg;
|
||||
`CVTINTUNIT: ResFlg = Flg;
|
||||
`CVTFPUNIT: ResFlg = Flg;
|
||||
endcase
|
||||
end
|
||||
endcase
|
||||
|
||||
// Use four state test sequence to handle div properly.
|
||||
// Four states should allow other operations to finish
|
||||
// properly and within time.
|
||||
case (state)
|
||||
S0: begin
|
||||
DivStart = 1'b0;
|
||||
nextstate = Start;
|
||||
end
|
||||
Start: begin
|
||||
if (UnitVal == `DIVUNIT)
|
||||
DivStart = 1'b1;
|
||||
else
|
||||
DivStart = 1'b0;
|
||||
nextstate = S2;
|
||||
end
|
||||
S2: begin
|
||||
DivStart = 1'b0;
|
||||
if ((FDivBusyE)|(~DivDone))
|
||||
nextstate = S2;
|
||||
else
|
||||
nextstate = Done;
|
||||
end
|
||||
Done: begin
|
||||
DivStart = 1'b0;
|
||||
nextstate = S0;
|
||||
end
|
||||
endcase // case (state)
|
||||
|
||||
end
|
||||
|
||||
// Provide reset for divsqrt to reset state
|
||||
initial
|
||||
begin
|
||||
#0 reset = 1'b1;
|
||||
#25 reset = 1'b0;
|
||||
end
|
||||
|
||||
// Left-over from before - will remove soon
|
||||
always @(posedge clk)
|
||||
OldFDivBusyE = FDivDoneE;
|
||||
|
||||
// For FP division this adds extra clock cycles to make sure the
|
||||
// computation completes.
|
||||
// state machine to handle timing for testing due
|
||||
// various cycle counts for different fp/int operations
|
||||
// Adds vector at start of clock
|
||||
always @(posedge clk) begin
|
||||
// Add extra clock cycles in beginning for fdivsqrt to adequate reset state
|
||||
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
|
||||
2'b11: begin
|
||||
repeat (20)
|
||||
@(posedge clk);
|
||||
end
|
||||
// HP
|
||||
2'b10: begin
|
||||
repeat (14)
|
||||
@(posedge clk);
|
||||
end
|
||||
// DP
|
||||
2'b01: begin
|
||||
repeat (18)
|
||||
@(posedge clk);
|
||||
end
|
||||
// SP
|
||||
2'b00: begin
|
||||
repeat (16)
|
||||
@(posedge clk);
|
||||
end
|
||||
endcase // case (FmtVal)
|
||||
if (reset != 1'b1)
|
||||
VectorNum += 1; // increment the vector
|
||||
end
|
||||
|
||||
// state machine element for testing
|
||||
if (reset)
|
||||
state <= S0;
|
||||
else
|
||||
state <= nextstate;
|
||||
|
||||
// Increment the vector when Done with each test
|
||||
if (state == Done)
|
||||
VectorNum += 1; // increment the vector
|
||||
|
||||
end
|
||||
|
||||
// check results on falling edge of clk
|
||||
|
@ -904,7 +917,7 @@ module testbenchfp;
|
|||
(YNaN&(Res[P.H_LEN-2:0] === {Y[P.H_LEN-2:P.H_NF],1'b1,Y[P.H_NF-2:0]})) |
|
||||
(ZNaN&(Res[P.H_LEN-2:0] === {Z[P.H_LEN-2:P.H_NF],1'b1,Z[P.H_NF-2:0]})));
|
||||
endcase
|
||||
else if (UnitVal === `CVTFPUNIT) // if converting from floating point to floating point OpCtrl contains the final FP format
|
||||
else if (UnitVal === `CVTFPUNIT) // if converting from FP to FP OpCtrl contains the final FP format
|
||||
case (OpCtrlVal[1:0])
|
||||
2'b11: NaNGood = (((P.IEEE754==0)&AnsNaN&(Res === {1'b0, {P.Q_NE+1{1'b1}}, {P.Q_NF-1{1'b0}}})) |
|
||||
(AnsFlg[4]&(Res[P.Q_LEN-2:0] === {{P.Q_NE+1{1'b1}}, {P.Q_NF-1{1'b0}}})) |
|
||||
|
@ -941,29 +954,22 @@ module testbenchfp;
|
|||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// check if result is correct
|
||||
// wait till the division result is done or one extra cylcle for early termination (to simulate the EM pipline stage)
|
||||
assign ResMatch = ((Res === Ans) | NaNGood | (NaNGood === 1'bx));
|
||||
assign FlagMatch = ((ResFlg === AnsFlg) | (AnsFlg === 5'bx));
|
||||
assign divsqrtop = (OpCtrlVal == `SQRT_OPCTRL) | (OpCtrlVal == `DIV_OPCTRL);
|
||||
assign FMAop = (OpCtrlVal == `FMAUNIT);
|
||||
assign DivDone = OldFDivBusyE & ~FDivBusyE;
|
||||
|
||||
// Maybe change OpCtrl but for now just look at TEST for fma test
|
||||
assign CheckNow = ((DivDone | ~divsqrtop) | (TEST == "add" | TEST == "fma" | TEST == "sub")) & (UnitVal !== `CVTINTUNIT) & (UnitVal !== `CMPUNIT);
|
||||
if (~(ResMatch & FlagMatch) & CheckNow) begin
|
||||
assign CheckNow = ((DivDone | ~divsqrtop) |
|
||||
(TEST == "all" | TEST == "add" | TEST == "fma" | TEST == "sub"))
|
||||
& (UnitVal !== `CVTINTUNIT) & (UnitVal !== `CMPUNIT);
|
||||
|
||||
if (~(ResMatch & FlagMatch) & CheckNow & (Ans[0] !== 1'bx)) begin
|
||||
errors += 1;
|
||||
$display("\nError in %s", Tests[TestNum]);
|
||||
$display("TestNum %d OpCtrl %d", TestNum, OpCtrl[TestNum]);
|
||||
$display("inputs: %h %h %h\nSrcA: %h\n Res: %h %h\n Expected: %h %h", X, Y, Z, SrcA, Res, ResFlg, Ans, AnsFlg);
|
||||
$stop;
|
||||
end else if (((UnitVal === `CVTINTUNIT) | (UnitVal === `CMPUNIT)) &
|
||||
~(ResMatch & FlagMatch) & (Ans[0] !== 1'bx)) begin // Check for conversion and comparisons
|
||||
errors += 1;
|
||||
$display("\nError in %s", Tests[TestNum]);
|
||||
$display("TestNum %d OpCtrl %d", TestNum, OpCtrl[TestNum]);
|
||||
$display("inputs: %h %h %h\nSrcA: %h\n Res: %h %h\n Ans: %h %h", X, Y, Z, SrcA, Res, ResFlg, Ans, AnsFlg);
|
||||
$stop;
|
||||
end
|
||||
end
|
||||
|
||||
if (TestVectors[VectorNum][0] === 1'bx & Tests[TestNum] !== "") begin // if reached the eof
|
||||
// increment the test
|
||||
|
@ -979,11 +985,12 @@ module testbenchfp;
|
|||
// increment the rounding mode or loop back to rne
|
||||
if (FrmNum < 4) FrmNum += 1;
|
||||
else begin
|
||||
FrmNum = 0;
|
||||
FrmNum = 0;
|
||||
// Add some time as a buffer between tests at the end of each test
|
||||
repeat (10)
|
||||
@(posedge clk);
|
||||
end
|
||||
// (to be removed)
|
||||
repeat (10)
|
||||
@(posedge clk);
|
||||
end
|
||||
// if no more Tests - finish
|
||||
if (Tests[TestNum] === "") begin
|
||||
$display("\nAll Tests completed with %d errors\n", errors);
|
||||
|
@ -996,28 +1003,27 @@ endmodule
|
|||
|
||||
|
||||
module readvectors import cvw::*; #(parameter cvw_t P) (
|
||||
input logic clk,
|
||||
input logic [P.FLEN*4+7:0] TestVector,
|
||||
input logic clk,
|
||||
input logic [P.FLEN*4+7:0] TestVector,
|
||||
input logic [P.FMTBITS-1: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 [P.FLEN-1:0] Ans,
|
||||
output logic [P.XLEN-1:0] SrcA,
|
||||
output logic [4:0] AnsFlg,
|
||||
output logic Xs, Ys, Zs, // sign bits of XYZ
|
||||
output logic [P.NE-1:0] Xe, Ye, Ze, // exponents of XYZ (converted to largest supported precision)
|
||||
output logic [P.NF:0] Xm, Ym, Zm, // mantissas of XYZ (converted to largest supported precision)
|
||||
output logic XNaN, YNaN, ZNaN, // is XYZ a NaN
|
||||
output logic XSNaN, YSNaN, ZSNaN, // is XYZ a signaling NaN
|
||||
output logic XSubnorm, ZSubnorm, // is XYZ denormalized
|
||||
output logic XZero, YZero, ZZero, // is XYZ zero
|
||||
output logic XInf, YInf, ZInf, // is XYZ infinity
|
||||
output logic XExpMax,
|
||||
output logic DivStart,
|
||||
output logic [P.FLEN-1:0] X, Y, Z, XPostBox
|
||||
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 [P.FLEN-1:0] Ans,
|
||||
output logic [P.XLEN-1:0] SrcA,
|
||||
output logic [4:0] AnsFlg,
|
||||
output logic Xs, Ys, Zs, // sign bits of XYZ
|
||||
output logic [P.NE-1:0] Xe, Ye, Ze, // exponents of XYZ (converted to largest supported precision)
|
||||
output logic [P.NF:0] Xm, Ym, Zm, // mantissas of XYZ (converted to largest supported precision)
|
||||
output logic XNaN, YNaN, ZNaN, // is XYZ a NaN
|
||||
output logic XSNaN, YSNaN, ZSNaN, // is XYZ a signaling NaN
|
||||
output logic XSubnorm, ZSubnorm, // is XYZ denormalized
|
||||
output logic XZero, YZero, ZZero, // is XYZ zero
|
||||
output logic XInf, YInf, ZInf, // is XYZ infinity
|
||||
output logic XExpMax,
|
||||
output logic [P.FLEN-1:0] X, Y, Z, XPostBox
|
||||
);
|
||||
|
||||
localparam Q_LEN = 32'd128;
|
||||
|
@ -1030,8 +1036,6 @@ module readvectors import cvw::*; #(parameter cvw_t P) (
|
|||
// apply test vectors on rising edge of clk
|
||||
// Format of vectors Inputs(1/2/3)_AnsFlg
|
||||
always @(VectorNum) begin
|
||||
DivStart = 1'b0;
|
||||
#1;
|
||||
AnsFlg = TestVector[4:0];
|
||||
case (Unit)
|
||||
`FMAUNIT:
|
||||
|
@ -1101,30 +1105,18 @@ module readvectors import cvw::*; #(parameter cvw_t P) (
|
|||
2'b11: begin // quad
|
||||
X = TestVector[8+2*(P.Q_LEN)-1:8+(P.Q_LEN)];
|
||||
Ans = TestVector[8+(P.Q_LEN-1):8];
|
||||
if (~clk) #5;
|
||||
DivStart = 1'b1; #10 // one clk cycle
|
||||
DivStart = 1'b0;
|
||||
end
|
||||
2'b01: if (P.D_SUPPORTED) begin // double
|
||||
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]};
|
||||
if (~clk) #5;
|
||||
DivStart = 1'b1; #10
|
||||
DivStart = 1'b0;
|
||||
end
|
||||
2'b00: if (P.S_SUPPORTED) begin // single
|
||||
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]};
|
||||
if (~clk) #5;
|
||||
DivStart = 1'b1; #10
|
||||
DivStart = 1'b0;
|
||||
end
|
||||
2'b10: begin // half
|
||||
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]};
|
||||
if (~clk) #5;
|
||||
DivStart = 1'b1; #10
|
||||
DivStart = 1'b0;
|
||||
end
|
||||
endcase
|
||||
else
|
||||
|
@ -1133,33 +1125,21 @@ module readvectors import cvw::*; #(parameter cvw_t P) (
|
|||
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)];
|
||||
Ans = TestVector[8+(P.Q_LEN-1):8];
|
||||
if (~clk) #5;
|
||||
DivStart = 1'b1; #10 // one clk cycle
|
||||
DivStart = 1'b0;
|
||||
end
|
||||
2'b01: if (P.D_SUPPORTED) begin // double
|
||||
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)]};
|
||||
Ans = {{P.FLEN-P.D_LEN{1'b1}}, TestVector[8+(P.D_LEN-1):8]};
|
||||
if (~clk) #5;
|
||||
DivStart = 1'b1; #10
|
||||
DivStart = 1'b0;
|
||||
end
|
||||
2'b00: if (P.S_SUPPORTED) begin // single
|
||||
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)]};
|
||||
Ans = {{P.FLEN-P.S_LEN{1'b1}}, TestVector[8+(P.S_LEN-1):8]};
|
||||
if (~clk) #5;
|
||||
DivStart = 1'b1; #10
|
||||
DivStart = 1'b0;
|
||||
end
|
||||
2'b10: begin // half
|
||||
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)]};
|
||||
Ans = {{P.FLEN-P.H_LEN{1'b1}}, TestVector[8+(P.H_LEN-1):8]};
|
||||
if (~clk) #5;
|
||||
DivStart = 1'b1; #10
|
||||
DivStart = 1'b0;
|
||||
end
|
||||
endcase
|
||||
`CMPUNIT:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue