mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Simplified cycle count logic
This commit is contained in:
parent
8f87860146
commit
2903791820
@ -30,12 +30,12 @@ module fdivsqrtcycles import cvw::*; #(parameter cvw_t P) (
|
|||||||
input logic [P.FMTBITS-1:0] FmtE,
|
input logic [P.FMTBITS-1:0] FmtE,
|
||||||
input logic SqrtE,
|
input logic SqrtE,
|
||||||
input logic IntDivE,
|
input logic IntDivE,
|
||||||
input logic [P.DIVBLEN:0] nE,
|
input logic [P.DIVBLEN:0] IntResultBits,
|
||||||
output logic [P.DURLEN-1:0] CyclesE
|
output logic [P.DURLEN-1:0] CyclesE
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [P.DURLEN+1:0] Nf, fbits; // number of fractional bits
|
logic [P.DURLEN+1:0] Nf, FPResultBits; // number of fractional bits
|
||||||
logic [P.DURLEN-1:0] fpcycles; // number of cycles for floating-point operation
|
logic [P.DIVBLEN:0] ResultBits; // number of result bits;
|
||||||
|
|
||||||
// DIVN = P.NF+3
|
// DIVN = P.NF+3
|
||||||
// NS = NF + 1
|
// NS = NF + 1
|
||||||
@ -68,13 +68,13 @@ module fdivsqrtcycles import cvw::*; #(parameter cvw_t P) (
|
|||||||
endcase
|
endcase
|
||||||
|
|
||||||
always_comb begin
|
always_comb begin
|
||||||
if (SqrtE) fbits = Nf + 2 + 1; // Nf + two fractional bits for round/guard + 2 for right shift by up to 2 *** unclear why it works with just +1; is it related to DIVCOPIES logic below?
|
if (SqrtE) FPResultBits = Nf + 2 + 1; // Nf + two fractional bits for round/guard + 2 for right shift by up to 2 *** unclear why it works with just +1 rather than +2; is it related to DIVCOPIES logic below?
|
||||||
// if (SqrtE) fbits = Nf + 2 + 2; // Nf + two fractional bits for round/guard + 2 for right shift by up to 2
|
else FPResultBits = Nf + 2 + P.LOGR; // Nf + two fractional bits for round/guard + integer bits - try this when placing results in msbs
|
||||||
else fbits = Nf + 2 + P.LOGR; // Nf + two fractional bits for round/guard + integer bits - try this when placing results in msbs
|
|
||||||
assign fpcycles = (fbits-1)/(P.RK) + 1;
|
|
||||||
|
|
||||||
if (P.IDIV_ON_FPU) CyclesE = IntDivE ? ((nE + 1)/P.DIVCOPIES) : fpcycles;
|
if (P.IDIV_ON_FPU) ResultBits = IntDivE ? IntResultBits : FPResultBits;
|
||||||
else CyclesE = fpcycles;
|
else ResultBits = FPResultBits;
|
||||||
|
|
||||||
|
assign CyclesE = (ResultBits-1)/(P.RK) + 1;
|
||||||
end
|
end
|
||||||
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
|
|||||||
logic [P.NE+1:0] UeE; // Result Exponent (FP only)
|
logic [P.NE+1:0] UeE; // Result Exponent (FP only)
|
||||||
logic [P.DIVb:0] IFX, IFD; // Correctly-sized inputs for iterator, selected from int or fp input
|
logic [P.DIVb:0] IFX, IFD; // Correctly-sized inputs for iterator, selected from int or fp input
|
||||||
logic [P.DIVBLEN:0] mE, nE, ell; // Leading zeros of inputs
|
logic [P.DIVBLEN:0] mE, nE, ell; // Leading zeros of inputs
|
||||||
|
logic [P.DIVBLEN:0] IntResultBits; // bits in integer result
|
||||||
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 SignedDivE; // signed division
|
logic SignedDivE; // signed division
|
||||||
@ -124,6 +125,10 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
|
|||||||
assign ALTBE = ZeroDiff[P.DIVBLEN]; // A less than B (A has more leading zeros)
|
assign ALTBE = ZeroDiff[P.DIVBLEN]; // A less than B (A has more leading zeros)
|
||||||
mux2 #(P.DIVBLEN+1) pmux(ZeroDiff, '0, ALTBE, p);
|
mux2 #(P.DIVBLEN+1) pmux(ZeroDiff, '0, ALTBE, p);
|
||||||
|
|
||||||
|
/* verilator lint_off WIDTH */
|
||||||
|
assign IntResultBits = P.LOGR + p; // Total number of result bits (r integer bits plus p fractional bits)
|
||||||
|
/* verilator lint_on WIDTH */
|
||||||
|
|
||||||
// Integer special cases (terminate immediately)
|
// Integer special cases (terminate immediately)
|
||||||
assign ISpecialCaseE = BZeroE | ALTBE;
|
assign ISpecialCaseE = BZeroE | ALTBE;
|
||||||
|
|
||||||
@ -131,14 +136,13 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
|
|||||||
|
|
||||||
if (P.LOGRK > 0) begin // more than 1 bit per cycle
|
if (P.LOGRK > 0) begin // more than 1 bit per cycle
|
||||||
logic [P.LOGRK-1:0] IntTrunc, RightShiftX;
|
logic [P.LOGRK-1:0] IntTrunc, RightShiftX;
|
||||||
logic [P.DIVBLEN:0] TotalIntBits, IntSteps;
|
logic [P.DIVBLEN:0] IntSteps;
|
||||||
/* verilator lint_off WIDTH */
|
/* verilator lint_off WIDTH */
|
||||||
// n = k*ceil((r+p)/rk) - 1
|
// n = k*ceil((r+p)/rk) - 1
|
||||||
assign TotalIntBits = P.LOGR + p; // Total number of result bits (r integer bits plus p fractional bits)
|
assign IntTrunc = IntResultBits % P.RK; // Truncation check for ceiling operator
|
||||||
assign IntTrunc = TotalIntBits % P.RK; // Truncation check for ceiling operator
|
assign IntSteps = (IntResultBits >> P.LOGRK) + |IntTrunc; // Number of steps for int div
|
||||||
assign IntSteps = (TotalIntBits >> P.LOGRK) + |IntTrunc; // Number of steps for int div
|
|
||||||
assign nE = (IntSteps * P.DIVCOPIES) - 1; // Fractional digits = total digits - 1 integer digit
|
assign nE = (IntSteps * P.DIVCOPIES) - 1; // Fractional digits = total digits - 1 integer digit
|
||||||
assign RightShiftX = P.RK - 1 - ((TotalIntBits - 1) % P.RK); // Right shift amount
|
assign RightShiftX = P.RK - 1 - ((IntResultBits - 1) % P.RK); // Right shift amount
|
||||||
assign DivXShifted = DivX >> RightShiftX; // shift X by up to R*K-1 to complete in nE steps
|
assign DivXShifted = DivX >> RightShiftX; // shift X by up to R*K-1 to complete in nE steps
|
||||||
/* verilator lint_on WIDTH */
|
/* verilator lint_on WIDTH */
|
||||||
end else begin // radix 2 1 copy doesn't require shifting
|
end else begin // radix 2 1 copy doesn't require shifting
|
||||||
@ -192,7 +196,7 @@ module fdivsqrtpreproc import cvw::*; #(parameter cvw_t P) (
|
|||||||
flopen #(P.NE+2) expreg(clk, IFDivStartE, UeE, UeM);
|
flopen #(P.NE+2) expreg(clk, IFDivStartE, UeE, UeM);
|
||||||
|
|
||||||
// Number of FSM cycles (to FSM)
|
// Number of FSM cycles (to FSM)
|
||||||
fdivsqrtcycles #(P) cyclecalc(.FmtE, .SqrtE, .IntDivE, .nE, .CyclesE);
|
fdivsqrtcycles #(P) cyclecalc(.FmtE, .SqrtE, .IntDivE, .IntResultBits, .CyclesE);
|
||||||
|
|
||||||
if (P.IDIV_ON_FPU) begin:intpipelineregs
|
if (P.IDIV_ON_FPU) begin:intpipelineregs
|
||||||
// pipeline registers
|
// pipeline registers
|
||||||
|
Loading…
Reference in New Issue
Block a user