mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Finished fpu parameterization using Lim's method.
This commit is contained in:
parent
29e0357f21
commit
f1b8689955
@ -25,16 +25,15 @@
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// 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 XNaN, // is NaN
|
||||
input logic XSNaN, // is signaling NaN
|
||||
input logic XSubnorm, // is Subnormal
|
||||
input logic XZero, // is zero
|
||||
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
|
||||
@ -63,6 +62,6 @@ module fclassify (
|
||||
// bit 7 - +Inf
|
||||
// bit 8 - signaling 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
|
||||
|
@ -27,8 +27,6 @@
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
// OpCtrl values
|
||||
// 110 min
|
||||
// 101 max
|
||||
@ -36,23 +34,23 @@
|
||||
// 001 less than
|
||||
// 011 less than or equal
|
||||
|
||||
module fcmp (
|
||||
input logic [`FMTBITS-1:0] Fmt, // format of fp number
|
||||
module fcmp import cvw::*; #(parameter cvw_t P) (
|
||||
input logic [P.FMTBITS-1:0] Fmt, // format of fp number
|
||||
input logic [2:0] OpCtrl, // see above table
|
||||
input logic Xs, Ys, // input signs
|
||||
input logic [`NE-1:0] Xe, Ye, // input exponents
|
||||
input logic [`NF:0] Xm, Ym, // input mantissa
|
||||
input logic [P.NE-1:0] Xe, Ye, // input exponents
|
||||
input logic [P.NF:0] Xm, Ym, // input mantissa
|
||||
input logic XZero, YZero, // is zero
|
||||
input logic XNaN, YNaN, // is 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 [`FLEN-1:0] CmpFpRes, // compare floating-point result
|
||||
output logic [`XLEN-1:0] CmpIntRes // compare integer result
|
||||
output logic [P.FLEN-1:0] CmpFpRes, // compare floating-point result
|
||||
output logic [P.XLEN-1:0] CmpIntRes // compare integer result
|
||||
);
|
||||
|
||||
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 EitherNaN, EitherSNaN; // are either input a (signaling) NaN
|
||||
|
||||
@ -85,44 +83,44 @@ module fcmp (
|
||||
// for RISC-V, return the canonical NaN
|
||||
|
||||
// select the NaN result
|
||||
if (`FPSIZES == 1)
|
||||
if(`IEEE754) assign NaNRes = {Xs, {`NE{1'b1}}, 1'b1, Xm[`NF-2:0]};
|
||||
else assign NaNRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}};
|
||||
if (P.FPSIZES == 1)
|
||||
if(P.IEEE754) assign NaNRes = {Xs, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]};
|
||||
else assign NaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
|
||||
|
||||
else if (`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]};
|
||||
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 if (P.FPSIZES == 2)
|
||||
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, {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
|
||||
case (Fmt)
|
||||
`FMT:
|
||||
if(`IEEE754) NaNRes = {Xs, {`NE{1'b1}}, 1'b1, Xm[`NF-2:0]};
|
||||
else NaNRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}};
|
||||
`FMT1:
|
||||
if(`IEEE754) NaNRes = {{`FLEN-`LEN1{1'b1}}, Xs, {`NE1{1'b1}}, 1'b1, Xm[`NF-2:`NF-`NF1]};
|
||||
else NaNRes = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)};
|
||||
`FMT2:
|
||||
if(`IEEE754) NaNRes = {{`FLEN-`LEN2{1'b1}}, Xs, {`NE2{1'b1}}, 1'b1, Xm[`NF-2:`NF-`NF2]};
|
||||
else NaNRes = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)};
|
||||
default: NaNRes = {`FLEN{1'bx}};
|
||||
P.FMT:
|
||||
if(P.IEEE754) NaNRes = {Xs, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]};
|
||||
else NaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
|
||||
P.FMT1:
|
||||
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 = {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, (P.NF1-1)'(0)};
|
||||
P.FMT2:
|
||||
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 = {{P.FLEN-P.LEN2{1'b1}}, 1'b0, {P.NE2{1'b1}}, 1'b1, (P.NF2-1)'(0)};
|
||||
default: NaNRes = {P.FLEN{1'bx}};
|
||||
endcase
|
||||
|
||||
else if (`FPSIZES == 4)
|
||||
else if (P.FPSIZES == 4)
|
||||
always_comb
|
||||
case (Fmt)
|
||||
2'h3:
|
||||
if(`IEEE754) NaNRes = {Xs, {`NE{1'b1}}, 1'b1, Xm[`NF-2:0]};
|
||||
else NaNRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}};
|
||||
if(P.IEEE754) NaNRes = {Xs, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]};
|
||||
else NaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
|
||||
2'h1:
|
||||
if(`IEEE754) NaNRes = {{`FLEN-`D_LEN{1'b1}}, Xs, {`D_NE{1'b1}}, 1'b1, Xm[`NF-2:`NF-`D_NF]};
|
||||
else NaNRes = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)};
|
||||
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 = {{P.FLEN-P.D_LEN{1'b1}}, 1'b0, {P.D_NE{1'b1}}, 1'b1, (P.D_NF-1)'(0)};
|
||||
2'h0:
|
||||
if(`IEEE754) NaNRes = {{`FLEN-`S_LEN{1'b1}}, Xs, {`S_NE{1'b1}}, 1'b1, Xm[`NF-2:`NF-`S_NF]};
|
||||
else NaNRes = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)};
|
||||
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 = {{P.FLEN-P.S_LEN{1'b1}}, 1'b0, {P.S_NE{1'b1}}, 1'b1, (P.S_NF-1)'(0)};
|
||||
2'h2:
|
||||
if(`IEEE754) NaNRes = {{`FLEN-`H_LEN{1'b1}}, Xs, {`H_NE{1'b1}}, 1'b1, Xm[`NF-2:`NF-`H_NF]};
|
||||
else NaNRes = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)};
|
||||
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 = {{P.FLEN-P.H_LEN{1'b1}}, 1'b0, {P.H_NE{1'b1}}, 1'b1, (P.H_NF-1)'(0)};
|
||||
endcase
|
||||
|
||||
|
||||
@ -155,6 +153,6 @@ module fcmp (
|
||||
// - -0 = 0
|
||||
// - inf = inf and -inf = -inf
|
||||
// - 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
|
||||
|
106
src/fpu/fcvt.sv
106
src/fpu/fcvt.sv
@ -27,23 +27,21 @@
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module fcvt (
|
||||
module fcvt import cvw::*; #(parameter cvw_t P) (
|
||||
input logic Xs, // input's sign
|
||||
input logic [`NE-1:0] Xe, // input's exponent
|
||||
input logic [`NF:0] Xm, // input's fraction
|
||||
input logic [`XLEN-1:0] Int, // integer input - from IEU
|
||||
input logic [P.NE-1:0] Xe, // input's exponent
|
||||
input logic [P.NF:0] Xm, // input's fraction
|
||||
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 ToInt, // is fp->int (since it's writting to the integer register)
|
||||
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)
|
||||
output logic [`NE:0] Ce, // the calculated expoent
|
||||
output logic [`LOGCVTLEN-1:0] ShiftAmt, // how much to shift by
|
||||
input logic [P.FMTBITS-1:0] Fmt, // the input's precision (11=quad 01=double 00=single 10=half)
|
||||
output logic [P.NE:0] Ce, // the calculated expoent
|
||||
output logic [P.LOGCVTLEN-1:0] ShiftAmt, // how much to shift by
|
||||
output logic ResSubnormUf,// does the result underflow or is subnormal
|
||||
output logic Cs, // the result's sign
|
||||
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:
|
||||
@ -56,16 +54,16 @@ module fcvt (
|
||||
// bit 2 bit 1 bit 0
|
||||
// for example: signed long -> single floating point has the OpCode 101
|
||||
|
||||
logic [`FMTBITS-1:0] OutFmt; // format of the output
|
||||
logic [`XLEN-1:0] PosInt; // the positive integer input
|
||||
logic [`XLEN-1:0] TrimInt; // integer trimmed to the correct size
|
||||
logic [`NE-2:0] NewBias; // the bias of the final result
|
||||
logic [`NE-1:0] OldExp; // the old exponent
|
||||
logic [P.FMTBITS-1:0] OutFmt; // format of the output
|
||||
logic [P.XLEN-1:0] PosInt; // the positive integer input
|
||||
logic [P.XLEN-1:0] TrimInt; // integer trimmed to the correct size
|
||||
logic [P.NE-2:0] NewBias; // the bias of the final result
|
||||
logic [P.NE-1:0] OldExp; // the old exponent
|
||||
logic Signed; // is the opperation with a signed integer?
|
||||
logic Int64; // is the integer 64 bits?
|
||||
logic IntToFp; // is the opperation an int->fp conversion?
|
||||
logic [`CVTLEN:0] LzcInFull; // input to the Leading Zero Counter (priority encoder)
|
||||
logic [`LOGCVTLEN-1:0] LeadingZeros; // output from the LZC
|
||||
logic [P.CVTLEN:0] LzcInFull; // input to the Leading Zero Counter (priority encoder)
|
||||
logic [P.LOGCVTLEN-1:0] LeadingZeros; // output from the LZC
|
||||
|
||||
|
||||
// seperate OpCtrl for code readability
|
||||
@ -76,9 +74,9 @@ module fcvt (
|
||||
// choose the ouptut format depending on the opperation
|
||||
// - fp -> fp: OpCtrl contains the percision of the output
|
||||
// - int -> fp: Fmt contains the percision of the output
|
||||
if (`FPSIZES == 2)
|
||||
assign OutFmt = IntToFp ? Fmt : (OpCtrl[1:0] == `FMT);
|
||||
else if (`FPSIZES == 3 | `FPSIZES == 4)
|
||||
if (P.FPSIZES == 2)
|
||||
assign OutFmt = IntToFp ? Fmt : (OpCtrl[1:0] == P.FMT);
|
||||
else if (P.FPSIZES == 3 | P.FPSIZES == 4)
|
||||
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)
|
||||
|
||||
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;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@ -99,13 +97,13 @@ module fcvt (
|
||||
// choose the input to the leading zero counter i.e. priority encoder
|
||||
// int -> fp : | positive integer | 00000... (if needed) |
|
||||
// fp -> fp : | fraction | 00000... (if needed) |
|
||||
assign LzcInFull = IntToFp ? {TrimInt, {`CVTLEN-`XLEN+1{1'b0}}} :
|
||||
{Xm, {`CVTLEN-`NF{1'b0}}};
|
||||
assign LzcInFull = IntToFp ? {TrimInt, {P.CVTLEN-P.XLEN+1{1'b0}}} :
|
||||
{Xm, {P.CVTLEN-P.NF{1'b0}}};
|
||||
|
||||
// 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
|
||||
@ -114,42 +112,42 @@ module fcvt (
|
||||
// Select the bias of the output
|
||||
// fp -> int : select 1
|
||||
// ??? -> fp : pick the new bias depending on the output format
|
||||
if (`FPSIZES == 1) begin
|
||||
assign NewBias = ToInt ? (`NE-1)'(1) : (`NE-1)'(`BIAS);
|
||||
if (P.FPSIZES == 1) begin
|
||||
assign NewBias = ToInt ? (P.NE-1)'(1) : (P.NE-1)'(P.BIAS);
|
||||
|
||||
end else if (`FPSIZES == 2) begin
|
||||
logic [`NE-2:0] NewBiasToFp;
|
||||
assign NewBiasToFp = OutFmt ? (`NE-1)'(`BIAS) : (`NE-1)'(`BIAS1);
|
||||
assign NewBias = ToInt ? (`NE-1)'(1) : NewBiasToFp;
|
||||
end else if (P.FPSIZES == 2) begin
|
||||
logic [P.NE-2:0] NewBiasToFp;
|
||||
assign NewBiasToFp = OutFmt ? (P.NE-1)'(P.BIAS) : (P.NE-1)'(P.BIAS1);
|
||||
assign NewBias = ToInt ? (P.NE-1)'(1) : NewBiasToFp;
|
||||
|
||||
end else if (`FPSIZES == 3) begin
|
||||
logic [`NE-2:0] NewBiasToFp;
|
||||
end else if (P.FPSIZES == 3) begin
|
||||
logic [P.NE-2:0] NewBiasToFp;
|
||||
always_comb
|
||||
case (OutFmt)
|
||||
`FMT: NewBiasToFp = (`NE-1)'(`BIAS);
|
||||
`FMT1: NewBiasToFp = (`NE-1)'(`BIAS1);
|
||||
`FMT2: NewBiasToFp = (`NE-1)'(`BIAS2);
|
||||
default: NewBiasToFp = {`NE-1{1'bx}};
|
||||
P.FMT: NewBiasToFp = (P.NE-1)'(P.BIAS);
|
||||
P.FMT1: NewBiasToFp = (P.NE-1)'(P.BIAS1);
|
||||
P.FMT2: NewBiasToFp = (P.NE-1)'(P.BIAS2);
|
||||
default: NewBiasToFp = {P.NE-1{1'bx}};
|
||||
endcase
|
||||
assign NewBias = ToInt ? (`NE-1)'(1) : NewBiasToFp;
|
||||
assign NewBias = ToInt ? (P.NE-1)'(1) : NewBiasToFp;
|
||||
|
||||
end else if (`FPSIZES == 4) begin
|
||||
logic [`NE-2:0] NewBiasToFp;
|
||||
end else if (P.FPSIZES == 4) begin
|
||||
logic [P.NE-2:0] NewBiasToFp;
|
||||
always_comb
|
||||
case (OutFmt)
|
||||
2'h3: NewBiasToFp = (`NE-1)'(`Q_BIAS);
|
||||
2'h1: NewBiasToFp = (`NE-1)'(`D_BIAS);
|
||||
2'h0: NewBiasToFp = (`NE-1)'(`S_BIAS);
|
||||
2'h2: NewBiasToFp = (`NE-1)'(`H_BIAS);
|
||||
2'h3: NewBiasToFp = (P.NE-1)'(P.Q_BIAS);
|
||||
2'h1: NewBiasToFp = (P.NE-1)'(P.D_BIAS);
|
||||
2'h0: NewBiasToFp = (P.NE-1)'(P.S_BIAS);
|
||||
2'h2: NewBiasToFp = (P.NE-1)'(P.H_BIAS);
|
||||
endcase
|
||||
assign NewBias = ToInt ? (`NE-1)'(1) : NewBiasToFp;
|
||||
assign NewBias = ToInt ? (P.NE-1)'(1) : NewBiasToFp;
|
||||
end
|
||||
|
||||
|
||||
// select the old exponent
|
||||
// int -> fp : largest bias + XLEN-1
|
||||
// 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
|
||||
// fp -> fp :
|
||||
@ -159,13 +157,13 @@ module fcvt (
|
||||
// - 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
|
||||
// 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:
|
||||
// - start
|
||||
// | `XLEN zeros | Mantissa | 0's if nessisary |
|
||||
// | P.XLEN zeros | Mantissa | 0's if nessisary |
|
||||
//
|
||||
// - 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
|
||||
//
|
||||
// - shift left till unbiased exponent is 0 (XExp - Largest Bias)
|
||||
@ -185,13 +183,13 @@ module fcvt (
|
||||
// - newBias to make the biased exponent
|
||||
//
|
||||
// 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
|
||||
// - if Calculated expoenent is 0 or negitive (and the input/result is not exactaly 0)
|
||||
// - 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
|
||||
// - rather have a few and-gates than an extra bit in the priority encoder??? *** is this true?
|
||||
always_comb
|
||||
if(ToInt) ShiftAmt = Ce[`LOGCVTLEN-1:0]&{`LOGCVTLEN{~Ce[`NE]}};
|
||||
else if (ResSubnormUf) ShiftAmt = (`LOGCVTLEN)'(`NF-1)+Ce[`LOGCVTLEN-1:0];
|
||||
if(ToInt) ShiftAmt = Ce[P.LOGCVTLEN-1:0]&{P.LOGCVTLEN{~Ce[P.NE]}};
|
||||
else if (ResSubnormUf) ShiftAmt = (P.LOGCVTLEN)'(P.NF-1)+Ce[P.LOGCVTLEN-1:0];
|
||||
else ShiftAmt = LeadingZeros;
|
||||
|
||||
|
||||
@ -227,7 +225,7 @@ module fcvt (
|
||||
// - otherwise: the floating point input's sign
|
||||
always_comb
|
||||
if(IntToFp)
|
||||
if(Int64) Cs = Int[`XLEN-1]&Signed;
|
||||
if(Int64) Cs = Int[P.XLEN-1]&Signed;
|
||||
else Cs = Int[31]&Signed;
|
||||
else Cs = Xs;
|
||||
|
||||
|
@ -245,20 +245,20 @@ module fpu import cvw::*; #(parameter cvw_t P) (
|
||||
.QmM, .FIntDivResultM);
|
||||
|
||||
// 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),
|
||||
.XSNaN(XSNaNE), .YSNaN(YSNaNE), .X(XE), .Y(YE), .CmpNV(CmpNVE),
|
||||
.CmpFpRes(CmpFpResE), .CmpIntRes(CmpIntResE));
|
||||
|
||||
// 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
|
||||
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));
|
||||
|
||||
// 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),
|
||||
.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
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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),
|
||||
.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),
|
||||
|
@ -26,14 +26,12 @@
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module fsgninj (
|
||||
module fsgninj import cvw::*; #(parameter cvw_t P) (
|
||||
input logic Xs, Ys, // X and Y sign bits
|
||||
input logic [`FLEN-1:0] X, // X
|
||||
input logic [`FMTBITS-1:0] Fmt, // format
|
||||
input logic [P.FLEN-1:0] X, // X
|
||||
input logic [P.FMTBITS-1:0] Fmt, // format
|
||||
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
|
||||
@ -50,30 +48,30 @@ module fsgninj (
|
||||
// - uses NaN-blocking format
|
||||
// - if there are any unused bits the most significant bits are filled with 1s
|
||||
|
||||
if (`FPSIZES == 1)
|
||||
assign SgnRes = {ResSgn, X[`FLEN-2:0]};
|
||||
else if (`FPSIZES == 2)
|
||||
assign SgnRes = {~Fmt|ResSgn, X[`FLEN-2:`LEN1], Fmt ? X[`LEN1-1] : ResSgn, X[`LEN1-2:0]};
|
||||
else if (`FPSIZES == 3) begin
|
||||
if (P.FPSIZES == 1)
|
||||
assign SgnRes = {ResSgn, X[P.FLEN-2:0]};
|
||||
else if (P.FPSIZES == 2)
|
||||
assign SgnRes = {~Fmt|ResSgn, X[P.FLEN-2:P.LEN1], Fmt ? X[P.LEN1-1] : ResSgn, X[P.LEN1-2:0]};
|
||||
else if (P.FPSIZES == 3) begin
|
||||
logic [2:0] SgnBits;
|
||||
always_comb
|
||||
case (Fmt)
|
||||
`FMT: SgnBits = {ResSgn, X[`LEN1-1], X[`LEN2-1]};
|
||||
`FMT1: SgnBits = {1'b1, ResSgn, X[`LEN2-1]};
|
||||
`FMT2: SgnBits = {2'b11, ResSgn};
|
||||
P.FMT: SgnBits = {ResSgn, X[P.LEN1-1], X[P.LEN2-1]};
|
||||
P.FMT1: SgnBits = {1'b1, ResSgn, X[P.LEN2-1]};
|
||||
P.FMT2: SgnBits = {2'b11, ResSgn};
|
||||
default: SgnBits = {3{1'bx}};
|
||||
endcase
|
||||
assign SgnRes = {SgnBits[2], X[`FLEN-2:`LEN1], SgnBits[1], X[`LEN1-2:`LEN2], SgnBits[0], X[`LEN2-2:0]};
|
||||
end else if (`FPSIZES == 4) begin
|
||||
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 (P.FPSIZES == 4) begin
|
||||
logic [3:0] SgnBits;
|
||||
always_comb
|
||||
case (Fmt)
|
||||
`Q_FMT: SgnBits = {ResSgn, X[`D_LEN-1], X[`S_LEN-1], X[`H_LEN-1]};
|
||||
`D_FMT: SgnBits = {1'b1, ResSgn, X[`S_LEN-1], X[`H_LEN-1]};
|
||||
`S_FMT: SgnBits = {2'b11, ResSgn, X[`H_LEN-1]};
|
||||
`H_FMT: SgnBits = {3'b111, ResSgn};
|
||||
P.Q_FMT: SgnBits = {ResSgn, X[P.D_LEN-1], X[P.S_LEN-1], X[P.H_LEN-1]};
|
||||
P.D_FMT: SgnBits = {1'b1, ResSgn, X[P.S_LEN-1], X[P.H_LEN-1]};
|
||||
P.S_FMT: SgnBits = {2'b11, ResSgn, X[P.H_LEN-1]};
|
||||
P.H_FMT: SgnBits = {3'b111, ResSgn};
|
||||
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
|
||||
|
||||
endmodule
|
||||
|
@ -26,22 +26,20 @@
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module cvtshiftcalc(
|
||||
module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
|
||||
input logic XZero, // is the input zero?
|
||||
input logic ToInt, // to integer conversion?
|
||||
input logic IntToFp, // interger to floating point conversion?
|
||||
input logic [`FMTBITS-1:0] OutFmt, // output format
|
||||
input logic [`NE:0] CvtCe, // the calculated expoent
|
||||
input logic [`NF:0] Xm, // input mantissas
|
||||
input logic [`CVTLEN-1:0] CvtLzcIn, // input to the Leading Zero Counter (without msb)
|
||||
input logic [P.FMTBITS-1:0] OutFmt, // output format
|
||||
input logic [P.NE:0] CvtCe, // the calculated expoent
|
||||
input logic [P.NF:0] Xm, // input mantissas
|
||||
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
|
||||
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
|
||||
@ -49,7 +47,7 @@ module cvtshiftcalc(
|
||||
|
||||
// seclect the input to the shifter
|
||||
// fp -> int:
|
||||
// | `XLEN zeros | mantissa | 0's if nessisary |
|
||||
// | P.XLEN zeros | mantissa | 0's if nessisary |
|
||||
// .
|
||||
// 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)
|
||||
@ -57,7 +55,7 @@ module cvtshiftcalc(
|
||||
// - ex: for the case 0010000.... (double)
|
||||
// ??? -> fp:
|
||||
// - 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:
|
||||
// | LzcInM | 0's if nessisary |
|
||||
@ -67,33 +65,33 @@ module cvtshiftcalc(
|
||||
// get rid of round 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}}};
|
||||
else if (CvtResSubnormUf) CvtShiftIn = {{`NF-1{1'b0}}, Xm, {`CVTLEN-`NF+1{1'b0}}};
|
||||
else CvtShiftIn = {CvtLzcIn, {`NF+1{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 = {{P.NF-1{1'b0}}, Xm, {P.CVTLEN-P.NF+1{1'b0}}};
|
||||
else CvtShiftIn = {CvtLzcIn, {P.NF+1{1'b0}}};
|
||||
|
||||
// choose the negative of the fraction size
|
||||
if (`FPSIZES == 1) begin
|
||||
assign ResNegNF = -($clog2(`NF)+1)'(`NF);
|
||||
if (P.FPSIZES == 1) begin
|
||||
assign ResNegNF = -($clog2(P.NF)+1)'(P.NF);
|
||||
|
||||
end else if (`FPSIZES == 2) begin
|
||||
assign ResNegNF = OutFmt ? -($clog2(`NF)+1)'(`NF) : -($clog2(`NF)+1)'(`NF1);
|
||||
end else if (P.FPSIZES == 2) begin
|
||||
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
|
||||
case (OutFmt)
|
||||
`FMT: ResNegNF = -($clog2(`NF)+1)'(`NF);
|
||||
`FMT1: ResNegNF = -($clog2(`NF)+1)'(`NF1);
|
||||
`FMT2: ResNegNF = -($clog2(`NF)+1)'(`NF2);
|
||||
P.FMT: ResNegNF = -($clog2(P.NF)+1)'(P.NF);
|
||||
P.FMT1: ResNegNF = -($clog2(P.NF)+1)'(P.NF1);
|
||||
P.FMT2: ResNegNF = -($clog2(P.NF)+1)'(P.NF2);
|
||||
default: ResNegNF = 1'bx;
|
||||
endcase
|
||||
|
||||
end else if (`FPSIZES == 4) begin
|
||||
end else if (P.FPSIZES == 4) begin
|
||||
always_comb
|
||||
case (OutFmt)
|
||||
2'h3: ResNegNF = -($clog2(`NF)+1)'(`Q_NF);
|
||||
2'h1: ResNegNF = -($clog2(`NF)+1)'(`D_NF);
|
||||
2'h0: ResNegNF = -($clog2(`NF)+1)'(`S_NF);
|
||||
2'h2: ResNegNF = -($clog2(`NF)+1)'(`H_NF);
|
||||
2'h3: ResNegNF = -($clog2(P.NF)+1)'(P.Q_NF);
|
||||
2'h1: ResNegNF = -($clog2(P.NF)+1)'(P.D_NF);
|
||||
2'h0: ResNegNF = -($clog2(P.NF)+1)'(P.S_NF);
|
||||
2'h2: ResNegNF = -($clog2(P.NF)+1)'(P.H_NF);
|
||||
endcase
|
||||
end
|
||||
|
||||
@ -102,6 +100,6 @@ module cvtshiftcalc(
|
||||
// determine if the result underflows ??? -> fp
|
||||
// - if the first 1 is shifted out of the result then the result underflows
|
||||
// - 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
|
@ -26,24 +26,22 @@
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////`include "wally-config.vh"
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module divshiftcalc(
|
||||
input logic [`DIVb:0] DivQm, // divsqrt significand
|
||||
input logic [`NE+1:0] DivQe, // divsqrt exponent
|
||||
output logic [`LOGNORMSHIFTSZ-1:0] DivShiftAmt, // divsqrt shift amount
|
||||
output logic [`NORMSHIFTSZ-1:0] DivShiftIn, // divsqrt shift input
|
||||
module divshiftcalc import cvw::*; #(parameter cvw_t P) (
|
||||
input logic [P.DIVb:0] DivQm, // divsqrt significand
|
||||
input logic [P.NE+1:0] DivQe, // divsqrt exponent
|
||||
output logic [P.LOGNORMSHIFTSZ-1:0] DivShiftAmt, // divsqrt shift amount
|
||||
output logic [P.NORMSHIFTSZ-1:0] DivShiftIn, // divsqrt shift input
|
||||
output logic DivResSubnorm, // is the divsqrt result subnormal
|
||||
output logic DivSubnormShiftPos // is the subnormal shift amount positive
|
||||
);
|
||||
|
||||
logic [`LOGNORMSHIFTSZ-1:0] NormShift; // normalized result shift amount
|
||||
logic [`LOGNORMSHIFTSZ-1:0] DivSubnormShiftAmt; // subnormal result shift amount (killed if negitive)
|
||||
logic [`NE+1:0] DivSubnormShift; // subnormal result shift amount
|
||||
logic [P.LOGNORMSHIFTSZ-1:0] NormShift; // normalized result shift amount
|
||||
logic [P.LOGNORMSHIFTSZ-1:0] DivSubnormShiftAmt; // subnormal result shift amount (killed if negitive)
|
||||
logic [P.NE+1:0] DivSubnormShift; // subnormal result shift amount
|
||||
|
||||
// is the result subnormal
|
||||
// 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
|
||||
// 00000000x.xxxxxx... Exp = DivQe
|
||||
@ -51,8 +49,8 @@ module divshiftcalc(
|
||||
// .00xxxxxxxxxxxxx... << DivQe+NF+1 Exp = +1
|
||||
// .0000xxxxxxxxxxx... >> 1 Exp = 1
|
||||
// Left shift amount = DivQe+NF+1-1
|
||||
assign DivSubnormShift = (`NE+2)'(`NF)+DivQe;
|
||||
assign DivSubnormShiftPos = ~DivSubnormShift[`NE+1];
|
||||
assign DivSubnormShift = (P.NE+2)'(P.NF)+DivQe;
|
||||
assign DivSubnormShiftPos = ~DivSubnormShift[P.NE+1];
|
||||
|
||||
// if the result is normalized
|
||||
// 00000000x.xxxxxx... Exp = DivQe
|
||||
@ -62,13 +60,13 @@ module divshiftcalc(
|
||||
// 00000000xx.xxxxx... << 1? Exp = DivQe-1 (determined after)
|
||||
// inital Left shift amount = NF
|
||||
// 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)
|
||||
// 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;
|
||||
|
||||
// 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
|
||||
|
@ -25,18 +25,17 @@
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// 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 [`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 XInf, YInf, ZInf, // inputs are infinity
|
||||
input logic NaNIn, // is a NaN input being used
|
||||
input logic XSNaN, YSNaN, ZSNaN, // inputs are signaling NaNs
|
||||
input logic XZero, YZero, // inputs are zero
|
||||
input logic [`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] FullRe, // Re with bits to determine sign and overflow
|
||||
input logic [P.NE+1:0] Me, // exponent of the normalized sum
|
||||
// rounding
|
||||
input logic Plus1, // do you add one for 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 Int64, // convert to 64 bit 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
|
||||
// divsqrt
|
||||
input logic DivOp, // conversion opperation?
|
||||
@ -92,33 +91,33 @@ module flags(
|
||||
// - 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
|
||||
// one of the later bits is one
|
||||
if (`FPSIZES == 1) begin
|
||||
assign ResExpGteMax = &FullRe[`NE-1:0] | FullRe[`NE];
|
||||
assign ShiftGtIntSz = (|FullRe[`NE:7]|(FullRe[6]&~Int64)) | ((|FullRe[4:0]|(FullRe[5]&Int64))&((FullRe[5]&~Int64) | FullRe[6]&Int64));
|
||||
if (P.FPSIZES == 1) begin
|
||||
assign ResExpGteMax = &FullRe[P.NE-1:0] | FullRe[P.NE];
|
||||
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
|
||||
assign ResExpGteMax = OutFmt ? &FullRe[`NE-1:0] | FullRe[`NE] : &FullRe[`NE1-1:0] | (|FullRe[`NE:`NE1]);
|
||||
end else if (P.FPSIZES == 2) begin
|
||||
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));
|
||||
end else if (`FPSIZES == 3) begin
|
||||
assign ShiftGtIntSz = (|FullRe[P.NE:7]|(FullRe[6]&~Int64)) | ((|FullRe[4:0]|(FullRe[5]&Int64))&((FullRe[5]&~Int64) | FullRe[6]&Int64));
|
||||
end else if (P.FPSIZES == 3) begin
|
||||
always_comb
|
||||
case (OutFmt)
|
||||
`FMT: ResExpGteMax = &FullRe[`NE-1:0] | FullRe[`NE];
|
||||
`FMT1: ResExpGteMax = &FullRe[`NE1-1:0] | (|FullRe[`NE:`NE1]);
|
||||
`FMT2: ResExpGteMax = &FullRe[`NE2-1:0] | (|FullRe[`NE:`NE2]);
|
||||
P.FMT: ResExpGteMax = &FullRe[P.NE-1:0] | FullRe[P.NE];
|
||||
P.FMT1: ResExpGteMax = &FullRe[P.NE1-1:0] | (|FullRe[P.NE:P.NE1]);
|
||||
P.FMT2: ResExpGteMax = &FullRe[P.NE2-1:0] | (|FullRe[P.NE:P.NE2]);
|
||||
default: ResExpGteMax = 1'bx;
|
||||
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
|
||||
case (OutFmt)
|
||||
`Q_FMT: ResExpGteMax = &FullRe[`Q_NE-1:0] | FullRe[`Q_NE];
|
||||
`D_FMT: ResExpGteMax = &FullRe[`D_NE-1:0] | (|FullRe[`Q_NE:`D_NE]);
|
||||
`S_FMT: ResExpGteMax = &FullRe[`S_NE-1:0] | (|FullRe[`Q_NE:`S_NE]);
|
||||
`H_FMT: ResExpGteMax = &FullRe[`H_NE-1:0] | (|FullRe[`Q_NE:`H_NE]);
|
||||
P.Q_FMT: ResExpGteMax = &FullRe[P.Q_NE-1:0] | FullRe[P.Q_NE];
|
||||
P.D_FMT: ResExpGteMax = &FullRe[P.D_NE-1:0] | (|FullRe[P.Q_NE:P.D_NE]);
|
||||
P.S_FMT: ResExpGteMax = &FullRe[P.S_NE-1:0] | (|FullRe[P.Q_NE:P.S_NE]);
|
||||
P.H_FMT: ResExpGteMax = &FullRe[P.H_NE-1:0] | (|FullRe[P.Q_NE:P.H_NE]);
|
||||
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
|
||||
|
||||
|
||||
@ -127,7 +126,7 @@ module flags(
|
||||
// | and the exponent isn't negitive
|
||||
// | | 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
|
||||
@ -141,7 +140,7 @@ module flags(
|
||||
// | | | | and if the result is not exact
|
||||
// | | | | | 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
|
||||
// | 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
|
||||
assign Inexact = ToInt ? IntInexact : FpInexact;
|
||||
@ -178,7 +177,7 @@ module flags(
|
||||
// | | | | or the res rounds up out of bounds
|
||||
// | | | | 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
|
||||
|
||||
|
@ -26,21 +26,19 @@
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module fmashiftcalc(
|
||||
input logic [`FMTBITS-1:0] Fmt, // precision 1 = double 0 = single
|
||||
input logic [`NE+1:0] FmaSe, // sum's exponent
|
||||
input logic [3*`NF+3:0] FmaSm, // the positive sum
|
||||
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
|
||||
module fmashiftcalc import cvw::*; #(parameter cvw_t P) (
|
||||
input logic [P.FMTBITS-1:0] Fmt, // precision 1 = double 0 = single
|
||||
input logic [P.NE+1:0] FmaSe, // sum's exponent
|
||||
input logic [3*P.NF+3:0] FmaSm, // the positive sum
|
||||
input logic [$clog2(3*P.NF+5)-1:0] FmaSCnt, // normalization shift count
|
||||
output logic [P.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 FmaPreResultSubnorm, // is the result subnormal - calculated before LZA corection
|
||||
output logic [$clog2(3*`NF+5)-1:0] FmaShiftAmt, // normalization shift count
|
||||
output logic [3*`NF+5:0] FmaShiftIn // is the sum zero
|
||||
output logic [$clog2(3*P.NF+5)-1:0] FmaShiftAmt, // normalization shift count
|
||||
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 [`NE+1:0] BiasCorr; // correction for bias
|
||||
logic [P.NE+1:0] PreNormSumExp; // the exponent of the normalized sum with the P.FLEN bias
|
||||
logic [P.NE+1:0] BiasCorr; // correction for bias
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Normalization
|
||||
@ -50,75 +48,75 @@ module fmashiftcalc(
|
||||
assign FmaSZero = ~(|FmaSm);
|
||||
|
||||
// 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
|
||||
if (`FPSIZES == 1) begin
|
||||
if (P.FPSIZES == 1) begin
|
||||
assign NormSumExp = PreNormSumExp;
|
||||
end else if (`FPSIZES == 2) begin
|
||||
assign BiasCorr = Fmt ? (`NE+2)'(0) : (`NE+2)'(`BIAS1-`BIAS);
|
||||
end else if (P.FPSIZES == 2) begin
|
||||
assign BiasCorr = Fmt ? (P.NE+2)'(0) : (P.NE+2)'(P.BIAS1-P.BIAS);
|
||||
assign NormSumExp = PreNormSumExp+BiasCorr;
|
||||
end else if (`FPSIZES == 3) begin
|
||||
end else if (P.FPSIZES == 3) begin
|
||||
always_comb begin
|
||||
case (Fmt)
|
||||
`FMT: BiasCorr = '0;
|
||||
`FMT1: BiasCorr = (`NE+2)'(`BIAS1-`BIAS);
|
||||
`FMT2: BiasCorr = (`NE+2)'(`BIAS2-`BIAS);
|
||||
P.FMT: BiasCorr = '0;
|
||||
P.FMT1: BiasCorr = (P.NE+2)'(P.BIAS1-P.BIAS);
|
||||
P.FMT2: BiasCorr = (P.NE+2)'(P.BIAS2-P.BIAS);
|
||||
default: BiasCorr = 'x;
|
||||
endcase
|
||||
end
|
||||
assign NormSumExp = PreNormSumExp+BiasCorr;
|
||||
end else if (`FPSIZES == 4) begin
|
||||
end else if (P.FPSIZES == 4) begin
|
||||
always_comb begin
|
||||
case (Fmt)
|
||||
2'h3: BiasCorr = '0;
|
||||
2'h1: BiasCorr = (`NE+2)'(`D_BIAS-`Q_BIAS);
|
||||
2'h0: BiasCorr = (`NE+2)'(`S_BIAS-`Q_BIAS);
|
||||
2'h2: BiasCorr = (`NE+2)'(`H_BIAS-`Q_BIAS);
|
||||
2'h1: BiasCorr = (P.NE+2)'(P.D_BIAS-P.Q_BIAS);
|
||||
2'h0: BiasCorr = (P.NE+2)'(P.S_BIAS-P.Q_BIAS);
|
||||
2'h2: BiasCorr = (P.NE+2)'(P.H_BIAS-P.Q_BIAS);
|
||||
endcase
|
||||
end
|
||||
assign NormSumExp = PreNormSumExp+BiasCorr;
|
||||
end
|
||||
|
||||
// determine if the result is subnormal: (NormSumExp <= 0) & (NormSumExp >= -FracLen) & ~FmaSZero
|
||||
if (`FPSIZES == 1) begin
|
||||
if (P.FPSIZES == 1) begin
|
||||
logic Sum0LEZ, Sum0GEFL;
|
||||
assign Sum0LEZ = PreNormSumExp[`NE+1] | ~|PreNormSumExp;
|
||||
assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF-2));
|
||||
assign Sum0LEZ = PreNormSumExp[P.NE+1] | ~|PreNormSumExp;
|
||||
assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF-2));
|
||||
assign FmaPreResultSubnorm = Sum0LEZ & Sum0GEFL & ~FmaSZero;
|
||||
end else if (`FPSIZES == 2) begin
|
||||
end else if (P.FPSIZES == 2) begin
|
||||
logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL;
|
||||
assign Sum0LEZ = PreNormSumExp[`NE+1] | ~|PreNormSumExp;
|
||||
assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF-2));
|
||||
assign Sum1LEZ = $signed(PreNormSumExp) <= $signed((`NE+2)'(`BIAS-`BIAS1));
|
||||
assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF1-2+`BIAS-`BIAS1)) | ~|PreNormSumExp;
|
||||
assign Sum0LEZ = PreNormSumExp[P.NE+1] | ~|PreNormSumExp;
|
||||
assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF-2));
|
||||
assign Sum1LEZ = $signed(PreNormSumExp) <= $signed((P.NE+2)'(P.BIAS-P.BIAS1));
|
||||
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;
|
||||
end else if (`FPSIZES == 3) begin
|
||||
end else if (P.FPSIZES == 3) begin
|
||||
logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL;
|
||||
assign Sum0LEZ = PreNormSumExp[`NE+1] | ~|PreNormSumExp;
|
||||
assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF-2));
|
||||
assign Sum1LEZ = $signed(PreNormSumExp) <= $signed((`NE+2)'(`BIAS-`BIAS1));
|
||||
assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF1-2+`BIAS-`BIAS1)) | ~|PreNormSumExp;
|
||||
assign Sum2LEZ = $signed(PreNormSumExp) <= $signed((`NE+2)'(`BIAS-`BIAS2));
|
||||
assign Sum2GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF2-2+`BIAS-`BIAS2)) | ~|PreNormSumExp;
|
||||
assign Sum0LEZ = PreNormSumExp[P.NE+1] | ~|PreNormSumExp;
|
||||
assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF-2));
|
||||
assign Sum1LEZ = $signed(PreNormSumExp) <= $signed((P.NE+2)'(P.BIAS-P.BIAS1));
|
||||
assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF1-2+P.BIAS-P.BIAS1)) | ~|PreNormSumExp;
|
||||
assign Sum2LEZ = $signed(PreNormSumExp) <= $signed((P.NE+2)'(P.BIAS-P.BIAS2));
|
||||
assign Sum2GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF2-2+P.BIAS-P.BIAS2)) | ~|PreNormSumExp;
|
||||
always_comb begin
|
||||
case (Fmt)
|
||||
`FMT: FmaPreResultSubnorm = Sum0LEZ & Sum0GEFL & ~FmaSZero;
|
||||
`FMT1: FmaPreResultSubnorm = Sum1LEZ & Sum1GEFL & ~FmaSZero;
|
||||
`FMT2: FmaPreResultSubnorm = Sum2LEZ & Sum2GEFL & ~FmaSZero;
|
||||
P.FMT: FmaPreResultSubnorm = Sum0LEZ & Sum0GEFL & ~FmaSZero;
|
||||
P.FMT1: FmaPreResultSubnorm = Sum1LEZ & Sum1GEFL & ~FmaSZero;
|
||||
P.FMT2: FmaPreResultSubnorm = Sum2LEZ & Sum2GEFL & ~FmaSZero;
|
||||
default: FmaPreResultSubnorm = 1'bx;
|
||||
endcase
|
||||
end
|
||||
end else if (`FPSIZES == 4) begin
|
||||
end else if (P.FPSIZES == 4) begin
|
||||
logic Sum0LEZ, Sum0GEFL, Sum1LEZ, Sum1GEFL, Sum2LEZ, Sum2GEFL, Sum3LEZ, Sum3GEFL;
|
||||
assign Sum0LEZ = PreNormSumExp[`NE+1] | ~|PreNormSumExp;
|
||||
assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`NF-2));
|
||||
assign Sum1LEZ = $signed(PreNormSumExp) <= $signed((`NE+2)'(`BIAS-`D_BIAS));
|
||||
assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`D_NF-2+`BIAS-`D_BIAS)) | ~|PreNormSumExp;
|
||||
assign Sum2LEZ = $signed(PreNormSumExp) <= $signed((`NE+2)'(`BIAS-`S_BIAS));
|
||||
assign Sum2GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`S_NF-2+`BIAS-`S_BIAS)) | ~|PreNormSumExp;
|
||||
assign Sum3LEZ = $signed(PreNormSumExp) <= $signed((`NE+2)'(`BIAS-`H_BIAS));
|
||||
assign Sum3GEFL = $signed(PreNormSumExp) >= $signed((`NE+2)'(-`H_NF-2+`BIAS-`H_BIAS)) | ~|PreNormSumExp;
|
||||
assign Sum0LEZ = PreNormSumExp[P.NE+1] | ~|PreNormSumExp;
|
||||
assign Sum0GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.NF-2));
|
||||
assign Sum1LEZ = $signed(PreNormSumExp) <= $signed((P.NE+2)'(P.BIAS-P.D_BIAS));
|
||||
assign Sum1GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.D_NF-2+P.BIAS-P.D_BIAS)) | ~|PreNormSumExp;
|
||||
assign Sum2LEZ = $signed(PreNormSumExp) <= $signed((P.NE+2)'(P.BIAS-P.S_BIAS));
|
||||
assign Sum2GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.S_NF-2+P.BIAS-P.S_BIAS)) | ~|PreNormSumExp;
|
||||
assign Sum3LEZ = $signed(PreNormSumExp) <= $signed((P.NE+2)'(P.BIAS-P.H_BIAS));
|
||||
assign Sum3GEFL = $signed(PreNormSumExp) >= $signed((P.NE+2)'(-P.H_NF-2+P.BIAS-P.H_BIAS)) | ~|PreNormSumExp;
|
||||
always_comb begin
|
||||
case (Fmt)
|
||||
2'h3: FmaPreResultSubnorm = Sum0LEZ & Sum0GEFL & ~FmaSZero;
|
||||
@ -132,6 +130,6 @@ module fmashiftcalc(
|
||||
// set and calculate the shift input and amount
|
||||
// - shift once if killing a product and the result is subnormal
|
||||
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;
|
||||
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;
|
||||
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*P.NF+5)-1:0]+($clog2(3*P.NF+5))'(P.NF+2)+BiasCorr[$clog2(3*P.NF+5)-1:0]: FmaSCnt+1;
|
||||
endmodule
|
||||
|
@ -25,26 +25,25 @@
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// 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 Int64, // is the integer input 64-bits
|
||||
input logic Plus1, // should one be added for rounding?
|
||||
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 [`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
|
||||
|
||||
// round and negate the positive res if needed
|
||||
assign CvtPreRes = {2'b0, Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`XLEN]}+{{`XLEN+1{1'b0}}, Plus1};
|
||||
mux2 #(`XLEN+2) resmux(CvtPreRes, -CvtPreRes, Xs, CvtNegRes);
|
||||
assign CvtPreRes = {2'b0, Shifted[P.NORMSHIFTSZ-1:P.NORMSHIFTSZ-P.XLEN]}+{{P.XLEN+1{1'b0}}, Plus1};
|
||||
mux2 #(P.XLEN+2) resmux(CvtPreRes, -CvtPreRes, Xs, CvtNegRes);
|
||||
|
||||
// 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);
|
||||
endmodule
|
@ -25,8 +25,6 @@
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
`include "wally-config.vh"
|
||||
|
||||
|
||||
// convert shift
|
||||
// fp -> int: | `XLEN zeros | Mantissa | 0's if nessisary | << CalcExp
|
||||
@ -72,10 +70,10 @@
|
||||
// | Nf 0's | Qm | << calculated shift amount
|
||||
// .
|
||||
|
||||
module normshift(
|
||||
input logic [`LOGNORMSHIFTSZ-1:0] ShiftAmt, // shift amount
|
||||
input logic [`NORMSHIFTSZ-1:0] ShiftIn, // number to be shifted
|
||||
output logic [`NORMSHIFTSZ-1:0] Shifted // shifted result
|
||||
module normshift import cvw::*; #(parameter cvw_t P) (
|
||||
input logic [P.LOGNORMSHIFTSZ-1:0] ShiftAmt, // shift amount
|
||||
input logic [P.NORMSHIFTSZ-1:0] ShiftIn, // number to be shifted
|
||||
output logic [P.NORMSHIFTSZ-1:0] Shifted // shifted result
|
||||
);
|
||||
|
||||
assign Shifted = ShiftIn << ShiftAmt;
|
||||
|
@ -26,14 +26,12 @@
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module postprocess (
|
||||
module postprocess import cvw::*; #(parameter cvw_t P) (
|
||||
// general signals
|
||||
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 [`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 XZero, YZero, // inputs are zero
|
||||
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 FmaPs, // the product's sign
|
||||
input logic FmaSs, // Sum sign
|
||||
input logic [`NE+1:0] FmaSe, // the sum's exponent
|
||||
input logic [3*`NF+3:0] FmaSm, // the positive sum
|
||||
input logic [P.NE+1:0] FmaSe, // the sum's exponent
|
||||
input logic [3*P.NF+3:0] FmaSm, // the positive sum
|
||||
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
|
||||
input logic DivSticky, // divider sticky bit
|
||||
input logic [`NE+1:0] DivQe, // divsqrt exponent
|
||||
input logic [`DIVb:0] DivQm, // divsqrt significand
|
||||
input logic [P.NE+1:0] DivQe, // divsqrt exponent
|
||||
input logic [P.DIVb:0] DivQm, // divsqrt significand
|
||||
// conversion signals
|
||||
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 [`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 [`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
|
||||
// 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 [`XLEN-1:0] FCvtIntRes // the integer conversion result
|
||||
output logic [P.XLEN-1:0] FCvtIntRes // the integer conversion result
|
||||
);
|
||||
|
||||
// general signals
|
||||
logic Rs; // result sign
|
||||
logic [`NF-1:0] Rf; // Result fraction
|
||||
logic [`NE-1:0] Re; // Result exponent
|
||||
logic [P.NF-1:0] Rf; // Result fraction
|
||||
logic [P.NE-1:0] Re; // Result exponent
|
||||
logic Ms; // norMalized sign
|
||||
logic [`CORRSHIFTSZ-1:0] Mf; // norMalized fraction
|
||||
logic [`NE+1:0] Me; // normalized exponent
|
||||
logic [`NE+1:0] FullRe; // Re with bits to determine sign and overflow
|
||||
logic [P.CORRSHIFTSZ-1:0] Mf; // norMalized fraction
|
||||
logic [P.NE+1:0] Me; // normalized exponent
|
||||
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 [`LOGNORMSHIFTSZ-1:0] ShiftAmt; // normalization shift amount
|
||||
logic [`NORMSHIFTSZ-1:0] ShiftIn; // input to normalization shift
|
||||
logic [`NORMSHIFTSZ-1:0] Shifted; // the ouput of the normalized shifter (before shift correction)
|
||||
logic [P.LOGNORMSHIFTSZ-1:0] ShiftAmt; // normalization shift amount
|
||||
logic [P.NORMSHIFTSZ-1:0] ShiftIn; // input to normalization shift
|
||||
logic [P.NORMSHIFTSZ-1:0] Shifted; // the ouput of the normalized shifter (before shift correction)
|
||||
logic Plus1; // add one to the final result?
|
||||
logic Overflow; // overflow flag used to select results
|
||||
logic Invalid; // invalid flag used to select results
|
||||
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
|
||||
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 [3*`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 [3*P.NF+5:0] FmaShiftIn; // fma shift input
|
||||
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 [$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
|
||||
logic [`LOGNORMSHIFTSZ-1:0] DivShiftAmt; // divsqrt shif amount
|
||||
logic [`NORMSHIFTSZ-1:0] DivShiftIn; // divsqrt shift input
|
||||
logic [`NE+1:0] Qe; // divsqrt corrected exponent after corretion shift
|
||||
logic [P.LOGNORMSHIFTSZ-1:0] DivShiftAmt; // divsqrt shif amount
|
||||
logic [P.NORMSHIFTSZ-1:0] DivShiftIn; // divsqrt shift input
|
||||
logic [P.NE+1:0] Qe; // divsqrt corrected exponent after corretion shift
|
||||
logic DivByZero; // divide by zero flag
|
||||
logic DivResSubnorm; // is the divsqrt result subnormal
|
||||
logic DivSubnormShiftPos; // is the divsqrt subnorm shift amout positive (not underflowed)
|
||||
// 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 [`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 IntInvalid; // invalid integer flag
|
||||
// readability signals
|
||||
@ -132,9 +130,9 @@ module postprocess (
|
||||
// choose the ouptut format depending on the opperation
|
||||
// - fp -> fp: OpCtrl contains the percision of the output
|
||||
// - otherwise: Fmt contains the percision of the output
|
||||
if (`FPSIZES == 2)
|
||||
assign OutFmt = IntToFp|~CvtOp ? Fmt : (OpCtrl[1:0] == `FMT);
|
||||
else if (`FPSIZES == 3 | `FPSIZES == 4)
|
||||
if (P.FPSIZES == 2)
|
||||
assign OutFmt = IntToFp|~CvtOp ? Fmt : (OpCtrl[1:0] == P.FMT);
|
||||
else if (P.FPSIZES == 3 | P.FPSIZES == 4)
|
||||
assign OutFmt = IntToFp|~CvtOp ? Fmt : OpCtrl[1:0];
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -142,40 +140,40 @@ module postprocess (
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// final claulations before shifting
|
||||
cvtshiftcalc cvtshiftcalc(.ToInt, .CvtCe, .CvtResSubnormUf, .Xm, .CvtLzcIn,
|
||||
cvtshiftcalc #(P) cvtshiftcalc(.ToInt, .CvtCe, .CvtResSubnormUf, .Xm, .CvtLzcIn,
|
||||
.XZero, .IntToFp, .OutFmt, .CvtResUf, .CvtShiftIn);
|
||||
|
||||
fmashiftcalc fmashiftcalc(.FmaSm, .FmaSCnt, .Fmt, .NormSumExp, .FmaSe,
|
||||
fmashiftcalc #(P) fmashiftcalc(.FmaSm, .FmaSCnt, .Fmt, .NormSumExp, .FmaSe,
|
||||
.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
|
||||
always_comb
|
||||
case(PostProcSel)
|
||||
2'b10: begin // fma
|
||||
ShiftAmt = {{`LOGNORMSHIFTSZ-$clog2(3*`NF+5){1'b0}}, FmaShiftAmt};
|
||||
ShiftIn = {FmaShiftIn, {`NORMSHIFTSZ-(3*`NF+6){1'b0}}};
|
||||
ShiftAmt = {{P.LOGNORMSHIFTSZ-$clog2(3*P.NF+5){1'b0}}, FmaShiftAmt};
|
||||
ShiftIn = {FmaShiftIn, {P.NORMSHIFTSZ-(3*P.NF+6){1'b0}}};
|
||||
end
|
||||
2'b00: begin // cvt
|
||||
ShiftAmt = {{`LOGNORMSHIFTSZ-$clog2(`CVTLEN+1){1'b0}}, CvtShiftAmt};
|
||||
ShiftIn = {CvtShiftIn, {`NORMSHIFTSZ-`CVTLEN-`NF-1{1'b0}}};
|
||||
ShiftAmt = {{P.LOGNORMSHIFTSZ-$clog2(P.CVTLEN+1){1'b0}}, CvtShiftAmt};
|
||||
ShiftIn = {CvtShiftIn, {P.NORMSHIFTSZ-P.CVTLEN-P.NF-1{1'b0}}};
|
||||
end
|
||||
2'b01: begin //divsqrt
|
||||
ShiftAmt = DivShiftAmt;
|
||||
ShiftIn = DivShiftIn;
|
||||
end
|
||||
default: begin
|
||||
ShiftAmt = {`LOGNORMSHIFTSZ{1'bx}};
|
||||
ShiftIn = {`NORMSHIFTSZ{1'bx}};
|
||||
ShiftAmt = {P.LOGNORMSHIFTSZ{1'bx}};
|
||||
ShiftIn = {P.NORMSHIFTSZ{1'bx}};
|
||||
end
|
||||
endcase
|
||||
|
||||
// main normalization shift
|
||||
normshift normshift (.ShiftIn, .ShiftAmt, .Shifted);
|
||||
normshift #(P) normshift (.ShiftIn, .ShiftAmt, .Shifted);
|
||||
|
||||
// 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);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -191,7 +189,7 @@ module postprocess (
|
||||
// calulate result sign used in rounding unit
|
||||
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,
|
||||
.DivSticky, .DivOp, .UfPlus1, .FullRe, .Rf, .Re, .Sticky, .Round, .Guard, .Me);
|
||||
|
||||
@ -206,7 +204,7 @@ module postprocess (
|
||||
// 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,
|
||||
.NaNIn, .FmaAs, .FmaPs, .Round, .IntInvalid, .DivByZero,
|
||||
.Guard, .Sticky, .UfPlus1, .CvtOp, .DivOp, .FmaOp, .FullRe, .Plus1,
|
||||
@ -216,9 +214,9 @@ module postprocess (
|
||||
// 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,
|
||||
.NaNIn, .IntToFp, .Int64, .Signed, .CvtOp, .FmaOp, .Plus1, .Invalid, .Overflow, .InfIn, .CvtNegRes,
|
||||
.XInf, .YInf, .DivOp, .DivByZero, .FullRe, .CvtCe, .Rs, .Re, .Rf, .PostProcRes, .FCvtIntRes);
|
||||
|
@ -26,8 +26,6 @@
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module resultsign(
|
||||
input logic [2:0] Frm, // rounding mode
|
||||
input logic FmaOp, // is the operation an Fma
|
||||
|
@ -26,42 +26,33 @@
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
// what position is XLEN in?
|
||||
// options:
|
||||
// 1: XLEN > NF > NF1
|
||||
// 2: NF > XLEN > NF1
|
||||
// 3: NF > NF1 > XLEN
|
||||
// single and double will always be smaller than XLEN
|
||||
`define XLENPOS ((`XLEN>`NF) ? 1 : (`XLEN>`NF1) ? 2 : 3)
|
||||
|
||||
module round(
|
||||
input logic [`FMTBITS-1:0] OutFmt, // output format
|
||||
module round import cvw::*; #(parameter cvw_t P) (
|
||||
input logic [P.FMTBITS-1:0] OutFmt, // output format
|
||||
input logic [2:0] Frm, // rounding mode
|
||||
input logic [1:0] PostProcSel, // select the postprocessor output
|
||||
input logic Ms, // normalized sign
|
||||
input logic [`CORRSHIFTSZ-1:0] Mf, // normalized fraction
|
||||
input logic [P.CORRSHIFTSZ-1:0] Mf, // normalized fraction
|
||||
// fma
|
||||
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
|
||||
// divsqrt
|
||||
input logic DivOp, // is a division opperation being done
|
||||
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
|
||||
input logic CvtOp, // is a convert opperation being done
|
||||
input logic ToInt, // is the cvt op a cvt to integer
|
||||
input logic CvtResSubnormUf, // is the cvt result subnormal or 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
|
||||
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 [`NE+1:0] FullRe, // Re with bits to determine sign and overflow
|
||||
output logic [`NE-1:0] Re, // Result exponent
|
||||
output logic [`NF-1:0] Rf, // Result fractionNormS
|
||||
output logic [P.NE+1:0] FullRe, // Re with bits to determine sign and overflow
|
||||
output logic [P.NE-1:0] Re, // Result exponent
|
||||
output logic [P.NF-1:0] Rf, // Result fractionNormS
|
||||
output logic Sticky, // sticky bit
|
||||
output logic Plus1, // do you add one to the final result
|
||||
output logic Round, Guard // bits needed to calculate rounding
|
||||
@ -69,7 +60,7 @@ module round(
|
||||
|
||||
logic UfCalcPlus1; // calculated plus one for unbounded exponent
|
||||
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 IntRes; // is the result an integer
|
||||
logic FpGuard, FpRound; // floating point round/guard bits
|
||||
@ -77,7 +68,16 @@ module round(
|
||||
logic LsbRes; // lsb of result
|
||||
logic CalcPlus1; // calculated plus1
|
||||
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
|
||||
@ -115,68 +115,68 @@ module round(
|
||||
assign FpRes = ~IntRes;
|
||||
|
||||
// sticky bit calculation
|
||||
if (`FPSIZES == 1) begin
|
||||
if (P.FPSIZES == 1) begin
|
||||
|
||||
// 1: XLEN > NF
|
||||
// | XLEN |
|
||||
// | NF |1|1|
|
||||
// ^ ^ if floating point result
|
||||
// ^ if not an FMA result
|
||||
if (`XLENPOS == 1)assign NormSticky = (|Mf[`CORRSHIFTSZ-`NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes) |
|
||||
(|Mf[`CORRSHIFTSZ-`XLEN-2:0]);
|
||||
if (XLENPOS == 1)assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.NF-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.XLEN-2:0]);
|
||||
// 2: NF > XLEN
|
||||
if (`XLENPOS == 2)assign NormSticky = (|Mf[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF-1]&IntRes) |
|
||||
(|Mf[`CORRSHIFTSZ-`NF-2:0]);
|
||||
if (XLENPOS == 2)assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.XLEN-2:P.CORRSHIFTSZ-P.NF-1]&IntRes) |
|
||||
(|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
|
||||
// so half and single are always smaller then XLEN
|
||||
|
||||
// 1: XLEN > NF > NF1
|
||||
if (`XLENPOS == 1) assign NormSticky = (|Mf[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&FpRes&~OutFmt) |
|
||||
(|Mf[`CORRSHIFTSZ-`NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes) |
|
||||
(|Mf[`CORRSHIFTSZ-`XLEN-2:0]);
|
||||
if (XLENPOS == 1) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.NF1-2:P.CORRSHIFTSZ-P.NF-1]&FpRes&~OutFmt) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.NF-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.XLEN-2:0]);
|
||||
// 2: NF > XLEN > NF1
|
||||
if (`XLENPOS == 2) assign NormSticky = (|Mf[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&~OutFmt) |
|
||||
(|Mf[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF-1]&(IntRes|~OutFmt)) |
|
||||
(|Mf[`CORRSHIFTSZ-`NF-2:0]);
|
||||
if (XLENPOS == 2) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.NF1-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes&~OutFmt) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.XLEN-2:P.CORRSHIFTSZ-P.NF-1]&(IntRes|~OutFmt)) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.NF-2:0]);
|
||||
// 3: NF > NF1 > XLEN
|
||||
if (`XLENPOS == 3) assign NormSticky = (|Mf[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF1-1]&IntRes) |
|
||||
(|Mf[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&(~OutFmt|IntRes)) |
|
||||
(|Mf[`CORRSHIFTSZ-`NF-2:0]);
|
||||
if (XLENPOS == 3) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.XLEN-2:P.CORRSHIFTSZ-P.NF1-1]&IntRes) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.NF1-2:P.CORRSHIFTSZ-P.NF-1]&(~OutFmt|IntRes)) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.NF-2:0]);
|
||||
|
||||
end else if (`FPSIZES == 3) begin
|
||||
end else if (P.FPSIZES == 3) begin
|
||||
// 1: XLEN > NF > NF1
|
||||
if (`XLENPOS == 1) assign NormSticky = (|Mf[`CORRSHIFTSZ-`NF2-2:`CORRSHIFTSZ-`NF1-1]&FpRes&(OutFmt==`FMT1)) |
|
||||
(|Mf[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&FpRes&~(OutFmt==`FMT)) |
|
||||
(|Mf[`CORRSHIFTSZ-`NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes) |
|
||||
(|Mf[`CORRSHIFTSZ-`XLEN-2:0]);
|
||||
if (XLENPOS == 1) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.NF2-2:P.CORRSHIFTSZ-P.NF1-1]&FpRes&(OutFmt==P.FMT1)) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.NF1-2:P.CORRSHIFTSZ-P.NF-1]&FpRes&~(OutFmt==P.FMT)) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.NF-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.XLEN-2:0]);
|
||||
// 2: NF > XLEN > NF1
|
||||
if (`XLENPOS == 2) assign NormSticky = (|Mf[`CORRSHIFTSZ-`NF2-2:`CORRSHIFTSZ-`NF1-1]&FpRes&(OutFmt==`FMT1)) |
|
||||
(|Mf[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&~(OutFmt==`FMT)) |
|
||||
(|Mf[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF-1]&(IntRes|~(OutFmt==`FMT))) |
|
||||
(|Mf[`CORRSHIFTSZ-`NF-2:0]);
|
||||
if (XLENPOS == 2) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.NF2-2:P.CORRSHIFTSZ-P.NF1-1]&FpRes&(OutFmt==P.FMT1)) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.NF1-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes&~(OutFmt==P.FMT)) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.XLEN-2:P.CORRSHIFTSZ-P.NF-1]&(IntRes|~(OutFmt==P.FMT))) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.NF-2:0]);
|
||||
// 3: NF > NF1 > XLEN
|
||||
if (`XLENPOS == 3) assign NormSticky = (|Mf[`CORRSHIFTSZ-`NF2-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&(OutFmt==`FMT1)) |
|
||||
(|Mf[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`NF1-1]&((OutFmt==`FMT1)|IntRes)) |
|
||||
(|Mf[`CORRSHIFTSZ-`NF1-2:`CORRSHIFTSZ-`NF-1]&(~(OutFmt==`FMT)|IntRes)) |
|
||||
(|Mf[`CORRSHIFTSZ-`NF-2:0]);
|
||||
if (XLENPOS == 3) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.NF2-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes&(OutFmt==P.FMT1)) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.XLEN-2:P.CORRSHIFTSZ-P.NF1-1]&((OutFmt==P.FMT1)|IntRes)) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.NF1-2:P.CORRSHIFTSZ-P.NF-1]&(~(OutFmt==P.FMT)|IntRes)) |
|
||||
(|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
|
||||
// 2: NF > XLEN > NF1
|
||||
if (`XLENPOS == 2) assign NormSticky = (|Mf[`CORRSHIFTSZ-`H_NF-2:`CORRSHIFTSZ-`S_NF-1]&FpRes&(OutFmt==`H_FMT)) |
|
||||
(|Mf[`CORRSHIFTSZ-`S_NF-2:`CORRSHIFTSZ-`D_NF-1]&FpRes&((OutFmt==`S_FMT)|(OutFmt==`H_FMT))) |
|
||||
(|Mf[`CORRSHIFTSZ-`D_NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&~(OutFmt==`Q_FMT)) |
|
||||
(|Mf[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`Q_NF-1]&(~(OutFmt==`Q_FMT)|IntRes)) |
|
||||
(|Mf[`CORRSHIFTSZ-`Q_NF-2:0]);
|
||||
if (XLENPOS == 2) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.H_NF-2:P.CORRSHIFTSZ-P.S_NF-1]&FpRes&(OutFmt==P.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[P.CORRSHIFTSZ-P.D_NF-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes&~(OutFmt==P.Q_FMT)) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.XLEN-2:P.CORRSHIFTSZ-P.Q_NF-1]&(~(OutFmt==P.Q_FMT)|IntRes)) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.Q_NF-2:0]);
|
||||
// 3: NF > NF1 > XLEN
|
||||
// The extra XLEN bit will be ored later when caculating the final sticky bit - the ufplus1 not needed for integer
|
||||
if (`XLENPOS == 3) assign NormSticky = (|Mf[`CORRSHIFTSZ-`H_NF-2:`CORRSHIFTSZ-`S_NF-1]&FpRes&(OutFmt==`H_FMT)) |
|
||||
(|Mf[`CORRSHIFTSZ-`S_NF-2:`CORRSHIFTSZ-`XLEN-1]&FpRes&((OutFmt==`S_FMT)|(OutFmt==`H_FMT))) |
|
||||
(|Mf[`CORRSHIFTSZ-`XLEN-2:`CORRSHIFTSZ-`D_NF-1]&((OutFmt==`S_FMT)|(OutFmt==`H_FMT)|IntRes)) |
|
||||
(|Mf[`CORRSHIFTSZ-`D_NF-2:`CORRSHIFTSZ-`Q_NF-1]&(~(OutFmt==`Q_FMT)|IntRes)) |
|
||||
(|Mf[`CORRSHIFTSZ-`Q_NF-2:0]);
|
||||
if (XLENPOS == 3) assign NormSticky = (|Mf[P.CORRSHIFTSZ-P.H_NF-2:P.CORRSHIFTSZ-P.S_NF-1]&FpRes&(OutFmt==P.H_FMT)) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.S_NF-2:P.CORRSHIFTSZ-P.XLEN-1]&FpRes&((OutFmt==P.S_FMT)|(OutFmt==P.H_FMT))) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.XLEN-2:P.CORRSHIFTSZ-P.D_NF-1]&((OutFmt==P.S_FMT)|(OutFmt==P.H_FMT)|IntRes)) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.D_NF-2:P.CORRSHIFTSZ-P.Q_NF-1]&(~(OutFmt==P.Q_FMT)|IntRes)) |
|
||||
(|Mf[P.CORRSHIFTSZ-P.Q_NF-2:0]);
|
||||
|
||||
end
|
||||
|
||||
@ -184,40 +184,40 @@ module round(
|
||||
|
||||
// only add the Addend sticky if doing an FMA opperation
|
||||
// - the shifter shifts too far left when there's an underflow (shifting out all possible sticky bits)
|
||||
assign 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
|
||||
// - underflow round bit is used to determint the underflow flag
|
||||
if (`FPSIZES == 1) begin
|
||||
assign FpGuard = Mf[`CORRSHIFTSZ-`NF-1];
|
||||
assign FpLsbRes = Mf[`CORRSHIFTSZ-`NF];
|
||||
assign FpRound = Mf[`CORRSHIFTSZ-`NF-2];
|
||||
if (P.FPSIZES == 1) begin
|
||||
assign FpGuard = Mf[P.CORRSHIFTSZ-P.NF-1];
|
||||
assign FpLsbRes = Mf[P.CORRSHIFTSZ-P.NF];
|
||||
assign FpRound = Mf[P.CORRSHIFTSZ-P.NF-2];
|
||||
|
||||
end else if (`FPSIZES == 2) begin
|
||||
assign FpGuard = OutFmt ? Mf[`CORRSHIFTSZ-`NF-1] : Mf[`CORRSHIFTSZ-`NF1-1];
|
||||
assign FpLsbRes = OutFmt ? Mf[`CORRSHIFTSZ-`NF] : Mf[`CORRSHIFTSZ-`NF1];
|
||||
assign FpRound = OutFmt ? Mf[`CORRSHIFTSZ-`NF-2] : Mf[`CORRSHIFTSZ-`NF1-2];
|
||||
end else if (P.FPSIZES == 2) begin
|
||||
assign FpGuard = OutFmt ? Mf[P.CORRSHIFTSZ-P.NF-1] : Mf[P.CORRSHIFTSZ-P.NF1-1];
|
||||
assign FpLsbRes = OutFmt ? Mf[P.CORRSHIFTSZ-P.NF] : Mf[P.CORRSHIFTSZ-P.NF1];
|
||||
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
|
||||
case (OutFmt)
|
||||
`FMT: begin
|
||||
FpGuard = Mf[`CORRSHIFTSZ-`NF-1];
|
||||
FpLsbRes = Mf[`CORRSHIFTSZ-`NF];
|
||||
FpRound = Mf[`CORRSHIFTSZ-`NF-2];
|
||||
P.FMT: begin
|
||||
FpGuard = Mf[P.CORRSHIFTSZ-P.NF-1];
|
||||
FpLsbRes = Mf[P.CORRSHIFTSZ-P.NF];
|
||||
FpRound = Mf[P.CORRSHIFTSZ-P.NF-2];
|
||||
end
|
||||
`FMT1: begin
|
||||
FpGuard = Mf[`CORRSHIFTSZ-`NF1-1];
|
||||
FpLsbRes = Mf[`CORRSHIFTSZ-`NF1];
|
||||
FpRound = Mf[`CORRSHIFTSZ-`NF1-2];
|
||||
P.FMT1: begin
|
||||
FpGuard = Mf[P.CORRSHIFTSZ-P.NF1-1];
|
||||
FpLsbRes = Mf[P.CORRSHIFTSZ-P.NF1];
|
||||
FpRound = Mf[P.CORRSHIFTSZ-P.NF1-2];
|
||||
end
|
||||
`FMT2: begin
|
||||
FpGuard = Mf[`CORRSHIFTSZ-`NF2-1];
|
||||
FpLsbRes = Mf[`CORRSHIFTSZ-`NF2];
|
||||
FpRound = Mf[`CORRSHIFTSZ-`NF2-2];
|
||||
P.FMT2: begin
|
||||
FpGuard = Mf[P.CORRSHIFTSZ-P.NF2-1];
|
||||
FpLsbRes = Mf[P.CORRSHIFTSZ-P.NF2];
|
||||
FpRound = Mf[P.CORRSHIFTSZ-P.NF2-2];
|
||||
end
|
||||
default: begin
|
||||
FpGuard = 1'bx;
|
||||
@ -225,35 +225,35 @@ module round(
|
||||
FpRound = 1'bx;
|
||||
end
|
||||
endcase
|
||||
end else if (`FPSIZES == 4) begin
|
||||
end else if (P.FPSIZES == 4) begin
|
||||
always_comb
|
||||
case (OutFmt)
|
||||
2'h3: begin
|
||||
FpGuard = Mf[`CORRSHIFTSZ-`Q_NF-1];
|
||||
FpLsbRes = Mf[`CORRSHIFTSZ-`Q_NF];
|
||||
FpRound = Mf[`CORRSHIFTSZ-`Q_NF-2];
|
||||
FpGuard = Mf[P.CORRSHIFTSZ-P.Q_NF-1];
|
||||
FpLsbRes = Mf[P.CORRSHIFTSZ-P.Q_NF];
|
||||
FpRound = Mf[P.CORRSHIFTSZ-P.Q_NF-2];
|
||||
end
|
||||
2'h1: begin
|
||||
FpGuard = Mf[`CORRSHIFTSZ-`D_NF-1];
|
||||
FpLsbRes = Mf[`CORRSHIFTSZ-`D_NF];
|
||||
FpRound = Mf[`CORRSHIFTSZ-`D_NF-2];
|
||||
FpGuard = Mf[P.CORRSHIFTSZ-P.D_NF-1];
|
||||
FpLsbRes = Mf[P.CORRSHIFTSZ-P.D_NF];
|
||||
FpRound = Mf[P.CORRSHIFTSZ-P.D_NF-2];
|
||||
end
|
||||
2'h0: begin
|
||||
FpGuard = Mf[`CORRSHIFTSZ-`S_NF-1];
|
||||
FpLsbRes = Mf[`CORRSHIFTSZ-`S_NF];
|
||||
FpRound = Mf[`CORRSHIFTSZ-`S_NF-2];
|
||||
FpGuard = Mf[P.CORRSHIFTSZ-P.S_NF-1];
|
||||
FpLsbRes = Mf[P.CORRSHIFTSZ-P.S_NF];
|
||||
FpRound = Mf[P.CORRSHIFTSZ-P.S_NF-2];
|
||||
end
|
||||
2'h2: begin
|
||||
FpGuard = Mf[`CORRSHIFTSZ-`H_NF-1];
|
||||
FpLsbRes = Mf[`CORRSHIFTSZ-`H_NF];
|
||||
FpRound = Mf[`CORRSHIFTSZ-`H_NF-2];
|
||||
FpGuard = Mf[P.CORRSHIFTSZ-P.H_NF-1];
|
||||
FpLsbRes = Mf[P.CORRSHIFTSZ-P.H_NF];
|
||||
FpRound = Mf[P.CORRSHIFTSZ-P.H_NF-2];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
assign Guard = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN-1] : FpGuard;
|
||||
assign LsbRes = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN] : FpLsbRes;
|
||||
assign Round = ToInt&CvtOp ? Mf[`CORRSHIFTSZ-`XLEN-2] : FpRound;
|
||||
assign Guard = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN-1] : FpGuard;
|
||||
assign LsbRes = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN] : FpLsbRes;
|
||||
assign Round = ToInt&CvtOp ? Mf[P.CORRSHIFTSZ-P.XLEN-2] : FpRound;
|
||||
|
||||
|
||||
always_comb begin
|
||||
@ -287,26 +287,26 @@ module round(
|
||||
|
||||
|
||||
// place Plus1 into the proper position for the format
|
||||
if (`FPSIZES == 1) begin
|
||||
assign RoundAdd = {{`FLEN{1'b0}}, FpPlus1};
|
||||
if (P.FPSIZES == 1) begin
|
||||
assign RoundAdd = {{P.FLEN{1'b0}}, FpPlus1};
|
||||
|
||||
end else if (`FPSIZES == 2) begin
|
||||
end else if (P.FPSIZES == 2) begin
|
||||
// \/FLEN+1
|
||||
// | NE+2 | NF |
|
||||
// '-NE+2-^----NF1----^
|
||||
// `FLEN+1-`NE-2-`NF1 = FLEN-1-NE-NF1
|
||||
assign RoundAdd = {(`NE+1+`NF1)'(0), FpPlus1&~OutFmt, (`NF-`NF1-1)'(0), FpPlus1&OutFmt};
|
||||
// P.FLEN+1-P.NE-2-P.NF1 = FLEN-1-NE-NF1
|
||||
assign RoundAdd = {(P.NE+1+P.NF1)'(0), FpPlus1&~OutFmt, (P.NF-P.NF1-1)'(0), FpPlus1&OutFmt};
|
||||
|
||||
end else if (`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)};
|
||||
end else if (P.FPSIZES == 3) begin
|
||||
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)
|
||||
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)};
|
||||
end else if (P.FPSIZES == 4)
|
||||
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
|
||||
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
|
||||
case(PostProcSel)
|
||||
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 = Qe; // divide
|
||||
default: Me = '0;
|
||||
@ -325,7 +325,7 @@ module round(
|
||||
// round the result
|
||||
// - if the fraction overflows one should be added to the exponent
|
||||
assign {FullRe, Rf} = {Me, RoundFrac} + RoundAdd;
|
||||
assign Re = FullRe[`NE-1:0];
|
||||
assign Re = FullRe[P.NE-1:0];
|
||||
|
||||
|
||||
endmodule
|
||||
|
@ -25,7 +25,6 @@
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
`include "wally-config.vh"
|
||||
|
||||
module roundsign(
|
||||
input logic Xs, // x sign
|
||||
|
@ -26,53 +26,51 @@
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module shiftcorrection(
|
||||
input logic [`NORMSHIFTSZ-1:0] Shifted, // the shifted sum before LZA correction
|
||||
module shiftcorrection import cvw::*; #(parameter cvw_t P) (
|
||||
input logic [P.NORMSHIFTSZ-1:0] Shifted, // the shifted sum before LZA correction
|
||||
// divsqrt
|
||||
input logic DivOp, // is it a divsqrt opperation
|
||||
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)
|
||||
//fma
|
||||
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 FmaSZero,
|
||||
// output
|
||||
output logic [`NE+1:0] FmaMe, // exponent of the normalized sum
|
||||
output logic [`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] FmaMe, // exponent of the normalized sum
|
||||
output logic [P.CORRSHIFTSZ-1:0] Mf, // the shifted sum before LZA correction
|
||||
output logic [P.NE+1:0] Qe // corrected exponent for divider
|
||||
);
|
||||
|
||||
logic [3*`NF+3:0] CorrSumShifted; // the shifted sum after LZA correction
|
||||
logic [`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 [3*P.NF+3:0] CorrSumShifted; // the shifted sum after LZA correction
|
||||
logic [P.CORRSHIFTSZ-1:0] CorrQm0, CorrQm1; // portions of Shifted to select for CorrQmShifted
|
||||
logic [P.CORRSHIFTSZ-1:0] CorrQmShifted; // the shifted divsqrt result after one bit shift
|
||||
logic ResSubnorm; // is the result Subnormal
|
||||
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
|
||||
|
||||
// LZA correction
|
||||
assign LZAPlus1 = Shifted[`NORMSHIFTSZ-1];
|
||||
assign LZAPlus1 = Shifted[P.NORMSHIFTSZ-1];
|
||||
|
||||
// correct the shifting error caused by the LZA
|
||||
// - 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
|
||||
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
|
||||
// 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 CorrQm0 = Shifted[`NORMSHIFTSZ-3:`NORMSHIFTSZ-`CORRSHIFTSZ-2];
|
||||
assign CorrQm1 = Shifted[`NORMSHIFTSZ-2:`NORMSHIFTSZ-`CORRSHIFTSZ-1];
|
||||
mux2 #(`CORRSHIFTSZ) divcorrmux(CorrQm0, CorrQm1, LeftShiftQm, CorrQmShifted);
|
||||
assign CorrQm0 = Shifted[P.NORMSHIFTSZ-3:P.NORMSHIFTSZ-P.CORRSHIFTSZ-2];
|
||||
assign CorrQm1 = Shifted[P.NORMSHIFTSZ-2:P.NORMSHIFTSZ-P.CORRSHIFTSZ-1];
|
||||
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
|
||||
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 Mf = Shifted[`NORMSHIFTSZ-1:`NORMSHIFTSZ-`CORRSHIFTSZ];
|
||||
else Mf = Shifted[P.NORMSHIFTSZ-1:P.NORMSHIFTSZ-P.CORRSHIFTSZ];
|
||||
|
||||
// Determine sum's exponent
|
||||
// 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 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
|
||||
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
|
||||
// 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
|
@ -26,14 +26,12 @@
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module specialcase(
|
||||
module specialcase import cvw::*; #(parameter cvw_t P) (
|
||||
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 [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 NaNIn, // are any input NaNs
|
||||
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 Rs, // the result's sign
|
||||
input logic Invalid, Overflow, // flags to choose the result
|
||||
input logic [`NE-1:0] Re, // Result exponent
|
||||
input logic [`NE+1:0] FullRe, // Result full exponent
|
||||
input logic [`NF-1:0] Rf, // Result fraction
|
||||
input logic [P.NE-1:0] Re, // Result exponent
|
||||
input logic [P.NE+1:0] FullRe, // Result full exponent
|
||||
input logic [P.NF-1:0] Rf, // Result fraction
|
||||
// fma
|
||||
input logic FmaOp, // is it a fma opperation
|
||||
// divsqrt
|
||||
@ -55,23 +53,23 @@ module specialcase(
|
||||
input logic IntToFp, // is cvt int -> fp opperation
|
||||
input logic Int64, // is the integer 64 bits
|
||||
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 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
|
||||
output logic [`FLEN-1:0] PostProcRes,// final result
|
||||
output logic [`XLEN-1:0] FCvtIntRes // final integer result
|
||||
output logic [P.FLEN-1:0] PostProcRes,// final result
|
||||
output logic [P.XLEN-1:0] FCvtIntRes // final integer result
|
||||
);
|
||||
|
||||
logic [`FLEN-1:0] XNaNRes; // X is NaN result
|
||||
logic [`FLEN-1:0] YNaNRes; // Y is NaN result
|
||||
logic [`FLEN-1:0] ZNaNRes; // Z is NaN result
|
||||
logic [`FLEN-1:0] InvalidRes; // Invalid result result
|
||||
logic [`FLEN-1:0] UfRes; // underflowed result result
|
||||
logic [`FLEN-1:0] OfRes; // overflowed result result
|
||||
logic [`FLEN-1:0] NormRes; // normal result
|
||||
logic [`XLEN-1:0] OfIntRes; // the overflow result for integer output
|
||||
logic [P.FLEN-1:0] XNaNRes; // X is NaN result
|
||||
logic [P.FLEN-1:0] YNaNRes; // Y is NaN result
|
||||
logic [P.FLEN-1:0] ZNaNRes; // Z is NaN result
|
||||
logic [P.FLEN-1:0] InvalidRes; // Invalid result result
|
||||
logic [P.FLEN-1:0] UfRes; // underflowed result result
|
||||
logic [P.FLEN-1:0] OfRes; // overflowed result result
|
||||
logic [P.FLEN-1:0] NormRes; // normal result
|
||||
logic [P.XLEN-1:0] OfIntRes; // the overflow result for integer output
|
||||
logic OfResMax; // does the of result output maximum norm fp number
|
||||
logic KillRes; // kill the result for underflow
|
||||
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));
|
||||
|
||||
// select correct outputs for special cases
|
||||
if (`FPSIZES == 1) begin
|
||||
if (P.FPSIZES == 1) begin
|
||||
//NaN res selection depending on standard
|
||||
if(`IEEE754) begin
|
||||
assign XNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Xm[`NF-2:0]};
|
||||
assign YNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Ym[`NF-2:0]};
|
||||
assign ZNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Zm[`NF-2:0]};
|
||||
assign InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}};
|
||||
if(P.IEEE754) begin
|
||||
assign XNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]};
|
||||
assign YNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Ym[P.NF-2:0]};
|
||||
assign ZNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Zm[P.NF-2:0]};
|
||||
assign InvalidRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
|
||||
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
|
||||
|
||||
assign OfRes = OfResMax ? {Rs, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {Rs, {`NE{1'b1}}, {`NF{1'b0}}};
|
||||
assign UfRes = {Rs, {`FLEN-2{1'b0}}, Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
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, {P.FLEN-2{1'b0}}, Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
assign NormRes = {Rs, Re, Rf};
|
||||
|
||||
end else if (`FPSIZES == 2) begin
|
||||
if(`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 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 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 InvalidRes = OutFmt ? {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)};
|
||||
end else if (P.FPSIZES == 2) begin
|
||||
if(P.IEEE754) begin
|
||||
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, {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, {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, {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
|
||||
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
|
||||
|
||||
always_comb
|
||||
if(OutFmt)
|
||||
if(OfResMax) OfRes = {Rs, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}};
|
||||
else OfRes = {Rs, {`NE{1'b1}}, {`NF{1'b0}}};
|
||||
if(OfResMax) OfRes = {Rs, {P.NE-1{1'b1}}, 1'b0, {P.NF{1'b1}}};
|
||||
else OfRes = {Rs, {P.NE{1'b1}}, {P.NF{1'b0}}};
|
||||
else
|
||||
if(OfResMax) OfRes = {{`FLEN-`LEN1{1'b1}}, Rs, {`NE1-1{1'b1}}, 1'b0, {`NF1{1'b1}}};
|
||||
else OfRes = {{`FLEN-`LEN1{1'b1}}, Rs, {`NE1{1'b1}}, (`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 NormRes = OutFmt ? {Rs, Re, Rf} : {{`FLEN-`LEN1{1'b1}}, Rs, Re[`NE1-1:0], Rf[`NF-1:`NF-`NF1]};
|
||||
if(OfResMax) OfRes = {{P.FLEN-P.LEN1{1'b1}}, Rs, {P.NE1-1{1'b1}}, 1'b0, {P.NF1{1'b1}}};
|
||||
else OfRes = {{P.FLEN-P.LEN1{1'b1}}, Rs, {P.NE1{1'b1}}, (P.NF1)'(0)};
|
||||
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} : {{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
|
||||
case (OutFmt)
|
||||
`FMT: begin
|
||||
if(`IEEE754) begin
|
||||
XNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Xm[`NF-2:0]};
|
||||
YNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Ym[`NF-2:0]};
|
||||
ZNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Zm[`NF-2:0]};
|
||||
InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}};
|
||||
P.FMT: begin
|
||||
if(P.IEEE754) begin
|
||||
XNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]};
|
||||
YNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Ym[P.NF-2:0]};
|
||||
ZNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Zm[P.NF-2:0]};
|
||||
InvalidRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
|
||||
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
|
||||
|
||||
OfRes = OfResMax ? {Rs, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {Rs, {`NE{1'b1}}, {`NF{1'b0}}};
|
||||
UfRes = {Rs, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
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, (P.FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
NormRes = {Rs, Re, Rf};
|
||||
end
|
||||
`FMT1: begin
|
||||
if(`IEEE754) begin
|
||||
XNaNRes = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, Xm[`NF-2:`NF-`NF1]};
|
||||
YNaNRes = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, Ym[`NF-2:`NF-`NF1]};
|
||||
ZNaNRes = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, Zm[`NF-2:`NF-`NF1]};
|
||||
InvalidRes = {{`FLEN-`LEN1{1'b1}}, 1'b0, {`NE1{1'b1}}, 1'b1, (`NF1-1)'(0)};
|
||||
P.FMT1: begin
|
||||
if(P.IEEE754) begin
|
||||
XNaNRes = {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.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 = {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, Zm[P.NF-2:P.NF-P.NF1]};
|
||||
InvalidRes = {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, (P.NF1-1)'(0)};
|
||||
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
|
||||
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)};
|
||||
UfRes = {{`FLEN-`LEN1{1'b1}}, Rs, (`LEN1-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
NormRes = {{`FLEN-`LEN1{1'b1}}, Rs, Re[`NE1-1:0], Rf[`NF-1:`NF-`NF1]};
|
||||
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 = {{P.FLEN-P.LEN1{1'b1}}, Rs, (P.LEN1-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
NormRes = {{P.FLEN-P.LEN1{1'b1}}, Rs, Re[P.NE1-1:0], Rf[P.NF-1:P.NF-P.NF1]};
|
||||
end
|
||||
`FMT2: begin
|
||||
if(`IEEE754) begin
|
||||
XNaNRes = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, Xm[`NF-2:`NF-`NF2]};
|
||||
YNaNRes = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, Ym[`NF-2:`NF-`NF2]};
|
||||
ZNaNRes = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, Zm[`NF-2:`NF-`NF2]};
|
||||
InvalidRes = {{`FLEN-`LEN2{1'b1}}, 1'b0, {`NE2{1'b1}}, 1'b1, (`NF2-1)'(0)};
|
||||
P.FMT2: begin
|
||||
if(P.IEEE754) begin
|
||||
XNaNRes = {{P.FLEN-P.LEN2{1'b1}}, 1'b0, {P.NE2{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.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 = {{P.FLEN-P.LEN2{1'b1}}, 1'b0, {P.NE2{1'b1}}, 1'b1, Zm[P.NF-2:P.NF-P.NF2]};
|
||||
InvalidRes = {{P.FLEN-P.LEN2{1'b1}}, 1'b0, {P.NE2{1'b1}}, 1'b1, (P.NF2-1)'(0)};
|
||||
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
|
||||
|
||||
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)};
|
||||
UfRes = {{`FLEN-`LEN2{1'b1}}, Rs, (`LEN2-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
NormRes = {{`FLEN-`LEN2{1'b1}}, Rs, Re[`NE2-1:0], Rf[`NF-1:`NF-`NF2]};
|
||||
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 = {{P.FLEN-P.LEN2{1'b1}}, Rs, (P.LEN2-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
NormRes = {{P.FLEN-P.LEN2{1'b1}}, Rs, Re[P.NE2-1:0], Rf[P.NF-1:P.NF-P.NF2]};
|
||||
end
|
||||
default: begin
|
||||
if(`IEEE754) begin
|
||||
XNaNRes = (`FLEN)'(0);
|
||||
YNaNRes = (`FLEN)'(0);
|
||||
ZNaNRes = (`FLEN)'(0);
|
||||
InvalidRes = (`FLEN)'(0);
|
||||
if(P.IEEE754) begin
|
||||
XNaNRes = (P.FLEN)'(0);
|
||||
YNaNRes = (P.FLEN)'(0);
|
||||
ZNaNRes = (P.FLEN)'(0);
|
||||
InvalidRes = (P.FLEN)'(0);
|
||||
end else begin
|
||||
InvalidRes = (`FLEN)'(0);
|
||||
InvalidRes = (P.FLEN)'(0);
|
||||
end
|
||||
OfRes = (`FLEN)'(0);
|
||||
UfRes = (`FLEN)'(0);
|
||||
NormRes = (`FLEN)'(0);
|
||||
OfRes = (P.FLEN)'(0);
|
||||
UfRes = (P.FLEN)'(0);
|
||||
NormRes = (P.FLEN)'(0);
|
||||
end
|
||||
endcase
|
||||
|
||||
end else if (`FPSIZES == 4) begin
|
||||
end else if (P.FPSIZES == 4) begin
|
||||
always_comb
|
||||
case (OutFmt)
|
||||
2'h3: begin
|
||||
if(`IEEE754) begin
|
||||
XNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Xm[`NF-2:0]};
|
||||
YNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Ym[`NF-2:0]};
|
||||
ZNaNRes = {1'b0, {`NE{1'b1}}, 1'b1, Zm[`NF-2:0]};
|
||||
InvalidRes = {1'b0, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}};
|
||||
if(P.IEEE754) begin
|
||||
XNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]};
|
||||
YNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Ym[P.NF-2:0]};
|
||||
ZNaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, Zm[P.NF-2:0]};
|
||||
InvalidRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
|
||||
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
|
||||
|
||||
OfRes = OfResMax ? {Rs, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} : {Rs, {`NE{1'b1}}, {`NF{1'b0}}};
|
||||
UfRes = {Rs, (`FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
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, (P.FLEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
NormRes = {Rs, Re, Rf};
|
||||
end
|
||||
2'h1: begin
|
||||
if(`IEEE754) begin
|
||||
XNaNRes = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, Xm[`NF-2:`NF-`D_NF]};
|
||||
YNaNRes = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, Ym[`NF-2:`NF-`D_NF]};
|
||||
ZNaNRes = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, Zm[`NF-2:`NF-`D_NF]};
|
||||
InvalidRes = {{`FLEN-`D_LEN{1'b1}}, 1'b0, {`D_NE{1'b1}}, 1'b1, (`D_NF-1)'(0)};
|
||||
if(P.IEEE754) begin
|
||||
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 = {{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 = {{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 = {{P.FLEN-P.D_LEN{1'b1}}, 1'b0, {P.D_NE{1'b1}}, 1'b1, (P.D_NF-1)'(0)};
|
||||
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
|
||||
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)};
|
||||
UfRes = {{`FLEN-`D_LEN{1'b1}}, Rs, (`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]};
|
||||
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 = {{P.FLEN-P.D_LEN{1'b1}}, Rs, (P.D_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
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
|
||||
2'h0: begin
|
||||
if(`IEEE754) begin
|
||||
XNaNRes = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, Xm[`NF-2:`NF-`S_NF]};
|
||||
YNaNRes = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, Ym[`NF-2:`NF-`S_NF]};
|
||||
ZNaNRes = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, Zm[`NF-2:`NF-`S_NF]};
|
||||
InvalidRes = {{`FLEN-`S_LEN{1'b1}}, 1'b0, {`S_NE{1'b1}}, 1'b1, (`S_NF-1)'(0)};
|
||||
if(P.IEEE754) begin
|
||||
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 = {{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 = {{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 = {{P.FLEN-P.S_LEN{1'b1}}, 1'b0, {P.S_NE{1'b1}}, 1'b1, (P.S_NF-1)'(0)};
|
||||
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
|
||||
|
||||
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)};
|
||||
UfRes = {{`FLEN-`S_LEN{1'b1}}, Rs, (`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]};
|
||||
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 = {{P.FLEN-P.S_LEN{1'b1}}, Rs, (P.S_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
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
|
||||
2'h2: begin
|
||||
if(`IEEE754) begin
|
||||
XNaNRes = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, Xm[`NF-2:`NF-`H_NF]};
|
||||
YNaNRes = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, Ym[`NF-2:`NF-`H_NF]};
|
||||
ZNaNRes = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, Zm[`NF-2:`NF-`H_NF]};
|
||||
InvalidRes = {{`FLEN-`H_LEN{1'b1}}, 1'b0, {`H_NE{1'b1}}, 1'b1, (`H_NF-1)'(0)};
|
||||
if(P.IEEE754) begin
|
||||
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 = {{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 = {{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 = {{P.FLEN-P.H_LEN{1'b1}}, 1'b0, {P.H_NE{1'b1}}, 1'b1, (P.H_NF-1)'(0)};
|
||||
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
|
||||
|
||||
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
|
||||
UfRes = {{`FLEN-`H_LEN{1'b1}}, Rs, (`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]};
|
||||
UfRes = {{P.FLEN-P.H_LEN{1'b1}}, Rs, (P.H_LEN-2)'(0), Plus1&Frm[1]&~(DivOp&YInf)};
|
||||
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
|
||||
endcase
|
||||
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
|
||||
// - 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
|
||||
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
|
||||
assign SelOfRes = Overflow|DivByZero|(InfIn&~(YInf&DivOp));
|
||||
|
||||
// output infinity with result sign if divide by zero
|
||||
if(`IEEE754)
|
||||
if(P.IEEE754)
|
||||
always_comb
|
||||
if(XNaN&~(IntToFp&CvtOp)) PostProcRes = XNaNRes;
|
||||
else if(YNaN&~CvtOp) PostProcRes = YNaNRes;
|
||||
@ -283,14 +281,14 @@ module specialcase(
|
||||
always_comb
|
||||
if(Signed)
|
||||
if(Xs&~NaNIn) // signed negitive
|
||||
if(Int64) OfIntRes = {1'b1, {`XLEN-1{1'b0}}};
|
||||
else OfIntRes = {{`XLEN-32{1'b1}}, 1'b1, {31{1'b0}}};
|
||||
if(Int64) OfIntRes = {1'b1, {P.XLEN-1{1'b0}}};
|
||||
else OfIntRes = {{P.XLEN-32{1'b1}}, 1'b1, {31{1'b0}}};
|
||||
else // signed positive
|
||||
if(Int64) OfIntRes = {1'b0, {`XLEN-1{1'b1}}};
|
||||
else OfIntRes = {{`XLEN-32{1'b0}}, 1'b0, {31{1'b1}}};
|
||||
if(Int64) OfIntRes = {1'b0, {P.XLEN-1{1'b1}}};
|
||||
else OfIntRes = {{P.XLEN-32{1'b0}}, 1'b0, {31{1'b1}}};
|
||||
else
|
||||
if(Xs&~NaNIn) OfIntRes = {`XLEN{1'b0}}; // unsigned negitive
|
||||
else OfIntRes = {`XLEN{1'b1}}; // unsigned positive
|
||||
if(Xs&~NaNIn) OfIntRes = {P.XLEN{1'b0}}; // unsigned negitive
|
||||
else OfIntRes = {P.XLEN{1'b1}}; // unsigned positive
|
||||
|
||||
|
||||
// select the integer output
|
||||
@ -301,9 +299,9 @@ module specialcase(
|
||||
// - otherwise output the normal res (trmined and sign extended if nessisary)
|
||||
always_comb
|
||||
if(IntInvalid) FCvtIntRes = OfIntRes;
|
||||
else if(CvtCe[`NE])
|
||||
if(Xs&Signed&Plus1) FCvtIntRes = {{`XLEN{1'b1}}};
|
||||
else FCvtIntRes = {{`XLEN-1{1'b0}}, Plus1};
|
||||
else if(Int64) FCvtIntRes = CvtNegRes[`XLEN-1:0];
|
||||
else FCvtIntRes = {{`XLEN-32{CvtNegRes[31]}}, CvtNegRes[31:0]};
|
||||
else if(CvtCe[P.NE])
|
||||
if(Xs&Signed&Plus1) FCvtIntRes = {{P.XLEN{1'b1}}};
|
||||
else FCvtIntRes = {{P.XLEN-1{1'b0}}, Plus1};
|
||||
else if(Int64) FCvtIntRes = CvtNegRes[P.XLEN-1:0];
|
||||
else FCvtIntRes = {{P.XLEN-32{CvtNegRes[31]}}, CvtNegRes[31:0]};
|
||||
endmodule
|
Loading…
Reference in New Issue
Block a user