mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
very basic early termination passes testfloat 64-bit tests
This commit is contained in:
parent
f25bb4a384
commit
f2d05911ca
@ -7,16 +7,15 @@ module divshiftcalc(
|
||||
input logic [$clog2(`DIVLEN/2+3)-1:0] EarlyTermShiftDiv2M,
|
||||
output logic [$clog2(`NORMSHIFTSZ)-1:0] DivShiftAmt,
|
||||
output logic [`NORMSHIFTSZ-1:0] DivShiftIn,
|
||||
output logic [`NE+1:0] CorrDivExp
|
||||
output logic DivResDenorm,
|
||||
output logic [`NE+1:0] DivDenormShift
|
||||
);
|
||||
logic ResDenorm;
|
||||
logic [`NE+1:0] DenormShift;
|
||||
logic [`NE+1:0] NormShift;
|
||||
logic [`NE+1:0] Nf, NfPlus1;
|
||||
|
||||
// is the result denromalized
|
||||
// if the exponent is 1 then the result needs to be normalized then the result is denormalizes
|
||||
assign ResDenorm = DivCalcExpM[`NE+1]|(~|DivCalcExpM[`NE+1:1]&~(DivCalcExpM[0]&Quot[`DIVLEN+2]));
|
||||
assign DivResDenorm = DivCalcExpM[`NE+1]|(~|DivCalcExpM[`NE+1:0]);
|
||||
// select the proper fraction lengnth
|
||||
if (`FPSIZES == 1) begin
|
||||
assign Nf = (`NE+2)'(`NF);
|
||||
@ -70,24 +69,22 @@ module divshiftcalc(
|
||||
// if the result is denormalized
|
||||
// 00000000x.xxxxxx... Exp = DivCalcExp
|
||||
// .00000000xxxxxxx... >> NF+1 Exp = DivCalcExp+NF+1
|
||||
// .000xxxxxxxxxxxx... << DivCalcExp+NF+1 Exp = 0
|
||||
// .00xxxxxxxxxxxxx... << DivCalcExp+NF+1 Exp = +1
|
||||
// .0000xxxxxxxxxxx... >> 1 Exp = 1
|
||||
// Left shift amount = DivCalcExp+NF+1-1
|
||||
assign DenormShift = Nf+DivCalcExpM;
|
||||
assign DivDenormShift = Nf+DivCalcExpM;
|
||||
// if the result is normalized
|
||||
// 00000000x.xxxxxx... Exp = DivCalcExp
|
||||
// .00000000xxxxxxx... >> NF+1 Exp = DivCalcExp+NF+1
|
||||
// 00000000x.xxxxxx... << NF+1 Exp = DivCalcExp
|
||||
// 00000000xx.xxxxx... << 1? Exp = DivCalcExp-1
|
||||
// Left shift amount = NF+1 plus 1 if normalization required
|
||||
assign NormShift = NfPlus1 + {(`NE+1)'(0), ~Quot[`DIVLEN+2]};
|
||||
// 00000000.xxxxxxx... << NF Exp = DivCalcExp+1
|
||||
// 00000000x.xxxxxx... << NF Exp = DivCalcExp (extra shift done afterwards)
|
||||
// 00000000xx.xxxxx... << 1? Exp = DivCalcExp-1 (determined after)
|
||||
// inital Left shift amount = NF
|
||||
assign NormShift = Nf;
|
||||
// if the shift amount is negitive then dont shift (keep sticky bit)
|
||||
assign DivShiftAmt = (ResDenorm ? DenormShift[$clog2(`NORMSHIFTSZ)-1:0]&{$clog2(`NORMSHIFTSZ){~DenormShift[`NE+1]}} : NormShift[$clog2(`NORMSHIFTSZ)-1:0])+{{$clog2(`NORMSHIFTSZ)-$clog2(`DIVLEN/2+3)-1{1'b0}}, EarlyTermShiftDiv2M, 1'b0};
|
||||
assign DivShiftAmt = (DivResDenorm ? DivDenormShift[$clog2(`NORMSHIFTSZ)-1:0]&{$clog2(`NORMSHIFTSZ){~DivDenormShift[`NE+1]}} : NormShift[$clog2(`NORMSHIFTSZ)-1:0])+{{$clog2(`NORMSHIFTSZ)-$clog2(`DIVLEN/2+3)-1{1'b0}}, EarlyTermShiftDiv2M&{$clog2(`DIVLEN/2+3){~DivDenormShift[`NE+1]}}, 1'b0};
|
||||
|
||||
// *** may be able to reduce shifter size
|
||||
assign DivShiftIn = {{`NF{1'b0}}, Quot[`DIVLEN+2:0], {`NORMSHIFTSZ-`DIVLEN-3-`NF{1'b0}}};
|
||||
// the quotent is in the range [.5,2) if there is no early termination
|
||||
// if the quotent < 1 and not denormal then subtract 1 to account for the normalization shift
|
||||
assign CorrDivExp = (ResDenorm&~DenormShift[`NE+1]) ? (`NE+2)'(0) : DivCalcExpM - {(`NE+1)'(0), ~Quot[`DIVLEN+2]};
|
||||
|
||||
endmodule
|
||||
|
@ -3,14 +3,20 @@
|
||||
module lzacorrection(
|
||||
input logic [`NORMSHIFTSZ-1:0] Shifted, // the shifted sum before LZA correction
|
||||
input logic FmaOp,
|
||||
input logic DivOp,
|
||||
input logic DivResDenorm,
|
||||
input logic [`NE+1:0] DivCalcExpM,
|
||||
input logic [`NE+1:0] DivDenormShift,
|
||||
input logic [`NE+1:0] ConvNormSumExp, // exponent of the normalized sum not taking into account denormal or zero results
|
||||
input logic PreResultDenorm, // is the result denormalized - calculated before LZA corection
|
||||
input logic KillProdM, // is the product set to zero
|
||||
input logic SumZero,
|
||||
output logic [`CORRSHIFTSZ-1:0] CorrShifted, // the shifted sum before LZA correction
|
||||
output logic [`NE+1:0] CorrDivExp,
|
||||
output logic [`NE+1:0] SumExp // exponent of the normalized sum
|
||||
);
|
||||
logic [3*`NF+5:0] CorrSumShifted; // the shifted sum after LZA correction
|
||||
logic [`CORRSHIFTSZ:0] CorrQuotShifted;
|
||||
logic ResDenorm; // is the result denormalized
|
||||
logic LZAPlus1, LZAPlus2; // add one or two to the sum's exponent due to LZA correction
|
||||
|
||||
@ -19,11 +25,17 @@ module lzacorrection(
|
||||
assign LZAPlus2 = Shifted[`NORMSHIFTSZ-1];
|
||||
// the only possible mantissa for a plus two is all zeroes - a one has to propigate all the way through a sum. so we can leave the bottom statement alone
|
||||
assign CorrSumShifted = LZAPlus1 ? Shifted[`NORMSHIFTSZ-3:1] : Shifted[`NORMSHIFTSZ-4:0];
|
||||
assign CorrShifted = FmaOp ? {CorrSumShifted, {`CORRSHIFTSZ-(3*`NF+6){1'b0}}} : Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`CORRSHIFTSZ];
|
||||
// if the msb is 1 or the exponent was one, but the shifted quotent was < 1 (Denorm)
|
||||
assign CorrQuotShifted = {LZAPlus2|(DivCalcExpM==1&~LZAPlus2) ? Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`CORRSHIFTSZ] : {Shifted[`NORMSHIFTSZ-2:`NORMSHIFTSZ-`CORRSHIFTSZ], 1'b0}, 1'b0};
|
||||
// if the result of the divider was calculated to be denormalized, then the result was correctly normalized, so select the top shifted bits
|
||||
assign CorrShifted = FmaOp ? {CorrSumShifted, {`CORRSHIFTSZ-(3*`NF+6){1'b0}}} : DivOp&~DivResDenorm ? CorrQuotShifted[`CORRSHIFTSZ-1:0] : Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`CORRSHIFTSZ];
|
||||
// Determine sum's exponent
|
||||
// if plus1 If plus2 if said denorm but norm plus 1 if said denorm but norm plus 2
|
||||
assign SumExp = (ConvNormSumExp+{{`NE+1{1'b0}}, LZAPlus1&~KillProdM}+{{`NE{1'b0}}, LZAPlus2&~KillProdM, 1'b0}+{{`NE+1{1'b0}}, ~ResDenorm&PreResultDenorm&~KillProdM}+{{`NE+1{1'b0}}, &ConvNormSumExp&Shifted[3*`NF+6]&~KillProdM}) & {`NE+2{~(SumZero|ResDenorm)}};
|
||||
// recalculate if the result is denormalized
|
||||
assign ResDenorm = PreResultDenorm&~Shifted[`NORMSHIFTSZ-3]&~Shifted[`NORMSHIFTSZ-2];
|
||||
|
||||
// the quotent is in the range [.5,2) if there is no early termination
|
||||
// if the quotent < 1 and not denormal then subtract 1 to account for the normalization shift
|
||||
assign CorrDivExp = ((DivResDenorm)&~DivDenormShift[`NE+1]) ? (`NE+2)'(0) : DivCalcExpM - {(`NE+1)'(0), ~LZAPlus2};
|
||||
endmodule
|
@ -112,6 +112,8 @@ module postprocess(
|
||||
logic UfLSBRes;
|
||||
logic Sqrt;
|
||||
logic [`FMTBITS-1:0] OutFmt;
|
||||
logic DivResDenorm;
|
||||
logic [`NE+1:0] DivDenormShift;
|
||||
|
||||
// signals to help readability
|
||||
assign Signed = FOpCtrlM[0];
|
||||
@ -144,7 +146,7 @@ module postprocess(
|
||||
.XZeroM, .IntToFp, .OutFmt, .CvtResUf, .CvtShiftIn);
|
||||
fmashiftcalc fmashiftcalc(.SumM, .ZExpM, .ProdExpM, .FmaNormCntM, .FmtM, .KillProdM, .ConvNormSumExp,
|
||||
.ZDenormM, .SumZero, .PreResultDenorm, .FmaShiftAmt, .FmaShiftIn);
|
||||
divshiftcalc divshiftcalc(.FmtM, .Quot, .DivCalcExpM, .EarlyTermShiftDiv2M, .CorrDivExp, .DivShiftAmt, .DivShiftIn);
|
||||
divshiftcalc divshiftcalc(.FmtM, .Quot, .DivCalcExpM, .EarlyTermShiftDiv2M, .DivResDenorm, .DivDenormShift, .DivShiftAmt, .DivShiftIn);
|
||||
|
||||
always_comb
|
||||
case(PostProcSelM)
|
||||
@ -169,7 +171,8 @@ module postprocess(
|
||||
normshift normshift (.ShiftIn, .ShiftAmt, .Shifted);
|
||||
|
||||
lzacorrection lzacorrection(.FmaOp, .KillProdM, .PreResultDenorm, .ConvNormSumExp,
|
||||
.SumZero, .Shifted, .SumExp, .CorrShifted);
|
||||
.DivResDenorm, .DivDenormShift, .DivOp, .DivCalcExpM,
|
||||
.CorrDivExp, .SumZero, .Shifted, .SumExp, .CorrShifted);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Rounding
|
||||
|
Loading…
Reference in New Issue
Block a user