fixed various bugs

This commit is contained in:
Katherine Parry 2021-03-04 22:18:19 +00:00
parent 57e484cd55
commit fdfc0dbf46
9 changed files with 149 additions and 133 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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],

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.