Finished fpu parameterization using Lim's method.

This commit is contained in:
Ross Thompson 2023-05-26 14:40:06 -05:00
parent 29e0357f21
commit f1b8689955
17 changed files with 556 additions and 582 deletions

View File

@ -25,16 +25,15 @@
// either express or implied. See the License for the specific language governing permissions // either express or implied. See the License for the specific language governing permissions
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module fclassify ( module fclassify import cvw::*; #(parameter cvw_t P) (
input logic Xs, // sign bit input logic Xs, // sign bit
input logic XNaN, // is NaN input logic XNaN, // is NaN
input logic XSNaN, // is signaling NaN input logic XSNaN, // is signaling NaN
input logic XSubnorm, // is Subnormal input logic XSubnorm, // is Subnormal
input logic XZero, // is zero input logic XZero, // is zero
input logic XInf, // is infinity input logic XInf, // is infinity
output logic [`XLEN-1:0] ClassRes // classify result output logic [P.XLEN-1:0] ClassRes // classify result
); );
logic PInf, PZero, PNorm, PSubnorm; // is the input a positive infinity/zero/normal/subnormal logic PInf, PZero, PNorm, PSubnorm; // is the input a positive infinity/zero/normal/subnormal
@ -63,6 +62,6 @@ module fclassify (
// bit 7 - +Inf // bit 7 - +Inf
// bit 8 - signaling NaN // bit 8 - signaling NaN
// bit 9 - quiet NaN // bit 9 - quiet NaN
assign ClassRes = {{`XLEN-10{1'b0}}, XNaN&~XSNaN, XSNaN, PInf, PNorm, PSubnorm, PZero, NZero, NSubnorm, NNorm, NInf}; assign ClassRes = {{P.XLEN-10{1'b0}}, XNaN&~XSNaN, XSNaN, PInf, PNorm, PSubnorm, PZero, NZero, NSubnorm, NNorm, NInf};
endmodule endmodule

View File

