mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Reduced number of cycles required for lower-precision sqrt
This commit is contained in:
parent
54ad15d595
commit
f65d941561
@ -67,8 +67,8 @@ module fdivsqrt(
|
|||||||
.clk, .DivStart(DivStartE), .Xm(XmE), .QeM, .Xe(XeE), .Fmt(FmtE), .Ye(YeE),
|
.clk, .DivStart(DivStartE), .Xm(XmE), .QeM, .Xe(XeE), .Fmt(FmtE), .Ye(YeE),
|
||||||
.Sqrt(SqrtE), .Ym(YmE), .XZero(XZeroE), .X, .Dpreproc);
|
.Sqrt(SqrtE), .Ym(YmE), .XZero(XZeroE), .X, .Dpreproc);
|
||||||
fdivsqrtfsm fdivsqrtfsm(
|
fdivsqrtfsm fdivsqrtfsm(
|
||||||
.reset, .XsE, .SqrtE,
|
.clk, .reset, .FmtE, .XsE, .SqrtE,
|
||||||
.DivBusy, .clk, .DivStart(DivStartE),.StallE, .StallM, .DivDone, .XZeroE, .YZeroE,
|
.DivBusy, .DivStart(DivStartE),.StallE, .StallM, .DivDone, .XZeroE, .YZeroE,
|
||||||
.XNaNE, .YNaNE,
|
.XNaNE, .YNaNE,
|
||||||
.XInfE, .YInfE, .EarlyTermShiftE(EarlyTermShiftM), .WZero);
|
.XInfE, .YInfE, .EarlyTermShiftE(EarlyTermShiftM), .WZero);
|
||||||
fdivsqrtiter fdivsqrtiter(
|
fdivsqrtiter fdivsqrtiter(
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
module fdivsqrtfsm(
|
module fdivsqrtfsm(
|
||||||
input logic clk,
|
input logic clk,
|
||||||
input logic reset,
|
input logic reset,
|
||||||
|
input logic [`FMTBITS-1:0] FmtE,
|
||||||
input logic XInfE, YInfE,
|
input logic XInfE, YInfE,
|
||||||
input logic XZeroE, YZeroE,
|
input logic XZeroE, YZeroE,
|
||||||
input logic XNaNE, YNaNE,
|
input logic XNaNE, YNaNE,
|
||||||
@ -59,13 +60,53 @@ module fdivsqrtfsm(
|
|||||||
// terminate immediately on special cases
|
// terminate immediately on special cases
|
||||||
assign SpecialCase = XZeroE | (YZeroE&~SqrtE) | XInfE | YInfE | XNaNE | YNaNE | (XsE&SqrtE);
|
assign SpecialCase = XZeroE | (YZeroE&~SqrtE) | XInfE | YInfE | XNaNE | YNaNE | (XsE&SqrtE);
|
||||||
|
|
||||||
assign cycles = (`DURLEN)'((`DIVN+2+(`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES)+(`RADIX/4));
|
// DIVN = `NF+3
|
||||||
|
// NS = NF + 1
|
||||||
|
// N = NS or NS+2 for div/sqrt.
|
||||||
|
|
||||||
|
/* verilator lint_off WIDTH */
|
||||||
|
logic [`DURLEN+1:0] Nf, fbits; // number of fractional bits
|
||||||
|
if (`FPSIZES == 1)
|
||||||
|
assign Nf = `NF;
|
||||||
|
else if (`FPSIZES == 2)
|
||||||
|
always_comb
|
||||||
|
case (FmtE)
|
||||||
|
1'b0: Nf = `NF1;
|
||||||
|
1'b1: Nf = `NF;
|
||||||
|
endcase
|
||||||
|
else if (`FPSIZES == 3)
|
||||||
|
always_comb
|
||||||
|
case (FmtE)
|
||||||
|
`FMT: Nf = `NF;
|
||||||
|
`FMT1: Nf = `NF1;
|
||||||
|
`FMT2: Nf = `NF2;
|
||||||
|
endcase
|
||||||
|
else if (`FPSIZES == 4)
|
||||||
|
always_comb
|
||||||
|
case(FmtE)
|
||||||
|
`S_FMT: Nf = `S_NF;
|
||||||
|
`D_FMT: Nf = `D_NF;
|
||||||
|
`H_FMT: Nf = `H_NF;
|
||||||
|
`Q_FMT: Nf = `Q_NF;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
if (SqrtE) fbits = Nf + 2 + 2; // Nf + two fractional bits for round/guard + 2 for right shift by up to 2
|
||||||
|
else fbits = Nf + 2 + `LOGR; // Nf + two fractional bits for round/guard + integer bits - try this when placing results in msbs
|
||||||
|
if (SqrtE) cycles = (fbits + (`LOGR*`DIVCOPIES)-1)/(`LOGR*`DIVCOPIES); // ceiling(fbits / r*k)
|
||||||
|
else cycles = `FPDUR; // *** line above should work once otfc is used to put results in upper bits
|
||||||
|
end
|
||||||
|
|
||||||
|
/* verilator lint_on WIDTH */
|
||||||
|
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
if (reset) begin
|
if (reset) begin
|
||||||
state <= #1 IDLE;
|
state <= #1 IDLE;
|
||||||
end else if (DivStart&~StallE) begin
|
end else if (DivStart&~StallE) begin
|
||||||
step <= cycles; // *** this should be adjusted to depend on the precision; sqrt should use one fewer step becasue firststep=1
|
step <= cycles; // *** this should be adjusted to depend on the precision; sqrt should use one fewer step becasue firststep=1
|
||||||
|
// $display("Setting Nf = %d fbits %d cycles = %d FmtE %d FPSIZES = %d Q_NF = %d num = %d denom = %d\n", Nf, fbits, cycles, FmtE, `FPSIZES, `Q_NF,
|
||||||
|
// (fbits +(`LOGR*`DIVCOPIES)-1), (`LOGR*`DIVCOPIES));
|
||||||
if (SpecialCase) state <= #1 DONE;
|
if (SpecialCase) state <= #1 DONE;
|
||||||
else state <= #1 BUSY;
|
else state <= #1 BUSY;
|
||||||
end else if (DivDone) begin
|
end else if (DivDone) begin
|
||||||
|
Loading…
Reference in New Issue
Block a user