forked from Github_Repos/cvw
Division cleanup
This commit is contained in:
parent
ce931d1fc5
commit
c24e81c57f
@ -54,21 +54,21 @@ module fdivsqrtpreproc (
|
|||||||
logic [`DIVb:0] PreSqrtX;
|
logic [`DIVb:0] PreSqrtX;
|
||||||
logic [`DIVb+3:0] DivX, DivXShifted, SqrtX, PreShiftX; // Variations of dividend, to be muxed
|
logic [`DIVb+3:0] DivX, DivXShifted, SqrtX, PreShiftX; // Variations of dividend, to be muxed
|
||||||
logic [`NE+1:0] QeE; // Quotient Exponent (FP only)
|
logic [`NE+1:0] QeE; // Quotient Exponent (FP only)
|
||||||
logic [`DIVb-1:0] IFNormLenX, IFNormLenD; // Correctly-sized inputs for iterator
|
logic [`DIVb-1:0] IFX, IFD; // Correctly-sized inputs for iterator, selected from int or fp input
|
||||||
logic [`DIVBLEN:0] mE, ell; // Leading zeros of inputs
|
logic [`DIVBLEN:0] mE, ell; // Leading zeros of inputs
|
||||||
logic NumerZeroE; // Numerator is zero (X or A)
|
logic NumerZeroE; // Numerator is zero (X or A)
|
||||||
logic AZeroE, BZeroE; // A or B is Zero for integer division
|
logic AZeroE, BZeroE; // A or B is Zero for integer division
|
||||||
|
logic signedDiv; // signed division
|
||||||
|
logic NegQuotE; // Integer quotient is negative
|
||||||
|
logic AsE, BsE; // Signs of integer inputs
|
||||||
|
logic [`XLEN-1:0] AE; // input A after W64 adjustment
|
||||||
|
|
||||||
if (`IDIV_ON_FPU) begin:intpreproc // Int Supported
|
if (`IDIV_ON_FPU) begin:intpreproc // Int Supported
|
||||||
logic signedDiv, NegQuotE;
|
logic [`XLEN-1:0] BE, PosA, PosB;
|
||||||
logic AsE, BsE, ALTBE;
|
|
||||||
logic [`XLEN-1:0] AE, BE, PosA, PosB;
|
|
||||||
logic [`DIVBLEN:0] ZeroDiff, p;
|
|
||||||
|
|
||||||
// Extract inputs, signs, zero, depending on W64 mode if applicable
|
// Extract inputs, signs, zero, depending on W64 mode if applicable
|
||||||
assign signedDiv = ~Funct3E[0];
|
assign signedDiv = ~Funct3E[0];
|
||||||
assign NegQuotE = AsE ^ BsE; // Quotient is negative
|
|
||||||
|
|
||||||
// Source handling
|
// Source handling
|
||||||
if (`XLEN==64) begin // 64-bit, supports W64
|
if (`XLEN==64) begin // 64-bit, supports W64
|
||||||
mux2 #(64) amux(ForwardedSrcAE, {{32{ForwardedSrcAE[31] & signedDiv}}, ForwardedSrcAE[31:0]}, W64E, AE);
|
mux2 #(64) amux(ForwardedSrcAE, {{32{ForwardedSrcAE[31] & signedDiv}}, ForwardedSrcAE[31:0]}, W64E, AE);
|
||||||
@ -81,14 +81,40 @@ module fdivsqrtpreproc (
|
|||||||
assign BZeroE = ~(|BE);
|
assign BZeroE = ~(|BE);
|
||||||
assign AsE = AE[`XLEN-1] & signedDiv;
|
assign AsE = AE[`XLEN-1] & signedDiv;
|
||||||
assign BsE = BE[`XLEN-1] & signedDiv;
|
assign BsE = BE[`XLEN-1] & signedDiv;
|
||||||
|
assign NegQuotE = AsE ^ BsE; // Integer Quotient is negative
|
||||||
|
|
||||||
// Force integer inputs to be postiive
|
// Force integer inputs to be postiive
|
||||||
mux2 #(`XLEN) posamux(AE, -AE, AsE, PosA);
|
mux2 #(`XLEN) posamux(AE, -AE, AsE, PosA);
|
||||||
mux2 #(`XLEN) posbmux(BE, -BE, BsE, PosB);
|
mux2 #(`XLEN) posbmux(BE, -BE, BsE, PosB);
|
||||||
|
|
||||||
// Select integer or floating point inputs
|
// Select integer or floating point inputs
|
||||||
mux2 #(`DIVb) ifxmux({Xm, {(`DIVb-`NF-1){1'b0}}}, {PosA, {(`DIVb-`XLEN){1'b0}}}, IntDivE, IFNormLenX);
|
mux2 #(`DIVb) ifxmux({Xm, {(`DIVb-`NF-1){1'b0}}}, {PosA, {(`DIVb-`XLEN){1'b0}}}, IntDivE, IFX);
|
||||||
mux2 #(`DIVb) ifdmux({Ym, {(`DIVb-`NF-1){1'b0}}}, {PosB, {(`DIVb-`XLEN){1'b0}}}, IntDivE, IFNormLenD);
|
mux2 #(`DIVb) ifdmux({Ym, {(`DIVb-`NF-1){1'b0}}}, {PosB, {(`DIVb-`XLEN){1'b0}}}, IntDivE, IFD);
|
||||||
|
|
||||||
|
|
||||||
|
end else begin // Int not supported
|
||||||
|
assign IFX = {Xm, {(`DIVb-`NF-1){1'b0}}};
|
||||||
|
assign IFD = {Ym, {(`DIVb-`NF-1){1'b0}}};
|
||||||
|
end
|
||||||
|
|
||||||
|
// count leading zeros for Subnorm FP and to normalize integer inputs
|
||||||
|
lzc #(`DIVb) lzcX (IFX, ell);
|
||||||
|
lzc #(`DIVb) lzcY (IFD, mE);
|
||||||
|
|
||||||
|
// Normalization shift
|
||||||
|
assign XPreproc = IFX << (ell + {{`DIVBLEN{1'b0}}, 1'b1}); // *** try to remove this +1
|
||||||
|
assign DPreproc = IFD << (mE + {{`DIVBLEN{1'b0}}, 1'b1});
|
||||||
|
|
||||||
|
// append leading 1 (for normal inputs)
|
||||||
|
// shift square root to be in range [1/4, 1)
|
||||||
|
// Normalized numbers are shifted right by 1 if the exponent is odd
|
||||||
|
// Denormalized numbers have Xe = 0 and an unbiased exponent of 1-BIAS. They are shifted right if the number of leading zeros is odd.
|
||||||
|
mux2 #(`DIVb+1) sqrtxmux({~XZeroE, XPreproc}, {1'b0, ~XZeroE, XPreproc[`DIVb-1:1]}, (Xe[0] ^ ell[0]), PreSqrtX);
|
||||||
|
assign DivX = {3'b000, ~NumerZeroE, XPreproc};
|
||||||
|
|
||||||
|
if (`IDIV_ON_FPU) begin:intrightshift // Int Supported
|
||||||
|
logic [`DIVBLEN:0] ZeroDiff, p;
|
||||||
|
logic ALTBE;
|
||||||
|
|
||||||
// calculate number of fractional bits p
|
// calculate number of fractional bits p
|
||||||
assign ZeroDiff = mE - ell; // Difference in number of leading zeros
|
assign ZeroDiff = mE - ell; // Difference in number of leading zeros
|
||||||
@ -127,34 +153,16 @@ module fdivsqrtpreproc (
|
|||||||
flopen #(1) negquotreg(clk, IFDivStartE, NegQuotE, NegQuotM);
|
flopen #(1) negquotreg(clk, IFDivStartE, NegQuotE, NegQuotM);
|
||||||
flopen #(1) bzeroreg(clk, IFDivStartE, BZeroE, BZeroM);
|
flopen #(1) bzeroreg(clk, IFDivStartE, BZeroE, BZeroM);
|
||||||
flopen #(1) asignreg(clk, IFDivStartE, AsE, AsM);
|
flopen #(1) asignreg(clk, IFDivStartE, AsE, AsM);
|
||||||
flopen #(`DIVBLEN+1) nreg(clk, IFDivStartE, nE, nM);
|
flopen #(`DIVBLEN+1) nreg(clk, IFDivStartE, nE, nM);
|
||||||
flopen #(`DIVBLEN+1) mreg(clk, IFDivStartE, mE, mM);
|
flopen #(`DIVBLEN+1) mreg(clk, IFDivStartE, mE, mM);
|
||||||
flopen #(`XLEN) srcareg(clk, IFDivStartE, AE, AM);
|
flopen #(`XLEN) srcareg(clk, IFDivStartE, AE, AM);
|
||||||
if (`XLEN==64)
|
if (`XLEN==64)
|
||||||
flopen #(1) w64reg(clk, IFDivStartE, W64E, W64M);
|
flopen #(1) w64reg(clk, IFDivStartE, W64E, W64M);
|
||||||
|
end else begin
|
||||||
end else begin // Int not supported
|
|
||||||
assign IFNormLenX = {Xm, {(`DIVb-`NF-1){1'b0}}};
|
|
||||||
assign IFNormLenD = {Ym, {(`DIVb-`NF-1){1'b0}}};
|
|
||||||
assign NumerZeroE = XZeroE;
|
assign NumerZeroE = XZeroE;
|
||||||
assign X = PreShiftX;
|
assign X = PreShiftX;
|
||||||
end
|
end
|
||||||
|
|
||||||
// count leading zeros for Subnorm FP and to normalize integer inputs
|
|
||||||
lzc #(`DIVb) lzcX (IFNormLenX, ell);
|
|
||||||
lzc #(`DIVb) lzcY (IFNormLenD, mE);
|
|
||||||
|
|
||||||
// Normalization shift
|
|
||||||
assign XPreproc = IFNormLenX << (ell + {{`DIVBLEN{1'b0}}, 1'b1}); // *** try to remove this +1
|
|
||||||
assign DPreproc = IFNormLenD << (mE + {{`DIVBLEN{1'b0}}, 1'b1});
|
|
||||||
|
|
||||||
// append leading 1 (for normal inputs)
|
|
||||||
// shift square root to be in range [1/4, 1)
|
|
||||||
// Normalized numbers are shifted right by 1 if the exponent is odd
|
|
||||||
// Denormalized numbers have Xe = 0 and an unbiased exponent of 1-BIAS. They are shifted right if the number of leading zeros is odd.
|
|
||||||
mux2 #(`DIVb+1) sqrtxmux({~XZeroE, XPreproc}, {1'b0, ~XZeroE, XPreproc[`DIVb-1:1]}, (Xe[0] ^ ell[0]), PreSqrtX);
|
|
||||||
assign DivX = {3'b000, ~NumerZeroE, XPreproc};
|
|
||||||
|
|
||||||
// Sqrt is initialized on step one as R(X-1), so depends on Radix
|
// Sqrt is initialized on step one as R(X-1), so depends on Radix
|
||||||
if (`RADIX == 2) assign SqrtX = {3'b111, PreSqrtX};
|
if (`RADIX == 2) assign SqrtX = {3'b111, PreSqrtX};
|
||||||
else assign SqrtX = {2'b11, PreSqrtX, 1'b0};
|
else assign SqrtX = {2'b11, PreSqrtX, 1'b0};
|
||||||
|
Loading…
Reference in New Issue
Block a user