@ -27,8 +27,6 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
// OpCtrl values // OpCtrl values
// 110 min // 110 min
// 101 max // 101 max
@ -36,23 +34,23 @@
// 001 less than // 001 less than
// 011 less than or equal // 011 less than or equal
module fcmp ( module fcmp import cvw::*; #(parameter cvw_t P) (
input logic [`FMTBITS-1:0] Fmt, // format of fp number input logic [P.FMTBITS-1:0] Fmt, // format of fp number
input logic [2:0] OpCtrl, // see above table input logic [2:0] OpCtrl, // see above table
input logic Xs, Ys, // input signs input logic Xs, Ys, // input signs
input logic [`NE-1:0] Xe, Ye, // input exponents input logic [P.NE-1:0] Xe, Ye, // input exponents
input logic [`NF:0] Xm, Ym, // input mantissa input logic [P.NF:0] Xm, Ym, // input mantissa
input logic XZero, YZero, // is zero input logic XZero, YZero, // is zero
input logic XNaN, YNaN, // is NaN input logic XNaN, YNaN, // is NaN
input logic XSNaN, YSNaN, // is signaling NaN input logic XSNaN, YSNaN, // is signaling NaN
input logic [`FLEN-1:0] X, Y, // original inputs (before unpacker) input logic [P.FLEN-1:0] X, Y, // original inputs (before unpacker)
output logic CmpNV, // invalid flag output logic CmpNV, // invalid flag
output logic [`FLEN-1:0] CmpFpRes, // compare floating-point result output logic [P.FLEN-1:0] CmpFpRes, // compare floating-point result
output logic [`XLEN-1:0] CmpIntRes // compare integer result output logic [P.XLEN-1:0] CmpIntRes // compare integer result
); );
logic LTabs, LT, EQ; // is X < or > or = Y logic LTabs, LT, EQ; // is X < or > or = Y
logic [`FLEN-1:0] NaNRes; // NaN result logic [P.FLEN-1:0] NaNRes; // NaN result
logic BothZero; // are both inputs zero logic BothZero; // are both inputs zero
logic EitherNaN, EitherSNaN; // are either input a (signaling) NaN logic EitherNaN, EitherSNaN; // are either input a (signaling) NaN
@ -85,44 +83,44 @@ module fcmp (
// for RISC-V, return the canonical NaN // for RISC-V, return the canonical NaN
// select the NaN result // select the NaN result
if (`FPSIZES == 1) if (P.FPSIZES == 1)
if(`IEEE754) assign NaNRes = {Xs, {`NE{1'b1}}, 1'b1, Xm[`NF-2:0]}; if(P.IEEE754) assign NaNRes = {Xs, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]};
else assign NaNRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; else assign NaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
else if (`FPSIZES == 2) else if (P.FPSIZES == 2)
if(`IEEE754) assign NaNRes = Fmt ? {Xs, {`NE{1'b1}}, 1'b1, Xm[`NF-2:0]} : {{`FLEN-`LEN1{1'b1}}, Xs, {`NE1{1'b1}}, 1'b1, Xm[`NF-2:`NF-`NF1]}; if(P.IEEE754) assign NaNRes = Fmt ? {Xs, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]} : {{P.FLEN-P.LEN1{1'b1}}, Xs, {P.NE1{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.NF1]};
else assign NaNRes = Fmt ? {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)}; else assign NaNRes = Fmt ? {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}} : {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, (P.NF1-1)'(0)};
else if (`FPSIZES == 3) else if (P.FPSIZES == 3)
always_comb always_comb
case (Fmt) case (Fmt)
`FMT: P.FMT:
if(`IEEE754) NaNRes = {Xs, {`NE{1'b1}}, 1'b1, Xm[`NF-2:0]}; if(P.IEEE754) NaNRes = {Xs, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]};
else NaNRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; else NaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
`FMT1: P.FMT1:
if(`IEEE754) NaNRes = {{`FLEN-`LEN1{1'b1}}, Xs, {`NE1{1'b1}}, 1'b1, Xm[`NF-2:`NF-`NF1]}; if(P.IEEE754) NaNRes = {{P.FLEN-P.LEN1{1'b1}}, Xs, {P.NE1{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.NF1]};
else NaNRes = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; else NaNRes = {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, (P.NF1-1)'(0)};
`FMT2: P.FMT2:
if(`IEEE754) NaNRes = {{`FLEN-`LEN2{1'b1}}, Xs, {`NE2{1'b1}}, 1'b1, Xm[`NF-2:`NF-`NF2]}; if(P.IEEE754) NaNRes = {{P.FLEN-P.LEN2{1'b1}}, Xs, {P.NE2{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.NF2]};
else NaNRes = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)}; else NaNRes = {{P.FLEN-P.LEN2{1'b1}}, 1'b0, {P.NE2{1'b1}}, 1'b1, (P.NF2-1)'(0)};
default: NaNRes = {`FLEN{1'bx}}; default: NaNRes = {P.FLEN{1'bx}};
endcase endcase
else if (`FPSIZES == 4) else if (P.FPSIZES == 4)
always_comb always_comb
case (Fmt) case (Fmt)
2'h3: 2'h3:
if(`IEEE754) NaNRes = {Xs, {`NE{1'b1}}, 1'b1, Xm[`NF-2:0]}; if(P.IEEE754) NaNRes = {Xs, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]};
else NaNRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; else NaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
2'h1: 2'h1:
if(`IEEE754) NaNRes = {{`FLEN-`D_LEN{1'b1}}, Xs, {`D_NE{1'b1}}, 1'b1, Xm[`NF-2:`NF-`D_NF]}; if(P.IEEE754) NaNRes = {{P.FLEN-P.D_LEN{1'b1}}, Xs, {P.D_NE{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.D_NF]};
else NaNRes = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)}; else NaNRes = {{P.FLEN-P.D_LEN{1'b1}}, 1'b0, {P.D_NE{1'b1}}, 1'b1, (P.D_NF-1)'(0)};
2'h0: 2'h0:
if(`IEEE754) NaNRes = {{`FLEN-`S_LEN{1'b1}}, Xs, {`S_NE{1'b1}}, 1'b1, Xm[`NF-2:`NF-`S_NF]}; if(P.IEEE754) NaNRes = {{P.FLEN-P.S_LEN{1'b1}}, Xs, {P.S_NE{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.S_NF]};
else NaNRes = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)}; else NaNRes = {{P.FLEN-P.S_LEN{1'b1}}, 1'b0, {P.S_NE{1'b1}}, 1'b1, (P.S_NF-1)'(0)};
2'h2: 2'h2:
if(`IEEE754) NaNRes = {{`FLEN-`H_LEN{1'b1}}, Xs, {`H_NE{1'b1}}, 1'b1, Xm[`NF-2:`NF-`H_NF]}; if(P.IEEE754) NaNRes = {{P.FLEN-P.H_LEN{1'b1}}, Xs, {P.H_NE{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.H_NF]};
else NaNRes = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)}; else NaNRes = {{P.FLEN-P.H_LEN{1'b1}}, 1'b0, {P.H_NE{1'b1}}, 1'b1, (P.H_NF-1)'(0)};
endcase endcase
@ -155,6 +153,6 @@ module fcmp (
// - -0 = 0 // - -0 = 0
// - inf = inf and -inf = -inf // - inf = inf and -inf = -inf
// - return 0 if comparison with NaN (unordered) // - return 0 if comparison with NaN (unordered)
assign CmpIntRes = {(`XLEN-1)'(0), (((EQ|BothZero)&OpCtrl[1])|(LT&OpCtrl[0]&~BothZero))&~EitherNaN}; assign CmpIntRes = {(P.XLEN-1)'(0), (((EQ|BothZero)&OpCtrl[1])|(LT&OpCtrl[0]&~BothZero))&~EitherNaN};
endmodule endmodule

View File

@ -27,23 +27,21 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh" module fcvt import cvw::*; #(parameter cvw_t P) (
module fcvt (
input logic Xs, // input's sign input logic Xs, // input's sign
input logic [`NE-1:0] Xe, // input's exponent input logic [P.NE-1:0] Xe, // input's exponent
input logic [`NF:0] Xm, // input's fraction input logic [P.NF:0] Xm, // input's fraction
input logic [`XLEN-1:0] Int, // integer input - from IEU input logic [P.XLEN-1:0] Int, // integer input - from IEU
input logic [2:0] OpCtrl, // choose which opperation (look below for values) input logic [2:0] OpCtrl, // choose which opperation (look below for values)
input logic ToInt, // is fp->int (since it's writting to the integer register) input logic ToInt, // is fp->int (since it's writting to the integer register)
input logic XZero, // is the input zero input logic XZero, // is the input zero
input logic [`FMTBITS-1:0] Fmt, // the input's precision (11=quad 01=double 00=single 10=half) input logic [P.FMTBITS-1:0] Fmt, // the input's precision (11=quad 01=double 00=single 10=half)
output logic [`NE:0] Ce, // the calculated expoent output logic [P.NE:0] Ce, // the calculated expoent
output logic [`LOGCVTLEN-1:0] ShiftAmt, // how much to shift by output logic [P.LOGCVTLEN-1:0] ShiftAmt, // how much to shift by
output logic ResSubnormUf,// does the result underflow or is subnormal output logic ResSubnormUf,// does the result underflow or is subnormal
output logic Cs, // the result's sign output logic Cs, // the result's sign
output logic IntZero, // is the integer zero? output logic IntZero, // is the integer zero?
output logic [`CVTLEN-1:0] LzcIn // input to the Leading Zero Counter (priority encoder) output logic [P.CVTLEN-1:0] LzcIn // input to the Leading Zero Counter (priority encoder)
); );
// OpCtrls: // OpCtrls:
@ -56,16 +54,16 @@ module fcvt (
// bit 2 bit 1 bit 0 // bit 2 bit 1 bit 0
// for example: signed long -> single floating point has the OpCode 101 // for example: signed long -> single floating point has the OpCode 101
logic [`FMTBITS-1:0] OutFmt; // format of the output logic [P.FMTBITS-1:0] OutFmt; // format of the output
logic [`XLEN-1:0] PosInt; // the positive integer input logic [P.XLEN-1:0] PosInt; // the positive integer input
logic [`XLEN-1:0] TrimInt; // integer trimmed to the correct size logic [P.XLEN-1:0] TrimInt; // integer trimmed to the correct size
logic [`NE-2:0] NewBias; // the bias of the final result logic [P.NE-2:0] NewBias; // the bias of the final result
logic [`NE-1:0] OldExp; // the old exponent logic [P.NE-1:0] OldExp; // the old exponent
logic Signed; // is the opperation with a signed integer? logic Signed; // is the opperation with a signed integer?
logic Int64; // is the integer 64 bits? logic Int64; // is the integer 64 bits?
logic IntToFp; // is the opperation an int->fp conversion? logic IntToFp; // is the opperation an int->fp conversion?
logic [`CVTLEN:0] LzcInFull; // input to the Leading Zero Counter (priority encoder) logic [P.CVTLEN:0] LzcInFull; // input to the Leading Zero Counter (priority encoder)
logic [`LOGCVTLEN-1:0] LeadingZeros; // output from the LZC logic [P.LOGCVTLEN-1:0] LeadingZeros; // output from the LZC
// seperate OpCtrl for code readability // seperate OpCtrl for code readability
@ -76,9 +74,9 @@ module fcvt (
// choose the ouptut format depending on the opperation // choose the ouptut format depending on the opperation
// - fp -> fp: OpCtrl contains the percision of the output // - fp -> fp: OpCtrl contains the percision of the output
// - int -> fp: Fmt contains the percision of the output // - int -> fp: Fmt contains the percision of the output
if (`FPSIZES == 2) if (P.FPSIZES == 2)
assign OutFmt = IntToFp ? Fmt : (OpCtrl[1:0] == `FMT); assign OutFmt = IntToFp ? Fmt : (OpCtrl[1:0] == P.FMT);
else if (`FPSIZES == 3 | `FPSIZES == 4) else if (P.FPSIZES == 3 | P.FPSIZES == 4)
assign OutFmt = IntToFp ? Fmt : OpCtrl[1:0]; assign OutFmt = IntToFp ? Fmt : OpCtrl[1:0];
@ -89,7 +87,7 @@ module fcvt (
// 2) trim the input to the proper size (kill the 32 most significant zeroes if needed) // 2) trim the input to the proper size (kill the 32 most significant zeroes if needed)
assign PosInt = Cs ? -Int : Int; assign PosInt = Cs ? -Int : Int;
assign TrimInt = {{`XLEN-32{Int64}}, {32{1'b1}}} & PosInt; assign TrimInt = {{P.XLEN-32{Int64}}, {32{1'b1}}} & PosInt;
assign IntZero = ~|TrimInt; assign IntZero = ~|TrimInt;
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -99,13 +97,13 @@ 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 ? {TrimInt, {`CVTLEN-`XLEN+1{1'b0}}} : assign LzcInFull = IntToFp ? {TrimInt, {P.CVTLEN-P.XLEN+1{1'b0}}} :
{Xm, {`CVTLEN-`NF{1'b0}}}; {Xm, {P.CVTLEN-P.NF{1'b0}}};
// used as shifter input in postprocessor // used as shifter input in postprocessor
assign LzcIn = LzcInFull[`CVTLEN-1:0]; assign LzcIn = LzcInFull[P.CVTLEN-1:0];
lzc #(`CVTLEN+1) lzc (.num(LzcInFull), .ZeroCnt(LeadingZeros)); lzc #(P.CVTLEN+1) lzc (.num(LzcInFull), .ZeroCnt(LeadingZeros));
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// exp calculations // exp calculations
@ -114,42 +112,42 @@ module fcvt (
// Select the bias of the output // Select the bias of the output
// fp -> int : select 1 // fp -> int : select 1
// ??? -> fp : pick the new bias depending on the output format // ??? -> fp : pick the new bias depending on the output format
if (`FPSIZES == 1) begin if (P.FPSIZES == 1) begin
assign NewBias = ToInt ? (`NE-1)'(1) : (`NE-1)'(`BIAS); assign NewBias = ToInt ? (P.NE-1)'(1) : (P.NE-1)'(P.BIAS);
end else if (`FPSIZES == 2) begin end else if (P.FPSIZES == 2) begin
logic [`NE-2:0] NewBiasToFp; logic [P.NE-2:0] NewBiasToFp;
assign NewBiasToFp = OutFmt ? (`NE-1)'(`BIAS) : (`NE-1)'(`BIAS1); assign NewBiasToFp = OutFmt ? (P.NE-1)'(P.BIAS) : (P.NE-1)'(P.BIAS1);
assign NewBias = ToInt ? (`NE-1)'(1) : NewBiasToFp; assign NewBias = ToInt ? (P.NE-1)'(1) : NewBiasToFp;
end else if (`FPSIZES == 3) begin end else if (P.FPSIZES == 3) begin
logic [`NE-2:0] NewBiasToFp; logic [P.NE-2:0] NewBiasToFp;
always_comb always_comb
case (OutFmt) case (OutFmt)
`FMT: NewBiasToFp = (`NE-1)'(`BIAS); P.FMT: NewBiasToFp = (P.NE-1)'(P.BIAS);
`FMT1: NewBiasToFp = (`NE-1)'(`BIAS1); P.FMT1: NewBiasToFp = (P.NE-1)'(P.BIAS1);
`FMT2: NewBiasToFp = (`NE-1)'(`BIAS2); P.FMT2: NewBiasToFp = (P.NE-1)'(P.BIAS2);
default: NewBiasToFp = {`NE-1{1'bx}}; default: NewBiasToFp = {P.NE-1{1'bx}};
endcase endcase
assign NewBias = ToInt ? (`NE-1)'(1) : NewBiasToFp; assign NewBias = ToInt ? (P.NE-1)'(1) : NewBiasToFp;
end else if (`FPSIZES == 4) begin end else if (P.FPSIZES == 4) begin
logic [`NE-2:0] NewBiasToFp; logic [P.NE-2:0] NewBiasToFp;
always_comb always_comb
case (OutFmt) case (OutFmt)
2'h3: NewBiasToFp = (`NE-1)'(`Q_BIAS); 2'h3: NewBiasToFp = (P.NE-1)'(P.Q_BIAS);
2'h1: NewBiasToFp = (`NE-1)'(`D_BIAS); 2'h1: NewBiasToFp = (P.NE-1)'(P.D_BIAS);
2'h0: NewBiasToFp = (`NE-1)'(`S_BIAS); 2'h0: NewBiasToFp = (P.NE-1)'(P.S_BIAS);
2'h2: NewBiasToFp = (`NE-1)'(`H_BIAS); 2'h2: NewBiasToFp = (P.NE-1)'(P.H_BIAS);
endcase endcase
assign NewBias = ToInt ? (`NE-1)'(1) : NewBiasToFp; assign NewBias = ToInt ? (P.NE-1)'(1) : NewBiasToFp;
end end
// select the old exponent // select the old exponent
// int -> fp : largest bias + XLEN-1 // int -> fp : largest bias + XLEN-1
// fp -> ??? : XExp // fp -> ??? : XExp
assign OldExp = IntToFp ? (`NE)'(`BIAS)+(`NE)'(`XLEN-1) : Xe; assign OldExp = IntToFp ? (P.NE)'(P.BIAS)+(P.NE)'(P.XLEN-1) : Xe;
// calculate CalcExp // calculate CalcExp
// fp -> fp : // fp -> fp :
@ -159,13 +157,13 @@ module fcvt (
// - correct the expoent when there is a normalization shift ( + LeadingZeros+1) // - correct the expoent when there is a normalization shift ( + LeadingZeros+1)
// - the plus 1 is built into the leading zeros by counting the leading zeroes in the mantissa rather than the fraction // - the plus 1 is built into the leading zeros by counting the leading zeroes in the mantissa rather than the fraction
// fp -> int : XExp - Largest Bias + 1 - (LeadingZeros+1) // fp -> int : XExp - Largest Bias + 1 - (LeadingZeros+1)
// | `XLEN zeros | Mantissa | 0's if nessisary | << CalcExp // | P.XLEN zeros | Mantissa | 0's if nessisary | << CalcExp
// process: // process:
// - start // - start
// | `XLEN zeros | Mantissa | 0's if nessisary | // | P.XLEN zeros | Mantissa | 0's if nessisary |
// //
// - shift left 1 (1) // - shift left 1 (1)
// | `XLEN-1 zeros |bit| frac | 0's if nessisary | // | P.XLEN-1 zeros |bit| frac | 0's if nessisary |
// . <- binary point // . <- binary point
// //
// - shift left till unbiased exponent is 0 (XExp - Largest Bias) // - shift left till unbiased exponent is 0 (XExp - Largest Bias)
@ -185,13 +183,13 @@ module fcvt (
// - newBias to make the biased exponent // - newBias to make the biased exponent
// //
// oldexp - biasold - LeadingZeros + newbias // oldexp - biasold - LeadingZeros + newbias
assign Ce = {1'b0, OldExp} - (`NE+1)'(`BIAS) - {{`NE-`LOGCVTLEN+1{1'b0}}, (LeadingZeros)} + {2'b0, NewBias}; assign Ce = {1'b0, OldExp} - (P.NE+1)'(P.BIAS) - {{P.NE-P.LOGCVTLEN+1{1'b0}}, (LeadingZeros)} + {2'b0, NewBias};
// find if the result is dnormal or underflows // find if the result is dnormal or underflows
// - if Calculated expoenent is 0 or negitive (and the input/result is not exactaly 0) // - if Calculated expoenent is 0 or negitive (and the input/result is not exactaly 0)
// - can't underflow an integer to Fp conversion // - can't underflow an integer to Fp conversion
assign ResSubnormUf = (~|Ce | Ce[`NE])&~XZero&~IntToFp; assign ResSubnormUf = (~|Ce | Ce[P.NE])&~XZero&~IntToFp;
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -211,8 +209,8 @@ module fcvt (
// - 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?
always_comb always_comb
if(ToInt) ShiftAmt = Ce[`LOGCVTLEN-1:0]&{`LOGCVTLEN{~Ce[`NE]}}; if(ToInt) ShiftAmt = Ce[P.LOGCVTLEN-1:0]&{P.LOGCVTLEN{~Ce[P.NE]}};
else if (ResSubnormUf) ShiftAmt = (`LOGCVTLEN)'(`NF-1)+Ce[`LOGCVTLEN-1:0]; else if (ResSubnormUf) ShiftAmt = (P.LOGCVTLEN)'(P.NF-1)+Ce[P.LOGCVTLEN-1:0];
else ShiftAmt = LeadingZeros; else ShiftAmt = LeadingZeros;
@ -227,7 +225,7 @@ module fcvt (
// - otherwise: the floating point input's sign // - otherwise: the floating point input's sign
always_comb always_comb
if(IntToFp) if(IntToFp)
if(Int64) Cs = Int[`XLEN-1]&Signed; if(Int64) Cs = Int[P.XLEN-1]&Signed;
else Cs = Int[31]&Signed; else Cs = Int[31]&Signed;
else Cs = Xs; else Cs = Xs;

View File

@ -245,20 +245,20 @@ module fpu import cvw::*; #(parameter cvw_t P) (
.QmM, .FIntDivResultM); .QmM, .FIntDivResultM);
// compare: fmin/fmax, flt/fle/feq // compare: fmin/fmax, flt/fle/feq
fcmp fcmp (.Fmt(FmtE), .OpCtrl(OpCtrlE), .Xs(XsE), .Ys(YsE), .Xe(XeE), .Ye(YeE), fcmp #(P) fcmp (.Fmt(FmtE), .OpCtrl(OpCtrlE), .Xs(XsE), .Ys(YsE), .Xe(XeE), .Ye(YeE),
.Xm(XmE), .Ym(YmE), .XZero(XZeroE), .YZero(YZeroE), .XNaN(XNaNE), .YNaN(YNaNE), .Xm(XmE), .Ym(YmE), .XZero(XZeroE), .YZero(YZeroE), .XNaN(XNaNE), .YNaN(YNaNE),
.XSNaN(XSNaNE), .YSNaN(YSNaNE), .X(XE), .Y(YE), .CmpNV(CmpNVE), .XSNaN(XSNaNE), .YSNaN(YSNaNE), .X(XE), .Y(YE), .CmpNV(CmpNVE),
.CmpFpRes(CmpFpResE), .CmpIntRes(CmpIntResE)); .CmpFpRes(CmpFpResE), .CmpIntRes(CmpIntResE));
// sign injection: fsgnj/fsgnjx/fsgnjn // sign injection: fsgnj/fsgnjx/fsgnjn
fsgninj fsgninj(.OpCtrl(OpCtrlE[1:0]), .Xs(XsE), .Ys(YsE), .X(XPostBoxE), .Fmt(FmtE), .SgnRes(SgnResE)); fsgninj #(P) fsgninj(.OpCtrl(OpCtrlE[1:0]), .Xs(XsE), .Ys(YsE), .X(XPostBoxE), .Fmt(FmtE), .SgnRes(SgnResE));
// classify: fclass // classify: fclass
fclassify fclassify (.Xs(XsE), .XSubnorm(XSubnormE), .XZero(XZeroE), .XNaN(XNaNE), fclassify #(P) fclassify (.Xs(XsE), .XSubnorm(XSubnormE), .XZero(XZeroE), .XNaN(XNaNE),
.XInf(XInfE), .XSNaN(XSNaNE), .ClassRes(ClassResE)); .XInf(XInfE), .XSNaN(XSNaNE), .ClassRes(ClassResE));
// convert: fcvt.*.* // convert: fcvt.*.*
fcvt fcvt (.Xs(XsE), .Xe(XeE), .Xm(XmE), .Int(ForwardedSrcAE), .OpCtrl(OpCtrlE), fcvt #(P) fcvt (.Xs(XsE), .Xe(XeE), .Xm(XmE), .Int(ForwardedSrcAE), .OpCtrl(OpCtrlE),
.ToInt(FWriteIntE), .XZero(XZeroE), .Fmt(FmtE), .Ce(CeE), .ShiftAmt(CvtShiftAmtE), .ToInt(FWriteIntE), .XZero(XZeroE), .Fmt(FmtE), .Ce(CeE), .ShiftAmt(CvtShiftAmtE),
.ResSubnormUf(CvtResSubnormUfE), .Cs(CsE), .IntZero(IntZeroE), .LzcIn(CvtLzcInE)); .ResSubnormUf(CvtResSubnormUfE), .Cs(CsE), .IntZero(IntZeroE), .LzcIn(CvtLzcInE));
@ -325,7 +325,7 @@ module fpu import cvw::*; #(parameter cvw_t P) (
// Memory Stage: postprocessor and result muxes // Memory Stage: postprocessor and result muxes
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
postprocess postprocess(.Xs(XsM), .Ys(YsM), .Xm(XmM), .Ym(YmM), .Zm(ZmM), .Frm(FrmM), .Fmt(FmtM), postprocess #(P) postprocess(.Xs(XsM), .Ys(YsM), .Xm(XmM), .Ym(YmM), .Zm(ZmM), .Frm(FrmM), .Fmt(FmtM),
.FmaASticky(FmaAStickyM), .XZero(XZeroM), .YZero(YZeroM), .XInf(XInfM), .YInf(YInfM), .DivQm(QmM), .FmaSs(SsM), .FmaASticky(FmaAStickyM), .XZero(XZeroM), .YZero(YZeroM), .XInf(XInfM), .YInf(YInfM), .DivQm(QmM), .FmaSs(SsM),
.ZInf(ZInfM), .XNaN(XNaNM), .YNaN(YNaNM), .ZNaN(ZNaNM), .XSNaN(XSNaNM), .YSNaN(YSNaNM), .ZSNaN(ZSNaNM), .ZInf(ZInfM), .XNaN(XNaNM), .YNaN(YNaNM), .ZNaN(ZNaNM), .XSNaN(XSNaNM), .YSNaN(YSNaNM), .ZSNaN(ZSNaNM),
.FmaSm(SmM), .DivQe(QeM), .FmaAs(AsM), .FmaPs(PsM), .OpCtrl(OpCtrlM), .FmaSCnt(SCntM), .FmaSe(SeM), .FmaSm(SmM), .DivQe(QeM), .FmaAs(AsM), .FmaPs(PsM), .OpCtrl(OpCtrlM), .FmaSCnt(SCntM), .FmaSe(SeM),

View File

@ -26,14 +26,12 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh" module fsgninj import cvw::*; #(parameter cvw_t P) (
module fsgninj (
input logic Xs, Ys, // X and Y sign bits input logic Xs, Ys, // X and Y sign bits
input logic [`FLEN-1:0] X, // X input logic [P.FLEN-1:0] X, // X
input logic [`FMTBITS-1:0] Fmt, // format input logic [P.FMTBITS-1:0] Fmt, // format
input logic [1:0] OpCtrl, // operation control input logic [1:0] OpCtrl, // operation control
output logic [`FLEN-1:0] SgnRes // result output logic [P.FLEN-1:0] SgnRes // result
); );
logic ResSgn; // result sign logic ResSgn; // result sign
@ -50,30 +48,30 @@ module fsgninj (
// - uses NaN-blocking format // - uses NaN-blocking format
// - if there are any unused bits the most significant bits are filled with 1s // - if there are any unused bits the most significant bits are filled with 1s
if (`FPSIZES == 1) if (P.FPSIZES == 1)
assign SgnRes = {ResSgn, X[`FLEN-2:0]}; assign SgnRes = {ResSgn, X[P.FLEN-2:0]};
else if (`FPSIZES == 2) else if (P.FPSIZES == 2)
assign SgnRes = {~Fmt|ResSgn, X[`FLEN-2:`LEN1], Fmt ? X[`LEN1-1] : ResSgn, X[`LEN1-2:0]}; assign SgnRes = {~Fmt|ResSgn, X[P.FLEN-2:P.LEN1], Fmt ? X[P.LEN1-1] : ResSgn, X[P.LEN1-2:0]};
else if (`FPSIZES == 3) begin else if (P.FPSIZES == 3) begin
logic [2:0] SgnBits; logic [2:0] SgnBits;
always_comb always_comb
case (Fmt) case (Fmt)
`FMT: SgnBits = {ResSgn, X[`LEN1-1], X[`LEN2-1]}; P.FMT: SgnBits = {ResSgn, X[P.LEN1-1], X[P.LEN2-1]};
`FMT1: SgnBits = {1'b1, ResSgn, X[`LEN2-1]}; P.FMT1: SgnBits = {1'b1, ResSgn, X[P.LEN2-1]};
`FMT2: SgnBits = {2'b11, ResSgn}; P.FMT2: SgnBits = {2'b11, ResSgn};
default: SgnBits = {3{1'bx}}; default: SgnBits = {3{1'bx}};
endcase endcase
assign SgnRes = {SgnBits[2], X[`FLEN-2:`LEN1], SgnBits[1], X[`LEN1-2:`LEN2], SgnBits[0], X[`LEN2-2:0]}; assign SgnRes = {SgnBits[2], X[P.FLEN-2:P.LEN1], SgnBits[1], X[P.LEN1-2:P.LEN2], SgnBits[0], X[P.LEN2-2:0]};
end else if (`FPSIZES == 4) begin end else if (P.FPSIZES == 4) begin
logic [3:0] SgnBits; logic [3:0] SgnBits;
always_comb always_comb
case (Fmt) case (Fmt)
`Q_FMT: SgnBits = {ResSgn, X[`D_LEN-1], X[`S_LEN-1], X[`H_LEN-1]}; P.Q_FMT: SgnBits = {ResSgn, X[P.D_LEN-1], X[P.S_LEN-1], X[P.H_LEN-1]};
`D_FMT: SgnBits = {1'b1, ResSgn, X[`S_LEN-1], X[`H_LEN-1]}; P.D_FMT: SgnBits = {1'b1, ResSgn, X[P.S_LEN-1], X[P.H_LEN-1]};
`S_FMT: SgnBits = {2'b11, ResSgn, X[`H_LEN-1]}; P.S_FMT: SgnBits = {2'b11, ResSgn, X[P.H_LEN-1]};
`H_FMT: SgnBits = {3'b111, ResSgn}; P.H_FMT: SgnBits = {3'b111, ResSgn};
endcase endcase
assign SgnRes = {SgnBits[3], X[`Q_LEN-2:`D_LEN], SgnBits[2], X[`D_LEN-2:`S_LEN], SgnBits[1], X[`S_LEN-2:`H_LEN], SgnBits[0], X[`H_LEN-2:0]}; assign SgnRes = {SgnBits[3], X[P.Q_LEN-2:P.D_LEN], SgnBits[2], X[P.D_LEN-2:P.S_LEN], SgnBits[1], X[P.S_LEN-2:P.H_LEN], SgnBits[0], X[P.H_LEN-2:0]};
end end
endmodule endmodule

View File

@ -26,22 +26,20 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh" module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
module cvtshiftcalc(
input logic XZero, // is the input zero? input logic XZero, // is the input zero?
input logic ToInt, // to integer conversion? input logic ToInt, // to integer conversion?
input logic IntToFp, // interger to floating point conversion? input logic IntToFp, // interger to floating point conversion?
input logic [`FMTBITS-1:0] OutFmt, // output format input logic [P.FMTBITS-1:0] OutFmt, // output format
input logic [`NE:0] CvtCe, // the calculated expoent input logic [P.NE:0] CvtCe, // the calculated expoent
input logic [`NF:0] Xm, // input mantissas input logic [P.NF:0] Xm, // input mantissas
input logic [`CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (without msb) input logic [P.CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (without msb)
input logic CvtResSubnormUf, // is the conversion result subnormal or underlows input logic CvtResSubnormUf, // is the conversion result subnormal or underlows
output logic CvtResUf, // does the cvt result unerflow output logic CvtResUf, // does the cvt result unerflow
output logic [`CVTLEN+`NF:0] CvtShiftIn // number to be shifted output logic [P.CVTLEN+P.NF:0] CvtShiftIn // number to be shifted
); );
logic [$clog2(`NF):0] ResNegNF; // the result's fraction length negated (-NF) logic [$clog2(P.NF):0] ResNegNF; // the result's fraction length negated (-NF)
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// shifter // shifter
@ -49,7 +47,7 @@ module cvtshiftcalc(
// seclect the input to the shifter // seclect the input to the shifter
// fp -> int: // fp -> int:
// | `XLEN zeros | mantissa | 0's if nessisary | // | P.XLEN zeros | mantissa | 0's if nessisary |
// . // .
// Other problems: // Other problems:
// - if shifting to the right (neg CalcExp) then don't a 1 in the round bit (to prevent an incorrect plus 1 later durring rounding) // - if shifting to the right (neg CalcExp) then don't a 1 in the round bit (to prevent an incorrect plus 1 later durring rounding)
@ -57,7 +55,7 @@ module cvtshiftcalc(
// - ex: for the case 0010000.... (double) // - ex: for the case 0010000.... (double)
// ??? -> fp: // ??? -> fp:
// - if result is subnormal or underflowed then we want to shift right i.e. shift right then shift left: // - if result is subnormal or underflowed then we want to shift right i.e. shift right then shift left:
// | `NF-1 zeros | mantissa | 0's if nessisary | // | P.NF-1 zeros | mantissa | 0's if nessisary |
// . // .
// - otherwise: // - otherwise:
// | LzcInM | 0's if nessisary | // | LzcInM | 0's if nessisary |
@ -67,33 +65,33 @@ module cvtshiftcalc(
// get rid of round bit if needed // get rid of round bit if needed
// | add sticky bit if needed // | add sticky bit if needed
// | | // | |
if (ToInt) CvtShiftIn = {{`XLEN{1'b0}}, Xm[`NF]&~CvtCe[`NE], Xm[`NF-1]|(CvtCe[`NE]&Xm[`NF]), Xm[`NF-2:0], {`CVTLEN-`XLEN{1'b0}}}; if (ToInt) CvtShiftIn = {{P.XLEN{1'b0}}, Xm[P.NF]&~CvtCe[P.NE], Xm[P.NF-1]|(CvtCe[P.NE]&Xm[P.NF]), Xm[P.NF-2:0], {P.CVTLEN-P.XLEN{1'b0}}};
else if (CvtResSubnormUf) CvtShiftIn = {{`NF-1{1'b0}}, Xm, {`CVTLEN-`NF+1{1'b0}}}; else if (CvtResSubnormUf) CvtShiftIn = {{P.NF-1{1'b0}}, Xm, {P.CVTLEN-P.NF+1{1'b0}}};
else CvtShiftIn = {CvtLzcIn, {`NF+1{1'b0}}}; else CvtShiftIn = {CvtLzcIn, {P.NF+1{1'b0}}};
// choose the negative of the fraction size // choose the negative of the fraction size
if (`FPSIZES == 1) begin if (P.FPSIZES == 1) begin
assign ResNegNF = -($clog2(`NF)+1)'(`NF); assign ResNegNF = -($clog2(P.NF)+1)'(P.NF);
end else if (`FPSIZES == 2) begin end else if (P.FPSIZES == 2) begin
assign ResNegNF = OutFmt ? -($clog2(`NF)+1)'(`NF) : -($clog2(`NF)+1)'(`NF1); assign ResNegNF = OutFmt ? -($clog2(P.NF)+1)'(P.NF) : -($clog2(P.NF)+1)'(P.NF1);
end else if (`FPSIZES == 3) begin end else if (P.FPSIZES == 3) begin
always_comb always_comb
case (OutFmt) case (OutFmt)
`FMT: ResNegNF = -($clog2(`NF)+1)'(`NF); P.FMT: ResNegNF = -($clog2(P.NF)+1)'(P.NF);
`FMT1: ResNegNF = -($clog2(`NF)+1)'(`NF1); P.FMT1: ResNegNF = -($clog2(P.NF)+1)'(P.NF1);
`FMT2: ResNegNF = -($clog2(`NF)+1)'(`NF2); P.FMT2: ResNegNF = -($clog2(P.NF)+1)'(P.NF2);
default: ResNegNF = 1'bx; default: ResNegNF = 1'bx;
endcase endcase
end else if (`FPSIZES == 4) begin end else if (P.FPSIZES == 4) begin
always_comb always_comb
case (OutFmt) case (OutFmt)
2'h3: ResNegNF = -($clog2(`NF)+1)'(`Q_NF); 2'h3: ResNegNF = -($clog2(P.NF)+1)'(P.Q_NF);
2'h1: ResNegNF = -($clog2(`NF)+1)'(`D_NF); 2'h1: ResNegNF = -($clog2(P.NF)+1)'(P.D_NF);
2'h0: ResNegNF = -($clog2(`NF)+1)'(`S_NF); 2'h0: ResNegNF = -($clog2(P.NF)+1)'(P.S_NF);
2'h2: ResNegNF = -($clog2(`NF)+1)'(`H_NF); 2'h2: ResNegNF = -($clog2(P.NF)+1)'(P.H_NF);
endcase endcase
end end
@ -102,6 +100,6 @@ module cvtshiftcalc(
// determine if the result underflows ??? -> fp // determine if the result underflows ??? -> fp
// - if the first 1 is shifted out of the result then the result underflows // - if the first 1 is shifted out of the result then the result underflows
// - can't underflow an integer to fp conversions // - can't underflow an integer to fp conversions
assign CvtResUf = ($signed(CvtCe) < $signed({{`NE-$clog2(`NF){1'b1}}, ResNegNF}))&~XZero&~IntToFp; assign CvtResUf = ($signed(CvtCe) < $signed({{P.NE-$clog2(P.NF){1'b1}}, ResNegNF}))&~XZero&~IntToFp;
endmodule endmodule

View File

@ -26,24 +26,22 @@
// and limitations under the License. // and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////`include "wally-config.vh" ////////////////////////////////////////////////////////////////////////////////////////////////`include "wally-config.vh"
`include "wally-config.vh" module divshiftcalc import cvw::*; #(parameter cvw_t P) (
input logic [P.DIVb:0] DivQm, // divsqrt significand
module divshiftcalc( input logic [P.NE+1:0] DivQe, // divsqrt exponent
input logic [`DIVb:0] DivQm, // divsqrt significand output logic [P.LOGNORMSHIFTSZ-1:0] DivShiftAmt, // divsqrt shift amount
input logic [`NE+1:0] DivQe, // divsqrt exponent output logic [P.NORMSHIFTSZ-1:0] DivShiftIn, // divsqrt shift input
output logic [`LOGNORMSHIFTSZ-1:0] DivShiftAmt, // divsqrt shift amount
output logic [`NORMSHIFTSZ-1:0] DivShiftIn, // divsqrt shift input
output logic DivResSubnorm, // is the divsqrt result subnormal output logic DivResSubnorm, // is the divsqrt result subnormal
output logic DivSubnormShiftPos // is the subnormal shift amount positive output logic DivSubnormShiftPos // is the subnormal shift amount positive
); );
logic [`LOGNORMSHIFTSZ-1:0] NormShift; // normalized result shift amount logic [P.LOGNORMSHIFTSZ-1:0] NormShift; // normalized result shift amount
logic [`LOGNORMSHIFTSZ-1:0] DivSubnormShiftAmt; // subnormal result shift amount (killed if negitive) logic [P.LOGNORMSHIFTSZ-1:0] DivSubnormShiftAmt; // subnormal result shift amount (killed if negitive)
logic [`NE+1:0] DivSubnormShift; // subnormal result shift amount logic [P.NE+1:0] DivSubnormShift; // subnormal result shift amount
// is the result subnormal // is the result subnormal
// if the exponent is 1 then the result needs to be normalized then the result is Subnormalizes // if the exponent is 1 then the result needs to be normalized then the result is Subnormalizes
assign DivResSubnorm = DivQe[`NE+1]|(~|DivQe[`NE+1:0]); assign DivResSubnorm = DivQe[P.NE+1]|(~|DivQe[P.NE+1:0]);
// if the result is subnormal // if the result is subnormal
// 00000000x.xxxxxx... Exp = DivQe // 00000000x.xxxxxx... Exp = DivQe
@ -51,8 +49,8 @@ module divshiftcalc(
// .00xxxxxxxxxxxxx... << DivQe+NF+1 Exp = +1 // .00xxxxxxxxxxxxx... << DivQe+NF+1 Exp = +1
// .0000xxxxxxxxxxx... >> 1 Exp = 1 // .0000xxxxxxxxxxx... >> 1 Exp = 1
// Left shift amount = DivQe+NF+1-1 // Left shift amount = DivQe+NF+1-1
assign DivSubnormShift = (`NE+2)'(`NF)+DivQe; assign DivSubnormShift = (P.NE+2)'(P.NF)+DivQe;
assign DivSubnormShiftPos = ~DivSubnormShift[`NE+1]; assign DivSubnormShiftPos = ~DivSubnormShift[P.NE+1];
// if the result is normalized // if the result is normalized
// 00000000x.xxxxxx... Exp = DivQe // 00000000x.xxxxxx... Exp = DivQe
@ -62,13 +60,13 @@ module divshiftcalc(
// 00000000xx.xxxxx... << 1? Exp = DivQe-1 (determined after) // 00000000xx.xxxxx... << 1? Exp = DivQe-1 (determined after)
// inital Left shift amount = NF // inital Left shift amount = NF
// shift one more if the it's a minimally redundent radix 4 - one entire cycle needed for integer bit // shift one more if the it's a minimally redundent radix 4 - one entire cycle needed for integer bit
assign NormShift = (`LOGNORMSHIFTSZ)'(`NF); assign NormShift = (P.LOGNORMSHIFTSZ)'(P.NF);
// if the shift amount is negitive then don't shift (keep sticky bit) // if the shift amount is negitive then don't shift (keep sticky bit)
// need to multiply the early termination shift by LOGR*DIVCOPIES = left shift of log2(LOGR*DIVCOPIES) // need to multiply the early termination shift by LOGR*DIVCOPIES = left shift of log2(LOGR*DIVCOPIES)
assign DivSubnormShiftAmt = DivSubnormShiftPos ? DivSubnormShift[`LOGNORMSHIFTSZ-1:0] : '0; assign DivSubnormShiftAmt = DivSubnormShiftPos ? DivSubnormShift[P.LOGNORMSHIFTSZ-1:0] : '0;
assign DivShiftAmt = DivResSubnorm ? DivSubnormShiftAmt : NormShift; assign DivShiftAmt = DivResSubnorm ? DivSubnormShiftAmt : NormShift;
// pre-shift the divider result for normalization // pre-shift the divider result for normalization
assign DivShiftIn = {{`NF{1'b0}}, DivQm, {`NORMSHIFTSZ-`DIVb-1-`NF{1'b0}}}; assign DivShiftIn = {{P.NF{1'b0}}, DivQm, {P.NORMSHIFTSZ-P.DIVb-1-P.NF{1'b0}}};
endmodule endmodule

View File

@ -25,18 +25,17 @@
// either express or implied. See the License for the specific language governing permissions // either express or implied. See the License for the specific language governing permissions
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module flags( module flags import cvw::*; #(parameter cvw_t P) (
input logic Xs, // X sign input logic Xs, // X sign
input logic [`FMTBITS-1:0] OutFmt, // output format input logic [P.FMTBITS-1:0] OutFmt, // output format
input logic InfIn, // is a Inf input being used input logic InfIn, // is a Inf input being used
input logic XInf, YInf, ZInf, // inputs are infinity input logic XInf, YInf, ZInf, // inputs are infinity
input logic NaNIn, // is a NaN input being used input logic NaNIn, // is a NaN input being used
input logic XSNaN, YSNaN, ZSNaN, // inputs are signaling NaNs input logic XSNaN, YSNaN, ZSNaN, // inputs are signaling NaNs
input logic XZero, YZero, // inputs are zero input logic XZero, YZero, // inputs are zero
input logic [`NE+1:0] FullRe, // Re with bits to determine sign and overflow input logic [P.NE+1:0] FullRe, // Re with bits to determine sign and overflow
input logic [`NE+1:0] Me, // exponent of the normalized sum input logic [P.NE+1:0] Me, // exponent of the normalized sum
// rounding // rounding
input logic Plus1, // do you add one for rounding input logic Plus1, // do you add one for rounding
input logic Round, Guard, Sticky, // bits used to determine rounding input logic Round, Guard, Sticky, // bits used to determine rounding
@ -47,7 +46,7 @@ module flags(
input logic IntToFp, // convert integer to floating point input logic IntToFp, // convert integer to floating point
input logic Int64, // convert to 64 bit integer input logic Int64, // convert to 64 bit integer
input logic Signed, // convert to a signed integer input logic Signed, // convert to a signed integer
input logic [`NE:0] CvtCe, // the calculated expoent - Cvt input logic [P.NE:0] CvtCe, // the calculated expoent - Cvt
input logic [1:0] CvtNegResMsbs, // the negitive integer result's most significant bits input logic [1:0] CvtNegResMsbs, // the negitive integer result's most significant bits
// divsqrt // divsqrt
input logic DivOp, // conversion opperation? input logic DivOp, // conversion opperation?
@ -92,33 +91,33 @@ module flags(
// - any of the bits after the most significan 1 is one // - any of the bits after the most significan 1 is one
// - the most signifcant in 65 or 33 is still a one in the number and // - the most signifcant in 65 or 33 is still a one in the number and
// one of the later bits is one // one of the later bits is one
if (`FPSIZES == 1) begin if (P.FPSIZES == 1) begin
assign ResExpGteMax = &FullRe[`NE-1:0] | FullRe[`NE]; assign ResExpGteMax = &FullRe[P.NE-1:0] | FullRe[P.NE];
assign ShiftGtIntSz = (|FullRe[`NE:7]|(FullRe[6]&~Int64)) | ((|FullRe[4:0]|(FullRe[5]&Int64))&((FullRe[5]&~Int64) | FullRe[6]&Int64)); assign ShiftGtIntSz = (|FullRe[P.NE:7]|(FullRe[6]&~Int64)) | ((|FullRe[4:0]|(FullRe[5]&Int64))&((FullRe[5]&~Int64) | FullRe[6]&Int64));
end else if (`FPSIZES == 2) begin end else if (P.FPSIZES == 2) begin
assign ResExpGteMax = OutFmt ? &FullRe[`NE-1:0] | FullRe[`NE] : &FullRe[`NE1-1:0] | (|FullRe[`NE:`NE1]); assign ResExpGteMax = OutFmt ? &FullRe[P.NE-1:0] | FullRe[P.NE] : &FullRe[P.NE1-1:0] | (|FullRe[P.NE:P.NE1]);
assign ShiftGtIntSz = (|FullRe[`NE:7]|(FullRe[6]&~Int64)) | ((|FullRe[4:0]|(FullRe[5]&Int64))&((FullRe[5]&~Int64) | FullRe[6]&Int64)); assign ShiftGtIntSz = (|FullRe[P.NE:7]|(FullRe[6]&~Int64)) | ((|FullRe[4:0]|(FullRe[5]&Int64))&((FullRe[5]&~Int64) | FullRe[6]&Int64));
end else if (`FPSIZES == 3) begin end else if (P.FPSIZES == 3) begin
always_comb always_comb
case (OutFmt) case (OutFmt)
`FMT: ResExpGteMax = &FullRe[`NE-1:0] | FullRe[`NE]; P.FMT: ResExpGteMax = &FullRe[P.NE-1:0] | FullRe[P.NE];
`FMT1: ResExpGteMax = &FullRe[`NE1-1:0] | (|FullRe[`NE:`NE1]); P.FMT1: ResExpGteMax = &FullRe[P.NE1-1:0] | (|FullRe[P.NE:P.NE1]);
`FMT2: ResExpGteMax = &FullRe[`NE2-1:0] | (|FullRe[`NE:`NE2]); P.FMT2: ResExpGteMax = &FullRe[P.NE2-1:0] | (|FullRe[P.NE:P.NE2]);
default: ResExpGteMax = 1'bx; default: ResExpGteMax = 1'bx;
endcase endcase
assign ShiftGtIntSz = (|FullRe[`NE:7]|(FullRe[6]&~Int64)) | ((|FullRe[4:0]|(FullRe[5]&Int64))&((FullRe[5]&~Int64) | FullRe[6]&Int64)); assign ShiftGtIntSz = (|FullRe[P.NE:7]|(FullRe[6]&~Int64)) | ((|FullRe[4:0]|(FullRe[5]&Int64))&((FullRe[5]&~Int64) | FullRe[6]&Int64));
end else if (`FPSIZES == 4) begin end else if (P.FPSIZES == 4) begin
always_comb always_comb
case (OutFmt) case (OutFmt)
`Q_FMT: ResExpGteMax = &FullRe[`Q_NE-1:0] | FullRe[`Q_NE]; P.Q_FMT: ResExpGteMax = &FullRe[P.Q_NE-1:0] | FullRe[P.Q_NE];
`D_FMT: ResExpGteMax = &FullRe[`D_NE-1:0] | (|FullRe[`Q_NE:`D_NE]); P.D_FMT: ResExpGteMax = &FullRe[P.D_NE-1:0] | (|FullRe[P.Q_NE:P.D_NE]);
`S_FMT: ResExpGteMax = &FullRe[`S_NE-1:0] | (|FullRe[`Q_NE:`S_NE]); P.S_FMT: ResExpGteMax = &FullRe[P.S_NE-1:0] | (|FullRe[P.Q_NE:P.S_NE]);
`H_FMT: ResExpGteMax = &FullRe[`H_NE-1:0] | (|FullRe[`Q_NE:`H_NE]); P.H_FMT: ResExpGteMax = &FullRe[P.H_NE-1:0] | (|FullRe[P.Q_NE:P.H_NE]);
endcase endcase
assign ShiftGtIntSz = (|FullRe[`Q_NE:7]|(FullRe[6]&~Int64)) | ((|FullRe[4:0]|(FullRe[5]&Int64))&((FullRe[5]&~Int64) | FullRe[6]&Int64)); assign ShiftGtIntSz = (|FullRe[P.Q_NE:7]|(FullRe[6]&~Int64)) | ((|FullRe[4:0]|(FullRe[5]&Int64))&((FullRe[5]&~Int64) | FullRe[6]&Int64));
end end
@ -127,7 +126,7 @@ module flags(
// | and the exponent isn't negitive // | and the exponent isn't negitive
// | | if the input isnt infinity or NaN // | | if the input isnt infinity or NaN
// | | | // | | |
assign Overflow = ResExpGteMax & ~FullRe[`NE+1]&~(InfIn|NaNIn|DivByZero); assign Overflow = ResExpGteMax & ~FullRe[P.NE+1]&~(InfIn|NaNIn|DivByZero);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Underflow // Underflow
@ -141,7 +140,7 @@ module flags(
// | | | | and if the result is not exact // | | | | and if the result is not exact
// | | | | | and if the input isnt infinity or NaN // | | | | | and if the input isnt infinity or NaN
// | | | | | | // | | | | | |
assign Underflow = ((FullRe[`NE+1] | (FullRe == 0) | ((FullRe == 1) & (Me == 0) & ~(UfPlus1&Guard)))&(Round|Sticky|Guard))&~(InfIn|NaNIn|DivByZero|Invalid); assign Underflow = ((FullRe[P.NE+1] | (FullRe == 0) | ((FullRe == 1) & (Me == 0) & ~(UfPlus1&Guard)))&(Round|Sticky|Guard))&~(InfIn|NaNIn|DivByZero|Invalid);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -156,7 +155,7 @@ module flags(
// if the res is too small to be represented and not 0 // if the res is too small to be represented and not 0
// | and if the res is not invalid (outside the integer bounds) // | and if the res is not invalid (outside the integer bounds)
// | | // | |
assign IntInexact = ((CvtCe[`NE]&~XZero)|Sticky|Round|Guard)&~IntInvalid; assign IntInexact = ((CvtCe[P.NE]&~XZero)|Sticky|Round|Guard)&~IntInvalid;
// select the inexact flag to output // select the inexact flag to output
assign Inexact = ToInt ? IntInexact : FpInexact; assign Inexact = ToInt ? IntInexact : FpInexact;
@ -178,7 +177,7 @@ module flags(
// | | | | or the res rounds up out of bounds // | | | | or the res rounds up out of bounds
// | | | | and the res didn't underflow // | | | | and the res didn't underflow
// | | | | | // | | | | |
assign IntInvalid = NaNIn|InfIn|(ShiftGtIntSz&~FullRe[`NE+1])|((Xs&~Signed)&(~((CvtCe[`NE]|(~|CvtCe))&~Plus1)))|(CvtNegResMsbs[1]^CvtNegResMsbs[0]); assign IntInvalid = NaNIn|InfIn|(ShiftGtIntSz&~FullRe[P.NE+1])|((Xs&~Signed)&(~((CvtCe[P.NE]|(~|CvtCe))&~Plus1)))|(CvtNegResMsbs[1]^CvtNegResMsbs[0]);
// | // |
// or when the positive res rounds up out of range // or when the positive res rounds up out of range

View File

@ -26,21 +26,19 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh" module fmashiftcalc import cvw::*; #(parameter cvw_t P) (
input logic [P.FMTBITS-1:0] Fmt, // precision 1 = double 0 = single
module fmashiftcalc( input logic [P.NE+1:0] FmaSe, // sum's exponent
input logic [`FMTBITS-1:0] Fmt, // precision 1 = double 0 = single input logic [3*P.NF+3:0] FmaSm, // the positive sum
input logic [`NE+1:0] FmaSe, // sum's exponent input logic [$clog2(3*P.NF+5)-1:0] FmaSCnt, // normalization shift count
input logic [3*`NF+3:0] FmaSm, // the positive sum output logic [P.NE+1:0] NormSumExp, // exponent of the normalized sum not taking into account Subnormal or zero results
input logic [$clog2(3*`NF+5)-1:0] FmaSCnt, // normalization shift count
output logic [`NE+1:0] NormSumExp, // exponent of the normalized sum not taking into account Subnormal or zero results
output logic FmaSZero, // is the result subnormal - calculated before LZA corection output logic FmaSZero, // is the result subnormal - calculated before LZA corection
output logic FmaPreResultSubnorm, // is the result subnormal - calculated before LZA corection output logic FmaPreResultSubnorm, // is the result subnormal - calculated before LZA corection
output logic [$clog2(3*`NF+5)-1:0] FmaShiftAmt, // normalization shift count output logic [$clog2(3*P.NF+5)-1:0] FmaShiftAmt, // normalization shift count
output logic [3*`NF+5:0] FmaShiftIn // is the sum zero output logic [3*P.NF+5:0] FmaShiftIn // is the sum zero
); );
logic [`NE+1:0] PreNormSumExp; // the exponent of the normalized sum with the `FLEN bias logic [P.NE+1:0] PreNormSumExp; // the exponent of the normalized sum with the P.FLEN bias
logic [`NE+1:0] BiasCorr; // correction for bias logic [P.NE+1:0] BiasCorr; // correction for bias
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Normalization // Normalization
@ -50,75 +48,75 @@ module fmashiftcalc(
assign FmaSZero = ~(|FmaSm); assign FmaSZero = ~(|FmaSm);
// calculate the sum's exponent // calculate the sum's exponent
assign PreNormSumExp = FmaSe + {{`NE+2-$unsigned($clog2(3*`NF+5)){1'b1}}, ~FmaSCnt} + (`NE+2)'(`NF+3); assign PreNormSumExp = FmaSe + {{P.NE+2-$unsigned($clog2(3*P.NF+5)){1'b1}}, ~FmaSCnt} + (P.NE+2)'(P.NF+3);
//convert the sum's exponent into the proper percision //convert the sum's exponent into the proper percision
if (`FPSIZES == 1) begin if (P.FPSIZES == 1) begin
assign NormSumExp = PreNormSumExp; assign NormSumExp = PreNormSumExp;
end else if (`FPSIZES == 2) begin end else if (P.FPSIZES == 2) begin
assign BiasCorr = Fmt ? (`NE+2)'(0) : (`NE+2)'(`BIAS1-`BIAS); assign BiasCorr = Fmt ? (P.NE+2)'(0) : (P.NE+2)'(P.BIAS1-P.BIAS);
assign NormSumExp = PreNormSumExp+BiasCorr; assign NormSumExp = PreNormSumExp+BiasCorr;
end else if (`FPSIZES == 3) begin end else if (P.FPSIZES == 3) begin
always_comb begin always_comb begin
case (Fmt) case (Fmt)
`FMT: BiasCorr = '0; P.FMT: BiasCorr = '0;
`FMT1: BiasCorr = (`NE+2)'(`BIAS1-`BIAS); P.FMT1: BiasCorr = (P.NE+2)'(P.BIAS1-P.BIAS);
`FMT2: BiasCorr = (`NE+2)'(`BIAS2-`BIAS); P.FMT2: BiasCorr = (P.NE+2)'(P.BIAS2-P.BIAS);
default: BiasCorr = 'x; default: BiasCorr = 'x;
endcase endcase
end end
assign NormSumExp = PreNormSumExp+BiasCorr; assign NormSumExp = PreNormSumExp+BiasCorr;
end else if (`FPSIZES == 4) begin end else if (P.FPSIZES == 4) begin
always_comb begin always_comb begin
case (Fmt) case (Fmt)
2'h3: BiasCorr = '0; 2'h3: BiasCorr = '0;
2'h1: BiasCorr = (`NE+2)'(`D_BIAS-`Q_BIAS); 2'h1: BiasCorr = (P.NE+2)'(P.D_BIAS-P.Q_BIAS);
2'h0: BiasCorr = (`NE+2)'(`S_BIAS-`Q_BIAS); 2'h0: BiasCorr = (P.NE+2)'(P.S_BIAS-P.Q_BIAS);
2'h2: BiasCorr = (`NE+2)'(`H_BIAS-`Q_BIAS); 2'h2: BiasCorr = (P.NE+2)'(P.H_BIAS-P.Q_BIAS);
endcase endcase
end end
assign NormSumExp = PreNormSumExp+BiasCorr; assign NormSumExp = PreNormSumExp+BiasCorr;
end end
// determine if the result is subnormal: (NormSumExp <= 0) & (NormSumExp >= -FracLen) & ~FmaSZero // determine if the result is subnormal: (NormSumExp <= 0) & (NormSumExp >= -FracLen) & ~FmaSZero
if (`FPSIZES == 1) begin if (P.FPSIZES == 1) begin
logic Sum0LEZ, Sum0GEFL; logic Sum0LEZ, Sum0GEFL;
assign Sum0LEZ = PreNormSumExp[`NE+1] | ~|PreNormSumExp; assign Sum0LEZ = PreNormSumExp[P.NE+1] | ~|PreNormSumExp;
assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF-2)); assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF-2));
assign FmaPreResultSubnorm = Sum0LEZ & Sum0GEFL & ~FmaSZero; assign FmaPreResultSubnorm = Sum0LEZ & Sum0GEFL & ~FmaSZero;
end else if (`FPSIZES == 2) begin end else if (P.FPSIZES == 2) begin
logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL; logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL;
assign Sum0LEZ = PreNormSumExp[`NE+1] | ~|PreNormSumExp; assign Sum0LEZ = PreNormSumExp[P.NE+1] | ~|PreNormSumExp;
assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF-2)); assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF-2));
assign Sum1LEZ = $signed(PreNormSumExp) <= $signed((`NE+2)'(`BIAS-`BIAS1)); assign Sum1LEZ = $signed(PreNormSumExp) <= $signed((P.NE+2)'(P.BIAS-P.BIAS1));
assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF1-2+`BIAS-`BIAS1)) | ~|PreNormSumExp; assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF1-2+P.BIAS-P.BIAS1)) | ~|PreNormSumExp;
assign FmaPreResultSubnorm = (Fmt ? Sum0LEZ : Sum1LEZ) & (Fmt ? Sum0GEFL : Sum1GEFL) & ~FmaSZero; assign FmaPreResultSubnorm = (Fmt ? Sum0LEZ : Sum1LEZ) & (Fmt ? Sum0GEFL : Sum1GEFL) & ~FmaSZero;
end else if (`FPSIZES == 3) begin end else if (P.FPSIZES == 3) begin
logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL; logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL;
assign Sum0LEZ = PreNormSumExp[`NE+1] | ~|PreNormSumExp; assign Sum0LEZ = PreNormSumExp[P.NE+1] | ~|PreNormSumExp;
assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF-2)); assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF-2));
assign Sum1LEZ = $signed(PreNormSumExp) <= $signed((`NE+2)'(`BIAS-`BIAS1)); assign Sum1LEZ = $signed(PreNormSumExp) <= $signed((P.NE+2)'(P.BIAS-P.BIAS1));
assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF1-2+`BIAS-`BIAS1)) | ~|PreNormSumExp; assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF1-2+P.BIAS-P.BIAS1)) | ~|PreNormSumExp;
assign Sum2LEZ = $signed(PreNormSumExp) <= $signed((`NE+2)'(`BIAS-`BIAS2)); assign Sum2LEZ = $signed(PreNormSumExp) <= $signed((P.NE+2)'(P.BIAS-P.BIAS2));
assign Sum2GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF2-2+`BIAS-`BIAS2)) | ~|PreNormSumExp; assign Sum2GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF2-2+P.BIAS-P.BIAS2)) | ~|PreNormSumExp;
always_comb begin always_comb begin
case (Fmt) case (Fmt)
`FMT: FmaPreResultSubnorm = Sum0LEZ & Sum0GEFL & ~FmaSZero; P.FMT: FmaPreResultSubnorm = Sum0LEZ & Sum0GEFL & ~FmaSZero;
`FMT1: FmaPreResultSubnorm = Sum1LEZ & Sum1GEFL & ~FmaSZero; P.FMT1: FmaPreResultSubnorm = Sum1LEZ & Sum1GEFL & ~FmaSZero;
`FMT2: FmaPreResultSubnorm = Sum2LEZ & Sum2GEFL & ~FmaSZero; P.FMT2: FmaPreResultSubnorm = Sum2LEZ & Sum2GEFL & ~FmaSZero;
default: FmaPreResultSubnorm = 1'bx; default: FmaPreResultSubnorm = 1'bx;
endcase endcase
end end
end else if (`FPSIZES == 4) begin end else if (P.FPSIZES == 4) begin
logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL, Sum3LEZ, Sum3GEFL; logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL, Sum3LEZ, Sum3GEFL;
assign Sum0LEZ = PreNormSumExp[`NE+1] | ~|PreNormSumExp; assign Sum0LEZ = PreNormSumExp[P.NE+1] | ~|PreNormSumExp;
assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF-2)); assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF-2));
assign Sum1LEZ = $signed(PreNormSumExp) <= $signed((`NE+2)'(`BIAS-`D_BIAS)); assign Sum1LEZ = $signed(PreNormSumExp) <= $signed((P.NE+2)'(P.BIAS-P.D_BIAS));
assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`D_NF-2+`BIAS-`D_BIAS)) | ~|PreNormSumExp; assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.D_NF-2+P.BIAS-P.D_BIAS)) | ~|PreNormSumExp;
assign Sum2LEZ = $signed(PreNormSumExp) <= $signed((`NE+2)'(`BIAS-`S_BIAS)); assign Sum2LEZ = $signed(PreNormSumExp) <= $signed((P.NE+2)'(P.BIAS-P.S_BIAS));
assign Sum2GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`S_NF-2+`BIAS-`S_BIAS)) | ~|PreNormSumExp; assign Sum2GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.S_NF-2+P.BIAS-P.S_BIAS)) | ~|PreNormSumExp;
assign Sum3LEZ = $signed(PreNormSumExp) <= $signed((`NE+2)'(`BIAS-`H_BIAS)); assign Sum3LEZ = $signed(PreNormSumExp) <= $signed((P.NE+2)'(P.BIAS-P.H_BIAS));
assign Sum3GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`H_NF-2+`BIAS-`H_BIAS)) | ~|PreNormSumExp; assign Sum3GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.H_NF-2+P.BIAS-P.H_BIAS)) | ~|PreNormSumExp;
always_comb begin always_comb begin
case (Fmt) case (Fmt)
2'h3: FmaPreResultSubnorm = Sum0LEZ & Sum0GEFL & ~FmaSZero; 2'h3: FmaPreResultSubnorm = Sum0LEZ & Sum0GEFL & ~FmaSZero;
@ -132,6 +130,6 @@ module fmashiftcalc(
// 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 subnormal // - shift once if killing a product and the result is subnormal
assign FmaShiftIn = {2'b0, FmaSm}; assign FmaShiftIn = {2'b0, FmaSm};
if (`FPSIZES == 1) assign FmaShiftAmt = FmaPreResultSubnorm ? FmaSe[$clog2(3*`NF+5)-1:0]+($clog2(3*`NF+5))'(`NF+2): FmaSCnt+1; if (P.FPSIZES == 1) assign FmaShiftAmt = FmaPreResultSubnorm ? FmaSe[$clog2(3*P.NF+5)-1:0]+($clog2(3*P.NF+5))'(P.NF+2): FmaSCnt+1;
else assign FmaShiftAmt = FmaPreResultSubnorm ? FmaSe[$clog2(3*`NF+5)-1:0]+($clog2(3*`NF+5))'(`NF+2)+BiasCorr[$clog2(3*`NF+5)-1:0]: FmaSCnt+1; else assign FmaShiftAmt = FmaPreResultSubnorm ? FmaSe[$clog2(3*P.NF+5)-1:0]+($clog2(3*P.NF+5))'(P.NF+2)+BiasCorr[$clog2(3*P.NF+5)-1:0]: FmaSCnt+1;
endmodule endmodule

View File

@ -25,26 +25,25 @@
// either express or implied. See the License for the specific language governing permissions // either express or implied. See the License for the specific language governing permissions
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module negateintres( module negateintres import cvw::*; #(parameter cvw_t P) (
input logic Signed, // is the integer input signed input logic Signed, // is the integer input signed
input logic Int64, // is the integer input 64-bits input logic Int64, // is the integer input 64-bits
input logic Plus1, // should one be added for rounding? input logic Plus1, // should one be added for rounding?
input logic Xs, // X sign input logic Xs, // X sign
input logic [`NORMSHIFTSZ-1:0] Shifted, // output from normalization shifter input logic [P.NORMSHIFTSZ-1:0] Shifted, // output from normalization shifter
output logic [1:0] CvtNegResMsbs, // most signigficant bits of possibly negated result output logic [1:0] CvtNegResMsbs, // most signigficant bits of possibly negated result
output logic [`XLEN+1:0] CvtNegRes // possibly negated integer result output logic [P.XLEN+1:0] CvtNegRes // possibly negated integer result
); );
logic [`XLEN+1:0] CvtPreRes; // integer result with rounding logic [P.XLEN+1:0] CvtPreRes; // integer result with rounding
logic [2:0] CvtNegResMsbs3; // first three msbs of possibly negated result logic [2:0] CvtNegResMsbs3; // first three msbs of possibly negated result
// round and negate the positive res if needed // round and negate the positive res if needed
assign CvtPreRes = {2'b0, Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`XLEN]}+{{`XLEN+1{1'b0}}, Plus1}; assign CvtPreRes = {2'b0, Shifted[P.NORMSHIFTSZ-1:P.NORMSHIFTSZ-P.XLEN]}+{{P.XLEN+1{1'b0}}, Plus1};
mux2 #(`XLEN+2) resmux(CvtPreRes, -CvtPreRes, Xs, CvtNegRes); mux2 #(P.XLEN+2) resmux(CvtPreRes, -CvtPreRes, Xs, CvtNegRes);
// select 2 most significant bits // select 2 most significant bits
mux2 #(3) msb3mux(CvtNegRes[33:31], CvtNegRes[`XLEN+1:`XLEN-1], Int64, CvtNegResMsbs3); mux2 #(3) msb3mux(CvtNegRes[33:31], CvtNegRes[P.XLEN+1:P.XLEN-1], Int64, CvtNegResMsbs3);
mux2 #(2) msb2mux(CvtNegResMsbs3[2:1], CvtNegResMsbs3[1:0], Signed, CvtNegResMsbs); mux2 #(2) msb2mux(CvtNegResMsbs3[2:1], CvtNegResMsbs3[1:0], Signed, CvtNegResMsbs);
endmodule endmodule

View File

@ -25,8 +25,6 @@
// either express or implied. See the License for the specific language governing permissions // either express or implied. See the License for the specific language governing permissions
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
// convert shift // convert shift
// fp -> int: | `XLEN zeros | Mantissa | 0's if nessisary | << CalcExp // fp -> int: | `XLEN zeros | Mantissa | 0's if nessisary | << CalcExp
@ -72,10 +70,10 @@
// | Nf 0's | Qm | << calculated shift amount // | Nf 0's | Qm | << calculated shift amount
// . // .
module normshift( module normshift import cvw::*; #(parameter cvw_t P) (
input logic [`LOGNORMSHIFTSZ-1:0] ShiftAmt, // shift amount input logic [P.LOGNORMSHIFTSZ-1:0] ShiftAmt, // shift amount
input logic [`NORMSHIFTSZ-1:0] ShiftIn, // number to be shifted input logic [P.NORMSHIFTSZ-1:0] ShiftIn, // number to be shifted
output logic [`NORMSHIFTSZ-1:0] Shifted // shifted result output logic [P.NORMSHIFTSZ-1:0] Shifted // shifted result
); );
assign Shifted = ShiftIn << ShiftAmt; assign Shifted = ShiftIn << ShiftAmt;

View File

@ -26,14 +26,12 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh" module postprocess import cvw::*; #(parameter cvw_t P) (
module postprocess (
// general signals // general signals
input logic Xs, Ys, // input signs input logic Xs, Ys, // input signs
input logic [`NF:0] Xm, Ym, Zm, // input mantissas input logic [P.NF:0] Xm, Ym, Zm, // input mantissas
input logic [2:0] Frm, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude input logic [2:0] Frm, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude
input logic [`FMTBITS-1:0] Fmt, // precision 1 = double 0 = single input logic [P.FMTBITS-1:0] Fmt, // precision 1 = double 0 = single
input logic [2:0] OpCtrl, // choose which opperation (look below for values) input logic [2:0] OpCtrl, // choose which opperation (look below for values)
input logic XZero, YZero, // inputs are zero input logic XZero, YZero, // inputs are zero
input logic XInf, YInf, ZInf, // inputs are infinity input logic XInf, YInf, ZInf, // inputs are infinity
@ -44,63 +42,63 @@ module postprocess (
input logic FmaAs, // the modified Z sign - depends on instruction input logic FmaAs, // the modified Z sign - depends on instruction
input logic FmaPs, // the product's sign input logic FmaPs, // the product's sign
input logic FmaSs, // Sum sign input logic FmaSs, // Sum sign
input logic [`NE+1:0] FmaSe, // the sum's exponent input logic [P.NE+1:0] FmaSe, // the sum's exponent
input logic [3*`NF+3:0] FmaSm, // the positive sum input logic [3*P.NF+3:0] FmaSm, // the positive sum
input logic FmaASticky, // sticky bit that is calculated during alignment input logic FmaASticky, // sticky bit that is calculated during alignment
input logic [$clog2(3*`NF+5)-1:0] FmaSCnt, // the normalization shift count input logic [$clog2(3*P.NF+5)-1:0] FmaSCnt, // the normalization shift count
//divide signals //divide signals
input logic DivSticky, // divider sticky bit input logic DivSticky, // divider sticky bit
input logic [`NE+1:0] DivQe, // divsqrt exponent input logic [P.NE+1:0] DivQe, // divsqrt exponent
input logic [`DIVb:0] DivQm, // divsqrt significand input logic [P.DIVb:0] DivQm, // divsqrt significand
// conversion signals // conversion signals
input logic CvtCs, // the result's sign input logic CvtCs, // the result's sign
input logic [`NE:0] CvtCe, // the calculated expoent input logic [P.NE:0] CvtCe, // the calculated expoent
input logic CvtResSubnormUf, // the convert result is subnormal or underflows input logic CvtResSubnormUf, // the convert result is subnormal or underflows
input logic [`LOGCVTLEN-1:0] CvtShiftAmt,// how much to shift by input logic [P.LOGCVTLEN-1:0] CvtShiftAmt,// how much to shift by
input logic ToInt, // is fp->int (since it's writting to the integer register) input logic ToInt, // is fp->int (since it's writting to the integer register)
input logic [`CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (without msb) input logic [P.CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (without msb)
input logic IntZero, // is the integer input zero input logic IntZero, // is the integer input zero
// final results // final results
output logic [`FLEN-1:0] PostProcRes,// postprocessor final result output logic [P.FLEN-1:0] PostProcRes,// postprocessor final result
output logic [4:0] PostProcFlg,// postprocesser flags output logic [4:0] PostProcFlg,// postprocesser flags
output logic [`XLEN-1:0] FCvtIntRes // the integer conversion result output logic [P.XLEN-1:0] FCvtIntRes // the integer conversion result
); );
// general signals // general signals
logic Rs; // result sign logic Rs; // result sign
logic [`NF-1:0] Rf; // Result fraction logic [P.NF-1:0] Rf; // Result fraction
logic [`NE-1:0] Re; // Result exponent logic [P.NE-1:0] Re; // Result exponent
logic Ms; // norMalized sign logic Ms; // norMalized sign
logic [`CORRSHIFTSZ-1:0] Mf; // norMalized fraction logic [P.CORRSHIFTSZ-1:0] Mf; // norMalized fraction
logic [`NE+1:0] Me; // normalized exponent logic [P.NE+1:0] Me; // normalized exponent
logic [`NE+1:0] FullRe; // Re with bits to determine sign and overflow logic [P.NE+1:0] FullRe; // Re with bits to determine sign and overflow
logic UfPlus1; // do you add one (for determining underflow flag) logic UfPlus1; // do you add one (for determining underflow flag)
logic [`LOGNORMSHIFTSZ-1:0] ShiftAmt; // normalization shift amount logic [P.LOGNORMSHIFTSZ-1:0] ShiftAmt; // normalization shift amount
logic [`NORMSHIFTSZ-1:0] ShiftIn; // input to normalization shift logic [P.NORMSHIFTSZ-1:0] ShiftIn; // input to normalization shift
logic [`NORMSHIFTSZ-1:0] Shifted; // the ouput of the normalized shifter (before shift correction) logic [P.NORMSHIFTSZ-1:0] Shifted; // the ouput of the normalized shifter (before shift correction)
logic Plus1; // add one to the final result? logic Plus1; // add one to the final result?
logic Overflow; // overflow flag used to select results logic Overflow; // overflow flag used to select results
logic Invalid; // invalid flag used to select results logic Invalid; // invalid flag used to select results
logic Guard, Round, Sticky; // bits needed to determine rounding logic Guard, Round, Sticky; // bits needed to determine rounding
logic [`FMTBITS-1:0] OutFmt; // output format logic [P.FMTBITS-1:0] OutFmt; // output format
// fma signals // fma signals
logic [`NE+1:0] FmaMe; // exponent of the normalized sum logic [P.NE+1:0] FmaMe; // exponent of the normalized sum
logic FmaSZero; // is the sum zero logic FmaSZero; // is the sum zero
logic [3*`NF+5:0] FmaShiftIn; // fma shift input logic [3*P.NF+5:0] FmaShiftIn; // fma shift input
logic [`NE+1:0] NormSumExp; // exponent of the normalized sum not taking into account Subnormal or zero results logic [P.NE+1:0] NormSumExp; // exponent of the normalized sum not taking into account Subnormal or zero results
logic FmaPreResultSubnorm; // is the result subnormal - calculated before LZA corection logic FmaPreResultSubnorm; // is the result subnormal - calculated before LZA corection
logic [$clog2(3*`NF+5)-1:0] FmaShiftAmt;// normalization shift amount for fma logic [$clog2(3*P.NF+5)-1:0] FmaShiftAmt;// normalization shift amount for fma
// division singals // division singals
logic [`LOGNORMSHIFTSZ-1:0] DivShiftAmt; // divsqrt shif amount logic [P.LOGNORMSHIFTSZ-1:0] DivShiftAmt; // divsqrt shif amount
logic [`NORMSHIFTSZ-1:0] DivShiftIn; // divsqrt shift input logic [P.NORMSHIFTSZ-1:0] DivShiftIn; // divsqrt shift input
logic [`NE+1:0] Qe; // divsqrt corrected exponent after corretion shift logic [P.NE+1:0] Qe; // divsqrt corrected exponent after corretion shift
logic DivByZero; // divide by zero flag logic DivByZero; // divide by zero flag
logic DivResSubnorm; // is the divsqrt result subnormal logic DivResSubnorm; // is the divsqrt result subnormal
logic DivSubnormShiftPos; // is the divsqrt subnorm shift amout positive (not underflowed) logic DivSubnormShiftPos; // is the divsqrt subnorm shift amout positive (not underflowed)
// conversion signals // conversion signals
logic [`CVTLEN+`NF:0] CvtShiftIn; // number to be shifted for converter logic [P.CVTLEN+P.NF:0] CvtShiftIn; // number to be shifted for converter
logic [1:0] CvtNegResMsbs; // most significant bits of possibly negated int result logic [1:0] CvtNegResMsbs; // most significant bits of possibly negated int result
logic [`XLEN+1:0] CvtNegRes; // possibly negated integer result logic [P.XLEN+1:0] CvtNegRes; // possibly negated integer result
logic CvtResUf; // did the convert result underflow logic CvtResUf; // did the convert result underflow
logic IntInvalid; // invalid integer flag logic IntInvalid; // invalid integer flag
// readability signals // readability signals
@ -132,9 +130,9 @@ module postprocess (
// choose the ouptut format depending on the opperation // choose the ouptut format depending on the opperation
// - fp -> fp: OpCtrl contains the percision of the output // - fp -> fp: OpCtrl contains the percision of the output
// - otherwise: Fmt contains the percision of the output // - otherwise: Fmt contains the percision of the output
if (`FPSIZES == 2) if (P.FPSIZES == 2)
assign OutFmt = IntToFp|~CvtOp ? Fmt : (OpCtrl[1:0] == `FMT); assign OutFmt = IntToFp|~CvtOp ? Fmt : (OpCtrl[1:0] == P.FMT);
else if (`FPSIZES == 3 | `FPSIZES == 4) else if (P.FPSIZES == 3 | P.FPSIZES == 4)
assign OutFmt = IntToFp|~CvtOp ? Fmt : OpCtrl[1:0]; assign OutFmt = IntToFp|~CvtOp ? Fmt : OpCtrl[1:0];
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -142,40 +140,40 @@ module postprocess (
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// final claulations before shifting // final claulations before shifting
cvtshiftcalc cvtshiftcalc(.ToInt, .CvtCe, .CvtResSubnormUf, .Xm, .CvtLzcIn, cvtshiftcalc #(P) cvtshiftcalc(.ToInt, .CvtCe, .CvtResSubnormUf, .Xm, .CvtLzcIn,
.XZero, .IntToFp, .OutFmt, .CvtResUf, .CvtShiftIn); .XZero, .IntToFp, .OutFmt, .CvtResUf, .CvtShiftIn);
fmashiftcalc fmashiftcalc(.FmaSm, .FmaSCnt, .Fmt, .NormSumExp, .FmaSe, fmashiftcalc #(P) fmashiftcalc(.FmaSm, .FmaSCnt, .Fmt, .NormSumExp, .FmaSe,
.FmaSZero, .FmaPreResultSubnorm, .FmaShiftAmt, .FmaShiftIn); .FmaSZero, .FmaPreResultSubnorm, .FmaShiftAmt, .FmaShiftIn);
divshiftcalc divshiftcalc(.DivQe, .DivQm, .DivResSubnorm, .DivSubnormShiftPos, .DivShiftAmt, .DivShiftIn); divshiftcalc #(P) divshiftcalc(.DivQe, .DivQm, .DivResSubnorm, .DivSubnormShiftPos, .DivShiftAmt, .DivShiftIn);
// select which unit's output to shift // select which unit's output to shift
always_comb always_comb
case(PostProcSel) case(PostProcSel)
2'b10: begin // fma 2'b10: begin // fma
ShiftAmt = {{`LOGNORMSHIFTSZ-$clog2(3*`NF+5){1'b0}}, FmaShiftAmt}; ShiftAmt = {{P.LOGNORMSHIFTSZ-$clog2(3*P.NF+5){1'b0}}, FmaShiftAmt};
ShiftIn = {FmaShiftIn, {`NORMSHIFTSZ-(3*`NF+6){1'b0}}}; ShiftIn = {FmaShiftIn, {P.NORMSHIFTSZ-(3*P.NF+6){1'b0}}};
end end
2'b00: begin // cvt 2'b00: begin // cvt
ShiftAmt = {{`LOGNORMSHIFTSZ-$clog2(`CVTLEN+1){1'b0}}, CvtShiftAmt}; ShiftAmt = {{P.LOGNORMSHIFTSZ-$clog2(P.CVTLEN+1){1'b0}}, CvtShiftAmt};
ShiftIn = {CvtShiftIn, {`NORMSHIFTSZ-`CVTLEN-`NF-1{1'b0}}}; ShiftIn = {CvtShiftIn, {P.NORMSHIFTSZ-P.CVTLEN-P.NF-1{1'b0}}};
end end
2'b01: begin //divsqrt 2'b01: begin //divsqrt
ShiftAmt = DivShiftAmt; ShiftAmt = DivShiftAmt;
ShiftIn = DivShiftIn; ShiftIn = DivShiftIn;
end end
default: begin default: begin
ShiftAmt = {`LOGNORMSHIFTSZ{1'bx}}; ShiftAmt = {P.LOGNORMSHIFTSZ{1'bx}};
ShiftIn = {`NORMSHIFTSZ{1'bx}}; ShiftIn = {P.NORMSHIFTSZ{1'bx}};
end end
endcase endcase
// main normalization shift // main normalization shift
normshift normshift (.ShiftIn, .ShiftAmt, .Shifted); normshift #(P) normshift (.ShiftIn, .ShiftAmt, .Shifted);
// correct for LZA/divsqrt error // correct for LZA/divsqrt error
shiftcorrection shiftcorrection(.FmaOp, .FmaPreResultSubnorm, .NormSumExp, shiftcorrection #(P) shiftcorrection(.FmaOp, .FmaPreResultSubnorm, .NormSumExp,
.DivResSubnorm, .DivSubnormShiftPos, .DivOp, .DivQe, .Qe, .FmaSZero, .Shifted, .FmaMe, .Mf); .DivResSubnorm, .DivSubnormShiftPos, .DivOp, .DivQe, .Qe, .FmaSZero, .Shifted, .FmaMe, .Mf);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -191,7 +189,7 @@ module postprocess (
// calulate result sign used in rounding unit // calulate result sign used in rounding unit
roundsign roundsign(.FmaOp, .DivOp, .CvtOp, .Sqrt, .FmaSs, .Xs, .Ys, .CvtCs, .Ms); roundsign roundsign(.FmaOp, .DivOp, .CvtOp, .Sqrt, .FmaSs, .Xs, .Ys, .CvtCs, .Ms);
round round(.OutFmt, .Frm, .FmaASticky, .Plus1, .PostProcSel, .CvtCe, .Qe, round #(P) round(.OutFmt, .Frm, .FmaASticky, .Plus1, .PostProcSel, .CvtCe, .Qe,
.Ms, .FmaMe, .FmaOp, .CvtOp, .CvtResSubnormUf, .Mf, .ToInt, .CvtResUf, .Ms, .FmaMe, .FmaOp, .CvtOp, .CvtResSubnormUf, .Mf, .ToInt, .CvtResUf,
.DivSticky, .DivOp, .UfPlus1, .FullRe, .Rf, .Re, .Sticky, .Round, .Guard, .Me); .DivSticky, .DivOp, .UfPlus1, .FullRe, .Rf, .Re, .Sticky, .Round, .Guard, .Me);
@ -206,7 +204,7 @@ module postprocess (
// Flags // Flags
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
flags flags(.XSNaN, .YSNaN, .ZSNaN, .XInf, .YInf, .ZInf, .InfIn, .XZero, .YZero, flags #(P) flags(.XSNaN, .YSNaN, .ZSNaN, .XInf, .YInf, .ZInf, .InfIn, .XZero, .YZero,
.Xs, .Sqrt, .ToInt, .IntToFp, .Int64, .Signed, .OutFmt, .CvtCe, .Xs, .Sqrt, .ToInt, .IntToFp, .Int64, .Signed, .OutFmt, .CvtCe,
.NaNIn, .FmaAs, .FmaPs, .Round, .IntInvalid, .DivByZero, .NaNIn, .FmaAs, .FmaPs, .Round, .IntInvalid, .DivByZero,
.Guard, .Sticky, .UfPlus1, .CvtOp, .DivOp, .FmaOp, .FullRe, .Plus1, .Guard, .Sticky, .UfPlus1, .CvtOp, .DivOp, .FmaOp, .FullRe, .Plus1,
@ -216,9 +214,9 @@ module postprocess (
// Select the result // Select the result
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
negateintres negateintres(.Xs, .Shifted, .Signed, .Int64, .Plus1, .CvtNegResMsbs, .CvtNegRes); negateintres #(P) negateintres(.Xs, .Shifted, .Signed, .Int64, .Plus1, .CvtNegResMsbs, .CvtNegRes);
specialcase specialcase(.Xs, .Xm, .Ym, .Zm, .XZero, .IntInvalid, specialcase #(P) specialcase(.Xs, .Xm, .Ym, .Zm, .XZero, .IntInvalid,
.IntZero, .Frm, .OutFmt, .XNaN, .YNaN, .ZNaN, .CvtResUf, .IntZero, .Frm, .OutFmt, .XNaN, .YNaN, .ZNaN, .CvtResUf,
.NaNIn, .IntToFp, .Int64, .Signed, .CvtOp, .FmaOp, .Plus1, .Invalid, .Overflow, .InfIn, .CvtNegRes, .NaNIn, .IntToFp, .Int64, .Signed, .CvtOp, .FmaOp, .Plus1, .Invalid, .Overflow, .InfIn, .CvtNegRes,
.XInf, .YInf, .DivOp, .DivByZero, .FullRe, .CvtCe, .Rs, .Re, .Rf, .PostProcRes, .FCvtIntRes); .XInf, .YInf, .DivOp, .DivByZero, .FullRe, .CvtCe, .Rs, .Re, .Rf, .PostProcRes, .FCvtIntRes);

View File

@ -26,8 +26,6 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module resultsign( module resultsign(
input logic [2:0] Frm, // rounding mode input logic [2:0] Frm, // rounding mode
input logic FmaOp, // is the operation an Fma input logic FmaOp, // is the operation an Fma

View File

@ -26,42 +26,33 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
// what position is XLEN in? module round import cvw::*; #(parameter cvw_t P) (
// options: input logic [P.FMTBITS-1:0] OutFmt, // output format
// 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, // output format
input logic [2:0] Frm, // rounding mode input logic [2:0] Frm, // rounding mode
input logic [1:0] PostProcSel, // select the postprocessor output input logic [1:0] PostProcSel, // select the postprocessor output
input logic Ms, // normalized sign input logic Ms, // normalized sign
input logic [`CORRSHIFTSZ-1:0] Mf, // normalized fraction input logic [P.CORRSHIFTSZ-1:0] Mf, // normalized fraction
// fma // fma
input logic FmaOp, // is an fma opperation being done? input logic FmaOp, // is an fma opperation being done?
input logic [`NE+1:0] FmaMe, // exponent of the normalized sum for fma input logic [P.NE+1:0] FmaMe, // exponent of the normalized sum for fma
input logic FmaASticky, // addend's sticky bit input logic FmaASticky, // addend's sticky bit
// divsqrt // divsqrt
input logic DivOp, // is a division opperation being done input logic DivOp, // is a division opperation being done
input logic DivSticky, // divsqrt sticky bit input logic DivSticky, // divsqrt sticky bit
input logic [`NE+1:0] Qe, // the divsqrt calculated expoent input logic [P.NE+1:0] Qe, // the divsqrt calculated expoent
// cvt // cvt
input logic CvtOp, // is a convert opperation being done input logic CvtOp, // is a convert opperation being done
input logic ToInt, // is the cvt op a cvt to integer input logic ToInt, // is the cvt op a cvt to integer
input logic CvtResSubnormUf, // is the cvt result subnormal or underflow input logic CvtResSubnormUf, // is the cvt result subnormal or underflow
input logic CvtResUf, // does the cvt result underflow input logic CvtResUf, // does the cvt result underflow
input logic [`NE:0] CvtCe, // the cvt calculated expoent input logic [P.NE:0] CvtCe, // the cvt calculated expoent
// outputs // outputs
output logic [`NE+1:0] Me, // normalied fraction output logic [P.NE+1:0] Me, // normalied fraction
output logic UfPlus1, // do you add one to the result if given an unbounded exponent output logic UfPlus1, // do you add one to the result if given an unbounded exponent
output logic [`NE+1:0] FullRe, // Re with bits to determine sign and overflow output logic [P.NE+1:0] FullRe, // Re with bits to determine sign and overflow
output logic [`NE-1:0] Re, // Result exponent output logic [P.NE-1:0] Re, // Result exponent
output logic [`NF-1:0] Rf, // Result fractionNormS output logic [P.NF-1:0] Rf, // Result fractionNormS
output logic Sticky, // sticky bit output logic Sticky, // sticky bit
output logic Plus1, // do you add one to the final result output logic Plus1, // do you add one to the final result
output logic Round, Guard // bits needed to calculate rounding output logic Round, Guard // bits needed to calculate rounding
@ -69,7 +60,7 @@ module round(
logic UfCalcPlus1; // calculated plus one for unbounded exponent logic UfCalcPlus1; // calculated plus one for unbounded exponent
logic NormSticky; // normalized sum's sticky bit logic NormSticky; // normalized sum's sticky bit
logic [`NF-1:0] RoundFrac; // rounded fraction logic [P.NF-1:0] RoundFrac; // rounded fraction
logic FpRes; // is the result a floating point logic FpRes; // is the result a floating point
logic IntRes; // is the result an integer logic IntRes; // is the result an integer
logic FpGuard, FpRound; // floating point round/guard bits logic FpGuard, FpRound; // floating point round/guard bits
@ -77,7 +68,16 @@ module round(
logic LsbRes; // lsb of result logic LsbRes; // lsb of result
logic CalcPlus1; // calculated plus1 logic CalcPlus1; // calculated plus1
logic FpPlus1; // do you add one to the fp result logic FpPlus1; // do you add one to the fp result
logic [`FLEN:0] RoundAdd; // how much to add to the result logic [P.FLEN:0] RoundAdd; // how much to add to the result
// 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)
localparam XLENPOS = P.XLEN > P.NF ? 1 : P.XLEN > P.NF1 ? 2 : 3;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Rounding // Rounding
@ -115,68 +115,68 @@ module round(
assign FpRes = ~IntRes; assign FpRes = ~IntRes;
// sticky bit calculation // sticky bit calculation
if (`FPSIZES == 1) begin if (P.FPSIZES == 1) begin
// 1: XLEN > NF // 1: XLEN > NF
// | XLEN | // | XLEN |
// | NF |1|1| // | NF |1|1|
// ^ ^ if floating point result // ^ ^ if floating point result
// ^ if not an FMA result // ^ if not an FMA result
if (`XLENPOS == 1)assign NormSticky = (|Mf[`CORRSHIFTSZ-`NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes) | if (XLENPOS == 1)assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.NF-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes) |
(|Mf[`CORRSHIFTSZ-`XLEN-2:0]); (|Mf[P.CORRSHIFTSZ-P.XLEN-2:0]);
// 2: NF > XLEN // 2: NF > XLEN
if (`XLENPOS == 2)assign NormSticky = (|Mf[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF-1]&IntRes) | if (XLENPOS == 2)assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.XLEN-2:P.CORRSHIFTSZ-P.NF-1]&IntRes) |
(|Mf[`CORRSHIFTSZ-`NF-2:0]); (|Mf[P.CORRSHIFTSZ-P.NF-2:0]);
end else if (`FPSIZES == 2) begin end else if (P.FPSIZES == 2) begin
// XLEN is either 64 or 32 // XLEN is either 64 or 32
// so half and single are always smaller then XLEN // so half and single are always smaller then XLEN
// 1: XLEN > NF > NF1 // 1: XLEN > NF > NF1
if (`XLENPOS == 1) assign NormSticky = (|Mf[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&FpRes&~OutFmt) | if (XLENPOS == 1) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.NF1-2:P.CORRSHIFTSZ-P.NF-1]&FpRes&~OutFmt) |
(|Mf[`CORRSHIFTSZ-`NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes) | (|Mf[P.CORRSHIFTSZ-P.NF-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes) |
(|Mf[`CORRSHIFTSZ-`XLEN-2:0]); (|Mf[P.CORRSHIFTSZ-P.XLEN-2:0]);
// 2: NF > XLEN > NF1 // 2: NF > XLEN > NF1
if (`XLENPOS == 2) assign NormSticky = (|Mf[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&~OutFmt) | if (XLENPOS == 2) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.NF1-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes&~OutFmt) |
(|Mf[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF-1]&(IntRes|~OutFmt)) | (|Mf[P.CORRSHIFTSZ-P.XLEN-2:P.CORRSHIFTSZ-P.NF-1]&(IntRes|~OutFmt)) |
(|Mf[`CORRSHIFTSZ-`NF-2:0]); (|Mf[P.CORRSHIFTSZ-P.NF-2:0]);
// 3: NF > NF1 > XLEN // 3: NF > NF1 > XLEN
if (`XLENPOS == 3) assign NormSticky = (|Mf[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF1-1]&IntRes) | if (XLENPOS == 3) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.XLEN-2:P.CORRSHIFTSZ-P.NF1-1]&IntRes) |
(|Mf[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&(~OutFmt|IntRes)) | (|Mf[P.CORRSHIFTSZ-P.NF1-2:P.CORRSHIFTSZ-P.NF-1]&(~OutFmt|IntRes)) |
(|Mf[`CORRSHIFTSZ-`NF-2:0]); (|Mf[P.CORRSHIFTSZ-P.NF-2:0]);
end else if (`FPSIZES == 3) begin end else if (P.FPSIZES == 3) begin
// 1: XLEN > NF > NF1 // 1: XLEN > NF > NF1
if (`XLENPOS == 1) assign NormSticky = (|Mf[`CORRSHIFTSZ-`NF2-2:`CORRSHIFTSZ-`NF1-1]&FpRes&(OutFmt==`FMT1)) | if (XLENPOS == 1) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.NF2-2:P.CORRSHIFTSZ-P.NF1-1]&FpRes&(OutFmt==P.FMT1)) |
(|Mf[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&FpRes&~(OutFmt==`FMT)) | (|Mf[P.CORRSHIFTSZ-P.NF1-2:P.CORRSHIFTSZ-P.NF-1]&FpRes&~(OutFmt==P.FMT)) |
(|Mf[`CORRSHIFTSZ-`NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes) | (|Mf[P.CORRSHIFTSZ-P.NF-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes) |
(|Mf[`CORRSHIFTSZ-`XLEN-2:0]); (|Mf[P.CORRSHIFTSZ-P.XLEN-2:0]);
// 2: NF > XLEN > NF1 // 2: NF > XLEN > NF1
if (`XLENPOS == 2) assign NormSticky = (|Mf[`CORRSHIFTSZ-`NF2-2:`CORRSHIFTSZ-`NF1-1]&FpRes&(OutFmt==`FMT1)) | if (XLENPOS == 2) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.NF2-2:P.CORRSHIFTSZ-P.NF1-1]&FpRes&(OutFmt==P.FMT1)) |
(|Mf[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&~(OutFmt==`FMT)) | (|Mf[P.CORRSHIFTSZ-P.NF1-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes&~(OutFmt==P.FMT)) |
(|Mf[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF-1]&(IntRes|~(OutFmt==`FMT))) | (|Mf[P.CORRSHIFTSZ-P.XLEN-2:P.CORRSHIFTSZ-P.NF-1]&(IntRes|~(OutFmt==P.FMT))) |
(|Mf[`CORRSHIFTSZ-`NF-2:0]); (|Mf[P.CORRSHIFTSZ-P.NF-2:0]);
// 3: NF > NF1 > XLEN // 3: NF > NF1 > XLEN
if (`XLENPOS == 3) assign NormSticky = (|Mf[`CORRSHIFTSZ-`NF2-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&(OutFmt==`FMT1)) | if (XLENPOS == 3) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.NF2-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes&(OutFmt==P.FMT1)) |
(|Mf[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF1-1]&((OutFmt==`FMT1)|IntRes)) | (|Mf[P.CORRSHIFTSZ-P.XLEN-2:P.CORRSHIFTSZ-P.NF1-1]&((OutFmt==P.FMT1)|IntRes)) |
(|Mf[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&(~(OutFmt==`FMT)|IntRes)) | (|Mf[P.CORRSHIFTSZ-P.NF1-2:P.CORRSHIFTSZ-P.NF-1]&(~(OutFmt==P.FMT)|IntRes)) |
(|Mf[`CORRSHIFTSZ-`NF-2:0]); (|Mf[P.CORRSHIFTSZ-P.NF-2:0]);
end else if (`FPSIZES == 4) begin end else if (P.FPSIZES == 4) begin
// Quad precision will always be greater than XLEN // Quad precision will always be greater than XLEN
// 2: NF > XLEN > NF1 // 2: NF > XLEN > NF1
if (`XLENPOS == 2) assign NormSticky = (|Mf[`CORRSHIFTSZ-`H_NF-2:`CORRSHIFTSZ-`S_NF-1]&FpRes&(OutFmt==`H_FMT)) | if (XLENPOS == 2) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.H_NF-2:P.CORRSHIFTSZ-P.S_NF-1]&FpRes&(OutFmt==P.H_FMT)) |
(|Mf[`CORRSHIFTSZ-`S_NF-2:`CORRSHIFTSZ-`D_NF-1]&FpRes&((OutFmt==`S_FMT)|(OutFmt==`H_FMT))) | (|Mf[P.CORRSHIFTSZ-P.S_NF-2:P.CORRSHIFTSZ-P.D_NF-1]&FpRes&((OutFmt==P.S_FMT)|(OutFmt==P.H_FMT))) |
(|Mf[`CORRSHIFTSZ-`D_NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&~(OutFmt==`Q_FMT)) | (|Mf[P.CORRSHIFTSZ-P.D_NF-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes&~(OutFmt==P.Q_FMT)) |
(|Mf[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`Q_NF-1]&(~(OutFmt==`Q_FMT)|IntRes)) | (|Mf[P.CORRSHIFTSZ-P.XLEN-2:P.CORRSHIFTSZ-P.Q_NF-1]&(~(OutFmt==P.Q_FMT)|IntRes)) |
(|Mf[`CORRSHIFTSZ-`Q_NF-2:0]); (|Mf[P.CORRSHIFTSZ-P.Q_NF-2:0]);
// 3: NF > NF1 > XLEN // 3: NF > NF1 > XLEN
// The extra XLEN bit will be ored later when caculating the final sticky bit - the ufplus1 not needed for integer // The extra XLEN bit will be ored later when caculating the final sticky bit - the ufplus1 not needed for integer
if (`XLENPOS == 3) assign NormSticky = (|Mf[`CORRSHIFTSZ-`H_NF-2:`CORRSHIFTSZ-`S_NF-1]&FpRes&(OutFmt==`H_FMT)) | if (XLENPOS == 3) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.H_NF-2:P.CORRSHIFTSZ-P.S_NF-1]&FpRes&(OutFmt==P.H_FMT)) |
(|Mf[`CORRSHIFTSZ-`S_NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&((OutFmt==`S_FMT)|(OutFmt==`H_FMT))) | (|Mf[P.CORRSHIFTSZ-P.S_NF-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes&((OutFmt==P.S_FMT)|(OutFmt==P.H_FMT))) |
(|Mf[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`D_NF-1]&((OutFmt==`S_FMT)|(OutFmt==`H_FMT)|IntRes)) | (|Mf[P.CORRSHIFTSZ-P.XLEN-2:P.CORRSHIFTSZ-P.D_NF-1]&((OutFmt==P.S_FMT)|(OutFmt==P.H_FMT)|IntRes)) |
(|Mf[`CORRSHIFTSZ-`D_NF-2:`CORRSHIFTSZ-`Q_NF-1]&(~(OutFmt==`Q_FMT)|IntRes)) | (|Mf[P.CORRSHIFTSZ-P.D_NF-2:P.CORRSHIFTSZ-P.Q_NF-1]&(~(OutFmt==P.Q_FMT)|IntRes)) |
(|Mf[`CORRSHIFTSZ-`Q_NF-2:0]); (|Mf[P.CORRSHIFTSZ-P.Q_NF-2:0]);
end end
@ -184,40 +184,40 @@ module round(
// only add the Addend sticky if doing an FMA opperation // 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) // - the shifter shifts too far left when there's an underflow (shifting out all possible sticky bits)
assign Sticky = FmaASticky&FmaOp | NormSticky | CvtResUf&CvtOp | FmaMe[`NE+1]&FmaOp | DivSticky&DivOp; assign Sticky = FmaASticky&FmaOp | NormSticky | CvtResUf&CvtOp | FmaMe[P.NE+1]&FmaOp | DivSticky&DivOp;
// determine round and LSB of the rounded value // determine round and LSB of the rounded value
// - underflow round bit is used to determint the underflow flag // - underflow round bit is used to determint the underflow flag
if (`FPSIZES == 1) begin if (P.FPSIZES == 1) begin
assign FpGuard = Mf[`CORRSHIFTSZ-`NF-1]; assign FpGuard = Mf[P.CORRSHIFTSZ-P.NF-1];
assign FpLsbRes = Mf[`CORRSHIFTSZ-`NF]; assign FpLsbRes = Mf[P.CORRSHIFTSZ-P.NF];
assign FpRound = Mf[`CORRSHIFTSZ-`NF-2]; assign FpRound = Mf[P.CORRSHIFTSZ-P.NF-2];
end else if (`FPSIZES == 2) begin end else if (P.FPSIZES == 2) begin
assign FpGuard = OutFmt ? Mf[`CORRSHIFTSZ-`NF-1] : Mf[`CORRSHIFTSZ-`NF1-1]; assign FpGuard = OutFmt ? Mf[P.CORRSHIFTSZ-P.NF-1] : Mf[P.CORRSHIFTSZ-P.NF1-1];
assign FpLsbRes = OutFmt ? Mf[`CORRSHIFTSZ-`NF] : Mf[`CORRSHIFTSZ-`NF1]; assign FpLsbRes = OutFmt ? Mf[P.CORRSHIFTSZ-P.NF] : Mf[P.CORRSHIFTSZ-P.NF1];
assign FpRound = OutFmt ? Mf[`CORRSHIFTSZ-`NF-2] : Mf[`CORRSHIFTSZ-`NF1-2]; assign FpRound = OutFmt ? Mf[P.CORRSHIFTSZ-P.NF-2] : Mf[P.CORRSHIFTSZ-P.NF1-2];
end else if (`FPSIZES == 3) begin end else if (P.FPSIZES == 3) begin
always_comb always_comb
case (OutFmt) case (OutFmt)
`FMT: begin P.FMT: begin
FpGuard = Mf[`CORRSHIFTSZ-`NF-1]; FpGuard = Mf[P.CORRSHIFTSZ-P.NF-1];
FpLsbRes = Mf[`CORRSHIFTSZ-`NF]; FpLsbRes = Mf[P.CORRSHIFTSZ-P.NF];
FpRound = Mf[`CORRSHIFTSZ-`NF-2]; FpRound = Mf[P.CORRSHIFTSZ-P.NF-2];
end end
`FMT1: begin P.FMT1: begin
FpGuard = Mf[`CORRSHIFTSZ-`NF1-1]; FpGuard = Mf[P.CORRSHIFTSZ-P.NF1-1];
FpLsbRes = Mf[`CORRSHIFTSZ-`NF1]; FpLsbRes = Mf[P.CORRSHIFTSZ-P.NF1];
FpRound = Mf[`CORRSHIFTSZ-`NF1-2]; FpRound = Mf[P.CORRSHIFTSZ-P.NF1-2];
end end
`FMT2: begin P.FMT2: begin
FpGuard = Mf[`CORRSHIFTSZ-`NF2-1]; FpGuard = Mf[P.CORRSHIFTSZ-P.NF2-1];
FpLsbRes = Mf[`CORRSHIFTSZ-`NF2]; FpLsbRes = Mf[P.CORRSHIFTSZ-P.NF2];
FpRound = Mf[`CORRSHIFTSZ-`NF2-2]; FpRound = Mf[P.CORRSHIFTSZ-P.NF2-2];
end end
default: begin default: begin
FpGuard = 1'bx; FpGuard = 1'bx;
@ -225,35 +225,35 @@ module round(
FpRound = 1'bx; FpRound = 1'bx;
end end
endcase endcase
end else if (`FPSIZES == 4) begin end else if (P.FPSIZES == 4) begin
always_comb always_comb
case (OutFmt) case (OutFmt)
2'h3: begin 2'h3: begin
FpGuard = Mf[`CORRSHIFTSZ-`Q_NF-1]; FpGuard = Mf[P.CORRSHIFTSZ-P.Q_NF-1];
FpLsbRes = Mf[`CORRSHIFTSZ-`Q_NF]; FpLsbRes = Mf[P.CORRSHIFTSZ-P.Q_NF];
FpRound = Mf[`CORRSHIFTSZ-`Q_NF-2]; FpRound = Mf[P.CORRSHIFTSZ-P.Q_NF-2];
end end
2'h1: begin 2'h1: begin
FpGuard = Mf[`CORRSHIFTSZ-`D_NF-1]; FpGuard = Mf[P.CORRSHIFTSZ-P.D_NF-1];
FpLsbRes = Mf[`CORRSHIFTSZ-`D_NF]; FpLsbRes = Mf[P.CORRSHIFTSZ-P.D_NF];
FpRound = Mf[`CORRSHIFTSZ-`D_NF-2]; FpRound = Mf[P.CORRSHIFTSZ-P.D_NF-2];
end end
2'h0: begin 2'h0: begin
FpGuard = Mf[`CORRSHIFTSZ-`S_NF-1]; FpGuard = Mf[P.CORRSHIFTSZ-P.S_NF-1];
FpLsbRes = Mf[`CORRSHIFTSZ-`S_NF]; FpLsbRes = Mf[P.CORRSHIFTSZ-P.S_NF];
FpRound = Mf[`CORRSHIFTSZ-`S_NF-2]; FpRound = Mf[P.CORRSHIFTSZ-P.S_NF-2];
end end
2'h2: begin 2'h2: begin
FpGuard = Mf[`CORRSHIFTSZ-`H_NF-1]; FpGuard = Mf[P.CORRSHIFTSZ-P.H_NF-1];
FpLsbRes = Mf[`CORRSHIFTSZ-`H_NF]; FpLsbRes = Mf[P.CORRSHIFTSZ-P.H_NF];
FpRound = Mf[`CORRSHIFTSZ-`H_NF-2]; FpRound = Mf[P.CORRSHIFTSZ-P.H_NF-2];
end end
endcase endcase
end end
assign Guard = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN-1] : FpGuard; assign Guard = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN-1] : FpGuard;
assign LsbRes = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN] : FpLsbRes; assign LsbRes = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN] : FpLsbRes;
assign Round = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN-2] : FpRound; assign Round = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN-2] : FpRound;
always_comb begin always_comb begin
@ -287,26 +287,26 @@ module round(
// place Plus1 into the proper position for the format // place Plus1 into the proper position for the format
if (`FPSIZES == 1) begin if (P.FPSIZES == 1) begin
assign RoundAdd = {{`FLEN{1'b0}}, FpPlus1}; assign RoundAdd = {{P.FLEN{1'b0}}, FpPlus1};
end else if (`FPSIZES == 2) begin end else if (P.FPSIZES == 2) begin
// \/FLEN+1 // \/FLEN+1
// | NE+2 | NF | // | NE+2 | NF |
// '-NE+2-^----NF1----^ // '-NE+2-^----NF1----^
// `FLEN+1-`NE-2-`NF1 = FLEN-1-NE-NF1 // P.FLEN+1-P.NE-2-P.NF1 = FLEN-1-NE-NF1
assign RoundAdd = {(`NE+1+`NF1)'(0), FpPlus1&~OutFmt, (`NF-`NF1-1)'(0), FpPlus1&OutFmt}; assign RoundAdd = {(P.NE+1+P.NF1)'(0), FpPlus1&~OutFmt, (P.NF-P.NF1-1)'(0), FpPlus1&OutFmt};
end else if (`FPSIZES == 3) begin end else if (P.FPSIZES == 3) begin
assign RoundAdd = {(`NE+1+`NF2)'(0), FpPlus1&(OutFmt==`FMT2), (`NF1-`NF2-1)'(0), FpPlus1&(OutFmt==`FMT1), (`NF-`NF1-1)'(0), FpPlus1&(OutFmt==`FMT)}; assign RoundAdd = {(P.NE+1+P.NF2)'(0), FpPlus1&(OutFmt==P.FMT2), (P.NF1-P.NF2-1)'(0), FpPlus1&(OutFmt==P.FMT1), (P.NF-P.NF1-1)'(0), FpPlus1&(OutFmt==P.FMT)};
end else if (`FPSIZES == 4) end else if (P.FPSIZES == 4)
assign RoundAdd = {(`Q_NE+1+`H_NF)'(0), FpPlus1&(OutFmt==`H_FMT), (`S_NF-`H_NF-1)'(0), FpPlus1&(OutFmt==`S_FMT), (`D_NF-`S_NF-1)'(0), FpPlus1&(OutFmt==`D_FMT), (`Q_NF-`D_NF-1)'(0), FpPlus1&(OutFmt==`Q_FMT)}; assign RoundAdd = {(P.Q_NE+1+P.H_NF)'(0), FpPlus1&(OutFmt==P.H_FMT), (P.S_NF-P.H_NF-1)'(0), FpPlus1&(OutFmt==P.S_FMT), (P.D_NF-P.S_NF-1)'(0), FpPlus1&(OutFmt==P.D_FMT), (P.Q_NF-P.D_NF-1)'(0), FpPlus1&(OutFmt==P.Q_FMT)};
// trim unneeded bits from fraction // trim unneeded bits from fraction
assign RoundFrac = Mf[`CORRSHIFTSZ-1:`CORRSHIFTSZ-`NF]; assign RoundFrac = Mf[P.CORRSHIFTSZ-1:P.CORRSHIFTSZ-P.NF];
@ -314,7 +314,7 @@ module round(
always_comb always_comb
case(PostProcSel) case(PostProcSel)
2'b10: Me = FmaMe; // fma 2'b10: Me = FmaMe; // fma
2'b00: Me = {CvtCe[`NE], CvtCe}&{`NE+2{~CvtResSubnormUf|CvtResUf}}; // cvt 2'b00: Me = {CvtCe[P.NE], CvtCe}&{P.NE+2{~CvtResSubnormUf|CvtResUf}}; // cvt
// 2'b01: Me = DivDone ? Qe : '0; // divide // 2'b01: Me = DivDone ? Qe : '0; // divide
2'b01: Me = Qe; // divide 2'b01: Me = Qe; // divide
default: Me = '0; default: Me = '0;
@ -325,7 +325,7 @@ module round(
// round the result // round the result
// - if the fraction overflows one should be added to the exponent // - if the fraction overflows one should be added to the exponent
assign {FullRe, Rf} = {Me, RoundFrac} + RoundAdd; assign {FullRe, Rf} = {Me, RoundFrac} + RoundAdd;
assign Re = FullRe[`NE-1:0]; assign Re = FullRe[P.NE-1:0];
endmodule endmodule

View File

@ -25,7 +25,6 @@
// either express or implied. See the License for the specific language governing permissions // either express or implied. See the License for the specific language governing permissions
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module roundsign( module roundsign(
input logic Xs, // x sign input logic Xs, // x sign

View File

@ -26,53 +26,51 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh" module shiftcorrection import cvw::*; #(parameter cvw_t P) (
input logic [P.NORMSHIFTSZ-1:0] Shifted, // the shifted sum before LZA correction
module shiftcorrection(
input logic [`NORMSHIFTSZ-1:0] Shifted, // the shifted sum before LZA correction
// divsqrt // divsqrt
input logic DivOp, // is it a divsqrt opperation input logic DivOp, // is it a divsqrt opperation
input logic DivResSubnorm, // is the divsqrt result subnormal input logic DivResSubnorm, // is the divsqrt result subnormal
input logic [`NE+1:0] DivQe, // the divsqrt result's exponent input logic [P.NE+1:0] DivQe, // the divsqrt result's exponent
input logic DivSubnormShiftPos, // is the subnorm divider shift amount positive (ie not underflowed) input logic DivSubnormShiftPos, // is the subnorm divider shift amount positive (ie not underflowed)
//fma //fma
input logic FmaOp, // is it an fma opperation input logic FmaOp, // is it an fma opperation
input logic [`NE+1:0] NormSumExp, // exponent of the normalized sum not taking into account Subnormal or zero results input logic [P.NE+1:0] NormSumExp, // exponent of the normalized sum not taking into account Subnormal or zero results
input logic FmaPreResultSubnorm, // is the result subnormal - calculated before LZA corection input logic FmaPreResultSubnorm, // is the result subnormal - calculated before LZA corection
input logic FmaSZero, input logic FmaSZero,
// output // output
output logic [`NE+1:0] FmaMe, // exponent of the normalized sum output logic [P.NE+1:0] FmaMe, // exponent of the normalized sum
output logic [`CORRSHIFTSZ-1:0] Mf, // the shifted sum before LZA correction output logic [P.CORRSHIFTSZ-1:0] Mf, // the shifted sum before LZA correction
output logic [`NE+1:0] Qe // corrected exponent for divider output logic [P.NE+1:0] Qe // corrected exponent for divider
); );
logic [3*`NF+3:0] CorrSumShifted; // the shifted sum after LZA correction logic [3*P.NF+3:0] CorrSumShifted; // the shifted sum after LZA correction
logic [`CORRSHIFTSZ-1:0] CorrQm0, CorrQm1; // portions of Shifted to select for CorrQmShifted logic [P.CORRSHIFTSZ-1:0] CorrQm0, CorrQm1; // portions of Shifted to select for CorrQmShifted
logic [`CORRSHIFTSZ-1:0] CorrQmShifted; // the shifted divsqrt result after one bit shift logic [P.CORRSHIFTSZ-1:0] CorrQmShifted; // the shifted divsqrt result after one bit shift
logic ResSubnorm; // is the result Subnormal logic ResSubnorm; // is the result Subnormal
logic LZAPlus1; // add one or two to the sum's exponent due to LZA correction logic LZAPlus1; // add one or two to the sum's exponent due to LZA correction
logic LeftShiftQm; // should the divsqrt result be shifted one to the left logic LeftShiftQm; // should the divsqrt result be shifted one to the left
// LZA correction // LZA correction
assign LZAPlus1 = Shifted[`NORMSHIFTSZ-1]; assign LZAPlus1 = Shifted[P.NORMSHIFTSZ-1];
// correct the shifting error caused by the LZA // correct the shifting error caused by the LZA
// - the only possible mantissa for a plus two is all zeroes // - 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 // - a one has to propigate all the way through a sum. so we can leave the bottom statement alone
mux2 #(`NORMSHIFTSZ-2) lzacorrmux(Shifted[`NORMSHIFTSZ-3:0], Shifted[`NORMSHIFTSZ-2:1], LZAPlus1, CorrSumShifted); mux2 #(P.NORMSHIFTSZ-2) lzacorrmux(Shifted[P.NORMSHIFTSZ-3:0], Shifted[P.NORMSHIFTSZ-2:1], LZAPlus1, CorrSumShifted);
// correct the shifting of the divsqrt caused by producing a result in (2, .5] range // correct the shifting of the divsqrt caused by producing a result in (2, .5] range
// condition: if the msb is 1 or the exponent was one, but the shifted quotent was < 1 (Subnorm) // condition: if the msb is 1 or the exponent was one, but the shifted quotent was < 1 (Subnorm)
assign LeftShiftQm = (LZAPlus1|(DivQe==1&~LZAPlus1)); assign LeftShiftQm = (LZAPlus1|(DivQe==1&~LZAPlus1));
assign CorrQm0 = Shifted[`NORMSHIFTSZ-3:`NORMSHIFTSZ-`CORRSHIFTSZ-2]; assign CorrQm0 = Shifted[P.NORMSHIFTSZ-3:P.NORMSHIFTSZ-P.CORRSHIFTSZ-2];
assign CorrQm1 = Shifted[`NORMSHIFTSZ-2:`NORMSHIFTSZ-`CORRSHIFTSZ-1]; assign CorrQm1 = Shifted[P.NORMSHIFTSZ-2:P.NORMSHIFTSZ-P.CORRSHIFTSZ-1];
mux2 #(`CORRSHIFTSZ) divcorrmux(CorrQm0, CorrQm1, LeftShiftQm, CorrQmShifted); mux2 #(P.CORRSHIFTSZ) divcorrmux(CorrQm0, CorrQm1, LeftShiftQm, CorrQmShifted);
// if the result of the divider was calculated to be subnormal, then the result was correctly normalized, so select the top shifted bits // if the result of the divider was calculated to be subnormal, then the result was correctly normalized, so select the top shifted bits
always_comb always_comb
if(FmaOp) Mf = {CorrSumShifted, {`CORRSHIFTSZ-(3*`NF+4){1'b0}}}; if(FmaOp) Mf = {CorrSumShifted, {P.CORRSHIFTSZ-(3*P.NF+4){1'b0}}};
else if (DivOp&~DivResSubnorm) Mf = CorrQmShifted; else if (DivOp&~DivResSubnorm) Mf = CorrQmShifted;
else Mf = Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`CORRSHIFTSZ]; else Mf = Shifted[P.NORMSHIFTSZ-1:P.NORMSHIFTSZ-P.CORRSHIFTSZ];
// Determine sum's exponent // Determine sum's exponent
// main exponent issues: // main exponent issues:
@ -82,12 +80,12 @@ module shiftcorrection(
// - if the result was calulated to be subnorm but it's norm and the LZA was off by 2 // - if the result was calulated to be subnorm but it's norm and the LZA was off by 2
// if plus1 If plus2 kill if the result Zero or actually subnormal // if plus1 If plus2 kill if the result Zero or actually subnormal
// | | | // | | |
assign FmaMe = (NormSumExp+{{`NE+1{1'b0}}, LZAPlus1} +{{`NE+1{1'b0}}, FmaPreResultSubnorm}) & {`NE+2{~(FmaSZero|ResSubnorm)}}; assign FmaMe = (NormSumExp+{{P.NE+1{1'b0}}, LZAPlus1} +{{P.NE+1{1'b0}}, FmaPreResultSubnorm}) & {P.NE+2{~(FmaSZero|ResSubnorm)}};
// recalculate if the result is subnormal after LZA correction // recalculate if the result is subnormal after LZA correction
assign ResSubnorm = FmaPreResultSubnorm&~Shifted[`NORMSHIFTSZ-2]&~Shifted[`NORMSHIFTSZ-1]; assign ResSubnorm = FmaPreResultSubnorm&~Shifted[P.NORMSHIFTSZ-2]&~Shifted[P.NORMSHIFTSZ-1];
// the quotent is in the range [.5,2) if there is no early termination // the quotent is in the range [.5,2) if there is no early termination
// if the quotent < 1 and not Subnormal then subtract 1 to account for the normalization shift // if the quotent < 1 and not Subnormal then subtract 1 to account for the normalization shift
assign Qe = (DivResSubnorm & DivSubnormShiftPos) ? '0 : DivQe - {(`NE+1)'(0), ~LZAPlus1}; assign Qe = (DivResSubnorm & DivSubnormShiftPos) ? '0 : DivQe - {(P.NE+1)'(0), ~LZAPlus1};
endmodule endmodule

View File

@ -26,14 +26,12 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh" module specialcase import cvw::*; #(parameter cvw_t P) (
module specialcase(
input logic Xs, // X sign input logic Xs, // X sign
input logic [`NF:0] Xm, Ym, Zm, // input significand's input logic [P.NF:0] Xm, Ym, Zm, // input significand's
input logic XNaN, YNaN, ZNaN, // are the inputs NaN input logic XNaN, YNaN, ZNaN, // are the inputs NaN
input logic [2:0] Frm, // rounding mode input logic [2:0] Frm, // rounding mode
input logic [`FMTBITS-1:0] OutFmt, // output format input logic [P.FMTBITS-1:0] OutFmt, // output format
input logic InfIn, // are any inputs infinity input logic InfIn, // are any inputs infinity
input logic NaNIn, // are any input NaNs input logic NaNIn, // are any input NaNs
input logic XInf, YInf, // are X or Y inifnity input logic XInf, YInf, // are X or Y inifnity
@ -41,9 +39,9 @@ module specialcase(
input logic Plus1, // do you add one for rounding input logic Plus1, // do you add one for rounding
input logic Rs, // the result's sign input logic Rs, // the result's sign
input logic Invalid, Overflow, // flags to choose the result input logic Invalid, Overflow, // flags to choose the result
input logic [`NE-1:0] Re, // Result exponent input logic [P.NE-1:0] Re, // Result exponent
input logic [`NE+1:0] FullRe, // Result full exponent input logic [P.NE+1:0] FullRe, // Result full exponent
input logic [`NF-1:0] Rf, // Result fraction input logic [P.NF-1:0] Rf, // Result fraction
// fma // fma
input logic FmaOp, // is it a fma opperation input logic FmaOp, // is it a fma opperation
// divsqrt // divsqrt
@ -55,23 +53,23 @@ module specialcase(
input logic IntToFp, // is cvt int -> fp opperation input logic IntToFp, // is cvt int -> fp opperation
input logic Int64, // is the integer 64 bits input logic Int64, // is the integer 64 bits
input logic Signed, // is the integer signed input logic Signed, // is the integer signed
input logic [`NE:0] CvtCe, // the calculated expoent for cvt input logic [P.NE:0] CvtCe, // the calculated expoent for cvt
input logic IntInvalid, // integer invalid flag to choose the result input logic IntInvalid, // integer invalid flag to choose the result
input logic CvtResUf, // does the convert result underflow input logic CvtResUf, // does the convert result underflow
input logic [`XLEN+1:0] CvtNegRes, // the possibly negated of the integer result input logic [P.XLEN+1:0] CvtNegRes, // the possibly negated of the integer result
// outputs // outputs
output logic [`FLEN-1:0] PostProcRes,// final result output logic [P.FLEN-1:0] PostProcRes,// final result
output logic [`XLEN-1:0] FCvtIntRes // final integer result output logic [P.XLEN-1:0] FCvtIntRes // final integer result
); );
logic [`FLEN-1:0] XNaNRes; // X is NaN result logic [P.FLEN-1:0] XNaNRes; // X is NaN result
logic [`FLEN-1:0] YNaNRes; // Y is NaN result logic [P.FLEN-1:0] YNaNRes; // Y is NaN result
logic [`FLEN-1:0] ZNaNRes; // Z is NaN result logic [P.FLEN-1:0] ZNaNRes; // Z is NaN result
logic [`FLEN-1:0] InvalidRes; // Invalid result result logic [P.FLEN-1:0] InvalidRes; // Invalid result result
logic [`FLEN-1:0] UfRes; // underflowed result result logic [P.FLEN-1:0] UfRes; // underflowed result result
logic [`FLEN-1:0] OfRes; // overflowed result result logic [P.FLEN-1:0] OfRes; // overflowed result result
logic [`FLEN-1:0] NormRes; // normal result logic [P.FLEN-1:0] NormRes; // normal result
logic [`XLEN-1:0] OfIntRes; // the overflow result for integer output logic [P.XLEN-1:0] OfIntRes; // the overflow result for integer output
logic OfResMax; // does the of result output maximum norm fp number logic OfResMax; // does the of result output maximum norm fp number
logic KillRes; // kill the result for underflow logic KillRes; // kill the result for underflow
logic SelOfRes; // should the overflow result be selected logic SelOfRes; // should the overflow result be selected
@ -82,158 +80,158 @@ module specialcase(
assign OfResMax = (~InfIn|(IntToFp&CvtOp))&~DivByZero&((Frm[1:0]==2'b01) | (Frm[1:0]==2'b10&~Rs) | (Frm[1:0]==2'b11&Rs)); assign OfResMax = (~InfIn|(IntToFp&CvtOp))&~DivByZero&((Frm[1:0]==2'b01) | (Frm[1:0]==2'b10&~Rs) | (Frm[1:0]==2'b11&Rs));
// select correct outputs for special cases // select correct outputs for special cases
if (`FPSIZES == 1) begin if (P.FPSIZES == 1) begin
//NaN res selection depending on standard //NaN res selection depending on standard
if(`IEEE754) begin if(P.IEEE754) begin
assign XNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Xm[`NF-2:0]}; assign XNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]};
assign YNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Ym[`NF-2:0]}; assign YNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Ym[P.NF-2:0]};
assign ZNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Zm[`NF-2:0]}; assign ZNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Zm[P.NF-2:0]};
assign InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; assign InvalidRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
end else begin end else begin
assign InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; assign InvalidRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
end end
assign OfRes = OfResMax ? {Rs, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {Rs, {`NE{1'b1}}, {`NF{1'b0}}}; assign OfRes = OfResMax ? {Rs, {P.NE-1{1'b1}}, 1'b0, {P.NF{1'b1}}} : {Rs, {P.NE{1'b1}}, {P.NF{1'b0}}};
assign UfRes = {Rs, {`FLEN-2{1'b0}}, Plus1&Frm[1]&~(DivOp&YInf)}; assign UfRes = {Rs, {P.FLEN-2{1'b0}}, Plus1&Frm[1]&~(DivOp&YInf)};
assign NormRes = {Rs, Re, Rf}; assign NormRes = {Rs, Re, Rf};
end else if (`FPSIZES == 2) begin end else if (P.FPSIZES == 2) begin
if(`IEEE754) begin if(P.IEEE754) begin
assign XNaNRes = OutFmt ? {1'b0, {`NE{1'b1}}, 1'b1, Xm[`NF-2:0]} : {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, Xm[`NF-2:`NF-`NF1]}; assign XNaNRes = OutFmt ? {1'b0, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]} : {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.NF1]};
assign YNaNRes = OutFmt ? {1'b0, {`NE{1'b1}}, 1'b1, Ym[`NF-2:0]} : {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, Ym[`NF-2:`NF-`NF1]}; assign YNaNRes = OutFmt ? {1'b0, {P.NE{1'b1}}, 1'b1, Ym[P.NF-2:0]} : {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, Ym[P.NF-2:P.NF-P.NF1]};
assign ZNaNRes = OutFmt ? {1'b0, {`NE{1'b1}}, 1'b1, Zm[`NF-2:0]} : {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, Zm[`NF-2:`NF-`NF1]}; assign ZNaNRes = OutFmt ? {1'b0, {P.NE{1'b1}}, 1'b1, Zm[P.NF-2:0]} : {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, Zm[P.NF-2:P.NF-P.NF1]};
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, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}} : {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, (P.NF1-1)'(0)};
end else begin end else begin
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, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}} : {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, (P.NF1-1)'(0)};
end end
always_comb always_comb
if(OutFmt) if(OutFmt)
if(OfResMax) OfRes = {Rs, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}}; if(OfResMax) OfRes = {Rs, {P.NE-1{1'b1}}, 1'b0, {P.NF{1'b1}}};
else OfRes = {Rs, {`NE{1'b1}}, {`NF{1'b0}}}; else OfRes = {Rs, {P.NE{1'b1}}, {P.NF{1'b0}}};
else else
if(OfResMax) OfRes = {{`FLEN-`LEN1{1'b1}}, Rs, {`NE1-1{1'b1}}, 1'b0, {`NF1{1'b1}}}; if(OfResMax) OfRes = {{P.FLEN-P.LEN1{1'b1}}, Rs, {P.NE1-1{1'b1}}, 1'b0, {P.NF1{1'b1}}};
else OfRes = {{`FLEN-`LEN1{1'b1}}, Rs, {`NE1{1'b1}}, (`NF1)'(0)}; else OfRes = {{P.FLEN-P.LEN1{1'b1}}, Rs, {P.NE1{1'b1}}, (P.NF1)'(0)};
assign UfRes = OutFmt ? {Rs, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)} : {{`FLEN-`LEN1{1'b1}}, Rs, (`LEN1-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)}; assign UfRes = OutFmt ? {Rs, (P.FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)} : {{P.FLEN-P.LEN1{1'b1}}, Rs, (P.LEN1-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
assign NormRes = OutFmt ? {Rs, Re, Rf} : {{`FLEN-`LEN1{1'b1}}, Rs, Re[`NE1-1:0], Rf[`NF-1:`NF-`NF1]}; assign NormRes = OutFmt ? {Rs, Re, Rf} : {{P.FLEN-P.LEN1{1'b1}}, Rs, Re[P.NE1-1:0], Rf[P.NF-1:P.NF-P.NF1]};
end else if (`FPSIZES == 3) begin end else if (P.FPSIZES == 3) begin
always_comb always_comb
case (OutFmt) case (OutFmt)
`FMT: begin P.FMT: begin
if(`IEEE754) begin if(P.IEEE754) begin
XNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Xm[`NF-2:0]}; XNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]};
YNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Ym[`NF-2:0]}; YNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Ym[P.NF-2:0]};
ZNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Zm[`NF-2:0]}; ZNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Zm[P.NF-2:0]};
InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; InvalidRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
end else begin end else begin
InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; InvalidRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
end end
OfRes = OfResMax ? {Rs, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {Rs, {`NE{1'b1}}, {`NF{1'b0}}}; OfRes = OfResMax ? {Rs, {P.NE-1{1'b1}}, 1'b0, {P.NF{1'b1}}} : {Rs, {P.NE{1'b1}}, {P.NF{1'b0}}};
UfRes = {Rs, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)}; UfRes = {Rs, (P.FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
NormRes = {Rs, Re, Rf}; NormRes = {Rs, Re, Rf};
end end
`FMT1: begin P.FMT1: begin
if(`IEEE754) begin if(P.IEEE754) begin
XNaNRes = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, Xm[`NF-2:`NF-`NF1]}; XNaNRes = {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.NF1]};
YNaNRes = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, Ym[`NF-2:`NF-`NF1]}; YNaNRes = {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, Ym[P.NF-2:P.NF-P.NF1]};
ZNaNRes = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, Zm[`NF-2:`NF-`NF1]}; ZNaNRes = {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, Zm[P.NF-2:P.NF-P.NF1]};
InvalidRes = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; InvalidRes = {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, (P.NF1-1)'(0)};
end else begin end else begin
InvalidRes = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)}; InvalidRes = {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, (P.NF1-1)'(0)};
end end
OfRes = OfResMax ? {{`FLEN-`LEN1{1'b1}}, Rs, {`NE1-1{1'b1}}, 1'b0, {`NF1{1'b1}}} : {{`FLEN-`LEN1{1'b1}}, Rs, {`NE1{1'b1}}, (`NF1)'(0)}; OfRes = OfResMax ? {{P.FLEN-P.LEN1{1'b1}}, Rs, {P.NE1-1{1'b1}}, 1'b0, {P.NF1{1'b1}}} : {{P.FLEN-P.LEN1{1'b1}}, Rs, {P.NE1{1'b1}}, (P.NF1)'(0)};
UfRes = {{`FLEN-`LEN1{1'b1}}, Rs, (`LEN1-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)}; UfRes = {{P.FLEN-P.LEN1{1'b1}}, Rs, (P.LEN1-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
NormRes = {{`FLEN-`LEN1{1'b1}}, Rs, Re[`NE1-1:0], Rf[`NF-1:`NF-`NF1]}; NormRes = {{P.FLEN-P.LEN1{1'b1}}, Rs, Re[P.NE1-1:0], Rf[P.NF-1:P.NF-P.NF1]};
end end
`FMT2: begin P.FMT2: begin
if(`IEEE754) begin if(P.IEEE754) begin
XNaNRes = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, Xm[`NF-2:`NF-`NF2]}; XNaNRes = {{P.FLEN-P.LEN2{1'b1}}, 1'b0, {P.NE2{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.NF2]};
YNaNRes = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, Ym[`NF-2:`NF-`NF2]}; YNaNRes = {{P.FLEN-P.LEN2{1'b1}}, 1'b0, {P.NE2{1'b1}}, 1'b1, Ym[P.NF-2:P.NF-P.NF2]};
ZNaNRes = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, Zm[`NF-2:`NF-`NF2]}; ZNaNRes = {{P.FLEN-P.LEN2{1'b1}}, 1'b0, {P.NE2{1'b1}}, 1'b1, Zm[P.NF-2:P.NF-P.NF2]};
InvalidRes = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)}; InvalidRes = {{P.FLEN-P.LEN2{1'b1}}, 1'b0, {P.NE2{1'b1}}, 1'b1, (P.NF2-1)'(0)};
end else begin end else begin
InvalidRes = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)}; InvalidRes = {{P.FLEN-P.LEN2{1'b1}}, 1'b0, {P.NE2{1'b1}}, 1'b1, (P.NF2-1)'(0)};
end end
OfRes = OfResMax ? {{`FLEN-`LEN2{1'b1}}, Rs, {`NE2-1{1'b1}}, 1'b0, {`NF2{1'b1}}} : {{`FLEN-`LEN2{1'b1}}, Rs, {`NE2{1'b1}}, (`NF2)'(0)}; OfRes = OfResMax ? {{P.FLEN-P.LEN2{1'b1}}, Rs, {P.NE2-1{1'b1}}, 1'b0, {P.NF2{1'b1}}} : {{P.FLEN-P.LEN2{1'b1}}, Rs, {P.NE2{1'b1}}, (P.NF2)'(0)};
UfRes = {{`FLEN-`LEN2{1'b1}}, Rs, (`LEN2-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)}; UfRes = {{P.FLEN-P.LEN2{1'b1}}, Rs, (P.LEN2-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
NormRes = {{`FLEN-`LEN2{1'b1}}, Rs, Re[`NE2-1:0], Rf[`NF-1:`NF-`NF2]}; NormRes = {{P.FLEN-P.LEN2{1'b1}}, Rs, Re[P.NE2-1:0], Rf[P.NF-1:P.NF-P.NF2]};
end end
default: begin default: begin
if(`IEEE754) begin if(P.IEEE754) begin
XNaNRes = (`FLEN)'(0); XNaNRes = (P.FLEN)'(0);
YNaNRes = (`FLEN)'(0); YNaNRes = (P.FLEN)'(0);
ZNaNRes = (`FLEN)'(0); ZNaNRes = (P.FLEN)'(0);
InvalidRes = (`FLEN)'(0); InvalidRes = (P.FLEN)'(0);
end else begin end else begin
InvalidRes = (`FLEN)'(0); InvalidRes = (P.FLEN)'(0);
end end
OfRes = (`FLEN)'(0); OfRes = (P.FLEN)'(0);
UfRes = (`FLEN)'(0); UfRes = (P.FLEN)'(0);
NormRes = (`FLEN)'(0); NormRes = (P.FLEN)'(0);
end end
endcase endcase
end else if (`FPSIZES == 4) begin end else if (P.FPSIZES == 4) begin
always_comb always_comb
case (OutFmt) case (OutFmt)
2'h3: begin 2'h3: begin
if(`IEEE754) begin if(P.IEEE754) begin
XNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Xm[`NF-2:0]}; XNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]};
YNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Ym[`NF-2:0]}; YNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Ym[P.NF-2:0]};
ZNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Zm[`NF-2:0]}; ZNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Zm[P.NF-2:0]};
InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; InvalidRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
end else begin end else begin
InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}}; InvalidRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
end end
OfRes = OfResMax ? {Rs, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {Rs, {`NE{1'b1}}, {`NF{1'b0}}}; OfRes = OfResMax ? {Rs, {P.NE-1{1'b1}}, 1'b0, {P.NF{1'b1}}} : {Rs, {P.NE{1'b1}}, {P.NF{1'b0}}};
UfRes = {Rs, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)}; UfRes = {Rs, (P.FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
NormRes = {Rs, Re, Rf}; NormRes = {Rs, Re, Rf};
end end
2'h1: begin 2'h1: begin
if(`IEEE754) begin if(P.IEEE754) begin
XNaNRes = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, Xm[`NF-2:`NF-`D_NF]}; XNaNRes = {{P.FLEN-P.D_LEN{1'b1}}, 1'b0, {P.D_NE{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.D_NF]};
YNaNRes = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, Ym[`NF-2:`NF-`D_NF]}; YNaNRes = {{P.FLEN-P.D_LEN{1'b1}}, 1'b0, {P.D_NE{1'b1}}, 1'b1, Ym[P.NF-2:P.NF-P.D_NF]};
ZNaNRes = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, Zm[`NF-2:`NF-`D_NF]}; ZNaNRes = {{P.FLEN-P.D_LEN{1'b1}}, 1'b0, {P.D_NE{1'b1}}, 1'b1, Zm[P.NF-2:P.NF-P.D_NF]};
InvalidRes = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)}; InvalidRes = {{P.FLEN-P.D_LEN{1'b1}}, 1'b0, {P.D_NE{1'b1}}, 1'b1, (P.D_NF-1)'(0)};
end else begin end else begin
InvalidRes = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)}; InvalidRes = {{P.FLEN-P.D_LEN{1'b1}}, 1'b0, {P.D_NE{1'b1}}, 1'b1, (P.D_NF-1)'(0)};
end end
OfRes = OfResMax ? {{`FLEN-`D_LEN{1'b1}}, Rs, {`D_NE-1{1'b1}}, 1'b0, {`D_NF{1'b1}}} : {{`FLEN-`D_LEN{1'b1}}, Rs, {`D_NE{1'b1}}, (`D_NF)'(0)}; OfRes = OfResMax ? {{P.FLEN-P.D_LEN{1'b1}}, Rs, {P.D_NE-1{1'b1}}, 1'b0, {P.D_NF{1'b1}}} : {{P.FLEN-P.D_LEN{1'b1}}, Rs, {P.D_NE{1'b1}}, (P.D_NF)'(0)};
UfRes = {{`FLEN-`D_LEN{1'b1}}, Rs, (`D_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)}; UfRes = {{P.FLEN-P.D_LEN{1'b1}}, Rs, (P.D_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
NormRes = {{`FLEN-`D_LEN{1'b1}}, Rs, Re[`D_NE-1:0], Rf[`NF-1:`NF-`D_NF]}; NormRes = {{P.FLEN-P.D_LEN{1'b1}}, Rs, Re[P.D_NE-1:0], Rf[P.NF-1:P.NF-P.D_NF]};
end end
2'h0: begin 2'h0: begin
if(`IEEE754) begin if(P.IEEE754) begin
XNaNRes = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, Xm[`NF-2:`NF-`S_NF]}; XNaNRes = {{P.FLEN-P.S_LEN{1'b1}}, 1'b0, {P.S_NE{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.S_NF]};
YNaNRes = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, Ym[`NF-2:`NF-`S_NF]}; YNaNRes = {{P.FLEN-P.S_LEN{1'b1}}, 1'b0, {P.S_NE{1'b1}}, 1'b1, Ym[P.NF-2:P.NF-P.S_NF]};
ZNaNRes = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, Zm[`NF-2:`NF-`S_NF]}; ZNaNRes = {{P.FLEN-P.S_LEN{1'b1}}, 1'b0, {P.S_NE{1'b1}}, 1'b1, Zm[P.NF-2:P.NF-P.S_NF]};
InvalidRes = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)}; InvalidRes = {{P.FLEN-P.S_LEN{1'b1}}, 1'b0, {P.S_NE{1'b1}}, 1'b1, (P.S_NF-1)'(0)};
end else begin end else begin
InvalidRes = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)}; InvalidRes = {{P.FLEN-P.S_LEN{1'b1}}, 1'b0, {P.S_NE{1'b1}}, 1'b1, (P.S_NF-1)'(0)};
end end
OfRes = OfResMax ? {{`FLEN-`S_LEN{1'b1}}, Rs, {`S_NE-1{1'b1}}, 1'b0, {`S_NF{1'b1}}} : {{`FLEN-`S_LEN{1'b1}}, Rs, {`S_NE{1'b1}}, (`S_NF)'(0)}; OfRes = OfResMax ? {{P.FLEN-P.S_LEN{1'b1}}, Rs, {P.S_NE-1{1'b1}}, 1'b0, {P.S_NF{1'b1}}} : {{P.FLEN-P.S_LEN{1'b1}}, Rs, {P.S_NE{1'b1}}, (P.S_NF)'(0)};
UfRes = {{`FLEN-`S_LEN{1'b1}}, Rs, (`S_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)}; UfRes = {{P.FLEN-P.S_LEN{1'b1}}, Rs, (P.S_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
NormRes = {{`FLEN-`S_LEN{1'b1}}, Rs, Re[`S_NE-1:0], Rf[`NF-1:`NF-`S_NF]}; NormRes = {{P.FLEN-P.S_LEN{1'b1}}, Rs, Re[P.S_NE-1:0], Rf[P.NF-1:P.NF-P.S_NF]};
end end
2'h2: begin 2'h2: begin
if(`IEEE754) begin if(P.IEEE754) begin
XNaNRes = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, Xm[`NF-2:`NF-`H_NF]}; XNaNRes = {{P.FLEN-P.H_LEN{1'b1}}, 1'b0, {P.H_NE{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.H_NF]};
YNaNRes = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, Ym[`NF-2:`NF-`H_NF]}; YNaNRes = {{P.FLEN-P.H_LEN{1'b1}}, 1'b0, {P.H_NE{1'b1}}, 1'b1, Ym[P.NF-2:P.NF-P.H_NF]};
ZNaNRes = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, Zm[`NF-2:`NF-`H_NF]}; ZNaNRes = {{P.FLEN-P.H_LEN{1'b1}}, 1'b0, {P.H_NE{1'b1}}, 1'b1, Zm[P.NF-2:P.NF-P.H_NF]};
InvalidRes = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)}; InvalidRes = {{P.FLEN-P.H_LEN{1'b1}}, 1'b0, {P.H_NE{1'b1}}, 1'b1, (P.H_NF-1)'(0)};
end else begin end else begin
InvalidRes = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)}; InvalidRes = {{P.FLEN-P.H_LEN{1'b1}}, 1'b0, {P.H_NE{1'b1}}, 1'b1, (P.H_NF-1)'(0)};
end end
OfRes = OfResMax ? {{`FLEN-`H_LEN{1'b1}}, Rs, {`H_NE-1{1'b1}}, 1'b0, {`H_NF{1'b1}}} : {{`FLEN-`H_LEN{1'b1}}, Rs, {`H_NE{1'b1}}, (`H_NF)'(0)}; OfRes = OfResMax ? {{P.FLEN-P.H_LEN{1'b1}}, Rs, {P.H_NE-1{1'b1}}, 1'b0, {P.H_NF{1'b1}}} : {{P.FLEN-P.H_LEN{1'b1}}, Rs, {P.H_NE{1'b1}}, (P.H_NF)'(0)};
// zero is exact if dividing by infinity so don't add 1 // zero is exact if dividing by infinity so don't add 1
UfRes = {{`FLEN-`H_LEN{1'b1}}, Rs, (`H_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)}; UfRes = {{P.FLEN-P.H_LEN{1'b1}}, Rs, (P.H_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
NormRes = {{`FLEN-`H_LEN{1'b1}}, Rs, Re[`H_NE-1:0], Rf[`NF-1:`NF-`H_NF]}; NormRes = {{P.FLEN-P.H_LEN{1'b1}}, Rs, Re[P.H_NE-1:0], Rf[P.NF-1:P.NF-P.H_NF]};
end end
endcase endcase
end end
@ -242,13 +240,13 @@ module specialcase(
// - do so if the res underflows, is zero (the exp doesnt calculate correctly). or the integer input is 0 // - do so if the res underflows, is zero (the exp doesnt calculate correctly). or the integer input is 0
// - dont set to zero if fp input is zero but not using the fp input // - dont set to zero if fp input is zero but not using the fp input
// - dont set to zero if int input is zero but not using the int input // - dont set to zero if int input is zero but not using the int input
assign KillRes = CvtOp ? (CvtResUf|(XZero&~IntToFp)|(IntZero&IntToFp)) : FullRe[`NE+1] | (((YInf&~XInf)|XZero)&DivOp);//Underflow & ~ResSubnorm & (Re!=1); assign KillRes = CvtOp ? (CvtResUf|(XZero&~IntToFp)|(IntZero&IntToFp)) : FullRe[P.NE+1] | (((YInf&~XInf)|XZero)&DivOp);//Underflow & ~ResSubnorm & (Re!=1);
// calculate if the overflow result should be selected // calculate if the overflow result should be selected
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) if(P.IEEE754)
always_comb always_comb
if(XNaN&~(IntToFp&CvtOp)) PostProcRes = XNaNRes; if(XNaN&~(IntToFp&CvtOp)) PostProcRes = XNaNRes;
else if(YNaN&~CvtOp) PostProcRes = YNaNRes; else if(YNaN&~CvtOp) PostProcRes = YNaNRes;
@ -283,14 +281,14 @@ module specialcase(
always_comb always_comb
if(Signed) if(Signed)
if(Xs&~NaNIn) // signed negitive if(Xs&~NaNIn) // signed negitive
if(Int64) OfIntRes = {1'b1, {`XLEN-1{1'b0}}}; if(Int64) OfIntRes = {1'b1, {P.XLEN-1{1'b0}}};
else OfIntRes = {{`XLEN-32{1'b1}}, 1'b1, {31{1'b0}}}; else OfIntRes = {{P.XLEN-32{1'b1}}, 1'b1, {31{1'b0}}};
else // signed positive else // signed positive
if(Int64) OfIntRes = {1'b0, {`XLEN-1{1'b1}}}; if(Int64) OfIntRes = {1'b0, {P.XLEN-1{1'b1}}};
else OfIntRes = {{`XLEN-32{1'b0}}, 1'b0, {31{1'b1}}}; else OfIntRes = {{P.XLEN-32{1'b0}}, 1'b0, {31{1'b1}}};
else else
if(Xs&~NaNIn) OfIntRes = {`XLEN{1'b0}}; // unsigned negitive if(Xs&~NaNIn) OfIntRes = {P.XLEN{1'b0}}; // unsigned negitive
else OfIntRes = {`XLEN{1'b1}}; // unsigned positive else OfIntRes = {P.XLEN{1'b1}}; // unsigned positive
// select the integer output // select the integer output
@ -301,9 +299,9 @@ module specialcase(
// - otherwise output the normal res (trmined and sign extended if nessisary) // - otherwise output the normal res (trmined and sign extended if nessisary)
always_comb always_comb
if(IntInvalid) FCvtIntRes = OfIntRes; if(IntInvalid) FCvtIntRes = OfIntRes;
else if(CvtCe[`NE]) else if(CvtCe[P.NE])
if(Xs&Signed&Plus1) FCvtIntRes = {{`XLEN{1'b1}}}; if(Xs&Signed&Plus1) FCvtIntRes = {{P.XLEN{1'b1}}};
else FCvtIntRes = {{`XLEN-1{1'b0}}, Plus1}; else FCvtIntRes = {{P.XLEN-1{1'b0}}, Plus1};
else if(Int64) FCvtIntRes = CvtNegRes[`XLEN-1:0]; else if(Int64) FCvtIntRes = CvtNegRes[P.XLEN-1:0];
else FCvtIntRes = {{`XLEN-32{CvtNegRes[31]}}, CvtNegRes[31:0]}; else FCvtIntRes = {{P.XLEN-32{CvtNegRes[31]}}, CvtNegRes[31:0]};
endmodule endmodule