diff --git a/libraries/base/common/src/vhdl/common_pkg.vhd b/libraries/base/common/src/vhdl/common_pkg.vhd
index a74053a4cd479ae002693585e009314e5857ceda..4b0b149032e7dc8e22f4cf8ba7ad3f818cdd1dfd 100644
--- a/libraries/base/common/src/vhdl/common_pkg.vhd
+++ b/libraries/base/common/src/vhdl/common_pkg.vhd
@@ -467,8 +467,6 @@ PACKAGE common_pkg IS
   FUNCTION s_round(   vec : STD_LOGIC_VECTOR; n : NATURAL; clip       : BOOLEAN) RETURN STD_LOGIC_VECTOR;  -- remove n LSBits from vec by rounding away from 0, so result has width vec'LENGTH-n, and clip to avoid wrap
   FUNCTION s_round(   vec : STD_LOGIC_VECTOR; n : NATURAL)                       RETURN STD_LOGIC_VECTOR;  -- remove n LSBits from vec by rounding away from 0, so result has width vec'LENGTH-n
   FUNCTION s_round(   vec : STD_LOGIC_VECTOR; n : NATURAL; clip, even : BOOLEAN) RETURN STD_LOGIC_VECTOR;  -- idem but round half to even for signed
-  FUNCTION s_round_up(vec : STD_LOGIC_VECTOR; n : NATURAL; clip       : BOOLEAN) RETURN STD_LOGIC_VECTOR;  -- idem but round up to +infinity (s_round_up = u_round)
-  FUNCTION s_round_up(vec : STD_LOGIC_VECTOR; n : NATURAL)                       RETURN STD_LOGIC_VECTOR;  -- idem but round up to +infinity (s_round_up = u_round)
   FUNCTION u_round(   vec : STD_LOGIC_VECTOR; n : NATURAL; clip       : BOOLEAN) RETURN STD_LOGIC_VECTOR;  -- idem round up for unsigned values
   FUNCTION u_round(   vec : STD_LOGIC_VECTOR; n : NATURAL)                       RETURN STD_LOGIC_VECTOR;  -- idem round up for unsigned values
   FUNCTION u_round(   vec : STD_LOGIC_VECTOR; n : NATURAL; clip, even : BOOLEAN) RETURN STD_LOGIC_VECTOR;  -- idem but round half to even for unsigned
@@ -2320,12 +2318,12 @@ PACKAGE BODY common_pkg IS
   -------------------------------------------------------------------------------------------------
   --
   -- From https://en.wikipedia.org/wiki/Rounding it follows that there are three main
-  -- catergories for rounding to integer:
+  -- categories for rounding to integer:
   --
   -- 1) Direct rounding to integer :
-  --    . down           : y = floor(x),
+  --    . down           : y = floor(x), is truncate of LSbits
   --    . up             : y = ceil(x),
-  --    . towards zero   : y = truncate(x)
+  --    . towards zero   : y = truncate(x) = int(x), is truncate of fraction, is keep the integer part
   --                         = sgn(x) floor(|x|) = floor(x) when x >= 0, else ceil(x)
   --    . away from zero : y = sgn(x) ceil(|x|) = ceil(x) when x >= 0, else floor(x)
   -- 2) Rounding to nearest integer :
@@ -2334,14 +2332,14 @@ PACKAGE BODY common_pkg IS
   --    . half towards zero   : y = sgn(x) ceil(|x| - 0.5) = ceil(x - 0.5) when x >= 0, else floor(x + 0.5)
   --    . half away from zero : y = sgn(x) floor(|x| + 0.5) = floor(x + 0.5) when x >= 0, else ceil(x - 0.5)
   --    . round half to even : rounds to the nearest even integer when fraction = 0.5 else use
