mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
reduced bit widths for integer on fpu
This commit is contained in:
parent
e1fc44a5bf
commit
9a59c8e07f
@ -104,6 +104,12 @@ 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;
|
||||||
|
localparam INTDIVBLEN = $clog2(INTDIVb+1);
|
||||||
|
|
||||||
// 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,9 @@ localparam cvw_t P = '{
|
|||||||
FPDUR : FPDUR,
|
FPDUR : FPDUR,
|
||||||
DURLEN : DURLEN,
|
DURLEN : DURLEN,
|
||||||
DIVb : DIVb,
|
DIVb : DIVb,
|
||||||
DIVBLEN : DIVBLEN
|
DIVBLEN : DIVBLEN,
|
||||||
|
INTRESBITS : INTRESBITS,
|
||||||
|
INTFPDUR : INTFPDUR,
|
||||||
|
INTDIVb : INTDIVb,
|
||||||
|
INTDIVBLEN : INTDIVBLEN
|
||||||
};
|
};
|
||||||
|
@ -294,6 +294,12 @@ typedef struct packed {
|
|||||||
int DURLEN ;
|
int DURLEN ;
|
||||||
int DIVb ;
|
int DIVb ;
|
||||||
int DIVBLEN ;
|
int DIVBLEN ;
|
||||||
|
// integer division/remainder constants
|
||||||
|
int INTRESBITS ;
|
||||||
|
int INTFPDUR ;
|
||||||
|
int INTDIVb ;
|
||||||
|
int INTDIVBLEN ;
|
||||||
|
|
||||||
} cvw_t;
|
} cvw_t;
|
||||||
|
|
||||||
endpackage
|
endpackage
|
||||||
|
@ -97,20 +97,26 @@ 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(Sum) >>> P.LOGR;
|
assign W = $signed(Sum) >>> P.LOGR;
|
||||||
assign UnsignedQuotM = {3'b000, PreUmM};
|
assign UnsignedQuotM = {3'b000, PreUmM[P.DIVb:P.DIVb-P.INTDIVb]};
|
||||||
|
|
||||||
|
|
||||||
// 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+D, NegStickyM, NormRemDM);
|
||||||
mux2 #(P.DIVb+4) normremsmux(NormRemDM, -NormRemDM, AsM, NormRemM);
|
mux2 #(P.INTDIVb+4) normremsmux(NormRemDM, -NormRemDM, AsM, NormRemM);
|
||||||
mux2 #(P.DIVb+4) quotresmux(UnsignedQuotM, -UnsignedQuotM, NegQuotM, NormQuotM);
|
mux2 #(P.INTDIVb+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(NormQuotM, NormRemM, RemOpM, PreResultM);
|
||||||
assign PreIntResultM = $signed(PreResultM >>> IntNormShiftM);
|
assign PreIntResultM = $signed(PreResultM >>> IntNormShiftM);
|
||||||
|
|
||||||
// special case logic
|
// special case logic
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user