diff --git a/libraries/base/common/src/vhdl/common_pkg.vhd b/libraries/base/common/src/vhdl/common_pkg.vhd index 55a7a6a8446deaa3f36105b592d966a147a37d67..4b7c0f4b718866c29995a2968116247b233103c2 100644 --- a/libraries/base/common/src/vhdl/common_pkg.vhd +++ b/libraries/base/common/src/vhdl/common_pkg.vhd @@ -388,7 +388,10 @@ PACKAGE common_pkg IS -- appropriate approach is to ignore the MSbit sign and just keep the LS part. For too large values this -- means that the result gets wrapped, but that is fine for default behaviour, because that is also what -- happens for RESIZE of UNSIGNED. Therefor this is what the RESIZE_NUM for SIGNED and the RESIZE_SVEC do - -- and better not use RESIZE for SIGNED anymore. + -- and better not use RESIZE for SIGNED anymore. When w keeps or increases the data width then the values + -- do not change (of course). When w reduces the data width then: + -- * RESIZE() wraps between -, 0 for negative and 0, + for positive, so it keeps the sign and w-1 LSbits + -- * RESIZE_NUM() removes MSbits, so it wraps from + to - and from - to +, and it keeps the w LSbits FUNCTION RESIZE_NUM( u : UNSIGNED; w : NATURAL) RETURN UNSIGNED; -- left extend with '0' or keep LS part (same as RESIZE for UNSIGNED) FUNCTION RESIZE_NUM( s : SIGNED; w : NATURAL) RETURN SIGNED; -- extend sign bit or keep LS part FUNCTION RESIZE_UVEC(sl : STD_LOGIC; w : NATURAL) RETURN STD_LOGIC_VECTOR; -- left extend with '0' into slv @@ -1975,8 +1978,8 @@ PACKAGE BODY common_pkg IS FUNCTION RESIZE_NUM(u : UNSIGNED; w : NATURAL) RETURN UNSIGNED IS BEGIN - -- left extend with '0' or keep LS part (same as RESIZE for UNSIGNED) - RETURN RESIZE(u, w); + -- left extend with '0' or remove MSbits and keep LS part (= u[w-1:0]) + RETURN RESIZE(u, w); -- same as RESIZE for UNSIGNED END; FUNCTION RESIZE_NUM(s : SIGNED; w : NATURAL) RETURN SIGNED IS @@ -1985,7 +1988,12 @@ PACKAGE BODY common_pkg IS IF w>s'LENGTH THEN RETURN RESIZE(s, w); -- extend sign bit ELSE - RETURN SIGNED(RESIZE(UNSIGNED(s), w)); -- keep LSbits (= vec[w-1:0]) + -- RESIZE() wraps between -, 0 for negative and 0, + for positive, so it keeps the sign and w-1 LSbits + -- RESIZE_NUM() removes MSbits, so it wraps from + to - and from - to +, and it keeps the w LSbits + + -- remove MSbits and keep LS part (= s[w-1:0]) + -- use RESIZE(UNSIGNED()) rather than s[w-1:0] to be independent of RANGE of s + RETURN SIGNED(RESIZE(UNSIGNED(s), w)); END IF; END;