THis includes fix for special case when conversion from fp to int/long. The previous src did not test both the flags and result and so missed this subtle bug when an Invalid happens for this type of conversion. These results are indications of undefined behavior for these operations. All fp operations now passs when this update is fixed. Much of the information why these outputs should occur is somewhat alluded to by Pascal Cuoq originally from INSA in Lyon here: https://frama-c.com/2013/10/09/Overflow-float-integer.html

This commit is contained in:
James E. Stine 2024-01-12 00:37:50 -06:00
parent dbe8394651
commit e707eeb7c8

View File

@ -266,28 +266,34 @@ module specialcase import cvw::*; #(parameter cvw_t P) (
// integer result selection // integer result selection
/////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////
// Causes undefined behavior for invalid:
// unsigned: if invalid (e.g., negative fp to unsigned int, result should overflow and
// overflows to the maximum value
// signed: if invalid, result should overflow to maximum negative value
// but is undefined and used for information only
// select the overflow integer res // select the overflow integer res
// - negitive infinity and out of range negitive input // - negitive infinity and out of range negitive input
// | int | long | // | int | long |
// signed | -2^31 | -2^63 | // signed | -2^31 | -2^63 |
// unsigned | 0 | 0 | // unsigned | 2^32-1 | 2^64-1 |
// //
// - positive infinity and out of range positive input and NaNs // - positive infinity and out of range positive input and NaNs
// | int | long | // | int | long |
// signed | 2^31-1 | 2^63-1 | // signed | -2^31 |-2^63 |
// unsigned | 2^32-1 | 2^64-1 | // unsigned | 2^32-1 | 2^64-1 |
// //
// other: 32 bit unsinged res should be sign extended as if it were a signed number // other: 32 bit unsigned res should be sign extended as if it were a signed number
always_comb always_comb
if(Signed) if(Signed)
if(Xs&~NaNIn) // signed negitive if(Xs&~NaNIn) // signed negitive
if(Int64) OfIntRes = {1'b1, {P.XLEN-1{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 OfIntRes = {{P.XLEN-32{1'b1}}, 1'b1, {31{1'b0}}};
else // signed positive else // signed positive
if(Int64) OfIntRes = {1'b0, {P.XLEN-1{1'b1}}}; if(Int64) OfIntRes = {1'b1, {P.XLEN-1{1'b0}}};
else OfIntRes = {{P.XLEN-32{1'b0}}, 1'b0, {31{1'b1}}}; else OfIntRes = {{P.XLEN-32{1'b1}}, 1'b1, {31{1'b0}}};
else else
if(Xs&~NaNIn) OfIntRes = {P.XLEN{1'b0}}; // unsigned negitive if(Xs&~NaNIn) OfIntRes = {P.XLEN{1'b1}}; // unsigned negitive
else OfIntRes = {P.XLEN{1'b1}}; // unsigned positive else OfIntRes = {P.XLEN{1'b1}}; // unsigned positive
// select the integer output // select the integer output