-  --      either floor(x + 0.5) or ceil(x - 0.5), because they are quivalent then. This avoid
+  --      either floor(x + 0.5) or ceil(x - 0.5), because they are equivalent then. This avoid
   --      DC bias and bias towards or away from zero.
   --
   -- 3) Randomized rounding to an integer : round to nearest when fraction != 0.5, round up or
   --    down when fraction = 0.5. This avoid DC bias and bias towards or away from zero:
   --    . alternate tie breaking : alternately select round up or round down when fraction = 0.5
   --        else either floor(x + 0.5) or ceil(x - 0.5), because they are equivalent then.
-  --    . random tie breaking : idem as alternate, but use random selection.
+  --    . random tie breaking : idem as alternate tie breaking, but use random selection.
   --    . stochastic rounding : round up or down with a probability that depends on proximity.
   --      This avoids DC bias when the input is not random, e.g. when the input has a constant
   --      fraction > 0. For DSP with ADC related data with sufficient dynamic range this does
@@ -2354,21 +2352,23 @@ PACKAGE BODY common_pkg IS
   --  a function for round using tie breaking requires an external state to manage the
   --  selection.
   --
-  --  * u_round() and s_round_up() use half up. This introduces +DC bias when fraction 0.5
-  --    occurs.
-  --  * s_round() uses half away from zero, similar as by round() in Matlab, Python, TCL.
-  --    This avoid DC bias, but does introduce bias away from zero, which can show as a up
-  --    bias in power values because (negative)**2 > 0 and (positive)**2 > 0.
+  --  * Half up introduces +DC bias when fraction 0.5 occurs.
+  --  * Half away from zero is also used by round() in VHDL math_real, Matlab, Python, TCL.
+  --  * Half away avoids DC bias, but does introduce bias away from zero, which can show
+  --    as a up bias in power values because (negative)**2 > 0 and (positive)**2 > 0.
   --
-  -- Functions s_round(), s_round_up() and u_round():
+  -- Functions s_round() and u_round():
   --
+  -- . u_round() supports half up (= half away) and half even.
+  -- . s_round() supports half away and half even.
   -- . The returned output width is input width - n.
   -- . If n=0 then the return value is the same as the input value so only
   --   wires (NOP, no operation).
   -- . Both have the same implementation but different c_max and c_clip values.
   -- . Round up for unsigned so +2.5 becomes 3
-  -- . Round away from zero for signed so round up for positive and round down for negative, so +2.5 becomes 3 and -2.5 becomes -3.
-  -- . Round away from zero is also used by round() in Matlab, Python, TCL
+  -- . Round away from zero for signed so round up for positive and round down for negative,
+  --   so +2.5 becomes 3 and -2.5 becomes -3.
+  -- . Round away from zero is also used by round() in VHDL math_real, Matlab, Python, TCL
   -- . Rounding up implies adding 0.5 and then truncation, use clip = TRUE to
   --   clip the potential overflow due to adding 0.5 to +max.
   -- . For negative values overflow due to rounding can not occur, because c_half-1 >= 0 for n>0
@@ -2388,14 +2388,15 @@ PACKAGE BODY common_pkg IS
     -- if fraction = 0.5 and v_out = odd:
     --   v_out -= 1
     -- Use SIGNED to avoid NATURAL (32 bit range) overflow error
