-- Model Name : syn_util.vhd -- Author : Zainalabedin Navabi -- Last Updated : 09 / 15 / 1996 -- This document is © copyrighted by the Author.
LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
--
PACKAGE synthesis_utilities IS
    FUNCTION all_or (v : std_logic_vector) RETURN std_logic;
    FUNCTION addsub_cv (a, b : std_logic_vector; cin : std_logic; add_sub : std_logic)
    RETURN std_logic_vector;
    SUBTYPE nibble IS std_logic_vector (3 DOWNTO 0);
    SUBTYPE byte IS std_logic_vector (7 DOWNTO 0);
    SUBTYPE twelve IS std_logic_vector (11 DOWNTO 0);
END synthesis_utilities;
--
PACKAGE BODY synthesis_utilities IS
    FUNCTION all_or (v : std_logic_vector) RETURN std_logic IS
      VARIABLE temp : std_logic;
      BEGIN
      temp := '0';
      FOR i IN v'RANGE LOOP
        temp := temp OR v(i);
      END LOOP;
      RETURN temp;
    END all_or;
    FUNCTION addsub_cv (a, b : std_logic_vector; cin : std_logic; add_sub : std_logic)
    RETURN std_logic_vector IS
    --for adding add_sub is 0, for subtracting add_sub is 1
    --left bits of a and b are sign bit
      VARIABLE r: std_logic_vector (a'LEFT + 2 DOWNTO 0); --intermediate result
      -- Left two bits of r are for v and c respectively
      VARIABLE c: std_logic_vector (a'LEFT DOWNTO 0); --intermediate carry
      VARIABLE a_sign, b_sign: std_logic; --sign bits of a and b
      VARIABLE cin_signed : std_logic; --complement cin for sub
      VARIABLE b_signed : std_logic_vector (b'RANGE); --complement b for sub
    BEGIN
    cin_signed := cin XOR add_sub;
    FOR i IN b'RANGE LOOP
      b_signed (i) := b(i) XOR add_sub;
    END LOOP;
    a_sign := a(a'LEFT);
    b_sign := b_signed(b'LEFT);
    r(0) := a(0) XOR b_signed(0) XOR cin_signed;
    c(0) := ((a(0) XOR b_signed(0)) AND cin_signed) OR (a(0) AND b_signed(0));
    FOR i IN 1 TO (a'LEFT) LOOP
      r(i) := a(i) XOR b_signed(i) XOR c(i-1);
      c(i) := ((a(i) XOR b_signed(i)) AND c(i-1)) OR (a(i) AND b_signed(i));
    END LOOP;
    r(a'LEFT+1) := c(a'LEFT);
    IF a_sign = b_sign AND r(a'LEFT) /= a_sign
      THEN r(a'LEFT+2) := '1'; --overflow
    ELSE r(a'LEFT+2) := '0'; END IF;
    RETURN r;
END addsub_cv; END synthesis_utilities;