forked from Github_Repos/cvw
		
	added input enables and improved forwarding
This commit is contained in:
		
							parent
							
								
									e8c9830b88
								
							
						
					
					
						commit
						67c99d3d1a
					
				@ -46,6 +46,8 @@ module fctrl (
 | 
			
		||||
  output logic [2:0] 	      FrmM,                   // FP rounding mode
 | 
			
		||||
  output logic [`FMTBITS-1:0] FmtE, FmtM,             // FP format
 | 
			
		||||
  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 [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
 | 
			
		||||
@ -173,23 +175,18 @@ module fctrl (
 | 
			
		||||
      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
 | 
			
		||||
//     assign InfIn = (XInf&~(IntToFp&CvtOp))|(YInf&~CvtOp)|(ZInf&FmaOp);
 | 
			
		||||
//     assign NaNIn = (XNaN&~(IntToFp&CvtOp))|(YNaN&~CvtOp)|(ZNaN&FmaOp);
 | 
			
		||||
 | 
			
		||||
// // enables:
 | 
			
		||||
// //    X - all except int->fp, store, load, mv int->fp
 | 
			
		||||
// //    Y - all except cvt, mv, load, class
 | 
			
		||||
// //    Z - fma ops only
 | 
			
		||||
//     assign XEnE = ;
 | 
			
		||||
//     assign YEnE = ~((FResSel==2'b10));
 | 
			
		||||
//     assign ZEnE = FmaOp&~OpCtrlE[2];
 | 
			
		||||
// enables:
 | 
			
		||||
//    X - all except int->fp, store, load, mv int->fp
 | 
			
		||||
//    Y - all except cvt, mv, load, class
 | 
			
		||||
//    Z - fma ops only
 | 
			
		||||
//                  load/store                        mv int->fp                      cvt int->fp
 | 
			
		||||
    assign XEnE = ~(((FResSelE==2'b10)&~FWriteIntE)|((FResSelE==2'b11)&FRegWriteE)|((FResSelE==2'b01)&(PostProcSelE==2'b00)&OpCtrlE[2]));
 | 
			
		||||
//                  load/class                                    mv               cvt
 | 
			
		||||
    assign YEnE = ~(((FResSelE==2'b10)&(FWriteIntE|FRegWriteE))|(FResSelE==2'b11)|((FResSelE==2'b01)&(PostProcSelE==2'b00)));    
 | 
			
		||||
    assign ZEnE = (PostProcSelE==2'b10)&(FResSelE==2'b01)&(~OpCtrlE[2]|OpCtrlE[1]);
 | 
			
		||||
    assign YEnForwardE = ~(((FResSelE==2'b10)&(FWriteIntE|FRegWriteE))|(FResSelE==2'b11)|((FResSelE==2'b01)&(PostProcSelE==2'b00)));    
 | 
			
		||||
    assign ZEnForwardE = (PostProcSelE==2'b10)&(FResSelE==2'b01)&~OpCtrlE[2];
 | 
			
		||||
 | 
			
		||||
//  Final Res Sel:
 | 
			
		||||
//        fp      int
 | 
			
		||||
 | 
			
		||||
@ -35,6 +35,7 @@ module fhazard(
 | 
			
		||||
    input  logic        FRegWriteM, FRegWriteW, // is the fp register 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        XEnE, YEnE, ZEnE,
 | 
			
		||||
    output logic        FStallD,                // stall the decode stage
 | 
			
		||||
    output logic [1:0]  ForwardXE, ForwardYE, ForwardZE // select a forwarded value
 | 
			
		||||
);
 | 
			
		||||
@ -47,33 +48,34 @@ module fhazard(
 | 
			
		||||
    ForwardZE = 2'b00; // choose FRD3E
 | 
			
		||||
    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 ((Adr1E == RdM) & FRegWriteM) 
 | 
			
		||||
      // if the result will be FResM (can be taken from the memory stage)
 | 
			
		||||
      if(FResSelM == 2'b00) ForwardXE = 2'b10; // choose FResM
 | 
			
		||||
      else FStallD = 1;                             // otherwise stall
 | 
			
		||||
    // if the needed value is in the writeback stage
 | 
			
		||||
    else if ((Adr1E == RdW) & FRegWriteW) ForwardXE = 2'b01; // choose FPUResult64W
 | 
			
		||||
    if(XEnE)
 | 
			
		||||
      if ((Adr1E == RdM) & FRegWriteM) 
 | 
			
		||||
        // if the result will be FResM (can be taken from the memory stage)
 | 
			
		||||
        if(FResSelM == 2'b00) ForwardXE = 2'b10; // choose FResM
 | 
			
		||||
        else FStallD = 1;                             // otherwise stall
 | 
			
		||||
      // 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 ((Adr2E == RdM) & FRegWriteM)
 | 
			
		||||
      // if the result will be FResM (can be taken from the memory stage)
 | 
			
		||||
      if(FResSelM == 2'b00) ForwardYE = 2'b10; // choose FResM
 | 
			
		||||
      else FStallD = 1;                             // otherwise stall
 | 
			
		||||
    // if the needed value is in the writeback stage
 | 
			
		||||
    else if ((Adr2E == RdW) & FRegWriteW) ForwardYE = 2'b01; // choose FPUResult64W
 | 
			
		||||
    if(YEnE)
 | 
			
		||||
      if ((Adr2E == RdM) & FRegWriteM)
 | 
			
		||||
        // if the result will be FResM (can be taken from the memory stage)
 | 
			
		||||
        if(FResSelM == 2'b00) ForwardYE = 2'b10; // choose FResM
 | 
			
		||||
        else FStallD = 1;                             // otherwise stall
 | 
			
		||||
      // 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 ((Adr3E == RdM) & FRegWriteM)
 | 
			
		||||
      // if the result will be FResM (can be taken from the memory stage)
 | 
			
		||||
      if(FResSelM == 2'b00) ForwardZE = 2'b10; // choose FResM
 | 
			
		||||
      else FStallD = 1;                             // otherwise stall
 | 
			
		||||
    // if the needed value is in the writeback stage
 | 
			
		||||
    else if ((Adr3E == RdW) & FRegWriteW) ForwardZE = 2'b01; // choose FPUResult64W
 | 
			
		||||
    if(ZEnE)
 | 
			
		||||
      if ((Adr3E == RdM) & FRegWriteM)
 | 
			
		||||
        // if the result will be FResM (can be taken from the memory stage)
 | 
			
		||||
        if(FResSelM == 2'b00) ForwardZE = 2'b10; // choose FResM
 | 
			
		||||
        else FStallD = 1;                             // otherwise stall
 | 
			
		||||
      // if the needed value is in the writeback stage
 | 
			
		||||
      else if ((Adr3E == RdW) & FRegWriteW) ForwardZE = 2'b01; // choose FPUResult64W
 | 
			
		||||
 | 
			
		||||
  end 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -37,7 +37,6 @@ module flags(
 | 
			
		||||
    input logic                 NaNIn,                  // is a NaN input being used
 | 
			
		||||
    input logic [`FMTBITS-1:0]  OutFmt,                 // output format
 | 
			
		||||
    input logic                 XZero, YZero,         // inputs are zero
 | 
			
		||||
    input logic                 XNaN, YNaN,           // inputs are NaN
 | 
			
		||||
    input logic                 Sqrt,                   // Sqrt?
 | 
			
		||||
    input logic                 ToInt,                  // convert to integer
 | 
			
		||||
    input logic                 IntToFp,                // convert integer to floating point
 | 
			
		||||
@ -153,11 +152,11 @@ module flags(
 | 
			
		||||
    //                  |           |                                  |                    |               or the res rounds up out of bounds
 | 
			
		||||
    //                  |           |                                  |                    |                       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
 | 
			
		||||
    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 Invalid = SigNaN | (FmaInvalid&FmaOp) | (DivInvalid&DivOp);
 | 
			
		||||
 | 
			
		||||
@ -73,6 +73,8 @@ module fpu (
 | 
			
		||||
   logic [1:0] 	      PostProcSelE, PostProcSelM; // select result in the post processing unit
 | 
			
		||||
   logic [4:0] 	      Adr1E, Adr2E, Adr3E;                // adresses of each input
 | 
			
		||||
   logic                IllegalFPUInstrM;
 | 
			
		||||
   logic                XEnE, YEnE, ZEnE;
 | 
			
		||||
   logic                YEnForwardE, ZEnForwardE;
 | 
			
		||||
 | 
			
		||||
   // regfile signals
 | 
			
		||||
   logic [`FLEN-1:0] FRD1D, FRD2D, FRD3D;                // Read Data from FP register - decode stage
 | 
			
		||||
@ -163,8 +165,8 @@ module fpu (
 | 
			
		||||
   // calculate FP control signals
 | 
			
		||||
   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,
 | 
			
		||||
               .reset, .clk, .IllegalFPUInstrD, .FRegWriteM, .FRegWriteW, .FrmM, .FmtE, .FmtM,
 | 
			
		||||
               .DivStartE, .FWriteIntE, .FWriteIntM, .OpCtrlE, .OpCtrlM, .IllegalFPUInstrM,
 | 
			
		||||
               .reset, .clk, .IllegalFPUInstrD, .FRegWriteM, .FRegWriteW, .FrmM, .FmtE, .FmtM, .YEnForwardE, .ZEnForwardE,
 | 
			
		||||
               .DivStartE, .FWriteIntE, .FWriteIntM, .OpCtrlE, .OpCtrlM, .IllegalFPUInstrM, .XEnE, .YEnE, .ZEnE,
 | 
			
		||||
               .FResSelE, .FResSelM, .FResSelW, .PostProcSelE, .PostProcSelM, .Adr1E, .Adr2E, .Adr3E);
 | 
			
		||||
 | 
			
		||||
   // FP register file
 | 
			
		||||
@ -193,7 +195,7 @@ module fpu (
 | 
			
		||||
   // Hazard unit for FPU  
 | 
			
		||||
   //    - determines if any forwarding or stalls are needed
 | 
			
		||||
   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
 | 
			
		||||
   mux3  #(`FLEN)  fxemux (FRD1E, FPUResultW, PreFpResM, ForwardXE, XE);
 | 
			
		||||
@ -233,11 +235,11 @@ module fpu (
 | 
			
		||||
   //    - splits FP inputs into their various parts
 | 
			
		||||
   //    - 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), 
 | 
			
		||||
                  .Xe(XeE), .Ye(YeE), .Ze(ZeE), .Xm(XmE), .Ym(YmE), .Zm(ZmE), 
 | 
			
		||||
                  .XNaN(XNaNE), .YNaN(YNaNE), .ZNaN(ZNaNE), .XSNaN(XSNaNE), 
 | 
			
		||||
                  .Xe(XeE), .Ye(YeE), .Ze(ZeE), .Xm(XmE), .Ym(YmE), .Zm(ZmE), .YEn(YEnE),
 | 
			
		||||
                  .XNaN(XNaNE), .YNaN(YNaNE), .ZNaN(ZNaNE), .XSNaN(XSNaNE), .XEn(XEnE), 
 | 
			
		||||
                  .YSNaN(YSNaNE), .ZSNaN(ZSNaNE), .XDenorm(XDenormE), .ZDenorm(ZDenormE), 
 | 
			
		||||
                  .XZero(XZeroE), .YZero(YZeroE), .ZZero(ZZeroE), .XInf(XInfE), .YInf(YInfE), 
 | 
			
		||||
                  .ZInf(ZInfE), .XExpMax(XExpMaxE));
 | 
			
		||||
                  .ZEn(ZEnE), .ZInf(ZInfE), .XExpMax(XExpMaxE));
 | 
			
		||||
   
 | 
			
		||||
   // fused multiply add
 | 
			
		||||
   //    - fadd/fsub
 | 
			
		||||
 | 
			
		||||
@ -135,8 +135,8 @@ module postprocess (
 | 
			
		||||
    assign Sqrt =  OpCtrl[0];
 | 
			
		||||
 | 
			
		||||
    // is there an input of infinity or NaN being used
 | 
			
		||||
    assign InfIn = (XInf&~(IntToFp&CvtOp))|(YInf&~CvtOp)|(ZInf&FmaOp);
 | 
			
		||||
    assign NaNIn = (XNaN&~(IntToFp&CvtOp))|(YNaN&~CvtOp)|(ZNaN&FmaOp);
 | 
			
		||||
    assign InfIn = XInf|YInf|ZInf;
 | 
			
		||||
    assign NaNIn = XNaN|YNaN|ZNaN;
 | 
			
		||||
 | 
			
		||||
    // choose the ouptut format depending on the opperation
 | 
			
		||||
    //      - 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, 
 | 
			
		||||
                .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,
 | 
			
		||||
                .Me, .CvtNegResMsbs, .Invalid, .Overflow, .PostProcFlg);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -280,14 +280,14 @@ module specialcase(
 | 
			
		||||
    //      other: 32 bit unsinged res should be sign extended as if it were a signed number
 | 
			
		||||
    always_comb
 | 
			
		||||
        if(Signed)
 | 
			
		||||
            if(Xs&~XNaN)    // signed negitive
 | 
			
		||||
            if(Xs&~NaNIn)    // signed negitive
 | 
			
		||||
                if(Int64)   OfIntRes = {1'b1, {`XLEN-1{1'b0}}};
 | 
			
		||||
                else        OfIntRes = {{`XLEN-32{1'b1}}, 1'b1, {31{1'b0}}};
 | 
			
		||||
            else            // signed positive
 | 
			
		||||
                if(Int64)   OfIntRes = {1'b0, {`XLEN-1{1'b1}}};
 | 
			
		||||
                else        OfIntRes = {{`XLEN-32{1'b0}}, 1'b0, {31{1'b1}}};
 | 
			
		||||
        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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -31,6 +31,7 @@
 | 
			
		||||
module unpack ( 
 | 
			
		||||
    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                     XEn, YEn, ZEn,
 | 
			
		||||
    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 [`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           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),
 | 
			
		||||
                            .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),
 | 
			
		||||
                            .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),
 | 
			
		||||
                            .Zero(ZZero), .Inf(ZInf), .ExpMax(ZExpMax), .FracZero(ZFracZero));
 | 
			
		||||
    // is the input denormalized
 | 
			
		||||
 | 
			
		||||
@ -30,7 +30,7 @@
 | 
			
		||||
 | 
			
		||||
module unpackinput ( 
 | 
			
		||||
    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
 | 
			
		||||
    output logic                    Sgn,    // sign bits of XYZ
 | 
			
		||||
    output logic [`NE-1:0]          Exp,    // exponents of XYZ (converted to largest supported precision)
 | 
			
		||||
@ -263,8 +263,8 @@ module unpackinput (
 | 
			
		||||
    // Output logic
 | 
			
		||||
    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 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 Inf = ExpMax & FracZero; // is the input infinity?
 | 
			
		||||
    assign Inf = ExpMax & FracZero &En; // is the input infinity?
 | 
			
		||||
    assign Zero = ~ExpNonZero & FracZero; // is the input zero?
 | 
			
		||||
endmodule
 | 
			
		||||
@ -66,9 +66,9 @@ module testbenchfp;
 | 
			
		||||
  logic [`XLEN-1:0]     IntRes, CmpRes;  // Results from each unit
 | 
			
		||||
  logic [4:0]           FmaFlg, CvtFlg, DivFlg, CmpFlg;  // Outputed flags
 | 
			
		||||
  logic                 AnsNaN, ResNaN, NaNGood;
 | 
			
		||||
  logic                 XSgn, YSgn, ZSgn;                     // sign of the inputs
 | 
			
		||||
  logic [`NE-1:0]       XExp, YExp, ZExp;                     // exponent of the inputs
 | 
			
		||||
  logic [`NF:0]         XMan, YMan, ZMan;                     // mantissas of the inputs
 | 
			
		||||
  logic                 Xs, Ys, Zs;                     // sign of the inputs
 | 
			
		||||
  logic [`NE-1:0]       Xe, Ye, Ze;                     // exponent of the inputs
 | 
			
		||||
  logic [`NF:0]         Xm, Ym, Zm;                     // mantissas of the inputs
 | 
			
		||||
  logic                 XNaN, YNaN, ZNaN;                     // is the input NaN
 | 
			
		||||
  logic                 XSNaN, YSNaN, ZSNaN;                  // is the input a signaling NaN
 | 
			
		||||
  logic                 XDenorm, ZDenorm;            // is the input denormalized
 | 
			
		||||
@ -99,7 +99,7 @@ module testbenchfp;
 | 
			
		||||
  logic [`NE+1:0]	      Se;
 | 
			
		||||
  logic 				        ZmSticky;
 | 
			
		||||
  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 			          InvA;
 | 
			
		||||
  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
 | 
			
		||||
  readvectors readvectors          (.clk, .Fmt(FmtVal), .ModFmt, .TestVector(TestVectors[VectorNum]), .VectorNum, .Ans(Ans), .AnsFlg(AnsFlg), .SrcA, 
 | 
			
		||||
                                    .XSgnE(XSgn), .YSgnE(YSgn), .ZSgnE(ZSgn), .Unit (UnitVal),
 | 
			
		||||
                                    .XExpE(XExp), .YExpE(YExp), .ZExpE(ZExp), .TestNum, .OpCtrl(OpCtrlVal),
 | 
			
		||||
                                    .XManE(XMan), .YManE(YMan), .ZManE(ZMan), .DivStart,
 | 
			
		||||
                                    .XNaNE(XNaN), .YNaNE(YNaN), .ZNaNE(ZNaN),
 | 
			
		||||
                                    .XSNaNE(XSNaN), .YSNaNE(YSNaN), .ZSNaNE(ZSNaN), 
 | 
			
		||||
                                    .XDenormE(XDenorm), .ZDenormE(ZDenorm), 
 | 
			
		||||
                                    .XZeroE(XZero), .YZeroE(YZero), .ZZeroE(ZZero),
 | 
			
		||||
                                    .XInfE(XInf), .YInfE(YInf), .ZInfE(ZInf), .XExpMaxE(XExpMax),
 | 
			
		||||
                                    .Xs, .Ys, .Zs, .Unit(UnitVal),
 | 
			
		||||
                                    .Xe, .Ye, .Ze, .TestNum, .OpCtrl(OpCtrlVal),
 | 
			
		||||
                                    .Xm, .Ym, .Zm, .DivStart,
 | 
			
		||||
                                    .XNaN, .YNaN, .ZNaN,
 | 
			
		||||
                                    .XSNaN, .YSNaN, .ZSNaN, 
 | 
			
		||||
                                    .XDenorm, .ZDenorm, 
 | 
			
		||||
                                    .XZero, .YZero, .ZZero,
 | 
			
		||||
                                    .XInf, .YInf, .ZInf, .XExpMax,
 | 
			
		||||
                                    .X, .Y, .Z);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -673,34 +673,34 @@ module testbenchfp;
 | 
			
		||||
  ///////////////////////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
 | 
			
		||||
  // instantiate devices under test
 | 
			
		||||
  fma fma(.Xs(XSgn), .Ys(YSgn), .Zs(ZSgn), 
 | 
			
		||||
          .Xe(XExp), .Ye(YExp), .Ze(ZExp), 
 | 
			
		||||
          .Xm(XMan), .Ym(YMan), .Zm(ZMan),
 | 
			
		||||
  fma fma(.Xs(Xs), .Ys(Ys), .Zs(Zs), 
 | 
			
		||||
          .Xe(Xe), .Ye(Ye), .Ze(Ze), 
 | 
			
		||||
          .Xm(Xm), .Ym(Ym), .Zm(Zm),
 | 
			
		||||
          .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); 
 | 
			
		||||
              
 | 
			
		||||
  postprocess postprocess(.Xs(XSgn), .Ys(YSgn), .PostProcSel(UnitVal[1:0]),
 | 
			
		||||
              .Ze(ZExp),  .ZDenorm(ZDenorm), .FOpCtrl(OpCtrlVal), .DivQm(Quot), .DivQe(DivCalcExp),
 | 
			
		||||
              .Xm(XMan), .Ym(YMan), .Zm(ZMan), .CvtCe(CvtCalcExpE), .DivS(DivSticky), .FmaSs(Ss),
 | 
			
		||||
  postprocess postprocess(.Xs(Xs), .Ys(Ys), .PostProcSel(UnitVal[1:0]),
 | 
			
		||||
              .Ze(Ze),  .ZDenorm(ZDenorm), .OpCtrl(OpCtrlVal), .DivQm(Quot), .DivQe(DivCalcExp),
 | 
			
		||||
              .Xm(Xm), .Ym(Ym), .Zm(Zm), .CvtCe(CvtCalcExpE), .DivS(DivSticky), .FmaSs(Ss),
 | 
			
		||||
              .XNaN(XNaN), .YNaN(YNaN), .ZNaN(ZNaN), .CvtResDenormUf(CvtResDenormUfE),
 | 
			
		||||
              .XZero(XZero), .YZero(YZero), .ZZero(ZZero), .CvtShiftAmt(CvtShiftAmtE),
 | 
			
		||||
              .XInf(XInf), .YInf(YInf), .ZInf(ZInf), .CvtCs(CvtResSgnE), .ToInt(WriteIntVal),
 | 
			
		||||
              .XSNaN(XSNaN), .YSNaN(YSNaN), .ZSNaN(ZSNaN), .CvtLzcIn(CvtLzcInE), .IntZero,
 | 
			
		||||
              .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));
 | 
			
		||||
  
 | 
			
		||||
  fcvt fcvt (.Xs(XSgn), .Xe(XExp), .Xm(XMan), .Int(SrcA), .ToInt(WriteIntVal), 
 | 
			
		||||
            .XZero(XZero), .XDenorm(XDenorm), .FOpCtrl(OpCtrlVal), .IntZero,
 | 
			
		||||
  fcvt fcvt (.Xs(Xs), .Xe(Xe), .Xm(Xm), .Int(SrcA), .ToInt(WriteIntVal), 
 | 
			
		||||
            .XZero(XZero), .XDenorm(XDenorm), .OpCtrl(OpCtrlVal), .IntZero,
 | 
			
		||||
            .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), 
 | 
			
		||||
              .XManE(XMan), .YManE(YMan), .XZeroE(XZero), .YZeroE(YZero), .CmpIntResE(CmpRes),
 | 
			
		||||
              .XNaNE(XNaN), .YNaNE(YNaN), .XSNaNE(XSNaN), .YSNaNE(YSNaN), .FSrcXE(X), .FSrcYE(Y), .CmpNVE(CmpFlg[4]), .CmpFpResE(FpCmpRes));
 | 
			
		||||
  divsqrt divsqrt(.clk, .reset, .FmtE(ModFmt), .XManE(XMan), .YManE(YMan), .XExpE(XExp), .YExpE(YExp), 
 | 
			
		||||
  fcmp fcmp   (.Fmt(ModFmt), .OpCtrl(OpCtrlVal), .Xs, .Ys, .Xe, .Ye, 
 | 
			
		||||
              .Xm, .Ym, .XZero, .YZero, .CmpIntRes(CmpRes),
 | 
			
		||||
              .XNaN, .YNaN, .XSNaN, .YSNaN, .X, .Y, .CmpNV(CmpFlg[4]), .CmpFpRes(FpCmpRes));
 | 
			
		||||
  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), 
 | 
			
		||||
                  .StallE(1'b0), .StallM(1'b0), .DivStickyM(DivSticky), .DivBusy, .DivCalcExpM(DivCalcExp),
 | 
			
		||||
                  .EarlyTermShiftM(EarlyTermShift), .QuotM(Quot), .DivDone);
 | 
			
		||||
                  .StallE(1'b0), .StallM(1'b0), .DivSM(DivSticky), .DivBusy, .QeM(DivCalcExp),
 | 
			
		||||
                  .EarlyTermShiftM(EarlyTermShift), .QmM(Quot), .DivDone);
 | 
			
		||||
 | 
			
		||||
  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 
 | 
			
		||||
    // 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))) | 
 | 
			
		||||
            (WriteIntVal&OpCtrlVal[0]&AnsFlg[4]&(~XSgn|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]&XSgn&~XNaN)&(Res === Ans | NaNGood | NaNGood === 1'bx))) & (ResFlg === AnsFlg | AnsFlg === 5'bx))) begin
 | 
			
		||||
    else if ((UnitVal === `CVTINTUNIT) & ~(((WriteIntVal&~OpCtrlVal[0]&AnsFlg[4]&Xs&(Res[`XLEN-1:0] === (`XLEN)'(0))) | 
 | 
			
		||||
            (WriteIntVal&OpCtrlVal[0]&AnsFlg[4]&(~Xs|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] === {{`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
 | 
			
		||||
      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, ResFlg, Ans, AnsFlg);
 | 
			
		||||
@ -924,18 +924,19 @@ module readvectors (
 | 
			
		||||
  output logic [`FLEN-1:0] Ans,
 | 
			
		||||
  output logic [`XLEN-1:0] SrcA,
 | 
			
		||||
  output logic [4:0] AnsFlg,
 | 
			
		||||
  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, ZDenormE,   // is XYZ denormalized
 | 
			
		||||
  output logic                    XZeroE, YZeroE, ZZeroE,         // is XYZ zero
 | 
			
		||||
  output logic                    XInfE, YInfE, ZInfE,            // is XYZ infinity
 | 
			
		||||
  output logic                    XExpMaxE,
 | 
			
		||||
  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 [`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                    XDenorm, ZDenorm,   // 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 [`FLEN-1:0] X, Y, Z
 | 
			
		||||
);
 | 
			
		||||
  logic XEn, YEn, ZEn;
 | 
			
		||||
 | 
			
		||||
  // apply test vectors on rising edge of clk
 | 
			
		||||
  // Format of vectors Inputs(1/2/3)_AnsFlg
 | 
			
		||||
@ -1257,8 +1258,12 @@ module readvectors (
 | 
			
		||||
    endcase  
 | 
			
		||||
  end
 | 
			
		||||
  
 | 
			
		||||
  unpack unpack(.X, .Y, .Z, .FmtE(ModFmt), .XSgnE, .YSgnE, .ZSgnE, .XExpE, .YExpE, .ZExpE,
 | 
			
		||||
                .XManE, .YManE, .ZManE, .XNaNE, .YNaNE, .ZNaNE, .XSNaNE, .YSNaNE, .ZSNaNE,
 | 
			
		||||
                .XDenormE, .ZDenormE, .XZeroE, .YZeroE, .ZZeroE, .XInfE, .YInfE, .ZInfE,
 | 
			
		||||
                .XExpMaxE);
 | 
			
		||||
  assign XEn = ~((Unit == `CVTINTUNIT)&OpCtrl[2]);
 | 
			
		||||
  assign YEn = ~((Unit == `CVTINTUNIT)|(Unit == `CVTFPUNIT));
 | 
			
		||||
  assign ZEn = (Unit == `FMAUNIT);
 | 
			
		||||
  
 | 
			
		||||
  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
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user