From 320d6c1bd67dfea1d71e46244a74f770be2f0416 Mon Sep 17 00:00:00 2001
From: Eric Kooistra <kooistra@astron.nl>
Date: Mon, 22 Jun 2020 17:54:41 +0200
Subject: [PATCH] Added NEGATE_SVEC().

---
 libraries/base/common/src/vhdl/common_pkg.vhd | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/libraries/base/common/src/vhdl/common_pkg.vhd b/libraries/base/common/src/vhdl/common_pkg.vhd
index 750cd5e6be..e81085087b 100644
--- a/libraries/base/common/src/vhdl/common_pkg.vhd
+++ b/libraries/base/common/src/vhdl/common_pkg.vhd
@@ -372,6 +372,9 @@ PACKAGE common_pkg IS
   
   FUNCTION RESIZE_UVEC_32(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;  -- = RESIZE_UVEC() with w=32 for t_slv_32_arr slv elements
   FUNCTION RESIZE_SVEC_32(vec : STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;  -- = RESIZE_SVEC() with w=32 for t_slv_32_arr slv elements
+
+  -- Negate vec, but avoid overflow by forcing -min to +max. Use w <= vec'LENGTH.
+  FUNCTION NEGATE_SVEC(vec : STD_LOGIC_VECTOR; w : INTEGER) RETURN STD_LOGIC_VECTOR;
   
   FUNCTION INCR_UVEC(vec : STD_LOGIC_VECTOR; dec : INTEGER)  RETURN STD_LOGIC_VECTOR;
   FUNCTION INCR_UVEC(vec : STD_LOGIC_VECTOR; dec : UNSIGNED) RETURN STD_LOGIC_VECTOR; 
@@ -1754,6 +1757,22 @@ PACKAGE BODY common_pkg IS
     RETURN RESIZE_SVEC(vec, 32);
   END;
   
+  -- Negate vec, but avoid overflow by forcing -min to +max. Use w <= vec'LENGTH.
+  FUNCTION NEGATE_SVEC(vec : STD_LOGIC_VECTOR; w : INTEGER) RETURN STD_LOGIC_VECTOR IS
+    CONSTANT c_max   : INTEGER :=  2**(w-1)-1;
+    CONSTANT c_min   : INTEGER := -2**(w-1);
+    CONSTANT c_vec_w : NATURAL := vec'LENGTH;
+    VARIABLE v_vec   : STD_LOGIC_VECTOR(c_vec_w-1 DOWNTO 0) := vec;  -- independent of vec'RANGE
+    VARIABLE v_val   : STD_LOGIC_VECTOR(w-1 DOWNTO 0);
+  BEGIN
+    v_val := v_vec(w-1 DOWNTO 0);  -- operate on width w and resize to c_vec_w for return
+    IF SIGNED(v_val) = c_min THEN
+      RETURN STD_LOGIC_VECTOR(TO_SIGNED(c_max, c_vec_w));  -- most negative becomes most positive
+    ELSE
+      RETURN STD_LOGIC_VECTOR(RESIZE_NUM(-SIGNED(v_val), c_vec_w));  -- negate by multiplying by -1
+    END IF;
+  END;
+
   FUNCTION INCR_UVEC(vec : STD_LOGIC_VECTOR; dec : INTEGER) RETURN STD_LOGIC_VECTOR IS
     VARIABLE v_dec : INTEGER;
   BEGIN
-- 
GitLab