mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
oprimized zeros and replaced complex ?: with always_comb
This commit is contained in:
parent
514674417e
commit
d61f84e751
@ -103,7 +103,7 @@ module fcvt (
|
|||||||
// choose the input to the leading zero counter i.e. priority encoder
|
// choose the input to the leading zero counter i.e. priority encoder
|
||||||
// int -> fp : | positive integer | 00000... (if needed) |
|
// int -> fp : | positive integer | 00000... (if needed) |
|
||||||
// fp -> fp : | fraction | 00000... (if needed) |
|
// fp -> fp : | fraction | 00000... (if needed) |
|
||||||
assign LzcInFull = IntToFp ? {1'b0, TrimInt, {`CVTLEN-`XLEN{1'b0}}} :
|
assign LzcInFull = IntToFp ? {TrimInt, {`CVTLEN-`XLEN+1{1'b0}}} :
|
||||||
{Xm, {`CVTLEN-`NF{1'b0}}};
|
{Xm, {`CVTLEN-`NF{1'b0}}};
|
||||||
assign LzcIn = LzcInFull[`CVTLEN-1:0];
|
assign LzcIn = LzcInFull[`CVTLEN-1:0];
|
||||||
|
|
||||||
@ -125,9 +125,10 @@ module fcvt (
|
|||||||
// - only shift fp -> fp if the intital value is denormalized
|
// - only shift fp -> fp if the intital value is denormalized
|
||||||
// - this is a problem because the input to the lzc was the fraction rather than the mantissa
|
// - this is a problem because the input to the lzc was the fraction rather than the mantissa
|
||||||
// - rather have a few and-gates than an extra bit in the priority encoder??? *** is this true?
|
// - rather have a few and-gates than an extra bit in the priority encoder??? *** is this true?
|
||||||
assign ShiftAmt = ToInt ? Ce[`LOGCVTLEN-1:0]&{`LOGCVTLEN{~Ce[`NE]}} :
|
always_comb
|
||||||
ResDenormUf&~IntToFp ? (`LOGCVTLEN)'(`NF-1)+Ce[`LOGCVTLEN-1:0] :
|
if(ToInt) ShiftAmt = Ce[`LOGCVTLEN-1:0]&{`LOGCVTLEN{~Ce[`NE]}};
|
||||||
(LeadingZeros);
|
else if (ResDenormUf&~IntToFp) ShiftAmt = (`LOGCVTLEN)'(`NF-1)+Ce[`LOGCVTLEN-1:0];
|
||||||
|
else ShiftAmt = LeadingZeros;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// exp calculations
|
// exp calculations
|
||||||
@ -150,7 +151,9 @@ module fcvt (
|
|||||||
assign NewBias = ToInt ? (`NE-1)'(1) : (`NE-1)'(`BIAS);
|
assign NewBias = ToInt ? (`NE-1)'(1) : (`NE-1)'(`BIAS);
|
||||||
|
|
||||||
end else if (`FPSIZES == 2) begin
|
end else if (`FPSIZES == 2) begin
|
||||||
assign NewBias = ToInt ? (`NE-1)'(1) : OutFmt ? (`NE-1)'(`BIAS) : (`NE-1)'(`BIAS1);
|
logic [`NE-2:0] NewBiasToFp;
|
||||||
|
assign NewBiasToFp = OutFmt ? (`NE-1)'(`BIAS) : (`NE-1)'(`BIAS1);
|
||||||
|
assign NewBias = ToInt ? (`NE-1)'(1) : NewBiasToFp;
|
||||||
|
|
||||||
end else if (`FPSIZES == 3) begin
|
end else if (`FPSIZES == 3) begin
|
||||||
logic [`NE-2:0] NewBiasToFp;
|
logic [`NE-2:0] NewBiasToFp;
|
||||||
@ -177,7 +180,7 @@ module fcvt (
|
|||||||
// select the old exponent
|
// select the old exponent
|
||||||
// int -> fp : largest bias + XLEN
|
// int -> fp : largest bias + XLEN
|
||||||
// fp -> ??? : XExp
|
// fp -> ??? : XExp
|
||||||
assign OldExp = IntToFp ? (`NE)'(`BIAS)+(`NE)'(`XLEN) : Xe;
|
assign OldExp = IntToFp ? (`NE)'(`BIAS)+(`NE)'(`XLEN-1) : Xe;
|
||||||
|
|
||||||
// calculate CalcExp
|
// calculate CalcExp
|
||||||
// fp -> fp :
|
// fp -> fp :
|
||||||
@ -222,7 +225,11 @@ module fcvt (
|
|||||||
// - if 64-bit : check the msb of the 64-bit integer input and if it's signed
|
// - if 64-bit : check the msb of the 64-bit integer input and if it's signed
|
||||||
// - if 32-bit : check the msb of the 32-bit integer input and if it's signed
|
// - if 32-bit : check the msb of the 32-bit integer input and if it's signed
|
||||||
// - otherwise: the floating point input's sign
|
// - otherwise: the floating point input's sign
|
||||||
assign Cs = IntToFp ? Int64 ? Int[`XLEN-1]&Signed : Int[31]&Signed : Xs;
|
always_comb
|
||||||
|
if(IntToFp)
|
||||||
|
if(Int64) Cs = Int[`XLEN-1]&Signed;
|
||||||
|
else Cs = Int[31]&Signed;
|
||||||
|
else Cs = Xs;
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
@ -42,7 +42,6 @@ module fmashiftcalc(
|
|||||||
output logic [$clog2(3*`NF+7)-1:0] FmaShiftAmt, // normalization shift count
|
output logic [$clog2(3*`NF+7)-1:0] FmaShiftAmt, // normalization shift count
|
||||||
output logic [3*`NF+8:0] FmaShiftIn // is the sum zero
|
output logic [3*`NF+8:0] FmaShiftIn // is the sum zero
|
||||||
);
|
);
|
||||||
logic [$clog2(3*`NF+7)-1:0] DenormShift; // right shift if the result is denormalized //***change this later
|
|
||||||
logic [`NE+1:0] PreNormSumExp; // the exponent of the normalized sum with the `FLEN bias
|
logic [`NE+1:0] PreNormSumExp; // the exponent of the normalized sum with the `FLEN bias
|
||||||
logic [`NE+1:0] BiasCorr;
|
logic [`NE+1:0] BiasCorr;
|
||||||
|
|
||||||
@ -149,9 +148,6 @@ module fmashiftcalc(
|
|||||||
// Determine if the result is denormal
|
// Determine if the result is denormal
|
||||||
// assign FmaPreResultDenorm = $signed(NormSumExp)<=0 & ($signed(NormSumExp)>=$signed(-FracLen)) & ~FmaSZero;
|
// assign FmaPreResultDenorm = $signed(NormSumExp)<=0 & ($signed(NormSumExp)>=$signed(-FracLen)) & ~FmaSZero;
|
||||||
|
|
||||||
// Determine the shift needed for denormal results
|
|
||||||
// - if not denorm add 1 to shift out the leading 1
|
|
||||||
assign DenormShift = FmaPreResultDenorm ? NormSumExp[$clog2(3*`NF+7)-1:0] : 1;
|
|
||||||
// set and calculate the shift input and amount
|
// set and calculate the shift input and amount
|
||||||
// - shift once if killing a product and the result is denormalized
|
// - shift once if killing a product and the result is denormalized
|
||||||
assign FmaShiftIn = {3'b0, FmaSm};
|
assign FmaShiftIn = {3'b0, FmaSm};
|
||||||
|
@ -42,7 +42,12 @@ module negateintres(
|
|||||||
// round and negate the positive res if needed
|
// round and negate the positive res if needed
|
||||||
assign CvtNegRes = Xs ? -({2'b0, Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`XLEN]}+{{`XLEN+1{1'b0}}, Plus1}) : {2'b0, Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`XLEN]}+{{`XLEN+1{1'b0}}, Plus1};
|
assign CvtNegRes = Xs ? -({2'b0, Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`XLEN]}+{{`XLEN+1{1'b0}}, Plus1}) : {2'b0, Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`XLEN]}+{{`XLEN+1{1'b0}}, Plus1};
|
||||||
|
|
||||||
assign CvtNegResMsbs = Signed ? Int64 ? CvtNegRes[`XLEN:`XLEN-1] : CvtNegRes[32:31] :
|
always_comb
|
||||||
Int64 ? CvtNegRes[`XLEN+1:`XLEN] : CvtNegRes[33:32];
|
if(Signed)
|
||||||
|
if(Int64) CvtNegResMsbs = CvtNegRes[`XLEN:`XLEN-1];
|
||||||
|
else CvtNegResMsbs = CvtNegRes[32:31];
|
||||||
|
else
|
||||||
|
if(Int64) CvtNegResMsbs = CvtNegRes[`XLEN+1:`XLEN];
|
||||||
|
else CvtNegResMsbs = CvtNegRes[33:32];
|
||||||
|
|
||||||
endmodule
|
endmodule
|
@ -46,11 +46,21 @@ module resultsign(
|
|||||||
logic Zeros;
|
logic Zeros;
|
||||||
logic Infs;
|
logic Infs;
|
||||||
|
|
||||||
// Determine the sign if the sum is zero
|
// The IEEE754-2019 standard specifies:
|
||||||
// if cancelation then 0 unless round to -infinity
|
// - the sign of an exact zero sum (with operands of diffrent signs) should be positive unless rounding toward negitive infinity
|
||||||
// if multiply then Psgn
|
// - when the exact result of an FMA opperation is non-zero, but is zero due to rounding, use the sign of the exact result
|
||||||
// otherwise psign
|
// - if x = +0 or -0 then x+x=x and x-(-x)=x
|
||||||
assign Zeros = (FmaPs^FmaAs)&~(FmaMe[`NE+1] | ((FmaMe == 0) & (R|S)))&~Mult ? Frm[1:0] == 2'b10 : FmaPs;
|
// - the sign of a product is the exclisive or or the opperand's signs
|
||||||
|
// Zero sign will only be selected if:
|
||||||
|
// - P=Z and a cancelation occurs - exact zero
|
||||||
|
// - Z is zero and P is zero - exact zero
|
||||||
|
// - P is killed and Z is zero - Psgn
|
||||||
|
// - Z is killed and P is zero - impossible
|
||||||
|
// Zero sign calculation:
|
||||||
|
// - if a multiply opperation is done, then use the products sign(Ps)
|
||||||
|
// - if the zero sum is not exactly zero i.e. R|S use the sign of the exact result (which is the product's sign)
|
||||||
|
// - if an effective addition occurs (P+A or -P+-A or P--A) then use the product's sign
|
||||||
|
assign Zeros = (FmaPs^FmaAs)&~(R|S)&~Mult ? Frm[1:0] == 2'b10 : FmaPs;
|
||||||
|
|
||||||
|
|
||||||
// is the result negitive
|
// is the result negitive
|
||||||
@ -58,6 +68,9 @@ module resultsign(
|
|||||||
// if -p + z is the Sum positive
|
// if -p + z is the Sum positive
|
||||||
// if -p - z then the Sum is negitive
|
// if -p - z then the Sum is negitive
|
||||||
assign Infs = ZInf ? FmaAs : FmaPs;
|
assign Infs = ZInf ? FmaAs : FmaPs;
|
||||||
assign Ws = InfIn&FmaOp ? Infs : FmaSZero&FmaOp ? Zeros : Ms;
|
always_comb
|
||||||
|
if(InfIn&FmaOp) Ws = Infs;
|
||||||
|
else if(FmaSZero&FmaOp) Ws = Zeros;
|
||||||
|
else Ws = Ms;
|
||||||
|
|
||||||
endmodule
|
endmodule
|
@ -55,7 +55,10 @@ module shiftcorrection(
|
|||||||
// if the msb is 1 or the exponent was one, but the shifted quotent was < 1 (Denorm)
|
// if the msb is 1 or the exponent was one, but the shifted quotent was < 1 (Denorm)
|
||||||
assign CorrQuotShifted = (LZAPlus2|(DivQe==1&~LZAPlus2)) ? Shifted[`NORMSHIFTSZ-2:`NORMSHIFTSZ-`CORRSHIFTSZ-1] : Shifted[`NORMSHIFTSZ-3:`NORMSHIFTSZ-`CORRSHIFTSZ-2];
|
assign CorrQuotShifted = (LZAPlus2|(DivQe==1&~LZAPlus2)) ? Shifted[`NORMSHIFTSZ-2:`NORMSHIFTSZ-`CORRSHIFTSZ-1] : Shifted[`NORMSHIFTSZ-3:`NORMSHIFTSZ-`CORRSHIFTSZ-2];
|
||||||
// if the result of the divider was calculated to be denormalized, then the result was correctly normalized, so select the top shifted bits
|
// if the result of the divider was calculated to be denormalized, then the result was correctly normalized, so select the top shifted bits
|
||||||
assign Mf = FmaOp ? {CorrSumShifted, {`CORRSHIFTSZ-(3*`NF+6){1'b0}}} : DivOp&~DivResDenorm ? CorrQuotShifted : Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`CORRSHIFTSZ];
|
always_comb
|
||||||
|
if(FmaOp) Mf = {CorrSumShifted, {`CORRSHIFTSZ-(3*`NF+6){1'b0}}};
|
||||||
|
else if (DivOp&~DivResDenorm) Mf = CorrQuotShifted;
|
||||||
|
else Mf = Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`CORRSHIFTSZ];
|
||||||
// Determine sum's exponent
|
// Determine sum's exponent
|
||||||
// if plus1 If plus2 if said denorm but norm plus 1 if said denorm but norm plus 2
|
// if plus1 If plus2 if said denorm but norm plus 1 if said denorm but norm plus 2
|
||||||
assign FmaMe = (NormSumExp+{{`NE+1{1'b0}}, LZAPlus1}+{{`NE{1'b0}}, LZAPlus2, 1'b0}+{{`NE+1{1'b0}}, ~ResDenorm&FmaPreResultDenorm}+{{`NE+1{1'b0}}, &NormSumExp&Shifted[3*`NF+6]}) & {`NE+2{~(FmaSZero|ResDenorm)}};
|
assign FmaMe = (NormSumExp+{{`NE+1{1'b0}}, LZAPlus1}+{{`NE{1'b0}}, LZAPlus2, 1'b0}+{{`NE+1{1'b0}}, ~ResDenorm&FmaPreResultDenorm}+{{`NE+1{1'b0}}, &NormSumExp&Shifted[3*`NF+6]}) & {`NE+2{~(FmaSZero|ResDenorm)}};
|
||||||
|
@ -96,8 +96,13 @@ module specialcase(
|
|||||||
assign InvalidRes = OutFmt ? {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)};
|
assign InvalidRes = OutFmt ? {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)};
|
||||||
end
|
end
|
||||||
|
|
||||||
assign OfRes = OutFmt ? OfResMax ? {Ws, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {Ws, {`NE{1'b1}}, {`NF{1'b0}}} :
|
always_comb
|
||||||
OfResMax ? {{`FLEN-`LEN1{1'b1}}, Ws, {`NE1-1{1'b1}}, 1'b0, {`NF1{1'b1}}} : {{`FLEN-`LEN1{1'b1}}, Ws, {`NE1{1'b1}}, (`NF1)'(0)};
|
if(OutFmt)
|
||||||
|
if(OfResMax) OfRes = {Ws, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}};
|
||||||
|
else OfRes = {Ws, {`NE{1'b1}}, {`NF{1'b0}}};
|
||||||
|
else
|
||||||
|
if(OfResMax) OfRes = {{`FLEN-`LEN1{1'b1}}, Ws, {`NE1-1{1'b1}}, 1'b0, {`NF1{1'b1}}};
|
||||||
|
else OfRes = {{`FLEN-`LEN1{1'b1}}, Ws, {`NE1{1'b1}}, (`NF1)'(0)};
|
||||||
assign UfRes = OutFmt ? {Ws, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)} : {{`FLEN-`LEN1{1'b1}}, Ws, (`LEN1-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
assign UfRes = OutFmt ? {Ws, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)} : {{`FLEN-`LEN1{1'b1}}, Ws, (`LEN1-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||||
assign NormRes = OutFmt ? {Ws, Re, Rf} : {{`FLEN-`LEN1{1'b1}}, Ws, Re[`NE1-1:0], Rf[`NF-1:`NF-`NF1]};
|
assign NormRes = OutFmt ? {Ws, Re, Rf} : {{`FLEN-`LEN1{1'b1}}, Ws, Re[`NE1-1:0], Rf[`NF-1:`NF-`NF1]};
|
||||||
|
|
||||||
@ -234,20 +239,21 @@ module specialcase(
|
|||||||
assign KillRes = CvtOp ? (CvtResUf|(XZero&~IntToFp)|(IntZero&IntToFp)) : FullRe[`NE+1] | (((YInf&~XInf)|XZero)&DivOp);//Underflow & ~ResDenorm & (Re!=1);
|
assign KillRes = CvtOp ? (CvtResUf|(XZero&~IntToFp)|(IntZero&IntToFp)) : FullRe[`NE+1] | (((YInf&~XInf)|XZero)&DivOp);//Underflow & ~ResDenorm & (Re!=1);
|
||||||
assign SelOfRes = Overflow|DivByZero|(InfIn&~(YInf&DivOp));
|
assign SelOfRes = Overflow|DivByZero|(InfIn&~(YInf&DivOp));
|
||||||
// output infinity with result sign if divide by zero
|
// output infinity with result sign if divide by zero
|
||||||
if(`IEEE754) begin
|
if(`IEEE754)
|
||||||
assign PostProcRes = XNaN&~(IntToFp&CvtOp) ? XNaNRes :
|
always_comb
|
||||||
YNaN&~CvtOp ? YNaNRes :
|
if(XNaN&~(IntToFp&CvtOp)) PostProcRes = XNaNRes;
|
||||||
ZNaN&FmaOp ? ZNaNRes :
|
else if(YNaN&~CvtOp) PostProcRes = YNaNRes;
|
||||||
Invalid ? InvalidRes :
|
else if(ZNaN&FmaOp) PostProcRes = ZNaNRes;
|
||||||
SelOfRes ? OfRes :
|
else if(Invalid) PostProcRes = InvalidRes;
|
||||||
KillRes ? UfRes :
|
else if(SelOfRes) PostProcRes = OfRes;
|
||||||
NormRes;
|
else if(KillRes) PostProcRes = UfRes;
|
||||||
end else begin
|
else PostProcRes = NormRes;
|
||||||
assign PostProcRes = NaNIn|Invalid ? InvalidRes :
|
else
|
||||||
SelOfRes ? OfRes :
|
always_comb
|
||||||
KillRes ? UfRes :
|
if(NaNIn|Invalid) PostProcRes = InvalidRes;
|
||||||
NormRes;
|
else if(SelOfRes) PostProcRes = OfRes;
|
||||||
end
|
else if(KillRes) PostProcRes = UfRes;
|
||||||
|
else PostProcRes = NormRes;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@ -272,10 +278,17 @@ module specialcase(
|
|||||||
// unsigned | 2^32-1 | 2^64-1 |
|
// unsigned | 2^32-1 | 2^64-1 |
|
||||||
//
|
//
|
||||||
// other: 32 bit unsinged res should be sign extended as if it were a signed number
|
// other: 32 bit unsinged res should be sign extended as if it were a signed number
|
||||||
assign OfIntRes = Signed ? Xs&~XNaN ? Int64 ? {1'b1, {`XLEN-1{1'b0}}} : {{`XLEN-32{1'b1}}, 1'b1, {31{1'b0}}} : // signed negitive
|
always_comb
|
||||||
Int64 ? {1'b0, {`XLEN-1{1'b1}}} : {{`XLEN-32{1'b0}}, 1'b0, {31{1'b1}}} : // signed positive
|
if(Signed)
|
||||||
Xs&~XNaN ? {`XLEN{1'b0}} : // unsigned negitive
|
if(Xs&~XNaN) // signed negitive
|
||||||
{`XLEN{1'b1}};// unsigned positive
|
if(Int64) OfIntRes = {1'b1, {`XLEN-1{1'b0}}};
|
||||||
|
else OfIntRes = {{`XLEN-32{1'b1}}, 1'b1, {31{1'b0}}};
|
||||||
|
else // signed positive
|
||||||
|
if(Int64) OfIntRes = {1'b0, {`XLEN-1{1'b1}}};
|
||||||
|
else OfIntRes = {{`XLEN-32{1'b0}}, 1'b0, {31{1'b1}}};
|
||||||
|
else
|
||||||
|
if(Xs&~XNaN) OfIntRes = {`XLEN{1'b0}}; // unsigned negitive
|
||||||
|
else OfIntRes = {`XLEN{1'b1}}; // unsigned positive
|
||||||
|
|
||||||
|
|
||||||
// select the integer output
|
// select the integer output
|
||||||
@ -284,7 +297,11 @@ module specialcase(
|
|||||||
// - if rounding and signed opperation and negitive input, output -1
|
// - if rounding and signed opperation and negitive input, output -1
|
||||||
// - otherwise output a rounded 0
|
// - otherwise output a rounded 0
|
||||||
// - otherwise output the normal res (trmined and sign extended if nessisary)
|
// - otherwise output the normal res (trmined and sign extended if nessisary)
|
||||||
assign FCvtIntRes = IntInvalid ? OfIntRes :
|
always_comb
|
||||||
CvtCe[`NE] ? Xs&Signed&Plus1 ? {{`XLEN{1'b1}}} : {{`XLEN-1{1'b0}}, Plus1} : //CalcExp has to come after invalid ***swap to actual mux at some point??
|
if(IntInvalid) FCvtIntRes = OfIntRes;
|
||||||
Int64 ? CvtNegRes[`XLEN-1:0] : {{`XLEN-32{CvtNegRes[31]}}, CvtNegRes[31:0]};
|
else if(CvtCe[`NE])
|
||||||
|
if(Xs&Signed&Plus1) FCvtIntRes = {{`XLEN{1'b1}}};
|
||||||
|
else FCvtIntRes = {{`XLEN-1{1'b0}}, Plus1};
|
||||||
|
else if(Int64) FCvtIntRes = CvtNegRes[`XLEN-1:0];
|
||||||
|
else FCvtIntRes = {{`XLEN-32{CvtNegRes[31]}}, CvtNegRes[31:0]};
|
||||||
endmodule
|
endmodule
|
Loading…
Reference in New Issue
Block a user