mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	Merge pull request #851 from kevindkim723/intdivb
Reduce Bit widths for IDIV on FPU
This commit is contained in:
		
						commit
						9f5e7b8653
					
				@ -104,6 +104,11 @@ localparam DIVb        = FPDUR*RK - LOGR;                           // divsqrt f
 | 
				
			|||||||
localparam DURLEN      = $clog2(FPDUR);                             // enough bits to count the duration
 | 
					localparam DURLEN      = $clog2(FPDUR);                             // enough bits to count the duration
 | 
				
			||||||
localparam DIVBLEN     = $clog2(DIVb+1);                            // enough bits to count number of fractional bits + 1 integer bit
 | 
					localparam DIVBLEN     = $clog2(DIVb+1);                            // enough bits to count number of fractional bits + 1 integer bit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// integer division/remainder constants
 | 
				
			||||||
 | 
					localparam INTRESBITS     = XLEN + LOGR; // number of bits in a result: r integer + XLEN fractional
 | 
				
			||||||
 | 
					localparam INTFPDUR       = (INTRESBITS-1)/RK + 1 ;                 
 | 
				
			||||||
 | 
					localparam INTDIVb        = INTFPDUR*RK - LOGR;                     
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// largest length in IEU/FPU
 | 
					// largest length in IEU/FPU
 | 
				
			||||||
localparam BASECVTLEN = `max(XLEN, NF); // convert length excluding Zfa fcvtmod.w.d
 | 
					localparam BASECVTLEN = `max(XLEN, NF); // convert length excluding Zfa fcvtmod.w.d
 | 
				
			||||||
localparam CVTLEN = (ZFA_SUPPORTED & D_SUPPORTED) ? `max(BASECVTLEN, 32'd84) : BASECVTLEN; // fcvtmod.w.d needs at least 32+52 because a double with 52 fractional bits might be into upper bits of 32 bit word
 | 
					localparam CVTLEN = (ZFA_SUPPORTED & D_SUPPORTED) ? `max(BASECVTLEN, 32'd84) : BASECVTLEN; // fcvtmod.w.d needs at least 32+52 because a double with 52 fractional bits might be into upper bits of 32 bit word
 | 
				
			||||||
 | 
				
			|||||||
@ -199,5 +199,7 @@ localparam cvw_t P = '{
 | 
				
			|||||||
  FPDUR       : FPDUR,
 | 
					  FPDUR       : FPDUR,
 | 
				
			||||||
  DURLEN      : DURLEN,
 | 
					  DURLEN      : DURLEN,
 | 
				
			||||||
  DIVb        : DIVb,
 | 
					  DIVb        : DIVb,
 | 
				
			||||||
  DIVBLEN     : DIVBLEN
 | 
					  DIVBLEN     : DIVBLEN,
 | 
				
			||||||
 | 
					  INTDIVb     : INTDIVb
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -294,6 +294,9 @@ typedef struct packed {
 | 
				
			|||||||
  int DURLEN     ;
 | 
					  int DURLEN     ;
 | 
				
			||||||
  int DIVb       ;
 | 
					  int DIVb       ;
 | 
				
			||||||
  int DIVBLEN    ;
 | 
					  int DIVBLEN    ;
 | 
				
			||||||
 | 
					// integer division/remainder constants
 | 
				
			||||||
 | 
					  int INTDIVb    ;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
} cvw_t;
 | 
					} cvw_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
endpackage
 | 
					endpackage
 | 
				
			||||||
 | 
				
			|||||||
@ -45,7 +45,8 @@ module fdivsqrtpostproc import cvw::*;  #(parameter cvw_t P) (
 | 
				
			|||||||
  output logic [P.XLEN-1:0]    FIntDivResultM     // U/Q(XLEN.0)
 | 
					  output logic [P.XLEN-1:0]    FIntDivResultM     // U/Q(XLEN.0)
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  logic [P.DIVb+3:0]         W, Sum;
 | 
					  logic [P.DIVb+3:0]         Sum;
 | 
				
			||||||
 | 
					  logic [P.INTDIVb+3:0]      W;
 | 
				
			||||||
  logic [P.DIVb:0]           PreUmM;
 | 
					  logic [P.DIVb:0]           PreUmM;
 | 
				
			||||||
  logic                      NegStickyM;
 | 
					  logic                      NegStickyM;
 | 
				
			||||||
  logic                      weq0E, WZeroM;
 | 
					  logic                      weq0E, WZeroM;
 | 
				
			||||||
