added input enables and improved forwarding

This commit is contained in:
Katherine Parry 2022-07-21 01:20:06 +00:00
parent e8c9830b88
commit 67c99d3d1a
9 changed files with 107 additions and 101 deletions

View File

@ -46,6 +46,8 @@ module fctrl (
output logic [2:0] FrmM, // FP rounding mode output logic [2:0] FrmM, // FP rounding mode
output logic [`FMTBITS-1:0] FmtE, FmtM, // FP format output logic [`FMTBITS-1:0] FmtE, FmtM, // FP format
output logic DivStartE, // Start division or squareroot output logic DivStartE, // Start division or squareroot
output logic XEnE, YEnE, ZEnE,
output logic YEnForwardE, ZEnForwardE,
output logic FWriteIntE, FWriteIntM, // Write to integer register output logic FWriteIntE, FWriteIntM, // Write to integer register
output logic [2:0] OpCtrlE, OpCtrlM, // Select which opperation to do in each component output logic [2:0] OpCtrlE, OpCtrlM, // Select which opperation to do in each component
output logic [1:0] FResSelE, FResSelM, FResSelW, // Select one of the results that finish in the memory stage output logic [1:0] FResSelE, FResSelM, FResSelW, // Select one of the results that finish in the memory stage
@ -173,23 +175,18 @@ module fctrl (
assign FmtD = ((Funct7D[6:3] == 4'b0100)&OpD[4]) ? Rs2D[1:0] : Funct7D[1:0]; assign FmtD = ((Funct7D[6:3] == 4'b0100)&OpD[4]) ? Rs2D[1:0] : Funct7D[1:0];
// // signals to help readability
// assign IntToFp = OpCtrl[2];
// assign CvtOp = (PostProcSelE == 2'b00)&(FResSelE == 2'b01);
// assign FmaOp = (PostProcSelE == 2'b10)&(FResSelE == 2'b01);
// assign Sqrt = OpCtrl[0];
// // is there an input of infinity or NaN being used // enables:
// assign InfIn = (XInf&~(IntToFp&CvtOp))|(YInf&~CvtOp)|(ZInf&FmaOp); // X - all except int->fp, store, load, mv int->fp
// assign NaNIn = (XNaN&~(IntToFp&CvtOp))|(YNaN&~CvtOp)|(ZNaN&FmaOp); // Y - all except cvt, mv, load, class
// Z - fma ops only
// // enables: // load/store mv int->fp cvt int->fp
// // X - all except int->fp, store, load, mv int->fp assign XEnE = ~(((FResSelE==2'b10)&~FWriteIntE)|((FResSelE==2'b11)&FRegWriteE)|((FResSelE==2'b01)&(PostProcSelE==2'b00)&OpCtrlE[2]));
// // Y - all except cvt, mv, load, class // load/class mv cvt
// // Z - fma ops only assign YEnE = ~(((FResSelE==2'b10)&(FWriteIntE|FRegWriteE))|(FResSelE==2'b11)|((FResSelE==2'b01)&(PostProcSelE==2'b00)));
// assign XEnE = ; assign ZEnE = (PostProcSelE==2'b10)&(FResSelE==2'b01)&(~OpCtrlE[2]|OpCtrlE[1]);
// assign YEnE = ~((FResSel==2'b10)); assign YEnForwardE = ~(((FResSelE==2'b10)&(FWriteIntE|FRegWriteE))|(FResSelE==2'b11)|((FResSelE==2'b01)&(PostProcSelE==2'b00)));
// assign ZEnE = FmaOp&~OpCtrlE[2]; assign ZEnForwardE = (PostProcSelE==2'b10)&(FResSelE==2'b01)&~OpCtrlE[2];
// Final Res Sel: // Final Res Sel:
// fp int // fp int

View File

@ -35,6 +35,7 @@ module fhazard(
input logic FRegWriteM, FRegWriteW, // is the fp register being written to input logic FRegWriteM, FRegWriteW, // is the fp register being written to
input logic [4:0] RdM, RdW, // the adress being written to input logic [4:0] RdM, RdW, // the adress being written to
input logic [1:0] FResSelM, // the result being selected input logic [1:0] FResSelM, // the result being selected
input logic XEnE, YEnE, ZEnE,
output logic FStallD, // stall the decode stage output logic FStallD, // stall the decode stage
output logic [1:0] ForwardXE, ForwardYE, ForwardZE // select a forwarded value output logic [1:0] ForwardXE, ForwardYE, ForwardZE // select a forwarded value
); );
@ -47,33 +48,34 @@ module fhazard(
ForwardZE = 2'b00; // choose FRD3E ForwardZE = 2'b00; // choose FRD3E
FStallD = 0; FStallD = 0;
//*** this hazard unit is waiting for all three inputs, change so that if an input isnt used then don't wait
// if the needed value is in the memory stage - input 1 // if the needed value is in the memory stage - input 1
if ((Adr1E == RdM) & FRegWriteM) if(XEnE)
// if the result will be FResM (can be taken from the memory stage) if ((Adr1E == RdM) & FRegWriteM)
if(FResSelM == 2'b00) ForwardXE = 2'b10; // choose FResM // if the result will be FResM (can be taken from the memory stage)
else FStallD = 1; // otherwise stall if(FResSelM == 2'b00) ForwardXE = 2'b10; // choose FResM
// if the needed value is in the writeback stage else FStallD = 1; // otherwise stall
else if ((Adr1E == RdW) & FRegWriteW) ForwardXE = 2'b01; // choose FPUResult64W // if the needed value is in the writeback stage
else if ((Adr1E == RdW) & FRegWriteW) ForwardXE = 2'b01; // choose FPUResult64W
// if the needed value is in the memory stage - input 2 // if the needed value is in the memory stage - input 2
if ((Adr2E == RdM) & FRegWriteM) if(YEnE)
// if the result will be FResM (can be taken from the memory stage) if ((Adr2E == RdM) & FRegWriteM)
if(FResSelM == 2'b00) ForwardYE = 2'b10; // choose FResM // if the result will be FResM (can be taken from the memory stage)
else FStallD = 1; // otherwise stall if(FResSelM == 2'b00) ForwardYE = 2'b10; // choose FResM
// if the needed value is in the writeback stage else FStallD = 1; // otherwise stall
else if ((Adr2E == RdW) & FRegWriteW) ForwardYE = 2'b01; // choose FPUResult64W // if the needed value is in the writeback stage
else if ((Adr2E == RdW) & FRegWriteW) ForwardYE = 2'b01; // choose FPUResult64W
// if the needed value is in the memory stage - input 3 // if the needed value is in the memory stage - input 3
if ((Adr3E == RdM) & FRegWriteM) if(ZEnE)
// if the result will be FResM (can be taken from the memory stage) if ((Adr3E == RdM) & FRegWriteM)
if(FResSelM == 2'b00) ForwardZE = 2'b10; // choose FResM // if the result will be FResM (can be taken from the memory stage)
else FStallD = 1; // otherwise stall if(FResSelM == 2'b00) ForwardZE = 2'b10; // choose FResM
// if the needed value is in the writeback stage else FStallD = 1; // otherwise stall
else if ((Adr3E == RdW) & FRegWriteW) ForwardZE = 2'b01; // choose FPUResult64W // if the needed value is in the writeback stage
else if ((Adr3E == RdW) & FRegWriteW) ForwardZE = 2'b01; // choose FPUResult64W
end end

View File

@ -37,7 +37,6 @@ module flags(
input logic NaNIn, // is a NaN input being used input logic NaNIn, // is a NaN input being used
input logic [`FMTBITS-1:0] OutFmt, // output format input logic [`FMTBITS-1:0] OutFmt, // output format
input logic XZero, YZero, // inputs are zero input logic XZero, YZero, // inputs are zero
input logic XNaN, YNaN, // inputs are NaN
input logic Sqrt, // Sqrt? input logic Sqrt, // Sqrt?
input logic ToInt, // convert to integer input logic ToInt, // convert to integer
input logic IntToFp, // convert integer to floating point input logic IntToFp, // convert integer to floating point
@ -153,11 +152,11 @@ module flags(
// | | | | or the res rounds up out of bounds // | | | | or the res rounds up out of bounds
// | | | | and the res didn't underflow // | | | | and the res didn't underflow
// | | | | | // | | | | |
assign IntInvalid = XNaN|XInf|(ShiftGtIntSz&~FullRe[`NE+1])|((Xs&~Signed)&(~((CvtCe[`NE]|(~|CvtCe))&~Plus1)))|(CvtNegResMsbs[1]^CvtNegResMsbs[0]); assign IntInvalid = NaNIn|InfIn|(ShiftGtIntSz&~FullRe[`NE+1])|((Xs&~Signed)&(~((CvtCe[`NE]|(~|CvtCe))&~Plus1)))|(CvtNegResMsbs[1]^CvtNegResMsbs[0]);
// | // |
// or when the positive res rounds up out of range // or when the positive res rounds up out of range
assign SigNaN = (XSNaN&~(IntToFp&CvtOp)) | (YSNaN&~CvtOp) | (ZSNaN&FmaOp); assign SigNaN = (XSNaN&~(IntToFp&CvtOp)) | (YSNaN&~CvtOp) | (ZSNaN&FmaOp);
assign FmaInvalid = ((XInf | YInf) & ZInf & (FmaPs ^ FmaAs) & ~XNaN & ~YNaN) | (XZero & YInf) | (YZero & XInf); assign FmaInvalid = ((XInf | YInf) & ZInf & (FmaPs ^ FmaAs) & ~NaNIn) | (XZero & YInf) | (YZero & XInf);
assign DivInvalid = ((XInf & YInf) | (XZero & YZero))&~Sqrt | (Xs&Sqrt); assign DivInvalid = ((XInf & YInf) | (XZero & YZero))&~Sqrt | (Xs&Sqrt);
assign Invalid = SigNaN | (FmaInvalid&FmaOp) | (DivInvalid&DivOp); assign Invalid = SigNaN | (FmaInvalid&FmaOp) | (DivInvalid&DivOp);

View File

@ -73,6 +73,8 @@ module fpu (
logic [1:0] PostProcSelE, PostProcSelM; // select result in the post processing unit logic [1:0] PostProcSelE, PostProcSelM; // select result in the post processing unit
logic [4:0] Adr1E, Adr2E, Adr3E; // adresses of each input logic [4:0] Adr1E, Adr2E, Adr3E; // adresses of each input
logic IllegalFPUInstrM; logic IllegalFPUInstrM;
logic XEnE, YEnE, ZEnE;
logic YEnForwardE, ZEnForwardE;
// regfile signals // regfile signals
logic [`FLEN-1:0] FRD1D, FRD2D, FRD3D; // Read Data from FP register - decode stage logic [`FLEN-1:0] FRD1D, FRD2D, FRD3D; // Read Data from FP register - decode stage
@ -163,8 +165,8 @@ module fpu (
// calculate FP control signals // calculate FP control signals
fctrl fctrl (.Funct7D(InstrD[31:25]), .OpD(InstrD[6:0]), .Rs2D(InstrD[24:20]), .Funct3D(InstrD[14:12]), .InstrD, fctrl fctrl (.Funct7D(InstrD[31:25]), .OpD(InstrD[6:0]), .Rs2D(InstrD[24:20]), .Funct3D(InstrD[14:12]), .InstrD,
.StallE, .StallM, .StallW, .FlushE, .FlushM, .FlushW, .FRM_REGW, .STATUS_FS, .FDivBusyE, .StallE, .StallM, .StallW, .FlushE, .FlushM, .FlushW, .FRM_REGW, .STATUS_FS, .FDivBusyE,
.reset, .clk, .IllegalFPUInstrD, .FRegWriteM, .FRegWriteW, .FrmM, .FmtE, .FmtM, .reset, .clk, .IllegalFPUInstrD, .FRegWriteM, .FRegWriteW, .FrmM, .FmtE, .FmtM, .YEnForwardE, .ZEnForwardE,
.DivStartE, .FWriteIntE, .FWriteIntM, .OpCtrlE, .OpCtrlM, .IllegalFPUInstrM, .DivStartE, .FWriteIntE, .FWriteIntM, .OpCtrlE, .OpCtrlM, .IllegalFPUInstrM, .XEnE, .YEnE, .ZEnE,
.FResSelE, .FResSelM, .FResSelW, .PostProcSelE, .PostProcSelM, .Adr1E, .Adr2E, .Adr3E); .FResSelE, .FResSelM, .FResSelW, .PostProcSelE, .PostProcSelM, .Adr1E, .Adr2E, .Adr3E);
// FP register file // FP register file
@ -193,7 +195,7 @@ module fpu (
// Hazard unit for FPU // Hazard unit for FPU
// - determines if any forwarding or stalls are needed // - determines if any forwarding or stalls are needed
fhazard fhazard(.Adr1E, .Adr2E, .Adr3E, .FRegWriteM, .FRegWriteW, .RdM, .RdW, .FResSelM, fhazard fhazard(.Adr1E, .Adr2E, .Adr3E, .FRegWriteM, .FRegWriteW, .RdM, .RdW, .FResSelM,
.FStallD, .ForwardXE, .ForwardYE, .ForwardZE); .XEnE, .YEnE(YEnForwardE), .ZEnE(ZEnForwardE), .FStallD, .ForwardXE, .ForwardYE, .ForwardZE);
// forwarding muxs // forwarding muxs
mux3 #(`FLEN) fxemux (FRD1E, FPUResultW, PreFpResM, ForwardXE, XE); mux3 #(`FLEN) fxemux (FRD1E, FPUResultW, PreFpResM, ForwardXE, XE);
@ -233,11 +235,11 @@ module fpu (
// - splits FP inputs into their various parts // - splits FP inputs into their various parts
// - does some classifications (SNaN, NaN, Denorm, Norm, Zero, Infifnity) // - does some classifications (SNaN, NaN, Denorm, Norm, Zero, Infifnity)
unpack unpack (.X(XE), .Y(YE), .Z(ZE), .Fmt(FmtE), .Xs(XsE), .Ys(YsE), .Zs(ZsE), unpack unpack (.X(XE), .Y(YE), .Z(ZE), .Fmt(FmtE), .Xs(XsE), .Ys(YsE), .Zs(ZsE),
.Xe(XeE), .Ye(YeE), .Ze(ZeE), .Xm(XmE), .Ym(YmE), .Zm(ZmE), .Xe(XeE), .Ye(YeE), .Ze(ZeE), .Xm(XmE), .Ym(YmE), .Zm(ZmE), .YEn(YEnE),
.XNaN(XNaNE), .YNaN(YNaNE), .ZNaN(ZNaNE), .XSNaN(XSNaNE), .XNaN(XNaNE), .YNaN(YNaNE), .ZNaN(ZNaNE), .XSNaN(XSNaNE), .XEn(XEnE),
.YSNaN(YSNaNE), .ZSNaN(ZSNaNE), .XDenorm(XDenormE), .ZDenorm(ZDenormE), .YSNaN(YSNaNE), .ZSNaN(ZSNaNE), .XDenorm(XDenormE), .ZDenorm(ZDenormE),
.XZero(XZeroE), .YZero(YZeroE), .ZZero(ZZeroE), .XInf(XInfE), .YInf(YInfE), .XZero(XZeroE), .YZero(YZeroE), .ZZero(ZZeroE), .XInf(XInfE), .YInf(YInfE),
.ZInf(ZInfE), .XExpMax(XExpMaxE)); .ZEn(ZEnE), .ZInf(ZInfE), .XExpMax(XExpMaxE));
// fused multiply add // fused multiply add
// - fadd/fsub // - fadd/fsub

View File

@ -135,8 +135,8 @@ module postprocess (
assign Sqrt = OpCtrl[0]; assign Sqrt = OpCtrl[0];
// is there an input of infinity or NaN being used // is there an input of infinity or NaN being used
assign InfIn = (XInf&~(IntToFp&CvtOp))|(YInf&~CvtOp)|(ZInf&FmaOp); assign InfIn = XInf|YInf|ZInf;
assign NaNIn = (XNaN&~(IntToFp&CvtOp))|(YNaN&~CvtOp)|(ZNaN&FmaOp); assign NaNIn = XNaN|YNaN|ZNaN;
// choose the ouptut format depending on the opperation // choose the ouptut format depending on the opperation
// - fp -> fp: OpCtrl contains the percision of the output // - fp -> fp: OpCtrl contains the percision of the output
@ -219,7 +219,7 @@ module postprocess (
flags flags(.XSNaN, .YSNaN, .ZSNaN, .XInf, .YInf, .ZInf, .InfIn, .XZero, .YZero, flags flags(.XSNaN, .YSNaN, .ZSNaN, .XInf, .YInf, .ZInf, .InfIn, .XZero, .YZero,
.Xs, .Sqrt, .ToInt, .IntToFp, .Int64, .Signed, .OutFmt, .CvtCe, .Xs, .Sqrt, .ToInt, .IntToFp, .Int64, .Signed, .OutFmt, .CvtCe,
.XNaN, .YNaN, .NaNIn, .FmaAs, .FmaPs, .R, .IntInvalid, .DivByZero, .NaNIn, .FmaAs, .FmaPs, .R, .IntInvalid, .DivByZero,
.UfL, .S, .UfPlus1, .CvtOp, .DivOp, .FmaOp, .FullRe, .Plus1, .UfL, .S, .UfPlus1, .CvtOp, .DivOp, .FmaOp, .FullRe, .Plus1,
.Me, .CvtNegResMsbs, .Invalid, .Overflow, .PostProcFlg); .Me, .CvtNegResMsbs, .Invalid, .Overflow, .PostProcFlg);

View File

@ -280,14 +280,14 @@ module specialcase(
// other: 32 bit unsinged res should be sign extended as if it were a signed number // other: 32 bit unsinged res should be sign extended as if it were a signed number
always_comb always_comb
if(Signed) if(Signed)
if(Xs&~XNaN) // signed negitive if(Xs&~NaNIn) // signed negitive
if(Int64) OfIntRes = {1'b1, {`XLEN-1{1'b0}}}; if(Int64) OfIntRes = {1'b1, {`XLEN-1{1'b0}}};
else OfIntRes = {{`XLEN-32{1'b1}}, 1'b1, {31{1'b0}}}; else OfIntRes = {{`XLEN-32{1'b1}}, 1'b1, {31{1'b0}}};
else // signed positive else // signed positive
if(Int64) OfIntRes = {1'b0, {`XLEN-1{1'b1}}}; if(Int64) OfIntRes = {1'b0, {`XLEN-1{1'b1}}};
else OfIntRes = {{`XLEN-32{1'b0}}, 1'b0, {31{1'b1}}}; else OfIntRes = {{`XLEN-32{1'b0}}, 1'b0, {31{1'b1}}};
else else
if(Xs&~XNaN) OfIntRes = {`XLEN{1'b0}}; // unsigned negitive if(Xs&~NaNIn) OfIntRes = {`XLEN{1'b0}}; // unsigned negitive
else OfIntRes = {`XLEN{1'b1}}; // unsigned positive else OfIntRes = {`XLEN{1'b1}}; // unsigned positive

View File

@ -31,6 +31,7 @@
module unpack ( module unpack (
input logic [`FLEN-1:0] X, Y, Z, // inputs from register file input logic [`FLEN-1:0] X, Y, Z, // inputs from register file
input logic [`FMTBITS-1:0] Fmt, // format signal 00 - single 01 - double 11 - quad 10 - half input logic [`FMTBITS-1:0] Fmt, // format signal 00 - single 01 - double 11 - quad 10 - half
input logic XEn, YEn, ZEn,
output logic Xs, Ys, Zs, // sign bits of XYZ output logic Xs, Ys, Zs, // sign bits of XYZ
output logic [`NE-1:0] Xe, Ye, Ze, // exponents of XYZ (converted to largest supported precision) output logic [`NE-1:0] Xe, Ye, Ze, // exponents of XYZ (converted to largest supported precision)
output logic [`NF:0] Xm, Ym, Zm, // mantissas of XYZ (converted to largest supported precision) output logic [`NF:0] Xm, Ym, Zm, // mantissas of XYZ (converted to largest supported precision)
@ -46,15 +47,15 @@ module unpack (
logic XFracZero, YFracZero, ZFracZero; // is the fraction zero logic XFracZero, YFracZero, ZFracZero; // is the fraction zero
logic YExpMax, ZExpMax; // is the exponent all 1s logic YExpMax, ZExpMax; // is the exponent all 1s
unpackinput unpackinputX (.In(X), .Fmt, .Sgn(Xs), .Exp(Xe), .Man(Xm), unpackinput unpackinputX (.In(X), .Fmt, .Sgn(Xs), .Exp(Xe), .Man(Xm), .En(XEn),
.NaN(XNaN), .SNaN(XSNaN), .ExpNonZero(XExpNonZero), .NaN(XNaN), .SNaN(XSNaN), .ExpNonZero(XExpNonZero),
.Zero(XZero), .Inf(XInf), .ExpMax(XExpMax), .FracZero(XFracZero)); .Zero(XZero), .Inf(XInf), .ExpMax(XExpMax), .FracZero(XFracZero));
unpackinput unpackinputY (.In(Y), .Fmt, .Sgn(Ys), .Exp(Ye), .Man(Ym), unpackinput unpackinputY (.In(Y), .Fmt, .Sgn(Ys), .Exp(Ye), .Man(Ym), .En(YEn),
.NaN(YNaN), .SNaN(YSNaN), .ExpNonZero(YExpNonZero), .NaN(YNaN), .SNaN(YSNaN), .ExpNonZero(YExpNonZero),
.Zero(YZero), .Inf(YInf), .ExpMax(YExpMax), .FracZero(YFracZero)); .Zero(YZero), .Inf(YInf), .ExpMax(YExpMax), .FracZero(YFracZero));
unpackinput unpackinputZ (.In(Z), .Fmt, .Sgn(Zs), .Exp(Ze), .Man(Zm), unpackinput unpackinputZ (.In(Z), .Fmt, .Sgn(Zs), .Exp(Ze), .Man(Zm), .En(ZEn),
.NaN(ZNaN), .SNaN(ZSNaN), .ExpNonZero(ZExpNonZero), .NaN(ZNaN), .SNaN(ZSNaN), .ExpNonZero(ZExpNonZero),
.Zero(ZZero), .Inf(ZInf), .ExpMax(ZExpMax), .FracZero(ZFracZero)); .Zero(ZZero), .Inf(ZInf), .ExpMax(ZExpMax), .FracZero(ZFracZero));
// is the input denormalized // is the input denormalized

View File

@ -30,7 +30,7 @@
module unpackinput ( module unpackinput (
input logic [`FLEN-1:0] In, // inputs from register file input logic [`FLEN-1:0] In, // inputs from register file
// input logic En, // enable the input input logic En, // enable the input
input logic [`FMTBITS-1:0] Fmt, // format signal 00 - single 01 - double 11 - quad 10 - half input logic [`FMTBITS-1:0] Fmt, // format signal 00 - single 01 - double 11 - quad 10 - half
output logic Sgn, // sign bits of XYZ output logic Sgn, // sign bits of XYZ
output logic [`NE-1:0] Exp, // exponents of XYZ (converted to largest supported precision) output logic [`NE-1:0] Exp, // exponents of XYZ (converted to largest supported precision)
@ -263,8 +263,8 @@ module unpackinput (
// Output logic // Output logic
assign FracZero = ~|Frac; // is the fraction zero? assign FracZero = ~|Frac; // is the fraction zero?
assign Man = {ExpNonZero, Frac}; // add the assumed one (or zero if denormal or zero) to create the significand assign Man = {ExpNonZero, Frac}; // add the assumed one (or zero if denormal or zero) to create the significand
assign NaN = (ExpMax & ~FracZero)|BadNaNBox; // is the input a NaN? assign NaN = ((ExpMax & ~FracZero)|BadNaNBox)&En; // is the input a NaN?
assign SNaN = NaN&~Frac[`NF-1]&~BadNaNBox; // is the input a singnaling NaN? assign SNaN = NaN&~Frac[`NF-1]&~BadNaNBox; // is the input a singnaling NaN?
assign Inf = ExpMax & FracZero; // is the input infinity? assign Inf = ExpMax & FracZero &En; // is the input infinity?
assign Zero = ~ExpNonZero & FracZero; // is the input zero? assign Zero = ~ExpNonZero & FracZero; // is the input zero?
endmodule endmodule

View File

@ -66,9 +66,9 @@ module testbenchfp;
logic [`XLEN-1:0] IntRes, CmpRes; // Results from each unit logic [`XLEN-1:0] IntRes, CmpRes; // Results from each unit
logic [4:0] FmaFlg, CvtFlg, DivFlg, CmpFlg; // Outputed flags logic [4:0] FmaFlg, CvtFlg, DivFlg, CmpFlg; // Outputed flags
logic AnsNaN, ResNaN, NaNGood; logic AnsNaN, ResNaN, NaNGood;
logic XSgn, YSgn, ZSgn; // sign of the inputs logic Xs, Ys, Zs; // sign of the inputs
logic [`NE-1:0] XExp, YExp, ZExp; // exponent of the inputs logic [`NE-1:0] Xe, Ye, Ze; // exponent of the inputs
logic [`NF:0] XMan, YMan, ZMan; // mantissas of the inputs logic [`NF:0] Xm, Ym, Zm; // mantissas of the inputs
logic XNaN, YNaN, ZNaN; // is the input NaN logic XNaN, YNaN, ZNaN; // is the input NaN
logic XSNaN, YSNaN, ZSNaN; // is the input a signaling NaN logic XSNaN, YSNaN, ZSNaN; // is the input a signaling NaN
logic XDenorm, ZDenorm; // is the input denormalized logic XDenorm, ZDenorm; // is the input denormalized
@ -99,7 +99,7 @@ module testbenchfp;
logic [`NE+1:0] Se; logic [`NE+1:0] Se;
logic ZmSticky; logic ZmSticky;
logic KillProd; logic KillProd;
logic [$clog2(3*`NF+7)-1:0] NCnt; logic [$clog2(3*`NF+7)-1:0] SCnt;
logic [3*`NF+5:0] Sm; logic [3*`NF+5:0] Sm;
logic InvA; logic InvA;
logic NegSum; logic NegSum;
@ -650,14 +650,14 @@ module testbenchfp;
// extract the inputs (X, Y, Z, SrcA) and the output (Ans, AnsFlg) from the current test vector // extract the inputs (X, Y, Z, SrcA) and the output (Ans, AnsFlg) from the current test vector
readvectors readvectors (.clk, .Fmt(FmtVal), .ModFmt, .TestVector(TestVectors[VectorNum]), .VectorNum, .Ans(Ans), .AnsFlg(AnsFlg), .SrcA, readvectors readvectors (.clk, .Fmt(FmtVal), .ModFmt, .TestVector(TestVectors[VectorNum]), .VectorNum, .Ans(Ans), .AnsFlg(AnsFlg), .SrcA,
.XSgnE(XSgn), .YSgnE(YSgn), .ZSgnE(ZSgn), .Unit (UnitVal), .Xs, .Ys, .Zs, .Unit(UnitVal),
.XExpE(XExp), .YExpE(YExp), .ZExpE(ZExp), .TestNum, .OpCtrl(OpCtrlVal), .Xe, .Ye, .Ze, .TestNum, .OpCtrl(OpCtrlVal),
.XManE(XMan), .YManE(YMan), .ZManE(ZMan), .DivStart, .Xm, .Ym, .Zm, .DivStart,
.XNaNE(XNaN), .YNaNE(YNaN), .ZNaNE(ZNaN), .XNaN, .YNaN, .ZNaN,
.XSNaNE(XSNaN), .YSNaNE(YSNaN), .ZSNaNE(ZSNaN), .XSNaN, .YSNaN, .ZSNaN,
.XDenormE(XDenorm), .ZDenormE(ZDenorm), .XDenorm, .ZDenorm,
.XZeroE(XZero), .YZeroE(YZero), .ZZeroE(ZZero), .XZero, .YZero, .ZZero,
.XInfE(XInf), .YInfE(YInf), .ZInfE(ZInf), .XExpMaxE(XExpMax), .XInf, .YInf, .ZInf, .XExpMax,
.X, .Y, .Z); .X, .Y, .Z);
@ -673,34 +673,34 @@ module testbenchfp;
/////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////
// instantiate devices under test // instantiate devices under test
fma fma(.Xs(XSgn), .Ys(YSgn), .Zs(ZSgn), fma fma(.Xs(Xs), .Ys(Ys), .Zs(Zs),
.Xe(XExp), .Ye(YExp), .Ze(ZExp), .Xe(Xe), .Ye(Ye), .Ze(Ze),
.Xm(XMan), .Ym(YMan), .Zm(ZMan), .Xm(Xm), .Ym(Ym), .Zm(Zm),
.XZero, .YZero, .ZZero, .Ss, .Se, .XZero, .YZero, .ZZero, .Ss, .Se,
.FOpCtrl(OpCtrlVal), .Fmt(ModFmt), .Sm, .NegSum, .InvA, .NCnt, .As, .Ps, .OpCtrl(OpCtrlVal), .Fmt(ModFmt), .Sm, .NegSum, .InvA, .SCnt, .As, .Ps,
.Pe, .ZmSticky, .KillProd); .Pe, .ZmSticky, .KillProd);
postprocess postprocess(.Xs(XSgn), .Ys(YSgn), .PostProcSel(UnitVal[1:0]), postprocess postprocess(.Xs(Xs), .Ys(Ys), .PostProcSel(UnitVal[1:0]),
.Ze(ZExp), .ZDenorm(ZDenorm), .FOpCtrl(OpCtrlVal), .DivQm(Quot), .DivQe(DivCalcExp), .Ze(Ze), .ZDenorm(ZDenorm), .OpCtrl(OpCtrlVal), .DivQm(Quot), .DivQe(DivCalcExp),
.Xm(XMan), .Ym(YMan), .Zm(ZMan), .CvtCe(CvtCalcExpE), .DivS(DivSticky), .FmaSs(Ss), .Xm(Xm), .Ym(Ym), .Zm(Zm), .CvtCe(CvtCalcExpE), .DivS(DivSticky), .FmaSs(Ss),
.XNaN(XNaN), .YNaN(YNaN), .ZNaN(ZNaN), .CvtResDenormUf(CvtResDenormUfE), .XNaN(XNaN), .YNaN(YNaN), .ZNaN(ZNaN), .CvtResDenormUf(CvtResDenormUfE),
.XZero(XZero), .YZero(YZero), .ZZero(ZZero), .CvtShiftAmt(CvtShiftAmtE), .XZero(XZero), .YZero(YZero), .ZZero(ZZero), .CvtShiftAmt(CvtShiftAmtE),
.XInf(XInf), .YInf(YInf), .ZInf(ZInf), .CvtCs(CvtResSgnE), .ToInt(WriteIntVal), .XInf(XInf), .YInf(YInf), .ZInf(ZInf), .CvtCs(CvtResSgnE), .ToInt(WriteIntVal),
.XSNaN(XSNaN), .YSNaN(YSNaN), .ZSNaN(ZSNaN), .CvtLzcIn(CvtLzcInE), .IntZero, .XSNaN(XSNaN), .YSNaN(YSNaN), .ZSNaN(ZSNaN), .CvtLzcIn(CvtLzcInE), .IntZero,
.FmaKillProd(KillProd), .FmaZmS(ZmSticky), .FmaPe(Pe), .DivDone, .FmaSe(Se), .FmaKillProd(KillProd), .FmaZmS(ZmSticky), .FmaPe(Pe), .DivDone, .FmaSe(Se),
.FmaSm(Sm), .FmaNegSum(NegSum), .FmaInvA(InvA), .FmaNCnt(NCnt), .DivEarlyTermShift(EarlyTermShift), .FmaAs(As), .FmaPs(Ps), .Fmt(ModFmt), .Frm(FrmVal), .FmaSm(Sm), .FmaNegSum(NegSum), .FmaInvA(InvA), .FmaSCnt(SCnt), .DivEarlyTermShift(EarlyTermShift), .FmaAs(As), .FmaPs(Ps), .Fmt(ModFmt), .Frm(FrmVal),
.PostProcFlg(Flg), .PostProcRes(FpRes), .FCvtIntRes(IntRes)); .PostProcFlg(Flg), .PostProcRes(FpRes), .FCvtIntRes(IntRes));
fcvt fcvt (.Xs(XSgn), .Xe(XExp), .Xm(XMan), .Int(SrcA), .ToInt(WriteIntVal), fcvt fcvt (.Xs(Xs), .Xe(Xe), .Xm(Xm), .Int(SrcA), .ToInt(WriteIntVal),
.XZero(XZero), .XDenorm(XDenorm), .FOpCtrl(OpCtrlVal), .IntZero, .XZero(XZero), .XDenorm(XDenorm), .OpCtrl(OpCtrlVal), .IntZero,
.Fmt(ModFmt), .Ce(CvtCalcExpE), .ShiftAmt(CvtShiftAmtE), .ResDenormUf(CvtResDenormUfE), .Cs(CvtResSgnE), .LzcIn(CvtLzcInE)); .Fmt(ModFmt), .Ce(CvtCalcExpE), .ShiftAmt(CvtShiftAmtE), .ResDenormUf(CvtResDenormUfE), .Cs(CvtResSgnE), .LzcIn(CvtLzcInE));
fcmp fcmp (.FmtE(ModFmt), .FOpCtrlE(OpCtrlVal), .XSgnE(XSgn), .YSgnE(YSgn), .XExpE(XExp), .YExpE(YExp), fcmp fcmp (.Fmt(ModFmt), .OpCtrl(OpCtrlVal), .Xs, .Ys, .Xe, .Ye,
.XManE(XMan), .YManE(YMan), .XZeroE(XZero), .YZeroE(YZero), .CmpIntResE(CmpRes), .Xm, .Ym, .XZero, .YZero, .CmpIntRes(CmpRes),
.XNaNE(XNaN), .YNaNE(YNaN), .XSNaNE(XSNaN), .YSNaNE(YSNaN), .FSrcXE(X), .FSrcYE(Y), .CmpNVE(CmpFlg[4]), .CmpFpResE(FpCmpRes)); .XNaN, .YNaN, .XSNaN, .YSNaN, .X, .Y, .CmpNV(CmpFlg[4]), .CmpFpRes(FpCmpRes));
divsqrt divsqrt(.clk, .reset, .FmtE(ModFmt), .XManE(XMan), .YManE(YMan), .XExpE(XExp), .YExpE(YExp), divsqrt divsqrt(.clk, .reset, .FmtE(ModFmt), .XmE(Xm), .YmE(Ym), .XeE(Xe), .YeE(Ye),
.XInfE(XInf), .YInfE(YInf), .XZeroE(XZero), .YZeroE(YZero), .XNaNE(XNaN), .YNaNE(YNaN), .DivStartE(DivStart), .XInfE(XInf), .YInfE(YInf), .XZeroE(XZero), .YZeroE(YZero), .XNaNE(XNaN), .YNaNE(YNaN), .DivStartE(DivStart),
.StallE(1'b0), .StallM(1'b0), .DivStickyM(DivSticky), .DivBusy, .DivCalcExpM(DivCalcExp), .StallE(1'b0), .StallM(1'b0), .DivSM(DivSticky), .DivBusy, .QeM(DivCalcExp),
.EarlyTermShiftM(EarlyTermShift), .QuotM(Quot), .DivDone); .EarlyTermShiftM(EarlyTermShift), .QmM(Quot), .DivDone);
assign CmpFlg[3:0] = 0; assign CmpFlg[3:0] = 0;
@ -868,10 +868,10 @@ end
// 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]&XSgn&(Res[`XLEN-1:0] === (`XLEN)'(0))) | else if ((UnitVal === `CVTINTUNIT) & ~(((WriteIntVal&~OpCtrlVal[0]&AnsFlg[4]&Xs&(Res[`XLEN-1:0] === (`XLEN)'(0))) |
(WriteIntVal&OpCtrlVal[0]&AnsFlg[4]&(~XSgn|XNaN)&OpCtrlVal[1]&(Res[`XLEN-1:0] === {1'b0, {`XLEN-1{1'b1}}})) | (WriteIntVal&OpCtrlVal[0]&AnsFlg[4]&(~Xs|XNaN)&OpCtrlVal[1]&(Res[`XLEN-1:0] === {1'b0, {`XLEN-1{1'b1}}})) |
(WriteIntVal&OpCtrlVal[0]&AnsFlg[4]&(~XSgn|XNaN)&~OpCtrlVal[1]&(Res[`XLEN-1:0] === {{`XLEN-32{1'b0}}, 1'b0, {31{1'b1}}})) | (WriteIntVal&OpCtrlVal[0]&AnsFlg[4]&(~Xs|XNaN)&~OpCtrlVal[1]&(Res[`XLEN-1:0] === {{`XLEN-32{1'b0}}, 1'b0, {31{1'b1}}})) |
(~(WriteIntVal&~OpCtrlVal[0]&AnsFlg[4]&XSgn&~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
errors += 1; errors += 1;
$display("There is an error in %s", Tests[TestNum]); $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, ResFlg, Ans, AnsFlg); $display("inputs: %h %h %h\nSrcA: %h\n Res: %h %h\n Ans: %h %h", X, Y, Z, SrcA, Res, ResFlg, Ans, AnsFlg);
@ -924,18 +924,19 @@ module readvectors (
output logic [`FLEN-1:0] Ans, output logic [`FLEN-1:0] Ans,
output logic [`XLEN-1:0] SrcA, output logic [`XLEN-1:0] SrcA,
output logic [4:0] AnsFlg, output logic [4:0] AnsFlg,
output logic XSgnE, YSgnE, ZSgnE, // sign bits of XYZ output logic Xs, Ys, Zs, // sign bits of XYZ
output logic [`NE-1:0] XExpE, YExpE, ZExpE, // exponents of XYZ (converted to largest supported precision) output logic [`NE-1:0] Xe, Ye, Ze, // 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 [`NF:0] Xm, Ym, Zm, // mantissas of XYZ (converted to largest supported precision)
output logic XNaNE, YNaNE, ZNaNE, // is XYZ a NaN output logic XNaN, YNaN, ZNaN, // is XYZ a NaN
output logic XSNaNE, YSNaNE, ZSNaNE, // is XYZ a signaling NaN output logic XSNaN, YSNaN, ZSNaN, // is XYZ a signaling NaN
output logic XDenormE, ZDenormE, // is XYZ denormalized output logic XDenorm, ZDenorm, // is XYZ denormalized
output logic XZeroE, YZeroE, ZZeroE, // is XYZ zero output logic XZero, YZero, ZZero, // is XYZ zero
output logic XInfE, YInfE, ZInfE, // is XYZ infinity output logic XInf, YInf, ZInf, // is XYZ infinity
output logic XExpMaxE, output logic XExpMax,
output logic DivStart, output logic DivStart,
output logic [`FLEN-1:0] X, Y, Z output logic [`FLEN-1:0] X, Y, Z
); );
logic XEn, YEn, ZEn;
// 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
@ -1257,8 +1258,12 @@ module readvectors (
endcase endcase
end end
unpack unpack(.X, .Y, .Z, .FmtE(ModFmt), .XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE, assign XEn = ~((Unit == `CVTINTUNIT)&OpCtrl[2]);
.XManE, .YManE, .ZManE, .XNaNE, .YNaNE, .ZNaNE, .XSNaNE, .YSNaNE, .ZSNaNE, assign YEn = ~((Unit == `CVTINTUNIT)|(Unit == `CVTFPUNIT));
.XDenormE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE, .XInfE, .YInfE, .ZInfE, assign ZEn = (Unit == `FMAUNIT);
.XExpMaxE);
unpack unpack(.X, .Y, .Z, .Fmt(ModFmt), .Xs, .Ys, .Zs, .Xe, .Ye, .Ze,
.Xm, .Ym, .Zm, .XNaN, .YNaN, .ZNaN, .XSNaN, .YSNaN, .ZSNaN,
.XDenorm, .ZDenorm, .XZero, .YZero, .ZZero, .XInf, .YInf, .ZInf,
.XEn, .YEn, .ZEn, .XExpMax);
endmodule endmodule