Skip to content
Snippets Groups Projects
Commit c425bf7d authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Improved description of RESIZE_NUM().

parent c0e5e498
No related branches found
No related tags found
1 merge request!165Resolve L2SDP-303
...@@ -383,15 +383,38 @@ PACKAGE common_pkg IS ...@@ -383,15 +383,38 @@ PACKAGE common_pkg IS
FUNCTION TO_UREAL(uvec : STD_LOGIC_VECTOR; resolution_w : INTEGER) RETURN REAL; -- convert unsigned fixed point slv of any length, and with resolution of 2**resolution_w, to REAL FUNCTION TO_UREAL(uvec : STD_LOGIC_VECTOR; resolution_w : INTEGER) RETURN REAL; -- convert unsigned fixed point slv of any length, and with resolution of 2**resolution_w, to REAL
FUNCTION TO_SREAL(svec : STD_LOGIC_VECTOR; resolution_w : INTEGER) RETURN REAL; -- convert signed fixed point slv of any length, and with resolution of 2**resolution_w, to REAL FUNCTION TO_SREAL(svec : STD_LOGIC_VECTOR; resolution_w : INTEGER) RETURN REAL; -- convert signed fixed point slv of any length, and with resolution of 2**resolution_w, to REAL
-- RESIZE_NUM() original description:
-- The RESIZE for SIGNED in IEEE.NUMERIC_STD extends the sign bit or it keeps the sign bit and LS part. This -- The RESIZE for SIGNED in IEEE.NUMERIC_STD extends the sign bit or it keeps the sign bit and LS part. This
-- behaviour of preserving the sign bit is less suitable for DSP and not necessary in general. A more -- behaviour of preserving the sign bit is less suitable for DSP and not necessary in general. A more
-- appropriate approach is to ignore the MSbit sign and just keep the LS part. For too large values this -- 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 -- 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 -- 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. When w keeps or increases the data width then the values -- and better not use RESIZE for SIGNED anymore.
-- 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() updated description (27 oct 2021):
-- * RESIZE_NUM() removes MSbits, so it wraps from + to - and from - to +, and it keeps the w LSbits -- The RESIZE() from IEEE.NUMERIC_STD keeps the sign bit and the w-1 LSbits, this results in a signal that
-- keeps the sign, but wraps between - and 0 for negative input, and that wraps between + and 0 for
-- positive input.
-- The RESIZE_NUM() from in this common_pkg.vhd simply keeps the w LSbits, so it wraps between - and +.
-- Hence RESIZE_NUM() works the same for SIGNED as for UNSIGNED. For an adder that sums multiple inputs,
-- it can be better to wrap over the entire -, + range, like RESIZE_NUM() does, because if the final adder
-- sum again fits in w bits, then any wrapping effects for intermediate sums will cancel in the end sum.
-- If the number of bit w is sufficient to have no resize overflow, then RESIZE() = RESIZE_NUM(). In an
-- application overflow should be avoided anyway, so then using either RESIZE() or RESIZE_NUM() is fine.
-- When w keeps or increases the data width then the values do not change (of course). When w reduces the
-- data width then overflow can occur in an application, so then use:
-- * RESIZE() to preserve the sign,
-- * RESIZE_NUM() to wrap similar for SIGNED as for UNSIGNED,
-- * common_resize.vhd to clip the overflow (and use symmetrical -, + clipping to avoid introducing DC bias).
-- The resize functions and component are verified by tb_tb_resize.vhd.
-- Conclusion:
-- 1) Keep original RESIZE_NUM(), so resize by selecting the w LSbits for both SIGNED and UNSIGNED.
-- 2) For applications without overflow RESIZE() = RESIZE_NUM() = common_resize.
-- 3) For applications with overflow choose to use RESIZE_NUM(), because it wraps similar for SIGNED as
-- for UNSIGNED (because both keep the w LSbits), instead of behaving differently for SIGNED like
-- RESIZE() does (keeping the MSbit and the w-1 LSbits). The wrapping of RESIZE_NUM() preserves the
-- capability of recovering from intermediate overflow in a summator, which can be beneficial for e.g.
-- a beamformer.
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( 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_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 FUNCTION RESIZE_UVEC(sl : STD_LOGIC; w : NATURAL) RETURN STD_LOGIC_VECTOR; -- left extend with '0' into slv
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment