2022-06-13 22:47:51 +00:00
|
|
|
`include "wally-config.vh"
|
|
|
|
// what position is XLEN in?
|
|
|
|
// options:
|
|
|
|
// 1: XLEN > NF > NF1
|
|
|
|
// 2: NF > XLEN > NF1
|
|
|
|
// 3: NF > NF1 > XLEN
|
|
|
|
// single and double will always be smaller than XLEN
|
|
|
|
`define XLENPOS ((`XLEN>`NF) ? 1 : (`XLEN>`NF1) ? 2 : 3)
|
|
|
|
|
|
|
|
module round(
|
|
|
|
input logic [`FMTBITS-1:0] OutFmt, // precision 1 = double 0 = single
|
|
|
|
input logic [2:0] FrmM, // rounding mode
|
|
|
|
input logic FmaOp,
|
|
|
|
input logic [1:0] PostProcSelM,
|
|
|
|
input logic CvtResDenormUfM,
|
|
|
|
input logic ToInt,
|
|
|
|
input logic CvtOp,
|
|
|
|
input logic CvtResUf,
|
|
|
|
input logic [`CORRSHIFTSZ-1:0] CorrShifted,
|
|
|
|
input logic AddendStickyM, // addend's sticky bit
|
|
|
|
input logic ZZeroM, // is Z zero
|
|
|
|
input logic InvZM, // invert Z
|
|
|
|
input logic [`NE+1:0] SumExp, // exponent of the normalized sum
|
2022-06-15 22:58:33 +00:00
|
|
|
input logic RoundSgn, // the result's sign
|
2022-06-13 22:47:51 +00:00
|
|
|
input logic [`NE:0] CvtCalcExpM, // the calculated expoent
|
|
|
|
output logic UfPlus1, // do you add or subtract on from the result
|
|
|
|
output logic [`NE+1:0] FullResExp, // ResExp with bits to determine sign and overflow
|
|
|
|
output logic [`NF-1:0] ResFrac, // Result fraction
|
|
|
|
output logic [`NE-1:0] ResExp, // Result exponent
|
|
|
|
output logic Sticky, // sticky bit
|
|
|
|
output logic [`NE+1:0] RoundExp,
|
|
|
|
output logic Plus1,
|
|
|
|
output logic [`FLEN:0] RoundAdd, // how much to add to the result
|
|
|
|
output logic Round, UfLSBRes // bits needed to calculate rounding
|
|
|
|
);
|
|
|
|
logic LSBRes; // bit used for rounding - least significant bit of the normalized sum
|
|
|
|
logic SubBySmallNum, UfSubBySmallNum; // was there supposed to be a subtraction by a small number
|
|
|
|
logic UfCalcPlus1, CalcMinus1, Minus1; // do you add or subtract on from the result
|
|
|
|
logic NormSumSticky; // normalized sum's sticky bit
|
|
|
|
logic UfSticky; // sticky bit for underlow calculation
|
|
|
|
logic [`NF-1:0] RoundFrac;
|
|
|
|
logic FpRes, IntRes;
|
|
|
|
logic UfRound;
|
|
|
|
logic FpRound, FpLSBRes, FpUfRound;
|
|
|
|
logic CalcPlus1, FpPlus1;
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Rounding
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// round to nearest even
|
|
|
|
// {Round, Sticky}
|
|
|
|
// 0x - do nothing
|
|
|
|
// 10 - tie - Plus1 if result is odd (LSBNormSum = 1)
|
|
|
|
// - don't add 1 if a small number was supposed to be subtracted
|
|
|
|
// 11 - do nothing if a small number was supposed to subtracted (the sticky bit was set by the small number)
|
|
|
|
// - plus 1 otherwise
|
|
|
|
|
|
|
|
// round to zero - subtract 1 if a small number was supposed to be subtracted from a positive result with guard and round bits of 0
|
|
|
|
|
|
|
|
// round to -infinity
|
|
|
|
// - Plus1 if negative unless a small number was supposed to be subtracted from a result with guard and round bits of 0
|
|
|
|
// - subtract 1 if a small number was supposed to be subtracted from a positive result with guard and round bits of 0
|
|
|
|
|
|
|
|
// round to infinity
|
|
|
|
// - Plus1 if positive unless a small number was supposed to be subtracted from a result with guard and round bits of 0
|
|
|
|
// - subtract 1 if a small number was supposed to be subtracted from a negative result with guard and round bits of 0
|
|
|
|
|
|
|
|
// round to nearest max magnitude
|
|
|
|
// {Guard, Round, Sticky}
|
|
|
|
// 0x - do nothing
|
|
|
|
// 10 - tie - Plus1
|
|
|
|
// - don't add 1 if a small number was supposed to be subtracted
|
|
|
|
// 11 - do nothing if a small number was supposed to subtracted (the sticky bit was set by the small number)
|
|
|
|
// - Plus 1 otherwise
|
|
|
|
|
|
|
|
assign IntRes = CvtOp & ToInt;
|
|
|
|
assign FpRes = ~IntRes;
|
|
|
|
|
|
|
|
// sticky bit calculation
|
|
|
|
if (`FPSIZES == 1) begin
|
|
|
|
|
|
|
|
// 1: XLEN > NF
|
|
|
|
// | XLEN |
|
|
|
|
// | NF |1|1|
|
|
|
|
// ^ ^ if floating point result
|
|
|
|
// ^ if not an FMA result
|
|
|
|
if (`XLENPOS == 1)assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:0]);
|
|
|
|
// 2: NF > XLEN
|
|
|
|
if (`XLENPOS == 2)assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF-1]&IntRes) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`NF-2:0]);
|
|
|
|
|
|
|
|
end else if (`FPSIZES == 2) begin
|
|
|
|
// XLEN is either 64 or 32
|
|
|
|
// so half and single are always smaller then XLEN
|
|
|
|
|
|
|
|
// 1: XLEN > NF > NF1
|
|
|
|
if (`XLENPOS == 1) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&FpRes&~OutFmt) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:0]);
|
|
|
|
// 2: NF > XLEN > NF1
|
|
|
|
if (`XLENPOS == 2) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&~OutFmt) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF-1]&(IntRes|~OutFmt)) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`NF-2:0]);
|
|
|
|
// 3: NF > NF1 > XLEN
|
|
|
|
if (`XLENPOS == 3) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF1-1]&IntRes) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&(~OutFmt|IntRes)) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`NF-2:0]);
|
|
|
|
|
|
|
|
end else if (`FPSIZES == 3) begin
|
|
|
|
// 1: XLEN > NF > NF1
|
|
|
|
if (`XLENPOS == 1) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`NF2-2:`CORRSHIFTSZ-`NF1-1]&FpRes&(OutFmt==`FMT1)) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&FpRes&~(OutFmt==`FMT)) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:0]);
|
|
|
|
// 2: NF > XLEN > NF1
|
|
|
|
if (`XLENPOS == 2) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`NF2-2:`CORRSHIFTSZ-`NF1-1]&FpRes&(OutFmt==`FMT1)) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&~(OutFmt==`FMT)) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF-1]&(IntRes|~(OutFmt==`FMT))) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`NF-2:0]);
|
|
|
|
// 3: NF > NF1 > XLEN
|
|
|
|
if (`XLENPOS == 3) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`NF2-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&(OutFmt==`FMT1)) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF1-1]&((OutFmt==`FMT1)|IntRes)) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&(~(OutFmt==`FMT)|IntRes)) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`NF-2:0]);
|
|
|
|
|
|
|
|
end else if (`FPSIZES == 4) begin
|
|
|
|
// Quad precision will always be greater than XLEN
|
|
|
|
// 2: NF > XLEN > NF1
|
|
|
|
if (`XLENPOS == 2) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`H_NF-2:`CORRSHIFTSZ-`S_NF-1]&FpRes&(OutFmt==`H_FMT)) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`S_NF-2:`CORRSHIFTSZ-`D_NF-1]&FpRes&((OutFmt==`S_FMT)|(OutFmt==`H_FMT))) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`D_NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&~(OutFmt==`Q_FMT)) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`Q_NF-1]&(~(OutFmt==`Q_FMT)|IntRes)) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`Q_NF-2:0]);
|
|
|
|
// 3: NF > NF1 > XLEN
|
|
|
|
// The extra XLEN bit will be ored later when caculating the final sticky bit - the ufplus1 not needed for integer
|
|
|
|
if (`XLENPOS == 3) assign NormSumSticky = (|CorrShifted[`CORRSHIFTSZ-`H_NF-2:`CORRSHIFTSZ-`S_NF-1]&FpRes&(OutFmt==`H_FMT)) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`S_NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&((OutFmt==`S_FMT)|(OutFmt==`H_FMT))) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`D_NF-1]&((OutFmt==`S_FMT)|(OutFmt==`H_FMT)|IntRes)) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`D_NF-2:`CORRSHIFTSZ-`Q_NF-1]&(~(OutFmt==`Q_FMT)|IntRes)) |
|
|
|
|
(|CorrShifted[`CORRSHIFTSZ-`Q_NF-2:0]);
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// only add the Addend sticky if doing an FMA opperation
|
|
|
|
// - the shifter shifts too far left when there's an underflow (shifting out all possible sticky bits)
|
|
|
|
assign UfSticky = AddendStickyM&FmaOp | NormSumSticky | CvtResUf&CvtOp | SumExp[`NE+1]&FmaOp;
|
|
|
|
|
|
|
|
// determine round and LSB of the rounded value
|
|
|
|
// - underflow round bit is used to determint the underflow flag
|
|
|
|
if (`FPSIZES == 1) begin
|
|
|
|
assign FpRound = CorrShifted[`CORRSHIFTSZ-`NF-1];
|
|
|
|
assign FpLSBRes = CorrShifted[`CORRSHIFTSZ-`NF];
|
|
|
|
assign FpUfRound = CorrShifted[`CORRSHIFTSZ-`NF-2];
|
|
|
|
|
|
|
|
end else if (`FPSIZES == 2) begin
|
|
|
|
assign FpRound = OutFmt ? CorrShifted[`CORRSHIFTSZ-`NF-1] : CorrShifted[`CORRSHIFTSZ-`NF1-1];
|
|
|
|
assign FpLSBRes = OutFmt ? CorrShifted[`CORRSHIFTSZ-`NF] : CorrShifted[`CORRSHIFTSZ-`NF1];
|
|
|
|
assign FpUfRound = OutFmt ? CorrShifted[`CORRSHIFTSZ-`NF-2] : CorrShifted[`CORRSHIFTSZ-`NF1-2];
|
|
|
|
|
|
|
|
end else if (`FPSIZES == 3) begin
|
|
|
|
always_comb
|
|
|
|
case (OutFmt)
|
|
|
|
`FMT: begin
|
|
|
|
FpRound = CorrShifted[`CORRSHIFTSZ-`NF-1];
|
|
|
|
FpLSBRes = CorrShifted[`CORRSHIFTSZ-`NF];
|
|
|
|
FpUfRound = CorrShifted[`CORRSHIFTSZ-`NF-2];
|
|
|
|
end
|
|
|
|
`FMT1: begin
|
|
|
|
FpRound = CorrShifted[`CORRSHIFTSZ-`NF1-1];
|
|
|
|
FpLSBRes = CorrShifted[`CORRSHIFTSZ-`NF1];
|
|
|
|
FpUfRound = CorrShifted[`CORRSHIFTSZ-`NF1-2];
|
|
|
|
end
|
|
|
|
`FMT2: begin
|
|
|
|
FpRound = CorrShifted[`CORRSHIFTSZ-`NF2-1];
|
|
|
|
FpLSBRes = CorrShifted[`CORRSHIFTSZ-`NF2];
|
|
|
|
FpUfRound = CorrShifted[`CORRSHIFTSZ-`NF2-2];
|
|
|
|
end
|
|
|
|
default: begin
|
|
|
|
FpRound = 1'bx;
|
|
|
|
FpLSBRes = 1'bx;
|
|
|
|
FpUfRound = 1'bx;
|
|
|
|
end
|
|
|
|
endcase
|
|
|
|
end else if (`FPSIZES == 4) begin
|
|
|
|
always_comb
|
|
|
|
case (OutFmt)
|
|
|
|
2'h3: begin
|
|
|
|
FpRound = CorrShifted[`CORRSHIFTSZ-`Q_NF-1];
|
|
|
|
FpLSBRes = CorrShifted[`CORRSHIFTSZ-`Q_NF];
|
|
|
|
FpUfRound = CorrShifted[`CORRSHIFTSZ-`Q_NF-2];
|
|
|
|
end
|
|
|
|
2'h1: begin
|
|
|
|
FpRound = CorrShifted[`CORRSHIFTSZ-`D_NF-1];
|
|
|
|
FpLSBRes = CorrShifted[`CORRSHIFTSZ-`D_NF];
|
|
|
|
FpUfRound = CorrShifted[`CORRSHIFTSZ-`D_NF-2];
|
|
|
|
end
|
|
|
|
2'h0: begin
|
|
|
|
FpRound = CorrShifted[`CORRSHIFTSZ-`S_NF-1];
|
|
|
|
FpLSBRes = CorrShifted[`CORRSHIFTSZ-`S_NF];
|
|
|
|
FpUfRound = CorrShifted[`CORRSHIFTSZ-`S_NF-2];
|
|
|
|
end
|
|
|
|
2'h2: begin
|
|
|
|
FpRound = CorrShifted[`CORRSHIFTSZ-`H_NF-1];
|
|
|
|
FpLSBRes = CorrShifted[`CORRSHIFTSZ-`H_NF];
|
|
|
|
FpUfRound = CorrShifted[`CORRSHIFTSZ-`H_NF-2];
|
|
|
|
end
|
|
|
|
endcase
|
|
|
|
end
|
|
|
|
|
|
|
|
assign Round = ToInt&CvtOp ? CorrShifted[`CORRSHIFTSZ-`XLEN-1] : FpRound;
|
|
|
|
assign LSBRes = ToInt&CvtOp ? CorrShifted[`CORRSHIFTSZ-`XLEN] : FpLSBRes;
|
|
|
|
assign UfRound = ToInt&CvtOp ? CorrShifted[`CORRSHIFTSZ-`XLEN-2] : FpUfRound;
|
|
|
|
|
|
|
|
// used to determine underflow flag
|
|
|
|
assign UfLSBRes = FpRound;
|
|
|
|
// determine sticky
|
|
|
|
assign Sticky = UfSticky | UfRound;
|
|
|
|
|
|
|
|
|
|
|
|
// Deterimine if a small number was supposed to be subtrated - For Fma calculation only
|
|
|
|
assign SubBySmallNum = AddendStickyM & InvZM & ~(NormSumSticky|UfRound) & ~ZZeroM & FmaOp;
|
|
|
|
assign UfSubBySmallNum = AddendStickyM & InvZM & ~(NormSumSticky) & ~ZZeroM & FmaOp;
|
|
|
|
|
|
|
|
always_comb begin
|
|
|
|
// Determine if you add 1
|
|
|
|
case (FrmM)
|
|
|
|
3'b000: CalcPlus1 = Round & ((Sticky| LSBRes)&~SubBySmallNum);//round to nearest even
|
|
|
|
3'b001: CalcPlus1 = 0;//round to zero
|
2022-06-15 22:58:33 +00:00
|
|
|
3'b010: CalcPlus1 = RoundSgn & ~(SubBySmallNum & ~Round);//round down
|
|
|
|
3'b011: CalcPlus1 = ~RoundSgn & ~(SubBySmallNum & ~Round);//round up
|
2022-06-13 22:47:51 +00:00
|
|
|
3'b100: CalcPlus1 = Round & ~SubBySmallNum;//round to nearest max magnitude
|
|
|
|
default: CalcPlus1 = 1'bx;
|
|
|
|
endcase
|
|
|
|
// Determine if you add 1 (for underflow flag)
|
|
|
|
case (FrmM)
|
|
|
|
3'b000: UfCalcPlus1 = UfRound & ((UfSticky| UfLSBRes)&~UfSubBySmallNum);//round to nearest even
|
|
|
|
3'b001: UfCalcPlus1 = 0;//round to zero
|
2022-06-15 22:58:33 +00:00
|
|
|
3'b010: UfCalcPlus1 = RoundSgn & ~(UfSubBySmallNum & ~UfRound);//round down
|
|
|
|
3'b011: UfCalcPlus1 = ~RoundSgn & ~(UfSubBySmallNum & ~UfRound);//round up
|
2022-06-13 22:47:51 +00:00
|
|
|
3'b100: UfCalcPlus1 = UfRound & ~UfSubBySmallNum;//round to nearest max magnitude
|
|
|
|
default: UfCalcPlus1 = 1'bx;
|
|
|
|
endcase
|
|
|
|
// Determine if you subtract 1
|
|
|
|
case (FrmM)
|
|
|
|
3'b000: CalcMinus1 = 0;//round to nearest even
|
|
|
|
3'b001: CalcMinus1 = SubBySmallNum & ~Round;//round to zero
|
2022-06-15 22:58:33 +00:00
|
|
|
3'b010: CalcMinus1 = ~RoundSgn & ~Round & SubBySmallNum;//round down
|
|
|
|
3'b011: CalcMinus1 = RoundSgn & ~Round & SubBySmallNum;//round up
|
2022-06-13 22:47:51 +00:00
|
|
|
3'b100: CalcMinus1 = 0;//round to nearest max magnitude
|
|
|
|
default: CalcMinus1 = 1'bx;
|
|
|
|
endcase
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
// If an answer is exact don't round
|
|
|
|
assign Plus1 = CalcPlus1 & (Sticky | Round);
|
|
|
|
assign FpPlus1 = Plus1&~(ToInt&CvtOp);
|
|
|
|
assign UfPlus1 = UfCalcPlus1 & Sticky; // UfRound is part of sticky
|
|
|
|
assign Minus1 = CalcMinus1 & (Sticky | Round);
|
|
|
|
|
|
|
|
// Compute rounded result
|
|
|
|
if (`FPSIZES == 1) begin
|
|
|
|
assign RoundAdd = Minus1 ? {`FLEN+1{1'b1}} : {{`FLEN{1'b0}}, FpPlus1};
|
|
|
|
|
|
|
|
end else if (`FPSIZES == 2) begin
|
|
|
|
// \/FLEN+1
|
|
|
|
// | NE+2 | NF |
|
|
|
|
// '-NE+2-^----NF1----^
|
|
|
|
// `FLEN+1-`NE-2-`NF1 = FLEN-1-NE-NF1
|
|
|
|
assign RoundAdd = OutFmt ? Minus1 ? {`FLEN+1{1'b1}} : {{{`FLEN{1'b0}}}, FpPlus1} :
|
|
|
|
Minus1 ? {{`NE+2+`NF1{1'b1}}, (`FLEN-1-`NE-`NF1)'(0)} : {(`NE+1+`NF1)'(0), FpPlus1, (`FLEN-1-`NE-`NF1)'(0)};
|
|
|
|
|
|
|
|
end else if (`FPSIZES == 3) begin
|
|
|
|
always_comb begin
|
|
|
|
case (OutFmt)
|
|
|
|
`FMT: RoundAdd = Minus1 ? {`FLEN+1{1'b1}} : {{{`FLEN{1'b0}}}, FpPlus1};
|
|
|
|
`FMT1: RoundAdd = Minus1 ? {{`NE+2+`NF1{1'b1}}, (`FLEN-1-`NE-`NF1)'(0)} : {(`NE+1+`NF1)'(0), FpPlus1, (`FLEN-1-`NE-`NF1)'(0)};
|
|
|
|
`FMT2: RoundAdd = Minus1 ? {{`NE+2+`NF2{1'b1}}, (`FLEN-1-`NE-`NF2)'(0)} : {(`NE+1+`NF2)'(0), FpPlus1, (`FLEN-1-`NE-`NF2)'(0)};
|
|
|
|
default: RoundAdd = (`FLEN+1)'(0);
|
|
|
|
endcase
|
|
|
|
end
|
|
|
|
|
|
|
|
end else if (`FPSIZES == 4) begin
|
|
|
|
always_comb begin
|
|
|
|
case (OutFmt)
|
|
|
|
2'h3: RoundAdd = Minus1 ? {`FLEN+1{1'b1}} : {{{`FLEN{1'b0}}}, FpPlus1};
|
|
|
|
2'h1: RoundAdd = Minus1 ? {{`NE+2+`D_NF{1'b1}}, (`FLEN-1-`NE-`D_NF)'(0)} : {(`NE+1+`D_NF)'(0), FpPlus1, (`FLEN-1-`NE-`D_NF)'(0)};
|
|
|
|
2'h0: RoundAdd = Minus1 ? {{`NE+2+`S_NF{1'b1}}, (`FLEN-1-`NE-`S_NF)'(0)} : {(`NE+1+`S_NF)'(0), FpPlus1, (`FLEN-1-`NE-`S_NF)'(0)};
|
|
|
|
2'h2: RoundAdd = Minus1 ? {{`NE+2+`H_NF{1'b1}}, (`FLEN-1-`NE-`H_NF)'(0)} : {(`NE+1+`H_NF)'(0), FpPlus1, (`FLEN-1-`NE-`H_NF)'(0)};
|
|
|
|
endcase
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
// determine the result to be roundned
|
|
|
|
assign RoundFrac = CorrShifted[`CORRSHIFTSZ-1:`CORRSHIFTSZ-`NF];
|
|
|
|
|
|
|
|
always_comb
|
|
|
|
case(PostProcSelM)
|
|
|
|
2'b10: RoundExp = SumExp; // fma
|
|
|
|
2'b00: RoundExp = {CvtCalcExpM[`NE], CvtCalcExpM}&{`NE+2{~CvtResDenormUfM|CvtResUf}}; // cvt
|
|
|
|
2'b01: RoundExp = 0; // divide
|
|
|
|
default: RoundExp = 0;
|
|
|
|
endcase
|
|
|
|
|
|
|
|
// round the result
|
|
|
|
// - if the fraction overflows one should be added to the exponent
|
|
|
|
assign {FullResExp, ResFrac} = {RoundExp, RoundFrac} + RoundAdd;
|
|
|
|
assign ResExp = FullResExp[`NE-1:0];
|
|
|
|
|
|
|
|
|
|
|
|
endmodule
|