@ -97,21 +98,27 @@ module fdivsqrtpostproc import cvw::*;  #(parameter cvw_t P) (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  // Integer quotient or remainder correction, normalization, and special cases
 | 
					  // Integer quotient or remainder correction, normalization, and special cases
 | 
				
			||||||
  if (P.IDIV_ON_FPU) begin:intpostproc // Int supported
 | 
					  if (P.IDIV_ON_FPU) begin:intpostproc // Int supported
 | 
				
			||||||
    logic [P.DIVb+3:0] UnsignedQuotM, NormRemM, NormRemDM, NormQuotM;
 | 
					    logic [P.INTDIVb+3:0] UnsignedQuotM, NormRemM, NormRemDM, NormQuotM;
 | 
				
			||||||
    logic signed [P.DIVb+3:0] PreResultM, PreIntResultM;
 | 
					    logic signed [P.INTDIVb+3:0] PreResultM, PreResultShiftedM, PreIntResultM;
 | 
				
			||||||
 | 
					    logic [P.INTDIVb+3:0] DTrunc, SumTrunc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assign SumTrunc = Sum[P.DIVb+3:P.DIVb-P.INTDIVb];
 | 
				
			||||||
 | 
					    assign DTrunc = D[P.DIVb+3:P.DIVb-P.INTDIVb];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assign W = $signed(SumTrunc) >>> P.LOGR;
 | 
				
			||||||
 | 
					    assign UnsignedQuotM = {3'b000, PreUmM[P.DIVb:P.DIVb-P.INTDIVb]};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assign W = $signed(Sum) >>> P.LOGR;
 | 
					 | 
				
			||||||
    assign UnsignedQuotM = {3'b000, PreUmM};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Integer remainder: sticky and sign correction muxes
 | 
					    // Integer remainder: sticky and sign correction muxes
 | 
				
			||||||
    assign NegQuotM = AsM ^ BsM; // Integer Quotient is negative
 | 
					    assign NegQuotM = AsM ^ BsM; // Integer Quotient is negative
 | 
				
			||||||
    mux2 #(P.DIVb+4) normremdmux(W, W+D, NegStickyM, NormRemDM);
 | 
					    mux2 #(P.INTDIVb+4) normremdmux(W, W+DTrunc, NegStickyM, NormRemDM);
 | 
				
			||||||
    mux2 #(P.DIVb+4) normremsmux(NormRemDM, -NormRemDM, AsM, NormRemM);
 | 
					
 | 
				
			||||||
    mux2 #(P.DIVb+4) quotresmux(UnsignedQuotM, -UnsignedQuotM, NegQuotM, NormQuotM);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Select quotient or remainder and do normalization shift
 | 
					    // Select quotient or remainder and do normalization shift
 | 
				
			||||||
    mux2 #(P.DIVb+4)    presresultmux(NormQuotM, NormRemM, RemOpM, PreResultM);
 | 
					    mux2 #(P.INTDIVb+4)    presresultmux(UnsignedQuotM, NormRemDM, RemOpM, PreResultM);
 | 
				
			||||||
    assign PreIntResultM = $signed(PreResultM >>> IntNormShiftM); 
 | 
					    assign PreResultShiftedM = PreResultM >> IntNormShiftM;
 | 
				
			||||||
 | 
					    mux2 #(P.INTDIVb+4)    preintresultmux(PreResultShiftedM, -PreResultShiftedM,AsM ^ (BsM&~RemOpM), PreIntResultM);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // special case logic
 | 
					    // special case logic
 | 
				
			||||||
    // terminates immediately when B is Zero (div 0) or |A| has more leading 0s than |B|
 | 
					    // terminates immediately when B is Zero (div 0) or |A| has more leading 0s than |B|
 | 
				
			||||||
 | 
				
			|||||||
@ -218,8 +218,8 @@ module fdivsqrtpreproc import cvw::*;  #(parameter cvw_t P) (
 | 
				
			|||||||
    logic               RemOpE;
 | 
					    logic               RemOpE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* verilator lint_off WIDTH */
 | 
					    /* verilator lint_off WIDTH */
 | 
				
			||||||
    assign IntDivNormShiftE = P.DIVb - (CyclesE * P.RK - P.LOGR); // b - rn, used for integer normalization right shift.  n = (Cycles * k - 1)
 | 
					    assign IntDivNormShiftE = P.INTDIVb - (CyclesE * P.RK - P.LOGR); // b - rn, used for integer normalization right shift.  n = (Cycles * k - 1)
 | 
				
			||||||
    assign IntRemNormShiftE = mE + (P.DIVb-(P.XLEN-1));           // m + b - (N-1) for remainder normalization shift
 | 
					    assign IntRemNormShiftE = mE + (P.INTDIVb-(P.XLEN-1));           // m + b - (N-1) for remainder normalization shift
 | 
				
			||||||
    /* verilator lint_on WIDTH */
 | 
					    /* verilator lint_on WIDTH */
 | 
				
			||||||
    assign RemOpE = Funct3E[1];
 | 
					    assign RemOpE = Funct3E[1];
 | 
				
			||||||
    mux2 #(P.DIVBLEN) normshiftmux(IntDivNormShiftE, IntRemNormShiftE, RemOpE, IntNormShiftE);
 | 
					    mux2 #(P.DIVBLEN) normshiftmux(IntDivNormShiftE, IntRemNormShiftE, RemOpE, IntNormShiftE);
 | 
				
			||||||
 | 
				
			|||||||
@ -1802,6 +1802,7 @@ string imperas32f[] = '{
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
  string arch64d_fma[] = '{
 | 
					  string arch64d_fma[] = '{
 | 
				
			||||||
    `RISCVARCHTEST,
 | 
					    `RISCVARCHTEST,
 | 
				
			||||||
    //"rv64i_m/D/src/fmadd.d_b15-01.S",
 | 
					    //"rv64i_m/D/src/fmadd.d_b15-01.S",
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user