-    CONSTANT c_in_w  : NATURAL := vec'LENGTH;
-    CONSTANT c_out_w : NATURAL := vec'LENGTH - n;
-    CONSTANT c_one   : SIGNED(c_in_w-1 DOWNTO 0) := TO_SIGNED(1, c_in_w);
-    CONSTANT c_half  : SIGNED(c_in_w-1 DOWNTO 0) := SHIFT_LEFT(c_one, n-1);                            -- = 2**(n-1)
-    CONSTANT c_max   : SIGNED(c_in_w-1 DOWNTO 0) := SIGNED('0' & c_slv1(c_in_w-2 DOWNTO 0)) - c_half;  -- = 2**(c_in_w-1)-1 - c_half  
-    CONSTANT c_clip  : SIGNED(c_out_w-1 DOWNTO 0) := SIGNED('0' & c_slv1(c_out_w-2 DOWNTO 0));         -- = 2**(c_out_w-1)-1
-    VARIABLE v_in    : SIGNED(c_in_w-1 DOWNTO 0);
-    VARIABLE v_out   : SIGNED(c_out_w-1 DOWNTO 0);
+    CONSTANT c_in_w     : NATURAL := vec'LENGTH;
+    CONSTANT c_out_w    : NATURAL := vec'LENGTH - n;
+    CONSTANT c_one      : SIGNED(c_in_w-1 DOWNTO 0) := TO_SIGNED(1, c_in_w);
+    CONSTANT c_half     : SIGNED(c_in_w-1 DOWNTO 0) := SHIFT_LEFT(c_one, n-1);                            -- = 2**(n-1)
+    CONSTANT c_max      : SIGNED(c_in_w-1 DOWNTO 0) := SIGNED('0' & c_slv1(c_in_w-2 DOWNTO 0)) - c_half;  -- = 2**(c_in_w-1)-1 - c_half
+    CONSTANT c_clip     : SIGNED(c_out_w-1 DOWNTO 0) := SIGNED('0' & c_slv1(c_out_w-2 DOWNTO 0));         -- = 2**(c_out_w-1)-1
+    VARIABLE v_in       : SIGNED(c_in_w-1 DOWNTO 0);
+    VARIABLE v_fraction : SIGNED(n-1 DOWNTO 0);
+    VARIABLE v_out      : SIGNED(c_out_w-1 DOWNTO 0);
   BEGIN
     v_in := SIGNED(vec);
     IF n > 0 THEN
@@ -2407,6 +2408,12 @@ PACKAGE BODY common_pkg IS
         ELSE
           v_out := RESIZE_NUM(SHIFT_RIGHT(v_in + c_half - 1, n), c_out_w);  -- Round down for negative
         END IF;
+        IF even = TRUE THEN
+          v_fraction := SIGNED(vec(n-1 DOWNTO 0));
+          IF v_fraction = c_half AND v_out(0) = '1' THEN              -- Round half to even, so when odd subtract 1
+            v_out := v_out - 1;                                       -- to make v_out even
+          END IF;
+        END IF;
       END IF;
     ELSE
       v_out := RESIZE_NUM(v_in, c_out_w);                             -- NOP
@@ -2414,7 +2421,7 @@ PACKAGE BODY common_pkg IS
     RETURN STD_LOGIC_VECTOR(v_out);
   END;
 
-  FUNCTION s_round(vec : STD_LOGIC_VECTOR; n : NATURAL; clip, even : BOOLEAN) RETURN STD_LOGIC_VECTOR IS
+  FUNCTION s_round(vec : STD_LOGIC_VECTOR; n : NATURAL; clip : BOOLEAN) RETURN STD_LOGIC_VECTOR IS
   BEGIN
     RETURN s_round(vec, n, clip, FALSE);  -- no round half to even
   END;
@@ -2424,17 +2431,6 @@ PACKAGE BODY common_pkg IS
     RETURN s_round(vec, n, FALSE);  -- no round clip
   END;
   
-  -- An alternative is to always round up, also for negative numbers (i.e. s_round_up = u_round).
-  FUNCTION s_round_up(vec : STD_LOGIC_VECTOR; n : NATURAL; clip : BOOLEAN) RETURN STD_LOGIC_VECTOR IS
-  BEGIN
-    RETURN u_round(vec, n, clip);
-  END;
-  
-  FUNCTION s_round_up(vec : STD_LOGIC_VECTOR; n : NATURAL) RETURN STD_LOGIC_VECTOR IS
-  BEGIN
-    RETURN u_round(vec, n, FALSE);  -- no round clip
-  END;
-  
   -- Unsigned numbers are round up (almost same as s_round, but without the else on negative vec)
   FUNCTION u_round(vec : STD_LOGIC_VECTOR; n : NATURAL; clip, even : BOOLEAN) RETURN STD_LOGIC_VECTOR IS
     -- # Round half to even algorithm: