Skip to content
Snippets Groups Projects

Resolve L2SDP-303

4 files
+ 218
63
Compare changes
  • Side-by-side
  • Inline

Files

@@ -383,12 +383,38 @@ PACKAGE common_pkg IS
@@ -383,12 +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
-- The RESIZE for SIGNED in IEEE.NUMERIC_STD extends the sign bit or it keeps the sign bit and LS part. This
-- 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
-- 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.
-- and better not use RESIZE for SIGNED anymore.
 
--
 
-- RESIZE_NUM() updated description (27 oct 2021):
 
-- 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
@@ -1975,8 +2001,8 @@ PACKAGE BODY common_pkg IS
@@ -1975,8 +2001,8 @@ PACKAGE BODY common_pkg IS
FUNCTION RESIZE_NUM(u : UNSIGNED; w : NATURAL) RETURN UNSIGNED IS
FUNCTION RESIZE_NUM(u : UNSIGNED; w : NATURAL) RETURN UNSIGNED IS
BEGIN
BEGIN
-- left extend with '0' or keep LS part (same as RESIZE for UNSIGNED)
-- left extend with '0' or remove MSbits and keep LS part (= u[w-1:0])
RETURN RESIZE(u, w);
RETURN RESIZE(u, w); -- same as RESIZE for UNSIGNED
END;
END;
FUNCTION RESIZE_NUM(s : SIGNED; w : NATURAL) RETURN SIGNED IS
FUNCTION RESIZE_NUM(s : SIGNED; w : NATURAL) RETURN SIGNED IS
@@ -1985,7 +2011,12 @@ PACKAGE BODY common_pkg IS
@@ -1985,7 +2011,12 @@ PACKAGE BODY common_pkg IS
IF w>s'LENGTH THEN
IF w>s'LENGTH THEN
RETURN RESIZE(s, w); -- extend sign bit
RETURN RESIZE(s, w); -- extend sign bit
ELSE
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 IF;
END;
END;
Loading