cvw/wally-pipelined/src/fpu/exception.sv

84 lines
3.2 KiB
Systemverilog
Raw Normal View History

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