forked from Github_Repos/cvw
fixed various bugs
This commit is contained in:
parent
57e484cd55
commit
fdfc0dbf46
@ -35,14 +35,14 @@ module add(r[105:0], s[105:0], t[157:0], sum[157:0],
|
|||||||
wire [157:0] sum0; // sum of compound adder +0 mode
|
wire [157:0] sum0; // sum of compound adder +0 mode
|
||||||
wire [157:0] sum1; // sum of compound adder +1 mode
|
wire [157:0] sum1; // sum of compound adder +1 mode
|
||||||
|
|
||||||
// Invert addend if necessary
|
// Invert addend if z's sign is diffrent from the product's sign
|
||||||
|
|
||||||
assign t2 = invz ? -t : t;
|
assign t2 = invz ? -t : t;
|
||||||
|
|
||||||
// Zero out product if Z >> product or product really should be zero
|
// Zero out product if Z >> product or product really should be zero
|
||||||
|
|
||||||
assign r2 = ~proddenorm & killprod ? 106'b0 : r;
|
assign r2 = killprod ? 106'b0 : r;
|
||||||
assign s2 = ~proddenorm & killprod ? 106'b0 : s;
|
assign s2 = killprod ? 106'b0 : s;
|
||||||
|
|
||||||
// Compound adder
|
// Compound adder
|
||||||
// Consists of 3:2 CSA followed by long compound CPA
|
// Consists of 3:2 CSA followed by long compound CPA
|
||||||
|
@ -15,17 +15,17 @@ module align(z[51:0], ae[12:0], aligncnt, xzero, yzero, zzero, zdenorm, proddeno
|
|||||||
killprod, bypsel[1], bypplus1, byppostnorm);
|
killprod, bypsel[1], bypplus1, byppostnorm);
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
input [51:0] z; // Fraction of addend z;
|
input [51:0] z; // Fraction of addend z;
|
||||||
input [12:0] ae; // sign of exponent of addend z;
|
input [12:0] ae; // sign of exponent of addend z;
|
||||||
input [11:0] aligncnt; // amount to shift
|
input [11:0] aligncnt; // amount to shift
|
||||||
input xzero; // Input X = 0
|
input xzero; // Input X = 0
|
||||||
input yzero; // Input Y = 0
|
input yzero; // Input Y = 0
|
||||||
input zzero; // Input Z = 0
|
input zzero; // Input Z = 0
|
||||||
input zdenorm; // Input Z = denorm
|
input zdenorm; // Input Z is denormalized
|
||||||
input proddenorm;
|
input proddenorm; // product is denormalized
|
||||||
input [1:1] bypsel; // Select bypass to X or Z
|
input [1:1] bypsel; // Select bypass to X or Z
|
||||||
input bypplus1; // Add one to bypassed result
|
input bypplus1; // Add one to bypassed result
|
||||||
input byppostnorm; // Postnormalize bypassed result
|
input byppostnorm; // Postnormalize bypassed result
|
||||||
output [157:0] t; // aligned addend (54 bits left of bpt)
|
output [157:0] t; // aligned addend (54 bits left of bpt)
|
||||||
output bs; // sticky bit of addend
|
output bs; // sticky bit of addend
|
||||||
output ps; // sticky bit of product
|
output ps; // sticky bit of product
|
||||||
@ -34,13 +34,13 @@ module align(z[51:0], ae[12:0], aligncnt, xzero, yzero, zzero, zdenorm, proddeno
|
|||||||
// Internal nodes
|
// Internal nodes
|
||||||
|
|
||||||
reg [157:0] t; // aligned addend from shifter
|
reg [157:0] t; // aligned addend from shifter
|
||||||
reg killprod; // Z >> product
|
reg killprod; // Z >> product
|
||||||
reg bs; // sticky bit of addend
|
reg bs; // sticky bit of addend
|
||||||
reg ps; // sticky bit of product
|
reg ps; // sticky bit of product
|
||||||
reg [7:0] i; // temp storage for finding sticky bit
|
reg [7:0] i; // temp storage for finding sticky bit
|
||||||
wire [52:0] z1; // Z plus 1
|
wire [52:0] z1; // Z plus 1
|
||||||
wire [51:0] z2; // Z selected after handling rounds
|
wire [51:0] z2; // Z selected after handling rounds
|
||||||
wire [11:0] align104; // alignment count + 104
|
wire [11:0] align104; // alignment count + 104
|
||||||
|
|
||||||
// Increment fraction of Z by one if necessary for prerounded bypass
|
// Increment fraction of Z by one if necessary for prerounded bypass
|
||||||
// This incrementor delay is masked by the alignment count computation
|
// This incrementor delay is masked by the alignment count computation
|
||||||
@ -56,7 +56,7 @@ module align(z[51:0], ae[12:0], aligncnt, xzero, yzero, zzero, zdenorm, proddeno
|
|||||||
// addend on right shifts. Handle special cases of shifting
|
// addend on right shifts. Handle special cases of shifting
|
||||||
// by too much.
|
// by too much.
|
||||||
|
|
||||||
always @(z2 or aligncnt or align104 or zzero or xzero or yzero or zdenorm)
|
always @(z2 or aligncnt or align104 or zzero or xzero or yzero or zdenorm or proddenorm)
|
||||||
begin
|
begin
|
||||||
|
|
||||||
// Default to clearing sticky bits
|
// Default to clearing sticky bits
|
||||||
@ -66,7 +66,7 @@ module align(z[51:0], ae[12:0], aligncnt, xzero, yzero, zzero, zdenorm, proddeno
|
|||||||
// And to using product as primary operand in adder I exponent gen
|
// And to using product as primary operand in adder I exponent gen
|
||||||
killprod = 0;
|
killprod = 0;
|
||||||
|
|
||||||
if(zzero) begin
|
if(zzero) begin // if z = 0
|
||||||
t = 158'b0;
|
t = 158'b0;
|
||||||
if (xzero || yzero) killprod = 1;
|
if (xzero || yzero) killprod = 1;
|
||||||
end else if ((aligncnt > 53 && ~aligncnt[11]) || xzero || yzero) begin
|
end else if ((aligncnt > 53 && ~aligncnt[11]) || xzero || yzero) begin
|
||||||
@ -75,8 +75,8 @@ module align(z[51:0], ae[12:0], aligncnt, xzero, yzero, zzero, zdenorm, proddeno
|
|||||||
t = {53'b0, ~zzero, z2, 52'b0};
|
t = {53'b0, ~zzero, z2, 52'b0};
|
||||||
killprod = 1;
|
killprod = 1;
|
||||||
ps = ~xzero && ~yzero;
|
ps = ~xzero && ~yzero;
|
||||||
end else if ((ae[12] && align104[11])) begin //***fix the if statement
|
end else if ((ae[12] && align104[11]) && ~proddenorm) begin //***fix the if statement
|
||||||
// KEP if the multiplier's exponent overflows
|
// KEP if the multiplier's exponent overflows
|
||||||
t = {53'b0, ~zzero, z2, 52'b0};
|
t = {53'b0, ~zzero, z2, 52'b0};
|
||||||
killprod = 1;
|
killprod = 1;
|
||||||
ps = ~xzero && ~yzero;
|
ps = ~xzero && ~yzero;
|
||||||
@ -85,7 +85,7 @@ module align(z[51:0], ae[12:0], aligncnt, xzero, yzero, zzero, zdenorm, proddeno
|
|||||||
t = 0;
|
t = 0;
|
||||||
end else if (~aligncnt[11]) begin // Left shift by reasonable amount
|
end else if (~aligncnt[11]) begin // Left shift by reasonable amount
|
||||||
t = {53'b0, ~zzero, z2, 52'b0} << aligncnt;
|
t = {53'b0, ~zzero, z2, 52'b0} << aligncnt;
|
||||||
end else begin // Otherwise right shift
|
end else begin // Otherwise right shift
|
||||||
t = {53'b0, ~zzero, z2, 52'b0} >> -aligncnt;
|
t = {53'b0, ~zzero, z2, 52'b0} >> -aligncnt;
|
||||||
|
|
||||||
// use some behavioral code to find sticky bit. This is really
|
// use some behavioral code to find sticky bit. This is really
|
||||||
|
@ -19,7 +19,7 @@ module expgen(x[62:52], y[62:52], z[62:52],
|
|||||||
earlyres[62:52], earlyressel, bypsel[1], byppostnorm,
|
earlyres[62:52], earlyressel, bypsel[1], byppostnorm,
|
||||||
killprod, sumzero, postnormalize, normcnt, infinity,
|
killprod, sumzero, postnormalize, normcnt, infinity,
|
||||||
invalid, overflow, underflow, inf,
|
invalid, overflow, underflow, inf,
|
||||||
nan, xnan, ynan, znan, zdenorm, specialsel,
|
nan, xnan, ynan, znan, zdenorm, proddenorm, specialsel,
|
||||||
aligncnt, w[62:52], wbypass[62:52],
|
aligncnt, w[62:52], wbypass[62:52],
|
||||||
prodof, sumof, sumuf, denorm0, ae[12:0]);
|
prodof, sumof, sumuf, denorm0, ae[12:0]);
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
@ -28,36 +28,37 @@ module expgen(x[62:52], y[62:52], z[62:52],
|
|||||||
input [62:52] y; // Exponent of multiplicand y
|
input [62:52] y; // Exponent of multiplicand y
|
||||||
input [62:52] z; // Exponent of addend z
|
input [62:52] z; // Exponent of addend z
|
||||||
input [62:52] earlyres; // Result from other FPU block
|
input [62:52] earlyres; // Result from other FPU block
|
||||||
input earlyressel; // Select result from other block
|
input earlyressel; // Select result from other block
|
||||||
input [1:1] bypsel; // Bypass X or Z
|
input [1:1] bypsel; // Bypass X or Z
|
||||||
input byppostnorm; // Postnormalize bypassed result
|
input byppostnorm; // Postnormalize bypassed result
|
||||||
input killprod; // Z >> product
|
input killprod; // Z >> product
|
||||||
input sumzero; // sum exactly equals zero
|
input sumzero; // sum exactly equals zero
|
||||||
input postnormalize; // postnormalize rounded result
|
input postnormalize; // postnormalize rounded result
|
||||||
input [8:0] normcnt; // normalization shift count
|
input [8:0] normcnt; // normalization shift count
|
||||||
input infinity; // generate infinity on overflow
|
input infinity; // generate infinity on overflow
|
||||||
input invalid; // Result invalid
|
input invalid; // Result invalid
|
||||||
input overflow; // Result overflowed
|
input overflow; // Result overflowed
|
||||||
input underflow; // Result underflowed
|
input underflow; // Result underflowed
|
||||||
input inf; // Some input is infinity
|
input inf; // Some input is infinity
|
||||||
input nan; // Some input is NaN
|
input nan; // Some input is NaN
|
||||||
input xnan; // X is NaN
|
input xnan; // X is NaN
|
||||||
input ynan; // Y is NaN
|
input ynan; // Y is NaN
|
||||||
input znan; // Z is NaN
|
input znan; // Z is NaN
|
||||||
input zdenorm; // Z is denorm
|
input zdenorm; // Z is denorm
|
||||||
input specialsel; // Select special result
|
input proddenorm; // product is denorm
|
||||||
|
input specialsel; // Select special result
|
||||||
output [11:0] aligncnt; // shift count for alignment shifter
|
output [11:0] aligncnt; // shift count for alignment shifter
|
||||||
output [62:52] w; // Exponent of result
|
output [62:52] w; // Exponent of result
|
||||||
output [62:52] wbypass; // Prerounded exponent for bypass
|
output [62:52] wbypass; // Prerounded exponent for bypass
|
||||||
output prodof; // X*Y exponent out of bounds
|
output prodof; // X*Y exponent out of bounds
|
||||||
output sumof; // X*Y+Z exponent out of bounds
|
output sumof; // X*Y+Z exponent out of bounds
|
||||||
output sumuf; // X*Y+Z exponent underflows
|
output sumuf; // X*Y+Z exponent underflows
|
||||||
output denorm0; // exponent = 0 for denorm
|
output denorm0; // exponent = 0 for denorm
|
||||||
output [12:0] ae; //exponent of multiply
|
output [12:0] ae; //exponent of multiply
|
||||||
|
|
||||||
// Internal nodes
|
// Internal nodes
|
||||||
|
|
||||||
wire [12:0] aetmp; // Exponent of Multiply
|
|
||||||
wire [12:0] aligncnt0; // Shift count for alignment
|
wire [12:0] aligncnt0; // Shift count for alignment
|
||||||
wire [12:0] aligncnt1; // Shift count for alignment
|
wire [12:0] aligncnt1; // Shift count for alignment
|
||||||
wire [12:0] be; // Exponent of multiply
|
wire [12:0] be; // Exponent of multiply
|
||||||
@ -72,9 +73,11 @@ module expgen(x[62:52], y[62:52], z[62:52],
|
|||||||
// Note that the exponent does not have to be incremented on a postrounding
|
// Note that the exponent does not have to be incremented on a postrounding
|
||||||
// normalization of X because the mantissa was already increased. Report
|
// normalization of X because the mantissa was already increased. Report
|
||||||
// if exponent is out of bounds
|
// if exponent is out of bounds
|
||||||
assign ae = x + y - 1023;
|
|
||||||
|
|
||||||
assign prodof = (ae > 2046 && ~ae[12] && ~killprod);
|
|
||||||
|
assign ae = x + y - 1023;
|
||||||
|
|
||||||
|
assign prodof = (ae > 2046 && ~ae[12]);
|
||||||
|
|
||||||
// Compute alignment shift count
|
// Compute alignment shift count
|
||||||
// Adjust for postrounding normalization of Z.
|
// Adjust for postrounding normalization of Z.
|
||||||
@ -82,8 +85,10 @@ module expgen(x[62:52], y[62:52], z[62:52],
|
|||||||
// check if a round overflows is shorter than the actual round and
|
// check if a round overflows is shorter than the actual round and
|
||||||
// is masked by the bypass mux and two 10 bit adder delays.
|
// is masked by the bypass mux and two 10 bit adder delays.
|
||||||
|
|
||||||
assign aligncnt0 = z - ae[10:0] + 13'b0;
|
assign aligncnt0 = z - ae + 13'b0;// KEP use all of ae
|
||||||
assign aligncnt1 = z - ae[10:0] + 13'b1;
|
assign aligncnt1 = z - ae + 13'b1;
|
||||||
|
//assign aligncnt0 = z - ae[10:0] + 13'b0;//original
|
||||||
|
//assign aligncnt1 = z - ae[10:0] + 13'b1;
|
||||||
assign aligncnt = bypsel[1] && byppostnorm ? aligncnt1 : aligncnt0;
|
assign aligncnt = bypsel[1] && byppostnorm ? aligncnt1 : aligncnt0;
|
||||||
|
|
||||||
// Select exponent (usually from product except in case of huge addend)
|
// Select exponent (usually from product except in case of huge addend)
|
||||||
@ -118,13 +123,17 @@ module expgen(x[62:52], y[62:52], z[62:52],
|
|||||||
// rounding mode. NaNs are propagated or generated.
|
// rounding mode. NaNs are propagated or generated.
|
||||||
|
|
||||||
assign specialres = earlyressel ? earlyres :
|
assign specialres = earlyressel ? earlyres :
|
||||||
invalid ? nanres :
|
invalid | nan ? nanres : // KEP added nan
|
||||||
overflow ? infinityres :
|
overflow ? infinityres :
|
||||||
inf ? 11'b11111111111 :
|
inf ? 11'b11111111111 :
|
||||||
underflow ? 11'b0 : 11'bx;
|
underflow ? 11'b0 : 11'bx;
|
||||||
|
|
||||||
assign infinityres = infinity ? 11'b11111111111 : 11'b11111111110;
|
assign infinityres = infinity ? 11'b11111111111 : 11'b11111111110;
|
||||||
|
|
||||||
|
// IEEE 754-2008 section 6.2.3 states:
|
||||||
|
// "If two or more inputs are NaN, then the payload of the resulting NaN should be
|
||||||
|
// identical to the payload of one of the input NaNs if representable in the destination
|
||||||
|
// format. This standard does not specify which of the input NaNs will provide the payload."
|
||||||
assign nanres = xnan ? x : (ynan ? y : (znan? z : 11'b11111111111));
|
assign nanres = xnan ? x : (ynan ? y : (znan? z : 11'b11111111111));
|
||||||
|
|
||||||
// A mux selects the early result from other FPU blocks or the
|
// A mux selects the early result from other FPU blocks or the
|
||||||
|
@ -13,31 +13,31 @@ module flag(xnan, ynan, znan, xinf, yinf, zinf, prodof, sumof, sumuf,
|
|||||||
inf, nan, invalid, overflow, underflow, inexact);
|
inf, nan, invalid, overflow, underflow, inexact);
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
input xnan; // X is NaN
|
input xnan; // X is NaN
|
||||||
input ynan; // Y is NaN
|
input ynan; // Y is NaN
|
||||||
input znan; // Z is NaN
|
input znan; // Z is NaN
|
||||||
input xinf; // X is Inf
|
input xinf; // X is Inf
|
||||||
input yinf; // Y is Inf
|
input yinf; // Y is Inf
|
||||||
input zinf; // Z is Inf
|
input zinf; // Z is Inf
|
||||||
input prodof; // X*Y overflows exponent
|
input prodof; // X*Y overflows exponent
|
||||||
input sumof; // X*Y + z underflows exponent
|
input sumof; // X*Y + z underflows exponent
|
||||||
input sumuf; // X*Y + z underflows exponent
|
input sumuf; // X*Y + z underflows exponent
|
||||||
input psign; // Sign of product
|
input psign; // Sign of product
|
||||||
input zsign; // Sign of z
|
input zsign; // Sign of z
|
||||||
input xzero; // x = 0
|
input xzero; // x = 0
|
||||||
input yzero; // y = 0
|
input yzero; // y = 0
|
||||||
input [1:0] v; // R and S bits of result
|
input [1:0] v; // R and S bits of result
|
||||||
output inf; // Some source is Inf
|
output inf; // Some source is Inf
|
||||||
output nan; // Some source is NaN
|
output nan; // Some source is NaN
|
||||||
output invalid; // Result is invalid
|
output invalid; // Result is invalid
|
||||||
output overflow; // Result overflowed
|
output overflow; // Result overflowed
|
||||||
output underflow; // Result underflowed
|
output underflow; // Result underflowed
|
||||||
output inexact; // Result is not an exact number
|
output inexact; // Result is not an exact number
|
||||||
|
|
||||||
// Internal nodes
|
// Internal nodes
|
||||||
|
|
||||||
wire prodinf; // X*Y larger than max possible
|
wire prodinf; // X*Y larger than max possible
|
||||||
wire suminf; // X*Y+Z larger than max possible
|
wire suminf; // X*Y+Z larger than max possible
|
||||||
|
|
||||||
// If any input is NaN, propagate the NaN
|
// If any input is NaN, propagate the NaN
|
||||||
|
|
||||||
@ -46,12 +46,14 @@ module flag(xnan, ynan, znan, xinf, yinf, zinf, prodof, sumof, sumuf,
|
|||||||
// Same with infinity (inf - inf and O * inf don't propagate inf
|
// Same with infinity (inf - inf and O * inf don't propagate inf
|
||||||
// but it's ok becaue illegal op takes higher precidence)
|
// but it's ok becaue illegal op takes higher precidence)
|
||||||
|
|
||||||
assign inf= xinf || yinf || zinf;
|
assign inf= xinf || yinf || zinf || suminf;//KEP added suminf
|
||||||
|
//assign inf= xinf || yinf || zinf;//original
|
||||||
|
|
||||||
// Generate infinity checks
|
// Generate infinity checks
|
||||||
|
|
||||||
assign prodinf = prodof && ~xnan && ~ynan;
|
assign prodinf = prodof && ~xnan && ~ynan;
|
||||||
assign suminf = sumof && ~xnan && ~ynan && ~znan;
|
//KEP added if the product is infinity then sum is infinity
|
||||||
|
assign suminf = prodinf | sumof && ~xnan && ~ynan && ~znan;
|
||||||
|
|
||||||
// Set invalid flag for following cases:
|
// Set invalid flag for following cases:
|
||||||
// 1) Inf - Inf
|
// 1) Inf - Inf
|
||||||
@ -59,8 +61,7 @@ module flag(xnan, ynan, znan, xinf, yinf, zinf, prodof, sumof, sumuf,
|
|||||||
// 3) Output = NaN (this is not part of the IEEE spec, only 486 proj)
|
// 3) Output = NaN (this is not part of the IEEE spec, only 486 proj)
|
||||||
|
|
||||||
assign invalid = (xinf || yinf || prodinf) && zinf && (psign ^ zsign) ||
|
assign invalid = (xinf || yinf || prodinf) && zinf && (psign ^ zsign) ||
|
||||||
xzero && yinf || yzero && xinf ||
|
xzero && yinf || yzero && xinf;// KEP remove case 3) above
|
||||||
nan;
|
|
||||||
|
|
||||||
// Set the overflow flag for the following cases:
|
// Set the overflow flag for the following cases:
|
||||||
// 1) Rounded multiply result would be out of bounds
|
// 1) Rounded multiply result would be out of bounds
|
||||||
|
@ -103,7 +103,7 @@ module fmac(xrf, y, zrf, rn, rz, rp, rm,
|
|||||||
earlyres[62:52], earlyressel, bypsel[1], byppostnorm,
|
earlyres[62:52], earlyressel, bypsel[1], byppostnorm,
|
||||||
killprod, sumzero, postnorrnalize, normcnt,
|
killprod, sumzero, postnorrnalize, normcnt,
|
||||||
infinity, invalid, overflow, underflow,
|
infinity, invalid, overflow, underflow,
|
||||||
inf, nan, xnan, ynan, znan, zdenorm, specialsel,
|
inf, nan, xnan, ynan, znan, zdenorm, proddenorm, specialsel,
|
||||||
aligncnt, w[62:52], wbypass[62:52],
|
aligncnt, w[62:52], wbypass[62:52],
|
||||||
prodof, sumof, sumuf, denorm0, ae);
|
prodof, sumof, sumuf, denorm0, ae);
|
||||||
// Instantiate special case detection across datapath & exponent path
|
// Instantiate special case detection across datapath & exponent path
|
||||||
@ -120,7 +120,7 @@ assign wbypass[63] = w[63];
|
|||||||
// Instantiate control logic
|
// Instantiate control logic
|
||||||
|
|
||||||
sign sign(x[63], y[63], z[63], negsum0, negsum1, bs, ps,
|
sign sign(x[63], y[63], z[63], negsum0, negsum1, bs, ps,
|
||||||
killprod, rm, sumzero, nan, invalid, xinf, yinf, inf,
|
killprod, rm, overflow, sumzero, nan, invalid, xinf, yinf, zinf, inf,
|
||||||
w[63], invz, negsum, selsum1, psign);
|
w[63], invz, negsum, selsum1, psign);
|
||||||
flag flag(xnan, ynan, znan, xinf, yinf, zinf, prodof, sumof, sumuf,
|
flag flag(xnan, ynan, znan, xinf, yinf, zinf, prodof, sumof, sumuf,
|
||||||
psign, z[63], xzero, yzero, v[1:0],
|
psign, z[63], xzero, yzero, v[1:0],
|
||||||
|
@ -18,12 +18,12 @@ module normalize(sum[157:0], normcnt, sumzero, bs, ps, denorm0, zdenorm, v[53:0]
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
input [157:0] sum; // sum
|
input [157:0] sum; // sum
|
||||||
input [8:0] normcnt; // normalization shift count
|
input [8:0] normcnt; // normalization shift count
|
||||||
input sumzero; // sum is zero
|
input sumzero; // sum is zero
|
||||||
input bs; // sticky bit for addend
|
input bs; // sticky bit for addend
|
||||||
input ps; // sticky bit for product
|
input ps; // sticky bit for product
|
||||||
input denorm0; // exponent = -1023
|
input denorm0; // exponent = -1023
|
||||||
input zdenorm; // Input Z is denormalized
|
input zdenorm; // Input Z is denormalized
|
||||||
output [53:0] v; // normalized sum, R, S bits
|
output [53:0] v; // normalized sum, R, S bits
|
||||||
|
|
||||||
// Internal nodes
|
// Internal nodes
|
||||||
|
|
||||||
|
@ -19,37 +19,37 @@ module round(v[53:0], earlyres[51:0], earlyressel, rz, rn, rp, rm, wsign,
|
|||||||
w[51:0], postnormalize, infinity, specialsel);
|
w[51:0], postnormalize, infinity, specialsel);
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
input [53:0] v; // normalized sum, R, S bits
|
input [53:0] v; // normalized sum, R, S bits
|
||||||
input [51:0] earlyres; // result from other FPU blocks
|
input [51:0] earlyres; // result from other FPU blocks
|
||||||
input earlyressel; // use result from other FPU blocks
|
input earlyressel; // use result from other FPU blocks
|
||||||
input rz; // Round toward zero
|
input rz; // Round toward zero
|
||||||
input rn; // Round toward nearest
|
input rn; // Round toward nearest
|
||||||
input rp; // Round toward plus infinity
|
input rp; // Round toward plus infinity
|
||||||
input rm; // Round toward minus infinity
|
input rm; // Round toward minus infinity
|
||||||
input wsign; // Sign of result
|
input wsign; // Sign of result
|
||||||
input invalid; // Trap on infinity, NaN, denorm
|
input invalid; // Trap on infinity, NaN, denorm
|
||||||
input overflow; // Result overflowed
|
input overflow; // Result overflowed
|
||||||
input underflow; // Result underflowed
|
input underflow; // Result underflowed
|
||||||
input inf; // Some input is infinity
|
input inf; // Some input is infinity
|
||||||
input nan; // Some input is NaN
|
input nan; // Some input is NaN
|
||||||
input xnan; // X is NaN
|
input xnan; // X is NaN
|
||||||
input ynan; // Y is NaN
|
input ynan; // Y is NaN
|
||||||
input znan; // Z is NaN
|
input znan; // Z is NaN
|
||||||
input [51:0] x; // Input X
|
input [51:0] x; // Input X
|
||||||
input [51:0] y; // Input Y
|
input [51:0] y; // Input Y
|
||||||
input [51:0] z; // Input Z
|
input [51:0] z; // Input Z
|
||||||
output [51:0] w; // rounded result of FMAC
|
output [51:0] w; // rounded result of FMAC
|
||||||
output postnormalize; // Right shift 1 for post-rounding norm
|
output postnormalize; // Right shift 1 for post-rounding norm
|
||||||
output infinity; // Generate infinity on overflow
|
output infinity; // Generate infinity on overflow
|
||||||
output specialsel; // Select special result
|
output specialsel; // Select special result
|
||||||
|
|
||||||
// Internal nodes
|
// Internal nodes
|
||||||
|
|
||||||
wire plus1; // Round by adding one
|
wire plus1; // Round by adding one
|
||||||
wire [52:0] v1; // Result + 1 (for rounding)
|
wire [52:0] v1; // Result + 1 (for rounding)
|
||||||
wire [51:0] specialres; // Result of exceptional case
|
wire [51:0] specialres; // Result of exceptional case
|
||||||
wire [51:0] infinityres; // Infinity or largest real number
|
wire [51:0] infinityres; // Infinity or largest real number
|
||||||
wire [51:0] nanres; // Propagated or generated NaN
|
wire [51:0] nanres; // Propagated or generated NaN
|
||||||
|
|
||||||
// Compute if round should occur. This equation is derived from
|
// Compute if round should occur. This equation is derived from
|
||||||
// the rounding tables.
|
// the rounding tables.
|
||||||
@ -77,7 +77,7 @@ module round(v[53:0], earlyres[51:0], earlyressel, rz, rn, rp, rm, wsign,
|
|||||||
assign specialsel = earlyressel || overflow || underflow || invalid ||
|
assign specialsel = earlyressel || overflow || underflow || invalid ||
|
||||||
nan || inf;
|
nan || inf;
|
||||||
assign specialres = earlyressel ? earlyres :
|
assign specialres = earlyressel ? earlyres :
|
||||||
invalid ? nanres :
|
invalid | nan ? nanres : //KEP added nan
|
||||||
overflow ? infinityres :
|
overflow ? infinityres :
|
||||||
inf ? 52'b0 :
|
inf ? 52'b0 :
|
||||||
underflow ? 52'b0 : 52'bx; // default to undefined
|
underflow ? 52'b0 : 52'bx; // default to undefined
|
||||||
@ -93,6 +93,11 @@ module round(v[53:0], earlyres[51:0], earlyressel, rz, rn, rp, rm, wsign,
|
|||||||
// NaN inputs are already quiet, we don't have to force them quiet.
|
// NaN inputs are already quiet, we don't have to force them quiet.
|
||||||
|
|
||||||
// assign nanres = xnan ? x: (ynan ? y : (znan ? z : {1'b1, 51'b0})); // original
|
// assign nanres = xnan ? x: (ynan ? y : (znan ? z : {1'b1, 51'b0})); // original
|
||||||
|
|
||||||
|
// IEEE 754-2008 section 6.2.3 states:
|
||||||
|
// "If two or more inputs are NaN, then the payload of the resulting NaN should be
|
||||||
|
// identical to the payload of one of the input NaNs if representable in the destination
|
||||||
|
// format. This standard does not specify which of the input NaNs will provide the payload."
|
||||||
assign nanres = xnan ? {1'b1, x[50:0]}: (ynan ? {1'b1, y[50:0]} : (znan ? {1'b1, z[50:0]} : {1'b1, 51'b0}));// KEP 210112 add the 1 to make NaNs quiet
|
assign nanres = xnan ? {1'b1, x[50:0]}: (ynan ? {1'b1, y[50:0]} : (znan ? {1'b1, z[50:0]} : {1'b1, 51'b0}));// KEP 210112 add the 1 to make NaNs quiet
|
||||||
|
|
||||||
// Select result with 4:1 mux
|
// Select result with 4:1 mux
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
module sign(xsign, ysign, zsign, negsum0, negsum1, bs, ps, killprod, rm,
|
module sign(xsign, ysign, zsign, negsum0, negsum1, bs, ps, killprod, rm, overflow,
|
||||||
sumzero, nan, invalid, xinf, yinf, inf, wsign, invz, negsum, selsum1, psign);
|
sumzero, nan, invalid, xinf, yinf, zinf, inf, wsign, invz, negsum, selsum1, psign);
|
||||||
////////////////////////////////////////////////////////////////////////////I
|
////////////////////////////////////////////////////////////////////////////I
|
||||||
|
|
||||||
input xsign; // Sign of X
|
input xsign; // Sign of X
|
||||||
@ -23,11 +23,13 @@ module sign(xsign, ysign, zsign, negsum0, negsum1, bs, ps, killprod, rm,
|
|||||||
input ps; // sticky bit from product
|
input ps; // sticky bit from product
|
||||||
input killprod; // Product forced to zero
|
input killprod; // Product forced to zero
|
||||||
input rm; // Round toward minus infinity
|
input rm; // Round toward minus infinity
|
||||||
|
input overflow; // Round toward minus infinity
|
||||||
input sumzero; // Sum = O
|
input sumzero; // Sum = O
|
||||||
input nan; // Some input is NaN
|
input nan; // Some input is NaN
|
||||||
input invalid; // Result invalid
|
input invalid; // Result invalid
|
||||||
input xinf; // X = Inf
|
input xinf; // X = Inf
|
||||||
input yinf; // Y = Inf
|
input yinf; // Y = Inf
|
||||||
|
input zinf; // Y = Inf
|
||||||
input inf; // Some input = Inf
|
input inf; // Some input = Inf
|
||||||
output wsign; // Sign of W
|
output wsign; // Sign of W
|
||||||
output invz; // Invert addend into adder
|
output invz; // Invert addend into adder
|
||||||
@ -47,13 +49,13 @@ module sign(xsign, ysign, zsign, negsum0, negsum1, bs, ps, killprod, rm,
|
|||||||
assign psign = xsign ^ ysign;
|
assign psign = xsign ^ ysign;
|
||||||
|
|
||||||
// Invert addend if sign of Z is different from sign of product assign invz = zsign ^ psign;
|
// Invert addend if sign of Z is different from sign of product assign invz = zsign ^ psign;
|
||||||
assign invz = zsign ^ psign;
|
assign invz = (zsign ^ psign);
|
||||||
// Select +l mode for adder and compute if result must be negated
|
// Select +l mode for adder and compute if result must be negated
|
||||||
// This is done according to cases based on the sticky bit.
|
// This is done according to cases based on the sticky bit.
|
||||||
|
|
||||||
always @(invz or negsum0 or negsum1 or bs or ps)
|
always @(invz or negsum0 or negsum1 or bs or ps)
|
||||||
begin
|
begin
|
||||||
if (~invz) begin // both inputs have same sign
|
if (~invz) begin // both inputs have same sign //KEP if overflow
|
||||||
negsum = 0;
|
negsum = 0;
|
||||||
selsum1 = 0;
|
selsum1 = 0;
|
||||||
end else if (bs) begin // sticky bit set on addend
|
end else if (bs) begin // sticky bit set on addend
|
||||||
@ -85,9 +87,8 @@ module sign(xsign, ysign, zsign, negsum0, negsum1, bs, ps, killprod, rm,
|
|||||||
// sum/difference shall be -0. However, x+x = x-(-X) retains the same sign as x even when x is zero."
|
// sum/difference shall be -0. However, x+x = x-(-X) retains the same sign as x even when x is zero."
|
||||||
|
|
||||||
assign zerosign = (~invz && killprod) ? zsign : rm;
|
assign zerosign = (~invz && killprod) ? zsign : rm;
|
||||||
assign infsign = psign; //KEP 210112 keep the correct sign when result is infinity
|
assign infsign = zinf ? zsign : psign; //KEP 210112 keep the correct sign when result is infinity
|
||||||
// assign infsign = xinf ? (yinf ? psign : xsign) : yinf ? ysign : zsign;//original
|
//assign infsign = xinf ? (yinf ? psign : xsign) : yinf ? ysign : zsign;//original
|
||||||
assign wsign =invalid? 0 : (inf ? infsign:
|
assign wsign = invalid ? 0 : (inf ? infsign :(sumzero ? zerosign : psign ^ negsum));
|
||||||
(sumzero ? zerosign : psign ^ negsum));
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -14,23 +14,23 @@ module special(x[63:0], y[63:0], z[63:0], ae, xzero, yzero, zzero,
|
|||||||
xnan, ynan, znan, xdenorm, ydenorm, zdenorm, proddenorm, xinf, yinf, zinf);
|
xnan, ynan, znan, xdenorm, ydenorm, zdenorm, proddenorm, xinf, yinf, zinf);
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
input [63:0] x; // Input x
|
input [63:0] x; // Input x
|
||||||
input [63:0] y; // Input Y
|
input [63:0] y; // Input Y
|
||||||
input [63:0] z; // Input z
|
input [63:0] z; // Input z
|
||||||
input [12:0] ae; // exponent of product
|
input [12:0] ae; // exponent of product
|
||||||
output xzero; // Input x = 0
|
output xzero; // Input x = 0
|
||||||
output yzero; // Input y = 0
|
output yzero; // Input y = 0
|
||||||
output zzero; // Input z = 0
|
output zzero; // Input z = 0
|
||||||
output xnan; // x is NaN
|
output xnan; // x is NaN
|
||||||
output ynan; // y is NaN
|
output ynan; // y is NaN
|
||||||
output znan; // z is NaN
|
output znan; // z is NaN
|
||||||
output xdenorm; // x is denormalized
|
output xdenorm; // x is denormalized
|
||||||
output ydenorm; // y is denormalized
|
output ydenorm; // y is denormalized
|
||||||
output zdenorm; // z is denormalized
|
output zdenorm; // z is denormalized
|
||||||
output proddenorm; // product is denormalized
|
output proddenorm; // product is denormalized
|
||||||
output xinf; // x is infinity
|
output xinf; // x is infinity
|
||||||
output yinf; // y is infinity
|
output yinf; // y is infinity
|
||||||
output zinf; // z is infinity
|
output zinf; // z is infinity
|
||||||
|
|
||||||
// In the actual circuit design, the gates looking at bits
|
// In the actual circuit design, the gates looking at bits
|
||||||
// 51:0 and at bits 62:52 should be shared among the various detectors.
|
// 51:0 and at bits 62:52 should be shared among the various detectors.
|
||||||
|
Loading…
Reference in New Issue
Block a user