2021-04-04 18:09:13 +00:00
|
|
|
// Exception logic for the floating point adder. Note: We may
|
|
|
|
// actually want to move to where the result is computed.
|
|
|
|
|
2021-07-29 03:49:21 +00:00
|
|
|
module exception (
|
|
|
|
|
|
|
|
input logic [2:0] op_type, // Function opcode
|
|
|
|
input logic XSgnE, YSgnE,
|
|
|
|
// input logic [52:0] XManE, YManE,
|
|
|
|
input logic XDenormE, YDenormE,
|
|
|
|
input logic XNormE, YNormE,
|
|
|
|
input logic XZeroE, YZeroE,
|
|
|
|
input logic XInfE, YInfE,
|
|
|
|
input logic XNaNE, YNaNE,
|
|
|
|
input logic XSNaNE, YSNaNE,
|
|
|
|
output logic [3:0] Ztype, // Indicates type of result (Z)
|
|
|
|
output logic Invalid, // Invalid operation exception
|
|
|
|
output logic Denorm, // Denormalized logic
|
|
|
|
output logic Sub // The effective operation is subtraction
|
|
|
|
);
|
2021-04-04 18:09:13 +00:00
|
|
|
wire ZQNaN; // '1' if result Z is a quiet NaN
|
|
|
|
wire ZPInf; // '1' if result Z positive infnity
|
|
|
|
wire ZNInf; // '1' if result Z negative infnity
|
|
|
|
wire add_sub; // '1' if operation is add or subtract
|
|
|
|
wire converts; // See if there are any converts
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Is this instruction a convert
|
2021-07-29 03:49:21 +00:00
|
|
|
assign converts = op_type[1];
|
2021-04-04 18:09:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// An "Invalid Operation" exception occurs if (A or B is a signalling NaN)
|
|
|
|
// or (A and B are both Infinite and the "effective operation" is
|
|
|
|
// subtraction).
|
2021-07-29 03:49:21 +00:00
|
|
|
assign add_sub = ~op_type[1];
|
|
|
|
assign Invalid = (XSNaNE | YSNaNE | (add_sub & XInfE & YInfE & (XSgnE^YSgnE^op_type[0]))) & ~converts;
|
2021-04-04 18:09:13 +00:00
|
|
|
|
|
|
|
// The Denorm flag is set if (A is denormlized and the operation is not integer
|
|
|
|
// conversion ) or (if B is normalized and the operation is addition or subtraction).
|
2021-07-29 03:49:21 +00:00
|
|
|
assign Denorm = XDenormE | YDenormE & add_sub;
|
2021-04-04 18:09:13 +00:00
|
|
|
|
|
|
|
// The result is a quiet NaN if (an "Invalid Operation" exception occurs)
|
|
|
|
// or (A is a NaN) or (B is a NaN and the operation uses B).
|
2021-07-29 03:49:21 +00:00
|
|
|
assign ZQNaN = Invalid | XNaNE | (YNaNE & add_sub);
|
2021-04-04 18:09:13 +00:00
|
|
|
|
|
|
|
// The result is +Inf if ((A is +Inf) or (B is -Inf and the operation is
|
|
|
|
// subtraction) or (B is +Inf and the operation is addition)) and (the
|
|
|
|
// result is not a quiet NaN).
|
2021-07-29 03:49:21 +00:00
|
|
|
assign ZPInf = (XInfE&XSgnE | add_sub&YInfE&(~YSgnE^op_type[0]))&~ZQNaN;
|
2021-04-04 18:09:13 +00:00
|
|
|
|
|
|
|
// The result is -Inf if ((A is -Inf) or (B is +Inf and the operation is
|
|
|
|
// subtraction) or (B is -Inf and the operation is addition)) and the
|
|
|
|
// result is not a quiet NaN.
|
2021-07-29 03:49:21 +00:00
|
|
|
assign ZNInf = (XInfE&~XSgnE | add_sub&YInfE&(YSgnE^op_type[0]))&~ZQNaN;
|
2021-04-04 18:09:13 +00:00
|
|
|
|
|
|
|
// Set the type of the result as follows:
|
|
|
|
// (needs optimization - got lazy or was late)
|
|
|
|
// Ztype Result
|
|
|
|
// 0000 Normal
|
|
|
|
// 0001 Quiet NaN
|
|
|
|
// 0010 Negative Infinity
|
|
|
|
// 0011 Positive Infinity
|
|
|
|
// 0100 +Bzero and +Azero (and vice-versa)
|
|
|
|
// 0101 +Bzero and -Azero (and vice-versa)
|
|
|
|
// 1000 Convert SP to DP (and vice-versa)
|
|
|
|
|
2021-07-29 03:49:21 +00:00
|
|
|
assign Ztype[0] = (ZQNaN | ZPInf) |
|
|
|
|
((XZeroE & YZeroE & (XSgnE^YSgnE^op_type[0]))
|
2021-04-04 18:09:13 +00:00
|
|
|
& ~converts);
|
2021-07-29 03:49:21 +00:00
|
|
|
assign Ztype[1] = (ZNInf | ZPInf) |
|
|
|
|
(((XZeroE & YZeroE & XSgnE & YSgnE & ~op_type[0]) |
|
|
|
|
(XZeroE & YZeroE & XSgnE & ~YSgnE & op_type[0]))
|
2021-04-04 18:09:13 +00:00
|
|
|
& ~converts);
|
2021-07-29 03:49:21 +00:00
|
|
|
assign Ztype[2] = ((XZeroE & YZeroE & ~op_type[1])
|
2021-04-04 18:09:13 +00:00
|
|
|
& ~converts);
|
2021-07-29 03:49:21 +00:00
|
|
|
assign Ztype[3] = (op_type[1] & ~op_type[0]);
|
2021-04-04 18:09:13 +00:00
|
|
|
|
|
|
|
// Determine if the effective operation is subtraction
|
2021-07-29 03:49:21 +00:00
|
|
|
assign Sub = add_sub & (XSgnE^YSgnE^op_type[0]);
|
2021-07-24 18:59:57 +00:00
|
|
|
|
2021-04-04 18:09:13 +00:00
|
|
|
endmodule // exception
|
|
|
|
|