summaryrefslogtreecommitdiff
path: root/libraries/mentor/std_logic_arith_body.vhdl
diff options
context:
space:
mode:
authorgingold2005-09-24 05:10:24 +0000
committergingold2005-09-24 05:10:24 +0000
commit977ff5e02c6d2f9bfdabcf8b4e98b81e2d83e849 (patch)
tree7bcf8e7aff40a8b54d4af83e90cccd73568e77bb /libraries/mentor/std_logic_arith_body.vhdl
downloadghdl-977ff5e02c6d2f9bfdabcf8b4e98b81e2d83e849.tar.gz
ghdl-977ff5e02c6d2f9bfdabcf8b4e98b81e2d83e849.tar.bz2
ghdl-977ff5e02c6d2f9bfdabcf8b4e98b81e2d83e849.zip
First import from sources
Diffstat (limited to 'libraries/mentor/std_logic_arith_body.vhdl')
-rw-r--r--libraries/mentor/std_logic_arith_body.vhdl2915
1 files changed, 2915 insertions, 0 deletions
diff --git a/libraries/mentor/std_logic_arith_body.vhdl b/libraries/mentor/std_logic_arith_body.vhdl
new file mode 100644
index 0000000..36f76cb
--- /dev/null
+++ b/libraries/mentor/std_logic_arith_body.vhdl
@@ -0,0 +1,2915 @@
+LIBRARY ieee;
+-- LIBRARY arithmetic;
+
+PACKAGE BODY std_logic_arith IS
+
+ USE ieee.std_logic_1164.ALL;
+ -- USE arithmetic.utils.all;
+
+ -------------------------------------------------------------------
+ -- Local Types
+ -------------------------------------------------------------------
+ TYPE stdlogic_1d IS ARRAY (std_ulogic) OF std_ulogic;
+ TYPE stdlogic_table IS ARRAY(std_ulogic, std_ulogic) OF std_ulogic;
+ TYPE stdlogic_boolean_table IS ARRAY(std_ulogic, std_ulogic) OF BOOLEAN;
+
+ --------------------------------------------------------------------
+ --------------------------------------------------------------------
+ -- FUNCTIONS DEFINED FOR SYNTHESIS
+ --------------------------------------------------------------------
+ --------------------------------------------------------------------
+
+ FUNCTION std_ulogic_wired_or ( input : std_ulogic_vector ) RETURN std_ulogic IS
+ VARIABLE result : std_ulogic := '-'; -- weakest state default
+ CONSTANT resolution_table : stdlogic_table := (
+ -- ---------------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ---------------------------------------------------------
+ ( 'X', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ), -- | U |
+ ( 'X', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ), -- | X |
+ ( 'X', 'X', '0', '1', '0', 'X', '0', '1', '0' ), -- | 0 |
+ ( '1', '1', '1', '1', '1', '1', '1', '1', '1' ), -- | 1 |
+ ( 'X', 'X', '0', '1', 'Z', 'X', '0', '1', 'Z' ), -- | Z |
+ ( 'X', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ), -- | W |
+ ( 'X', 'X', '0', '1', '0', 'X', '0', '1', '0' ), -- | L |
+ ( '1', '1', '1', '1', '1', '1', '1', '1', '1' ), -- | H |
+ ( 'X', 'X', '0', '1', 'Z', 'X', '0', '1', 'Z' ) -- | D |
+ );
+
+ BEGIN
+ -- Iterate through all inputs
+ FOR i IN input'range LOOP
+ result := resolution_table(result, input(i));
+ END LOOP;
+ -- Return the resultant value
+ RETURN result;
+ END std_ulogic_wired_or;
+
+ FUNCTION std_ulogic_wired_and ( input : std_ulogic_vector ) RETURN std_ulogic IS
+ VARIABLE result : std_ulogic := '-'; -- weakest state default
+ CONSTANT resolution_table : stdlogic_table := (
+ -- ---------------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ---------------------------------------------------------
+ ( 'X', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), -- | U |
+ ( 'X', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), -- | X |
+ ( '0', '0', '0', '0', '0', '0', '0', '0', '0' ), -- | 0 |
+ ( 'X', 'X', '0', '1', '1', 'X', '0', '1', '1' ), -- | 1 |
+ ( 'X', 'X', '0', '1', 'Z', 'X', '0', '1', 'Z' ), -- | Z |
+ ( 'X', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), -- | W |
+ ( '0', '0', '0', '0', '0', '0', '0', '0', '0' ), -- | L |
+ ( 'X', 'X', '0', '1', '1', 'X', '0', '1', '1' ), -- | H |
+ ( 'X', 'X', '0', '1', 'Z', 'X', '0', '1', 'Z' ) -- | D |
+ );
+
+ BEGIN
+ -- Iterate through all inputs
+ FOR i IN input'range LOOP
+ result := resolution_table(result, input(i));
+ END LOOP;
+ -- Return the resultant value
+ RETURN result;
+ END std_ulogic_wired_and;
+
+--
+-- MGC base level functions
+--
+--
+-- Convert Base Type to Integer
+--
+ FUNCTION to_integer (arg1 : STD_ULOGIC_VECTOR; x : INTEGER := 0 ) RETURN INTEGER IS
+ VARIABLE tmp : SIGNED( arg1'length - 1 DOWNTO 0 ) := (OTHERS => '0');
+ VARIABLE result : INTEGER;
+ BEGIN
+ tmp := SIGNED(arg1);
+ result := TO_INTEGER( tmp, x );
+ RETURN (result);
+ END to_integer;
+
+ FUNCTION to_integer (arg1 : STD_LOGIC_VECTOR; x : INTEGER := 0 ) RETURN INTEGER IS
+ VARIABLE tmp : SIGNED( arg1'length - 1 DOWNTO 0 ) := (OTHERS => '0');
+ VARIABLE result : INTEGER;
+ BEGIN
+ tmp := SIGNED(arg1);
+ result := TO_INTEGER( tmp, x );
+ RETURN (result);
+ END to_integer;
+
+ FUNCTION to_integer (arg1 : UNSIGNED; x : INTEGER := 0 ) RETURN NATURAL IS
+ VARIABLE tmp : SIGNED( arg1'length DOWNTO 0 ) := (OTHERS => '0');
+ VARIABLE result : NATURAL;
+ BEGIN
+ tmp := '0' & SIGNED(arg1);
+ result := TO_INTEGER( tmp, x );
+ RETURN (result);
+ END to_integer;
+
+ FUNCTION TO_INTEGER (arg1 : SIGNED; x : INTEGER := 0 ) RETURN INTEGER IS
+ VARIABLE return_int,x_tmp : INTEGER := 0;
+ BEGIN
+ ASSERT arg1'length > 0
+ REPORT "NULL vector, returning 0"
+ SEVERITY NOTE;
+ assert arg1'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ ASSERT arg1'length <= 32 -- implementation dependent limit
+ REPORT "vector too large, conversion may cause overflow"
+ SEVERITY WARNING;
+ IF x /= 0 THEN
+ x_tmp := 1;
+ END IF;
+ IF arg1(arg1'left) = '0' OR arg1(arg1'left) = 'L' OR -- positive value
+ ( x_tmp = 0 AND arg1(arg1'left) /= '1' AND arg1(arg1'left) /= 'H') THEN
+ FOR i IN arg1'range LOOP
+ return_int := return_int * 2;
+ CASE arg1(i) IS
+ WHEN '0'|'L' => NULL;
+ WHEN '1'|'H' => return_int := return_int + 1;
+ WHEN OTHERS => return_int := return_int + x_tmp;
+ END CASE;
+ END LOOP;
+ ELSE -- negative value
+ IF (x_tmp = 0) THEN
+ x_tmp := 1;
+ ELSE
+ x_tmp := 0;
+ END IF;
+ FOR i IN arg1'range LOOP
+ return_int := return_int * 2;
+ CASE arg1(i) IS
+ WHEN '0'|'L' => return_int := return_int + 1;
+ WHEN '1'|'H' => NULL;
+ WHEN OTHERS => return_int := return_int + x_tmp;
+ END CASE;
+ END LOOP;
+ return_int := (-return_int) - 1;
+ END IF;
+ RETURN return_int;
+ END TO_INTEGER;
+
+ FUNCTION to_integer (arg1:STD_LOGIC; x : INTEGER := 0 ) RETURN NATURAL IS
+ BEGIN
+ IF(arg1 = '0' OR arg1 = 'L' OR (x = 0 AND arg1 /= '1' AND arg1 /= 'H')) THEN
+ RETURN(0);
+ ELSE
+ RETURN(1) ;
+ END IF ;
+ END ;
+
+ FUNCTION conv_integer (arg1 : STD_ULOGIC_VECTOR; x : INTEGER := 0 ) RETURN INTEGER IS
+ VARIABLE tmp : SIGNED( arg1'length - 1 DOWNTO 0 ) := (OTHERS => '0');
+ VARIABLE result : INTEGER;
+ BEGIN
+ tmp := SIGNED(arg1);
+ result := TO_INTEGER( tmp, x );
+ RETURN (result);
+ END ;
+
+ FUNCTION conv_integer (arg1 : STD_LOGIC_VECTOR; x : INTEGER := 0 ) RETURN INTEGER IS
+ VARIABLE tmp : SIGNED( arg1'length -1 DOWNTO 0 ) := (OTHERS => '0');
+ VARIABLE result : INTEGER;
+ BEGIN
+ tmp := SIGNED(arg1);
+ result := TO_INTEGER( tmp, x );
+ RETURN (result);
+ END ;
+
+ FUNCTION conv_integer (arg1 : UNSIGNED; x : INTEGER := 0 ) RETURN NATURAL IS
+ VARIABLE tmp : SIGNED( arg1'length DOWNTO 0 ) := (OTHERS => '0');
+ VARIABLE result : NATURAL;
+ BEGIN
+ tmp := '0' & SIGNED(arg1);
+ result := TO_INTEGER( tmp, x );
+ RETURN (result);
+ END ;
+
+ FUNCTION conv_INTEGER (arg1 : SIGNED; x : INTEGER := 0 ) RETURN INTEGER IS
+ VARIABLE return_int,x_tmp : INTEGER := 0;
+ BEGIN
+ ASSERT arg1'length > 0
+ REPORT "NULL vector, returning 0"
+ SEVERITY NOTE;
+ assert arg1'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ ASSERT arg1'length <= 32 -- implementation dependent limit
+ REPORT "vector too large, conversion may cause overflow"
+ SEVERITY WARNING;
+ IF x /= 0 THEN
+ x_tmp := 1;
+ END IF;
+ IF arg1(arg1'left) = '0' OR arg1(arg1'left) = 'L' OR -- positive value
+ ( x_tmp = 0 AND arg1(arg1'left) /= '1' AND arg1(arg1'left) /= 'H') THEN
+ FOR i IN arg1'range LOOP
+ return_int := return_int * 2;
+ CASE arg1(i) IS
+ WHEN '0'|'L' => NULL;
+ WHEN '1'|'H' => return_int := return_int + 1;
+ WHEN OTHERS => return_int := return_int + x_tmp;
+ END CASE;
+ END LOOP;
+ ELSE -- negative value
+ IF (x_tmp = 0) THEN
+ x_tmp := 1;
+ ELSE
+ x_tmp := 0;
+ END IF;
+ FOR i IN arg1'range LOOP
+ return_int := return_int * 2;
+ CASE arg1(i) IS
+ WHEN '0'|'L' => return_int := return_int + 1;
+ WHEN '1'|'H' => NULL;
+ WHEN OTHERS => return_int := return_int + x_tmp;
+ END CASE;
+ END LOOP;
+ return_int := (-return_int) - 1;
+ END IF;
+ RETURN return_int;
+ END ;
+
+ FUNCTION conv_integer (arg1:STD_LOGIC; x : INTEGER := 0 ) RETURN NATURAL IS
+ BEGIN
+ IF(arg1 = '0' OR arg1 = 'L' OR (x = 0 AND arg1 /= '1' AND arg1 /= 'H')) THEN
+ RETURN(0);
+ ELSE
+ RETURN(1) ;
+ END IF ;
+ END ;
+
+--
+-- Convert Base Type to STD_LOGIC
+--
+
+ FUNCTION to_stdlogic (arg1:BOOLEAN) RETURN STD_LOGIC IS
+ BEGIN
+ IF(arg1) THEN
+ RETURN('1') ;
+ ELSE
+ RETURN('0') ;
+ END IF ;
+ END ;
+
+--
+-- Convert Base Type to STD_LOGIC_VECTOR
+--
+ FUNCTION To_StdlogicVector (arg1 : integer; size : NATURAL) RETURN std_logic_vector IS
+ VARIABLE vector : std_logic_vector(0 TO size-1);
+ VARIABLE tmp_int : integer := arg1;
+ VARIABLE carry : std_logic := '1'; -- setup to add 1 if needed
+ VARIABLE carry2 : std_logic;
+ BEGIN
+ FOR i IN size-1 DOWNTO 0 LOOP
+ IF tmp_int MOD 2 = 1 THEN
+ vector(i) := '1';
+ ELSE
+ vector(i) := '0';
+ END IF;
+ tmp_int := tmp_int / 2;
+ END LOOP;
+
+ IF arg1 < 0 THEN
+ FOR i IN size-1 DOWNTO 0 LOOP
+ carry2 := (NOT vector(i)) AND carry;
+ vector(i) := (NOT vector(i)) XOR carry;
+ carry := carry2;
+ END LOOP;
+ END IF;
+ RETURN vector;
+ END To_StdlogicVector;
+
+ FUNCTION To_StdUlogicVector (arg1 : integer; size : NATURAL) RETURN std_ulogic_vector IS
+ VARIABLE vector : std_ulogic_vector(0 TO size-1);
+ VARIABLE tmp_int : integer := arg1;
+ VARIABLE carry : std_ulogic := '1'; -- setup to add 1 if needed
+ VARIABLE carry2 : std_ulogic;
+ BEGIN
+ FOR i IN size-1 DOWNTO 0 LOOP
+ IF tmp_int MOD 2 = 1 THEN
+ vector(i) := '1';
+ ELSE
+ vector(i) := '0';
+ END IF;
+ tmp_int := tmp_int / 2;
+ END LOOP;
+
+ IF arg1 < 0 THEN
+ FOR i IN size-1 DOWNTO 0 LOOP
+ carry2 := (NOT vector(i)) AND carry;
+ vector(i) := (NOT vector(i)) XOR carry;
+ carry := carry2;
+ END LOOP;
+ END IF;
+ RETURN vector;
+ END To_StdUlogicVector;
+
+
+--
+-- Convert Base Type to UNSIGNED
+--
+
+ FUNCTION to_unsigned (arg1:NATURAL ; size:NATURAL) RETURN UNSIGNED IS
+ VARIABLE vector : UNSIGNED(0 TO size-1) := (OTHERS => '0');
+ VARIABLE tmp_int : INTEGER := arg1;
+ BEGIN
+ FOR i IN size-1 DOWNTO 0 LOOP
+ IF tmp_int MOD 2 = 1 THEN
+ vector(i) := '1';
+ ELSE
+ vector(i) := '0';
+ END IF;
+ tmp_int := tmp_int / 2;
+ END LOOP;
+
+ RETURN vector;
+ END ;
+
+ FUNCTION conv_unsigned (arg1:NATURAL ; size:NATURAL) RETURN UNSIGNED IS
+ VARIABLE vector : UNSIGNED(0 TO size-1) := (OTHERS => '0');
+ VARIABLE tmp_int : INTEGER := arg1;
+ BEGIN
+ FOR i IN size-1 DOWNTO 0 LOOP
+ IF tmp_int MOD 2 = 1 THEN
+ vector(i) := '1';
+ ELSE
+ vector(i) := '0';
+ END IF;
+ tmp_int := tmp_int / 2;
+ END LOOP;
+
+ RETURN vector;
+ END ;
+
+--
+-- Convert Base Type to SIGNED
+--
+
+ FUNCTION to_signed (arg1:INTEGER ; size : NATURAL) RETURN SIGNED IS
+ VARIABLE vector : SIGNED(0 TO size-1) := (OTHERS => '0');
+ VARIABLE tmp_int : INTEGER := arg1;
+ VARIABLE carry : STD_LOGIC := '1'; -- setup to add 1 if needed
+ VARIABLE carry2 : STD_LOGIC := '0';
+ BEGIN
+ FOR i IN size-1 DOWNTO 0 LOOP
+ IF tmp_int MOD 2 = 1 THEN
+ vector(i) := '1';
+ ELSE
+ vector(i) := '0';
+ END IF;
+ tmp_int := tmp_int / 2;
+ END LOOP;
+
+ IF arg1 < 0 THEN
+ FOR i IN size-1 DOWNTO 0 LOOP
+ carry2 := (NOT vector(i)) AND carry;
+ vector(i) := (NOT vector(i)) XOR carry;
+ carry := carry2;
+ END LOOP;
+ END IF;
+ RETURN vector;
+ END ;
+
+ FUNCTION conv_signed (arg1:INTEGER ; size : NATURAL) RETURN SIGNED IS
+ VARIABLE vector : SIGNED(0 TO size-1) := (OTHERS => '0');
+ VARIABLE tmp_int : INTEGER := arg1;
+ VARIABLE carry : STD_LOGIC := '1'; -- setup to add 1 if needed
+ VARIABLE carry2 : STD_LOGIC := '0';
+ BEGIN
+ FOR i IN size-1 DOWNTO 0 LOOP
+ IF tmp_int MOD 2 = 1 THEN
+ vector(i) := '1';
+ ELSE
+ vector(i) := '0';
+ END IF;
+ tmp_int := tmp_int / 2;
+ END LOOP;
+
+ IF arg1 < 0 THEN
+ FOR i IN size-1 DOWNTO 0 LOOP
+ carry2 := (NOT vector(i)) AND carry;
+ vector(i) := (NOT vector(i)) XOR carry;
+ carry := carry2;
+ END LOOP;
+ END IF;
+ RETURN vector;
+ END ;
+
+ -- sign/zero extend functions
+ --
+
+ FUNCTION zero_extend ( arg1 : STD_ULOGIC_VECTOR; size : NATURAL ) RETURN STD_ULOGIC_VECTOR
+ IS
+ VARIABLE answer : STD_ULOGIC_VECTOR(size-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ ASSERT arg1'length <= size
+ REPORT "Vector is already larger then size."
+ SEVERITY WARNING ;
+ answer := (OTHERS => '0') ;
+ answer(arg1'length-1 DOWNTO 0) := arg1;
+ RETURN(answer) ;
+ END ;
+
+ FUNCTION zero_extend ( arg1 : STD_LOGIC_VECTOR; size : NATURAL ) RETURN STD_LOGIC_VECTOR
+ IS
+ VARIABLE answer : STD_LOGIC_VECTOR(size-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ ASSERT arg1'length <= size
+ REPORT "Vector is already larger then size."
+ SEVERITY WARNING ;
+ answer := (OTHERS => '0') ;
+ answer(arg1'length-1 DOWNTO 0) := arg1;
+ RETURN(answer) ;
+ END ;
+
+ FUNCTION zero_extend ( arg1 : STD_LOGIC; size : NATURAL ) RETURN STD_LOGIC_VECTOR
+ IS
+ VARIABLE answer : STD_LOGIC_VECTOR(size-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ answer := (OTHERS => '0') ;
+ answer(0) := arg1;
+ RETURN(answer) ;
+ END ;
+
+ FUNCTION zero_extend ( arg1 : UNSIGNED; size : NATURAL ) RETURN UNSIGNED IS
+ VARIABLE answer : UNSIGNED(size-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ ASSERT arg1'length <= size
+ REPORT "Vector is already larger then size."
+ SEVERITY WARNING ;
+ answer := (OTHERS => '0') ;
+ answer(arg1'length - 1 DOWNTO 0) := arg1;
+ RETURN(answer) ;
+ END ;
+
+ FUNCTION sign_extend ( arg1 : SIGNED; size : NATURAL ) RETURN SIGNED IS
+ VARIABLE answer : SIGNED(size-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ ASSERT arg1'length <= size
+ REPORT "Vector is already larger then size."
+ SEVERITY WARNING ;
+ answer := (OTHERS => arg1(arg1'left)) ;
+ answer(arg1'length - 1 DOWNTO 0) := arg1;
+ RETURN(answer) ;
+ END ;
+
+
+
+ -- Some useful generic functions
+
+ --//// Zero Extend ////
+ --
+ -- Function zxt
+ --
+ FUNCTION zxt( q : STD_ULOGIC_VECTOR; i : INTEGER ) RETURN STD_ULOGIC_VECTOR IS
+ VARIABLE qs : STD_ULOGIC_VECTOR (1 TO i);
+ VARIABLE qt : STD_ULOGIC_VECTOR (1 TO q'length);
+ BEGIN
+ qt := q;
+ IF i < q'length THEN
+ qs := qt( (q'length-i+1) TO qt'right);
+ ELSIF i > q'length THEN
+ qs := (OTHERS=>'0');
+ qs := qs(1 TO (i-q'length)) & qt;
+ ELSE
+ qs := qt;
+ END IF;
+ RETURN qs;
+ END;
+
+ --//// Zero Extend ////
+ --
+ -- Function zxt
+ --
+ FUNCTION zxt( q : STD_LOGIC_VECTOR; i : INTEGER ) RETURN STD_LOGIC_VECTOR IS
+ VARIABLE qs : STD_LOGIC_VECTOR (1 TO i);
+ VARIABLE qt : STD_LOGIC_VECTOR (1 TO q'length);
+ BEGIN
+ qt := q;
+ IF i < q'length THEN
+ qs := qt( (q'length-i+1) TO qt'right);
+ ELSIF i > q'length THEN
+ qs := (OTHERS=>'0');
+ qs := qs(1 TO (i-q'length)) & qt;
+ ELSE
+ qs := qt;
+ END IF;
+ RETURN qs;
+ END;
+
+ --//// Zero Extend ////
+ --
+ -- Function zxt
+ --
+ FUNCTION zxt( q : UNSIGNED; i : INTEGER ) RETURN UNSIGNED IS
+ VARIABLE qs : UNSIGNED (1 TO i);
+ VARIABLE qt : UNSIGNED (1 TO q'length);
+ BEGIN
+ qt := q;
+ IF i < q'length THEN
+ qs := qt( (q'length-i+1) TO qt'right);
+ ELSIF i > q'length THEN
+ qs := (OTHERS=>'0');
+ qs := qs(1 TO (i-q'length)) & qt;
+ ELSE
+ qs := qt;
+ END IF;
+ RETURN qs;
+ END;
+
+--------------------------------------
+-- Synthesizable addition Functions --
+--------------------------------------
+
+ FUNCTION "+" ( arg1, arg2 : STD_LOGIC ) RETURN STD_LOGIC IS
+ -- truth table for "xor" function
+ CONSTANT xor_table : stdlogic_table := (
+ -- ----------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------
+ ( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- | U |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | 0 |
+ ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' ), -- | 1 |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | Z |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | W |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | L |
+ ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' ), -- | H |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ) -- | D |
+ );
+ BEGIN
+ RETURN xor_table( arg1, arg2 );
+ END "+";
+
+ function maximum (arg1, arg2: integer) return integer is
+ begin
+ if arg1 > arg2 then
+ return arg1;
+ else
+ return arg2;
+ end if;
+ end;
+
+ FUNCTION "+" (arg1, arg2 :STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR IS
+ CONSTANT ml : INTEGER := maximum(arg1'length,arg2'length);
+ VARIABLE lt : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE rt : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE res : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE carry : STD_ULOGIC := '0';
+ VARIABLE a,b,s1 : STD_ULOGIC;
+ BEGIN
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+
+ FOR i IN res'reverse_range LOOP
+ a := lt(i);
+ b := rt(i);
+ s1 := a + b;
+ res(i) := s1 + carry;
+ carry := (a AND b) OR (s1 AND carry);
+ END LOOP;
+ RETURN res;
+ END;
+
+ FUNCTION "+" (arg1, arg2 :STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+ CONSTANT ml : INTEGER := maximum(arg1'length,arg2'length);
+ VARIABLE lt : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE rt : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE res : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE carry : STD_LOGIC := '0';
+ VARIABLE a,b,s1 : STD_LOGIC;
+ BEGIN
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+
+ FOR i IN res'reverse_range LOOP
+ a := lt(i);
+ b := rt(i);
+ s1 := a + b;
+ res(i) := s1 + carry;
+ carry := (a AND b) OR (s1 AND carry);
+ END LOOP;
+ RETURN res;
+ END;
+
+ FUNCTION "+" (arg1, arg2:UNSIGNED) RETURN UNSIGNED IS
+ CONSTANT ml : INTEGER := maximum(arg1'length,arg2'length);
+ VARIABLE lt : UNSIGNED(1 TO ml);
+ VARIABLE rt : UNSIGNED(1 TO ml);
+ VARIABLE res : UNSIGNED(1 TO ml);
+ VARIABLE carry : STD_LOGIC := '0';
+ VARIABLE a,b,s1 : STD_LOGIC;
+ BEGIN
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+
+ FOR i IN res'reverse_range LOOP
+ a := lt(i);
+ b := rt(i);
+ s1 := a + b;
+ res(i) := s1 + carry;
+ carry := (a AND b) OR (s1 AND carry);
+ END LOOP;
+ RETURN res;
+ END;
+
+ FUNCTION "+" (arg1, arg2:SIGNED) RETURN SIGNED IS
+ CONSTANT len : INTEGER := maximum(arg1'length,arg2'length) ;
+ VARIABLE a,b : UNSIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ VARIABLE answer : SIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ assert arg1'length > 1 AND arg2'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ a := (OTHERS => arg1(arg1'left)) ;
+ a(arg1'length - 1 DOWNTO 0) := UNSIGNED(arg1);
+ b := (OTHERS => arg2(arg2'left)) ;
+ b(arg2'length - 1 DOWNTO 0) := UNSIGNED(arg2);
+ answer := SIGNED(a + b);
+ RETURN (answer);
+ END ;
+
+-----------------------------------------
+-- Synthesizable subtraction Functions --
+-----------------------------------------
+
+ FUNCTION "-" ( arg1, arg2 : std_logic ) RETURN std_logic IS
+ -- truth table for "xor" function
+ CONSTANT xor_table : stdlogic_table := (
+ -- ----------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------
+ ( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- | U |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | 0 |
+ ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' ), -- | 1 |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | Z |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | W |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | L |
+ ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' ), -- | H |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ) -- | D |
+ );
+ BEGIN
+ RETURN xor_table( arg1, arg2 );
+ END "-";
+
+ FUNCTION "-" (arg1, arg2:STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR IS
+ CONSTANT ml : INTEGER := maximum(arg1'length,arg2'length);
+ VARIABLE lt : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE rt : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE res : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE borrow : STD_ULOGIC := '1';
+ VARIABLE a,b,s1 : STD_ULOGIC;
+ BEGIN
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+
+ FOR i IN res'reverse_range LOOP
+ a := lt(i);
+ b := NOT rt(i);
+ s1 := a + b;
+ res(i) := s1 + borrow;
+ borrow := (a AND b) OR (s1 AND borrow);
+ END LOOP;
+ RETURN res;
+ END "-";
+
+ FUNCTION "-" (arg1, arg2:STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+ CONSTANT ml : INTEGER := maximum(arg1'length,arg2'length);
+ VARIABLE lt : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE rt : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE res : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE borrow : STD_LOGIC := '1';
+ VARIABLE a,b,s1 : STD_LOGIC;
+ BEGIN
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+
+ FOR i IN res'reverse_range LOOP
+ a := lt(i);
+ b := NOT rt(i);
+ s1 := a + b;
+ res(i) := s1 + borrow;
+ borrow := (a AND b) OR (s1 AND borrow);
+ END LOOP;
+ RETURN res;
+ END "-";
+
+ FUNCTION "-" (arg1, arg2:UNSIGNED) RETURN UNSIGNED IS
+ CONSTANT ml : INTEGER := maximum(arg1'length,arg2'length);
+ VARIABLE lt : UNSIGNED(1 TO ml);
+ VARIABLE rt : UNSIGNED(1 TO ml);
+ VARIABLE res : UNSIGNED(1 TO ml);
+ VARIABLE borrow : STD_LOGIC := '1';
+ VARIABLE a,b,s1 : STD_LOGIC;
+ BEGIN
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+
+ FOR i IN res'reverse_range LOOP
+ a := lt(i);
+ b := NOT rt(i);
+ s1 := a + b;
+ res(i) := s1 + borrow;
+ borrow := (a AND b) OR (s1 AND borrow);
+ END LOOP;
+ RETURN res;
+ END "-";
+
+
+ FUNCTION "-" (arg1, arg2:SIGNED) RETURN SIGNED IS
+ CONSTANT len : INTEGER := maximum(arg1'length,arg2'length) ;
+ VARIABLE a,b : UNSIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ VARIABLE answer : SIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ assert arg1'length > 1 AND arg2'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ a := (OTHERS => arg1(arg1'left)) ;
+ a(arg1'length - 1 DOWNTO 0) := UNSIGNED(arg1);
+ b := (OTHERS => arg2(arg2'left)) ;
+ b(arg2'length - 1 DOWNTO 0) := UNSIGNED(arg2);
+ answer := SIGNED( a - b );
+ RETURN (answer);
+ END ;
+
+-----------------------------------------
+-- Unary subtract and add Functions --
+-----------------------------------------
+ FUNCTION "+" (arg1:STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR IS
+ BEGIN
+ RETURN (arg1);
+ END;
+
+ FUNCTION "+" (arg1:STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+ BEGIN
+ RETURN (arg1);
+ END;
+
+ FUNCTION "+" (arg1:UNSIGNED) RETURN UNSIGNED IS
+ BEGIN
+ RETURN (arg1);
+ END;
+
+ FUNCTION "+" (arg1:SIGNED) RETURN SIGNED IS
+ BEGIN
+ RETURN (arg1);
+ END;
+
+ FUNCTION hasx( v : SIGNED ) RETURN BOOLEAN IS
+ BEGIN
+ FOR i IN v'range LOOP
+ IF v(i) = '0' OR v(i) = '1' OR v(i) = 'L' OR v(i) = 'H'THEN
+ NULL;
+ ELSE
+ RETURN TRUE;
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END hasx;
+
+ FUNCTION "-" (arg1:SIGNED) RETURN SIGNED IS
+ constant len : integer := arg1'length;
+ VARIABLE answer, tmp : SIGNED( len-1 downto 0 ) := (others=>'0');
+ VARIABLE index : integer := len;
+ BEGIN
+ assert arg1'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ IF hasx(arg1) THEN
+ answer := (OTHERS => 'X');
+ ELSE
+ tmp := arg1;
+ lp1 : FOR i IN answer'REVERSE_RANGE LOOP
+ IF (tmp(i) = '1' OR tmp(i) = 'H') THEN
+ index := i+1;
+ answer(i downto 0) := tmp(i downto 0);
+ exit;
+ END IF;
+ END LOOP lp1;
+ answer(len-1 downto index) := NOT tmp(len-1 downto index);
+ end if;
+ RETURN (answer);
+ END ;
+
+--------------------------------------------
+-- Synthesizable multiplication Functions --
+--------------------------------------------
+ FUNCTION shift( v : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR IS
+ VARIABLE v1 : STD_ULOGIC_VECTOR( v'range );
+ BEGIN
+ FOR i IN (v'left+1) TO v'right LOOP
+ v1(i-1) := v(i);
+ END LOOP;
+ v1(v1'right) := '0';
+ RETURN v1;
+ END shift;
+
+ PROCEDURE copy(a : IN STD_ULOGIC_VECTOR; b : OUT STD_ULOGIC_VECTOR) IS
+ VARIABLE bi : INTEGER := b'right;
+ BEGIN
+ FOR i IN a'reverse_range LOOP
+ b(bi) := a(i);
+ bi := bi - 1;
+ END LOOP;
+ END copy;
+
+ FUNCTION shift( v : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR IS
+ VARIABLE v1 : STD_LOGIC_VECTOR( v'range );
+ BEGIN
+ FOR i IN (v'left+1) TO v'right LOOP
+ v1(i-1) := v(i);
+ END LOOP;
+ v1(v1'right) := '0';
+ RETURN v1;
+ END shift;
+
+ PROCEDURE copy(a : IN STD_LOGIC_VECTOR; b : OUT STD_LOGIC_VECTOR) IS
+ VARIABLE bi : INTEGER := b'right;
+ BEGIN
+ FOR i IN a'reverse_range LOOP
+ b(bi) := a(i);
+ bi := bi - 1;
+ END LOOP;
+ END copy;
+
+ FUNCTION shift( v : SIGNED ) RETURN SIGNED IS
+ VARIABLE v1 : SIGNED( v'range );
+ BEGIN
+ FOR i IN (v'left+1) TO v'right LOOP
+ v1(i-1) := v(i);
+ END LOOP;
+ v1(v1'right) := '0';
+ RETURN v1;
+ END shift;
+
+ PROCEDURE copy(a : IN SIGNED; b : OUT SIGNED) IS
+ VARIABLE bi : INTEGER := b'right;
+ BEGIN
+ FOR i IN a'reverse_range LOOP
+ b(bi) := a(i);
+ bi := bi - 1;
+ END LOOP;
+ END copy;
+
+ FUNCTION shift( v : UNSIGNED ) RETURN UNSIGNED IS
+ VARIABLE v1 : UNSIGNED( v'range );
+ BEGIN
+ FOR i IN (v'left+1) TO v'right LOOP
+ v1(i-1) := v(i);
+ END LOOP;
+ v1(v1'right) := '0';
+ RETURN v1;
+ END shift;
+
+ PROCEDURE copy(a : IN UNSIGNED; b : OUT UNSIGNED) IS
+ VARIABLE bi : INTEGER := b'right;
+ BEGIN
+ FOR i IN a'reverse_range LOOP
+ b(bi) := a(i);
+ bi := bi - 1;
+ END LOOP;
+ END copy;
+
+ FUNCTION "*" (arg1, arg2:STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR IS
+ VARIABLE ml : INTEGER := arg1'length + arg2'length;
+ VARIABLE lt : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE rt : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE prod : STD_ULOGIC_VECTOR(1 TO ml) := (OTHERS=>'0');
+ BEGIN
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN rt'reverse_range LOOP
+ IF rt(i) = '1' THEN
+ prod := prod + lt;
+ END IF;
+ lt := shift(lt);
+ END LOOP;
+ RETURN prod;
+ END "*";
+
+ FUNCTION "*" (arg1, arg2:STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+ VARIABLE ml : INTEGER := arg1'length + arg2'length;
+ VARIABLE lt : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE rt : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE prod : STD_LOGIC_VECTOR(1 TO ml) := (OTHERS=>'0');
+ BEGIN
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN rt'reverse_range LOOP
+ IF rt(i) = '1' THEN
+ prod := prod + lt;
+ END IF;
+ lt := shift(lt);
+ END LOOP;
+ RETURN prod;
+ END "*";
+
+ FUNCTION "*" (arg1, arg2:UNSIGNED) RETURN UNSIGNED IS
+ VARIABLE ml : INTEGER := arg1'length + arg2'length;
+ VARIABLE lt : UNSIGNED(1 TO ml);
+ VARIABLE rt : UNSIGNED(1 TO ml);
+ VARIABLE prod : UNSIGNED(1 TO ml) := (OTHERS=>'0');
+ BEGIN
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN rt'reverse_range LOOP
+ IF rt(i) = '1' THEN
+ prod := prod + lt;
+ END IF;
+ lt := shift(lt);
+ END LOOP;
+ RETURN prod;
+ END "*";
+
+ --//// Sign Extend ////
+ --
+ -- Function sxt
+ --
+ FUNCTION sxt( q : SIGNED; i : INTEGER ) RETURN SIGNED IS
+ VARIABLE qs : SIGNED (1 TO i);
+ VARIABLE qt : SIGNED (1 TO q'length);
+ BEGIN
+ qt := q;
+ IF i < q'length THEN
+ qs := qt( (q'length-i+1) TO qt'right);
+ ELSIF i > q'length THEN
+ qs := (OTHERS=>q(q'left));
+ qs := qs(1 TO (i-q'length)) & qt;
+ ELSE
+ qs := qt;
+ END IF;
+ RETURN qs;
+ END;
+
+ FUNCTION "*" (arg1, arg2:SIGNED) RETURN SIGNED IS
+ VARIABLE ml : INTEGER := arg1'length + arg2'length;
+ VARIABLE lt : SIGNED(1 TO ml);
+ VARIABLE rt : SIGNED(1 TO ml);
+ VARIABLE prod : SIGNED(1 TO ml) := (OTHERS=>'0');
+ BEGIN
+ assert arg1'length > 1 AND arg2'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := sxt( arg1, ml );
+ rt := sxt( arg2, ml );
+ FOR i IN rt'reverse_range LOOP
+ IF rt(i) = '1' THEN
+ prod := prod + lt;
+ END IF;
+ lt := shift(lt);
+ END LOOP;
+ RETURN prod;
+ END "*";
+
+ FUNCTION rshift( v : STD_ULOGIC_VECTOR ) RETURN STD_ULOGIC_VECTOR IS
+ VARIABLE v1 : STD_ULOGIC_VECTOR( v'range );
+ BEGIN
+ FOR i IN v'left TO v'right-1 LOOP
+ v1(i+1) := v(i);
+ END LOOP;
+ v1(v1'left) := '0';
+ RETURN v1;
+ END rshift;
+
+ FUNCTION hasx( v : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
+ BEGIN
+ FOR i IN v'range LOOP
+ IF v(i) = '0' OR v(i) = '1' OR v(i) = 'L' OR v(i) = 'H'THEN
+ NULL;
+ ELSE
+ RETURN TRUE;
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END hasx;
+
+ FUNCTION rshift( v : STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR IS
+ VARIABLE v1 : STD_LOGIC_VECTOR( v'range );
+ BEGIN
+ FOR i IN v'left TO v'right-1 LOOP
+ v1(i+1) := v(i);
+ END LOOP;
+ v1(v1'left) := '0';
+ RETURN v1;
+ END rshift;
+
+ FUNCTION hasx( v : STD_LOGIC_VECTOR ) RETURN BOOLEAN IS
+ BEGIN
+ FOR i IN v'range LOOP
+ IF v(i) = '0' OR v(i) = '1' OR v(i) = 'L' OR v(i) = 'H'THEN
+ NULL;
+ ELSE
+ RETURN TRUE;
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END hasx;
+
+ FUNCTION rshift( v : UNSIGNED ) RETURN UNSIGNED IS
+ VARIABLE v1 : UNSIGNED( v'range );
+ BEGIN
+ FOR i IN v'left TO v'right-1 LOOP
+ v1(i+1) := v(i);
+ END LOOP;
+ v1(v1'left) := '0';
+ RETURN v1;
+ END rshift;
+
+ FUNCTION hasx( v : UNSIGNED ) RETURN BOOLEAN IS
+ BEGIN
+ FOR i IN v'range LOOP
+ IF v(i) = '0' OR v(i) = '1' OR v(i) = 'L' OR v(i) = 'H'THEN
+ NULL;
+ ELSE
+ RETURN TRUE;
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END hasx;
+
+ FUNCTION rshift( v : SIGNED ) RETURN SIGNED IS
+ VARIABLE v1 : SIGNED( v'range );
+ BEGIN
+ FOR i IN v'left TO v'right-1 LOOP
+ v1(i+1) := v(i);
+ END LOOP;
+ v1(v1'left) := '0';
+ RETURN v1;
+ END rshift;
+
+ FUNCTION "/" (l, r :STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR IS
+
+ CONSTANT ml : INTEGER := maximum(l'length,r'length);
+ VARIABLE lt : STD_ULOGIC_VECTOR(0 TO ml+1);
+ VARIABLE rt : STD_ULOGIC_VECTOR(0 TO ml+1);
+ VARIABLE quote : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE tmp : STD_ULOGIC_VECTOR(0 TO ml+1) := (OTHERS=>'0');
+ VARIABLE n : STD_ULOGIC_VECTOR(0 TO ml+1) := (OTHERS=>'0');
+
+ BEGIN
+ ASSERT NOT (r = "0")
+ REPORT "Attempted divide by ZERO"
+ SEVERITY ERROR;
+ IF hasx(l) OR hasx(r) THEN
+ FOR i IN quote'range LOOP
+ quote(i) := 'X';
+ END LOOP;
+ ELSE
+ lt := zxt( l, ml+2 );
+ WHILE lt >= r LOOP
+ rt := zxt( r, ml+2 );
+ n := (OTHERS=>'0');
+ n(n'right) := '1';
+ WHILE rt <= lt LOOP
+ rt := shift(rt);
+ n := shift(n);
+ END LOOP;
+ rt := rshift(rt);
+ lt := lt - rt;
+ n := rshift(n);
+ tmp := tmp + n;
+ END LOOP;
+ END IF;
+ quote := tmp(2 TO ml+1);
+ RETURN quote;
+ END "/";
+
+ FUNCTION "/" (l, r :STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+
+ CONSTANT ml : INTEGER := maximum(l'length,r'length);
+ VARIABLE lt : STD_LOGIC_VECTOR(0 TO ml+1);
+ VARIABLE rt : STD_LOGIC_VECTOR(0 TO ml+1);
+ VARIABLE quote : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE tmp : STD_LOGIC_VECTOR(0 TO ml+1) := (OTHERS=>'0');
+ VARIABLE n : STD_LOGIC_VECTOR(0 TO ml+1) := (OTHERS=>'0');
+
+ BEGIN
+ ASSERT NOT (r = "0")
+ REPORT "Attempted divide by ZERO"
+ SEVERITY ERROR;
+ IF hasx(l) OR hasx(r) THEN
+ FOR i IN quote'range LOOP
+ quote(i) := 'X';
+ END LOOP;
+ ELSE
+ lt := zxt( l, ml+2 );
+ WHILE lt >= r LOOP
+ rt := zxt( r, ml+2 );
+ n := (OTHERS=>'0');
+ n(n'right) := '1';
+ WHILE rt <= lt LOOP
+ rt := shift(rt);
+ n := shift(n);
+ END LOOP;
+ rt := rshift(rt);
+ lt := lt - rt;
+ n := rshift(n);
+ tmp := tmp + n;
+ END LOOP;
+ END IF;
+ quote := tmp(2 TO ml+1);
+ RETURN quote;
+ END "/";
+
+ FUNCTION "/" (l, r :UNSIGNED) RETURN UNSIGNED IS
+
+ CONSTANT ml : INTEGER := maximum(l'length,r'length);
+ VARIABLE lt : UNSIGNED(0 TO ml+1);
+ VARIABLE rt : UNSIGNED(0 TO ml+1);
+ VARIABLE quote : UNSIGNED(1 TO ml);
+ VARIABLE tmp : UNSIGNED(0 TO ml+1) := (OTHERS=>'0');
+ VARIABLE n : UNSIGNED(0 TO ml+1) := (OTHERS=>'0');
+
+ BEGIN
+ ASSERT NOT (r = "0")
+ REPORT "Attempted divide by ZERO"
+ SEVERITY ERROR;
+ IF hasx(l) OR hasx(r) THEN
+ FOR i IN quote'range LOOP
+ quote(i) := 'X';
+ END LOOP;
+ ELSE
+ lt := zxt( l, ml+2 );
+ WHILE lt >= r LOOP
+ rt := zxt( r, ml+2 );
+ n := (OTHERS=>'0');
+ n(n'right) := '1';
+ WHILE rt <= lt LOOP
+ rt := shift(rt);
+ n := shift(n);
+ END LOOP;
+ rt := rshift(rt);
+ lt := lt - rt;
+ n := rshift(n);
+ tmp := tmp + n;
+ END LOOP;
+ END IF;
+ quote := tmp(2 TO ml+1);
+ RETURN quote;
+ END "/";
+
+ FUNCTION "/" (l, r :SIGNED) RETURN SIGNED IS
+
+ CONSTANT ml : INTEGER := maximum(l'length,r'length);
+ VARIABLE lt : SIGNED(0 TO ml+1);
+ VARIABLE rt : SIGNED(0 TO ml+1);
+ VARIABLE quote : SIGNED(1 TO ml);
+ VARIABLE tmp : SIGNED(0 TO ml+1) := (OTHERS=>'0');
+ VARIABLE n : SIGNED(0 TO ml+1) := (OTHERS=>'0');
+
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ ASSERT NOT (r = "0")
+ REPORT "Attempted divide by ZERO"
+ SEVERITY ERROR;
+ IF hasx(l) OR hasx(r) THEN
+ FOR i IN quote'range LOOP
+ quote(i) := 'X';
+ END LOOP;
+ ELSE
+ lt := sxt( l, ml+2 );
+ WHILE lt >= r LOOP
+ rt := sxt( r, ml+2 );
+ n := (OTHERS=>'0');
+ n(n'right) := '1';
+ WHILE rt <= lt LOOP
+ rt := shift(rt);
+ n := shift(n);
+ END LOOP;
+ rt := rshift(rt);
+ lt := lt - rt;
+ n := rshift(n);
+ tmp := tmp + n;
+ END LOOP;
+ END IF;
+ quote := tmp(2 TO ml+1);
+ RETURN quote;
+ END "/";
+
+ FUNCTION "MOD" (l, r :STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR IS
+
+ CONSTANT ml : INTEGER := maximum(l'length,r'length);
+ VARIABLE lt : STD_ULOGIC_VECTOR(0 TO ml+1);
+ VARIABLE rt : STD_ULOGIC_VECTOR(0 TO ml+1);
+ VARIABLE quote : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE tmp : STD_ULOGIC_VECTOR(0 TO ml+1) := (OTHERS=>'0');
+ VARIABLE n : STD_ULOGIC_VECTOR(0 TO ml) := (OTHERS=>'0');
+
+ BEGIN
+ ASSERT NOT (r = "0")
+ REPORT "Attempted divide by ZERO"
+ SEVERITY ERROR;
+ IF hasx(l) OR hasx(r) THEN
+ FOR i IN lt'range LOOP
+ lt(i) := 'X';
+ END LOOP;
+ ELSE
+ lt := zxt( l, ml+2 );
+ WHILE lt >= r LOOP
+ rt := zxt( r, ml+2 );
+ WHILE rt <= lt LOOP
+ rt := shift(rt);
+ END LOOP;
+ rt := rshift(rt);
+ lt := lt - rt;
+ END LOOP;
+ END IF;
+ RETURN lt(2 TO ml+1);
+ END "MOD";
+
+ FUNCTION "MOD" (l, r :STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+
+ CONSTANT ml : INTEGER := maximum(l'length,r'length);
+ VARIABLE lt : STD_LOGIC_VECTOR(0 TO ml+1);
+ VARIABLE rt : STD_LOGIC_VECTOR(0 TO ml+1);
+ VARIABLE quote : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE tmp : STD_LOGIC_VECTOR(0 TO ml+1) := (OTHERS=>'0');
+ VARIABLE n : STD_LOGIC_VECTOR(0 TO ml) := (OTHERS=>'0');
+
+ BEGIN
+ ASSERT NOT (r = "0")
+ REPORT "Attempted divide by ZERO"
+ SEVERITY ERROR;
+ IF hasx(l) OR hasx(r) THEN
+ FOR i IN lt'range LOOP
+ lt(i) := 'X';
+ END LOOP;
+ ELSE
+ lt := zxt( l, ml+2 );
+ WHILE lt >= r LOOP
+ rt := zxt( r, ml+2 );
+ WHILE rt <= lt LOOP
+ rt := shift(rt);
+ END LOOP;
+ rt := rshift(rt);
+ lt := lt - rt;
+ END LOOP;
+ END IF;
+ RETURN lt(2 TO ml+1);
+ END "MOD";
+
+ FUNCTION "MOD" (l, r :UNSIGNED) RETURN UNSIGNED IS
+
+ CONSTANT ml : INTEGER := maximum(l'length,r'length);
+ VARIABLE lt : UNSIGNED(0 TO ml+1);
+ VARIABLE rt : UNSIGNED(0 TO ml+1);
+ VARIABLE quote : UNSIGNED(1 TO ml);
+ VARIABLE tmp : UNSIGNED(0 TO ml+1) := (OTHERS=>'0');
+ VARIABLE n : UNSIGNED(0 TO ml) := (OTHERS=>'0');
+
+ BEGIN
+ ASSERT NOT (r = "0")
+ REPORT "Attempted divide by ZERO"
+ SEVERITY ERROR;
+ IF hasx(l) OR hasx(r) THEN
+ FOR i IN lt'range LOOP
+ lt(i) := 'X';
+ END LOOP;
+ ELSE
+ lt := zxt( l, ml+2 );
+ WHILE lt >= r LOOP
+ rt := zxt( r, ml+2 );
+ WHILE rt <= lt LOOP
+ rt := shift(rt);
+ END LOOP;
+ rt := rshift(rt);
+ lt := lt - rt;
+ END LOOP;
+ END IF;
+ RETURN lt(2 TO ml+1);
+ END "MOD";
+
+ FUNCTION "REM" (l, r :STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR IS
+
+ CONSTANT ml : INTEGER := maximum(l'length,r'length);
+ VARIABLE lt : STD_ULOGIC_VECTOR(0 TO ml+1);
+ VARIABLE rt : STD_ULOGIC_VECTOR(0 TO ml+1);
+ VARIABLE quote : STD_ULOGIC_VECTOR(1 TO ml);
+ VARIABLE tmp : STD_ULOGIC_VECTOR(0 TO ml+1) := (OTHERS=>'0');
+ VARIABLE n : STD_ULOGIC_VECTOR(0 TO ml) := (OTHERS=>'0');
+
+ BEGIN
+ ASSERT NOT (r = "0")
+ REPORT "Attempted divide by ZERO"
+ SEVERITY ERROR;
+ IF hasx(l) OR hasx(r) THEN
+ FOR i IN lt'range LOOP
+ lt(i) := 'X';
+ END LOOP;
+ ELSE
+ lt := zxt( l, ml+2 );
+ WHILE lt >= r LOOP
+ rt := zxt( r, ml+2 );
+ WHILE rt <= lt LOOP
+ rt := shift(rt);
+ END LOOP;
+ rt := rshift(rt);
+ lt := lt - rt;
+ END LOOP;
+ END IF;
+ RETURN lt(2 TO ml+1);
+ END "REM";
+
+ FUNCTION "REM" (l, r :STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+
+ CONSTANT ml : INTEGER := maximum(l'length,r'length);
+ VARIABLE lt : STD_LOGIC_VECTOR(0 TO ml+1);
+ VARIABLE rt : STD_LOGIC_VECTOR(0 TO ml+1);
+ VARIABLE quote : STD_LOGIC_VECTOR(1 TO ml);
+ VARIABLE tmp : STD_LOGIC_VECTOR(0 TO ml+1) := (OTHERS=>'0');
+ VARIABLE n : STD_LOGIC_VECTOR(0 TO ml) := (OTHERS=>'0');
+
+ BEGIN
+ ASSERT NOT (r = "0")
+ REPORT "Attempted divide by ZERO"
+ SEVERITY ERROR;
+ IF hasx(l) OR hasx(r) THEN
+ FOR i IN lt'range LOOP
+ lt(i) := 'X';
+ END LOOP;
+ ELSE
+ lt := zxt( l, ml+2 );
+ WHILE lt >= r LOOP
+ rt := zxt( r, ml+2 );
+ WHILE rt <= lt LOOP
+ rt := shift(rt);
+ END LOOP;
+ rt := rshift(rt);
+ lt := lt - rt;
+ END LOOP;
+ END IF;
+ RETURN lt(2 TO ml+1);
+ END "REM";
+
+ FUNCTION "REM" (l, r :UNSIGNED) RETURN UNSIGNED IS
+
+ CONSTANT ml : INTEGER := maximum(l'length,r'length);
+ VARIABLE lt : UNSIGNED(0 TO ml+1);
+ VARIABLE rt : UNSIGNED(0 TO ml+1);
+ VARIABLE quote : UNSIGNED(1 TO ml);
+ VARIABLE tmp : UNSIGNED(0 TO ml+1) := (OTHERS=>'0');
+ VARIABLE n : UNSIGNED(0 TO ml) := (OTHERS=>'0');
+
+ BEGIN
+ ASSERT NOT (r = "0")
+ REPORT "Attempted divide by ZERO"
+ SEVERITY ERROR;
+ IF hasx(l) OR hasx(r) THEN
+ FOR i IN lt'range LOOP
+ lt(i) := 'X';
+ END LOOP;
+ ELSE
+ lt := zxt( l, ml+2 );
+ WHILE lt >= r LOOP
+ rt := zxt( r, ml+2 );
+ WHILE rt <= lt LOOP
+ rt := shift(rt);
+ END LOOP;
+ rt := rshift(rt);
+ lt := lt - rt;
+ END LOOP;
+ END IF;
+ RETURN lt(2 TO ml+1);
+ END "REM";
+
+ FUNCTION "**" (l, r :STD_ULOGIC_VECTOR) RETURN STD_ULOGIC_VECTOR IS
+
+ VARIABLE return_vector : STD_ULOGIC_VECTOR(l'range) := (OTHERS=>'0');
+ VARIABLE tmp : STD_ULOGIC_VECTOR(1 TO (2 * l'length)) := (OTHERS=>'0');
+ CONSTANT lsh_l : INTEGER := l'length+1;
+ CONSTANT lsh_r : INTEGER := 2 * l'length;
+ VARIABLE pow : INTEGER;
+
+ BEGIN
+ IF (hasx(l) OR hasx(r)) THEN
+ FOR i IN return_vector'range LOOP
+ return_vector(i) := 'X';
+ END LOOP;
+ ELSE
+ pow := to_integer( r, 0 );
+ tmp( tmp'right ) := '1';
+ FOR i IN 1 TO pow LOOP
+ tmp := tmp(lsh_l TO lsh_r) * l;
+ END LOOP;
+ return_vector := tmp(lsh_l TO lsh_r);
+ END IF;
+ RETURN return_vector;
+ END "**";
+
+ FUNCTION "**" (l, r :STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
+
+ VARIABLE return_vector : STD_LOGIC_VECTOR(l'range) := (OTHERS=>'0');
+ VARIABLE tmp : STD_LOGIC_VECTOR(1 TO (2 * l'length)) := (OTHERS=>'0');
+ CONSTANT lsh_l : INTEGER := l'length+1;
+ CONSTANT lsh_r : INTEGER := 2 * l'length;
+ VARIABLE pow : INTEGER;
+
+ BEGIN
+ IF (hasx(l) OR hasx(r)) THEN
+ FOR i IN return_vector'range LOOP
+ return_vector(i) := 'X';
+ END LOOP;
+ ELSE
+ pow := to_integer( r, 0 );
+ tmp( tmp'right ) := '1';
+ FOR i IN 1 TO pow LOOP
+ tmp := tmp(lsh_l TO lsh_r) * l;
+ END LOOP;
+ return_vector := tmp(lsh_l TO lsh_r);
+ END IF;
+ RETURN return_vector;
+ END "**";
+
+ FUNCTION "**" (l, r :UNSIGNED) RETURN UNSIGNED IS
+
+ VARIABLE return_vector : UNSIGNED(l'range) := (OTHERS=>'0');
+ VARIABLE tmp : UNSIGNED(1 TO (2 * l'length)) := (OTHERS=>'0');
+ CONSTANT lsh_l : INTEGER := l'length+1;
+ CONSTANT lsh_r : INTEGER := 2 * l'length;
+ VARIABLE pow : INTEGER;
+
+ BEGIN
+ IF (hasx(l) OR hasx(r)) THEN
+ FOR i IN return_vector'range LOOP
+ return_vector(i) := 'X';
+ END LOOP;
+ ELSE
+ pow := to_integer( r, 0 );
+ tmp( tmp'right ) := '1';
+ FOR i IN 1 TO pow LOOP
+ tmp := tmp(lsh_l TO lsh_r) * l;
+ END LOOP;
+ return_vector := tmp(lsh_l TO lsh_r);
+ END IF;
+ RETURN return_vector;
+ END "**";
+
+--
+-- Absolute Value Functions
+--
+ FUNCTION "abs" (arg1:SIGNED) RETURN SIGNED IS
+ constant len : integer := arg1'length;
+ VARIABLE answer, tmp : SIGNED( len-1 downto 0 ) := (others=>'0');
+ VARIABLE index : integer := len;
+ BEGIN
+ assert arg1'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ IF hasx(arg1) THEN
+ answer := (OTHERS => 'X');
+ ELSIF (arg1(arg1'left) = '0' OR arg1(arg1'left) = 'L') THEN
+ answer := arg1;
+ ELSE
+ tmp := arg1;
+ lp1 : FOR i IN answer'REVERSE_RANGE LOOP
+ IF (tmp(i) = '1' OR tmp(i) = 'H') THEN
+ index := i+1;
+ answer(i downto 0) := tmp(i downto 0);
+ exit;
+ END IF;
+ END LOOP lp1;
+ answer(len-1 downto index) := NOT tmp(len-1 downto index);
+ end if;
+ RETURN (answer);
+ END ;
+
+--
+-- Shift Left (arithmetic) Functions
+--
+
+ FUNCTION "sla" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL) RETURN STD_ULOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : std_ulogic_vector(1 to len) := (others => arg1(arg1'right));
+ VARIABLE ans : STD_ULOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(arg2+1 to len) & se(1 to arg2));
+ END IF;
+ END ;
+
+ FUNCTION "sla" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL) RETURN STD_LOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : std_logic_vector(1 to len) := (others => arg1(arg1'right));
+ VARIABLE ans : STD_LOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(arg2+1 to len) & se(1 to arg2));
+ END IF;
+ END ;
+
+ FUNCTION "sla" (arg1:UNSIGNED ; arg2:NATURAL) RETURN UNSIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : UNSIGNED(1 to len) := (others => arg1(arg1'right));
+ VARIABLE ans : UNSIGNED(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(arg2+1 to len) & se(1 to arg2));
+ END IF;
+ END ;
+
+ FUNCTION "sla" (arg1:SIGNED ; arg2:NATURAL) RETURN SIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : SIGNED(1 to len) := (others => arg1(arg1'right));
+ VARIABLE ans : SIGNED(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(arg2+1 to len) & se(1 to arg2));
+ END IF;
+ END ;
+
+--
+-- Shift Right (arithmetics) Functions
+--
+ FUNCTION "sra" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL) RETURN STD_ULOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : std_ulogic_vector(1 to len) := (others => arg1(arg1'left));
+ VARIABLE ans : STD_ULOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (se(1 to arg2) & ans(1 to len-arg2));
+ END IF;
+ END ;
+
+ FUNCTION "sra" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL) RETURN STD_LOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : std_logic_vector(1 to len) := (others => arg1(arg1'left));
+ VARIABLE ans : STD_LOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (se(1 to arg2) & ans(1 to len-arg2));
+ END IF;
+ END ;
+
+ FUNCTION "sra" (arg1:UNSIGNED ; arg2:NATURAL) RETURN UNSIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : UNSIGNED(1 to len) := (others => arg1(arg1'left));
+ VARIABLE ans : UNSIGNED(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (se(1 to arg2) & ans(1 to len-arg2));
+ END IF;
+ END ;
+
+ FUNCTION "sra" (arg1:SIGNED ; arg2:NATURAL) RETURN SIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : SIGNED(1 to len) := (others => arg1(arg1'left));
+ VARIABLE ans : SIGNED(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (se(1 to arg2) & ans(1 to len-arg2));
+ END IF;
+ END ;
+
+--
+-- Shift Left (logical) Functions
+--
+
+ FUNCTION "sll" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL) RETURN STD_ULOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : std_ulogic_vector(1 to len) := (others =>'0');
+ VARIABLE ans : STD_ULOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(arg2+1 to len) & se(1 to arg2));
+ END IF;
+ END ;
+
+ FUNCTION "sll" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL) RETURN STD_LOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : std_logic_vector(1 to len) := (others =>'0');
+ VARIABLE ans : STD_LOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(arg2+1 to len) & se(1 to arg2));
+ END IF;
+ END ;
+
+ FUNCTION "sll" (arg1:UNSIGNED ; arg2:NATURAL) RETURN UNSIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : UNSIGNED(1 to len) := (others =>'0');
+ VARIABLE ans : UNSIGNED(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(arg2+1 to len) & se(1 to arg2));
+ END IF;
+ END ;
+
+ FUNCTION "sll" (arg1:SIGNED ; arg2:NATURAL) RETURN SIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : SIGNED(1 to len) := (others =>'0');
+ VARIABLE ans : SIGNED(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(arg2+1 to len) & se(1 to arg2));
+ END IF;
+ END ;
+
+--
+-- Shift Right (logical) Functions
+--
+ FUNCTION "srl" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL) RETURN STD_ULOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : std_ulogic_vector(1 to len) := (others => '0');
+ VARIABLE ans : STD_ULOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (se(1 to arg2) & ans(1 to len-arg2));
+ END IF;
+ END ;
+
+ FUNCTION "srl" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL) RETURN STD_LOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : std_logic_vector(1 to len) := (others => '0');
+ VARIABLE ans : STD_LOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (se(1 to arg2) & ans(1 to len-arg2));
+ END IF;
+ END ;
+
+ FUNCTION "srl" (arg1:UNSIGNED ; arg2:NATURAL) RETURN UNSIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : UNSIGNED(1 to len) := (others => '0');
+ VARIABLE ans : UNSIGNED(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (se(1 to arg2) & ans(1 to len-arg2));
+ END IF;
+ END ;
+
+ FUNCTION "srl" (arg1:SIGNED ; arg2:NATURAL) RETURN SIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT se : SIGNED(1 to len) := (others => '0');
+ VARIABLE ans : SIGNED(1 to len) := arg1;
+ BEGIN
+ IF (arg2 >= len) THEN
+ RETURN (se);
+ ELSIF (arg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (se(1 to arg2) & ans(1 to len-arg2));
+ END IF;
+ END ;
+
+--
+-- Rotate Left (Logical) Functions
+--
+ FUNCTION "rol" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL) RETURN STD_ULOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT marg2 : integer := arg2 mod len;
+ VARIABLE ans : STD_ULOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (marg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(marg2+1 to len) & ans(1 to marg2));
+ END IF;
+ END ;
+
+ FUNCTION "rol" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL) RETURN STD_LOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT marg2 : integer := arg2 mod len;
+ VARIABLE ans : STD_LOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (marg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(marg2+1 to len) & ans(1 to marg2));
+ END IF;
+ END ;
+
+ FUNCTION "rol" (arg1:UNSIGNED ; arg2:NATURAL) RETURN UNSIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT marg2 : integer := arg2 mod len;
+ VARIABLE ans : UNSIGNED(1 to len) := arg1;
+ BEGIN
+ IF (marg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(marg2+1 to len) & ans(1 to marg2));
+ END IF;
+ END ;
+
+ FUNCTION "rol" (arg1:SIGNED ; arg2:NATURAL) RETURN SIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT marg2 : integer := arg2 mod len;
+ VARIABLE ans : SIGNED(1 to len) := arg1;
+ BEGIN
+ IF (marg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(marg2+1 to len) & ans(1 to marg2));
+ END IF;
+ END ;
+
+--
+-- Rotate Right (Logical) Functions
+--
+ FUNCTION "ror" (arg1:STD_ULOGIC_VECTOR ; arg2:NATURAL) RETURN STD_ULOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT marg2 : integer := arg2 mod len;
+ VARIABLE ans : STD_ULOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (marg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(len-marg2+1 to len) & ans(1 to len-marg2));
+ END IF;
+ END ;
+
+ FUNCTION "ror" (arg1:STD_LOGIC_VECTOR ; arg2:NATURAL) RETURN STD_LOGIC_VECTOR IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT marg2 : integer := arg2 mod len;
+ VARIABLE ans : STD_LOGIC_VECTOR(1 to len) := arg1;
+ BEGIN
+ IF (marg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(len-marg2+1 to len) & ans(1 to len-marg2));
+ END IF;
+ END ;
+
+ FUNCTION "ror" (arg1:UNSIGNED ; arg2:NATURAL) RETURN UNSIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT marg2 : integer := arg2 mod len;
+ VARIABLE ans : UNSIGNED(1 to len) := arg1;
+ BEGIN
+ IF (marg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(len-marg2+1 to len) & ans(1 to len-marg2));
+ END IF;
+ END ;
+
+ FUNCTION "ror" (arg1:SIGNED ; arg2:NATURAL) RETURN SIGNED IS
+ CONSTANT len : INTEGER := arg1'length ;
+ CONSTANT marg2 : integer := arg2 mod len;
+ VARIABLE ans : SIGNED(1 to len) := arg1;
+ BEGIN
+ IF (marg2 = 0) THEN
+ RETURN (arg1);
+ ELSE
+ RETURN (ans(len-marg2+1 to len) & ans(1 to len-marg2));
+ END IF;
+ END ;
+
+--
+-- Equal functions.
+--
+ CONSTANT eq_table : stdlogic_boolean_table := (
+ -- ----------------------------------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------------------------------
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | U |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | X |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | 0 |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | 1 |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | Z |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | W |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | L |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | H |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) -- | D |
+ );
+
+ FUNCTION eq ( l, r : STD_LOGIC ) RETURN BOOLEAN IS
+ BEGIN
+ RETURN eq_table( l, r );
+ END;
+
+ FUNCTION eq ( l,r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : STD_ULOGIC_VECTOR ( 1 TO ml );
+ VARIABLE rt : STD_ULOGIC_VECTOR ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF NOT eq( lt(i), rt(i) ) THEN
+ RETURN FALSE;
+ END IF;
+ END LOOP;
+ RETURN TRUE;
+ END;
+
+ FUNCTION eq ( l,r : STD_LOGIC_VECTOR ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : STD_LOGIC_VECTOR ( 1 TO ml );
+ VARIABLE rt : STD_LOGIC_VECTOR ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF NOT eq( lt(i), rt(i) ) THEN
+ RETURN FALSE;
+ END IF;
+ END LOOP;
+ RETURN TRUE;
+ END;
+
+ FUNCTION eq ( l,r : UNSIGNED ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : UNSIGNED ( 1 TO ml );
+ VARIABLE rt : UNSIGNED ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF NOT eq( lt(i), rt(i) ) THEN
+ RETURN FALSE;
+ END IF;
+ END LOOP;
+ RETURN TRUE;
+ END;
+
+ FUNCTION eq ( l,r : SIGNED ) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt, rt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := (OTHERS => l(l'left)) ;
+ lt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rt := (OTHERS => r(r'left)) ;
+ rt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ RETURN (eq( lt, rt ));
+ END;
+
+ FUNCTION "=" ( l,r : UNSIGNED ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : UNSIGNED ( 1 TO ml );
+ VARIABLE rt : UNSIGNED ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF NOT eq( lt(i), rt(i) ) THEN
+ RETURN FALSE;
+ END IF;
+ END LOOP;
+ RETURN TRUE;
+ END;
+
+ FUNCTION "=" ( l,r : SIGNED ) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt, rt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := (OTHERS => l(l'left)) ;
+ lt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rt := (OTHERS => r(r'left)) ;
+ rt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ RETURN (eq( lt, rt ));
+ END;
+
+--
+-- Not Equal function.
+--
+ CONSTANT neq_table : stdlogic_boolean_table := (
+ -- ----------------------------------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------------------------------
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | U |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | X |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | 0 |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | 1 |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | Z |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | W |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | L |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | H |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) -- | D |
+ );
+
+
+ FUNCTION ne ( l, r : STD_LOGIC ) RETURN BOOLEAN IS
+ BEGIN
+ RETURN neq_table( l, r );
+ END;
+
+ FUNCTION ne ( l,r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : STD_ULOGIC_VECTOR ( 1 TO ml );
+ VARIABLE rt : STD_ULOGIC_VECTOR ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF ne( lt(i), rt(i) ) THEN
+ RETURN TRUE;
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION ne ( l,r : STD_LOGIC_VECTOR ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : STD_LOGIC_VECTOR ( 1 TO ml );
+ VARIABLE rt : STD_LOGIC_VECTOR ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF ne( lt(i), rt(i) ) THEN
+ RETURN TRUE;
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION ne ( l,r : UNSIGNED ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : UNSIGNED ( 1 TO ml );
+ VARIABLE rt : UNSIGNED ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF ne( lt(i), rt(i) ) THEN
+ RETURN TRUE;
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION ne ( l,r : SIGNED ) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt, rt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := (OTHERS => l(l'left)) ;
+ lt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rt := (OTHERS => r(r'left)) ;
+ rt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ RETURN (ne( lt, rt ));
+ END;
+
+ FUNCTION "/=" ( l,r : UNSIGNED ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : UNSIGNED ( 1 TO ml );
+ VARIABLE rt : UNSIGNED ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF ne( lt(i), rt(i) ) THEN
+ RETURN TRUE;
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION "/=" ( l,r : SIGNED ) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt, rt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := (OTHERS => l(l'left)) ;
+ lt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rt := (OTHERS => r(r'left)) ;
+ rt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ RETURN (ne( lt, rt ));
+ END;
+
+--
+-- Less Than functions.
+--
+ CONSTANT ltb_table : stdlogic_boolean_table := (
+ -- ----------------------------------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------------------------------
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | U |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | X |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | 0 |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | 1 |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | Z |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | W |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | L |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | H |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) -- | D |
+ );
+
+ FUNCTION lt ( l, r : STD_LOGIC ) RETURN BOOLEAN IS
+ BEGIN
+ RETURN ltb_table( l, r );
+ END;
+
+ FUNCTION lt ( l,r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE ltt : STD_ULOGIC_VECTOR ( 1 TO ml );
+ VARIABLE rtt : STD_ULOGIC_VECTOR ( 1 TO ml );
+ BEGIN
+ ltt := zxt( l, ml );
+ rtt := zxt( r, ml );
+ FOR i IN ltt'range LOOP
+ IF NOT eq( ltt(i), rtt(i) ) THEN
+ RETURN lt( ltt(i), rtt(i) );
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION lt ( l,r : STD_LOGIC_VECTOR ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE ltt : STD_LOGIC_VECTOR ( 1 TO ml );
+ VARIABLE rtt : STD_LOGIC_VECTOR ( 1 TO ml );
+ BEGIN
+ ltt := zxt( l, ml );
+ rtt := zxt( r, ml );
+ FOR i IN ltt'range LOOP
+ IF NOT eq( ltt(i), rtt(i) ) THEN
+ RETURN lt( ltt(i), rtt(i) );
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION lt ( l,r : UNSIGNED ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE ltt : UNSIGNED ( 1 TO ml );
+ VARIABLE rtt : UNSIGNED ( 1 TO ml );
+ BEGIN
+ ltt := zxt( l, ml );
+ rtt := zxt( r, ml );
+ FOR i IN ltt'range LOOP
+ IF NOT eq( ltt(i), rtt(i) ) THEN
+ RETURN lt( ltt(i), rtt(i) );
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION lt ( l,r : SIGNED ) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE ltt, rtt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ ltt := (OTHERS => l(l'left)) ;
+ ltt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rtt := (OTHERS => r(r'left)) ;
+ rtt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ IF(ltt(ltt'left) = '1' AND rtt(rtt'left) = '0') THEN
+ RETURN(TRUE) ;
+ ELSIF(ltt(ltt'left) = '0' AND rtt(rtt'left) = '1') THEN
+ RETURN(FALSE) ;
+ ELSE
+ RETURN (lt( ltt, rtt ));
+ END IF ;
+ END;
+
+ FUNCTION "<" ( l,r : UNSIGNED ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE ltt : UNSIGNED ( 1 TO ml );
+ VARIABLE rtt : UNSIGNED ( 1 TO ml );
+ BEGIN
+ ltt := zxt( l, ml );
+ rtt := zxt( r, ml );
+ FOR i IN ltt'range LOOP
+ IF NOT eq( ltt(i), rtt(i) ) THEN
+ RETURN lt( ltt(i), rtt(i) );
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION "<" ( l,r : SIGNED ) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE ltt, rtt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ ltt := (OTHERS => l(l'left)) ;
+ ltt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rtt := (OTHERS => r(r'left)) ;
+ rtt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ IF(ltt(ltt'left) = '1' AND rtt(rtt'left) = '0') THEN
+ RETURN(TRUE) ;
+ ELSIF(ltt(ltt'left) = '0' AND rtt(rtt'left) = '1') THEN
+ RETURN(FALSE) ;
+ ELSE
+ RETURN (lt( ltt, rtt ));
+ END IF ;
+ END;
+
+--
+-- Greater Than functions.
+--
+ CONSTANT gtb_table : stdlogic_boolean_table := (
+ -- ----------------------------------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------------------------------
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | U |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | X |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | 0 |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | 1 |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | Z |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | W |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ), -- | L |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | H |
+ ( FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE ) -- | D |
+ );
+
+ FUNCTION gt ( l, r : std_logic ) RETURN BOOLEAN IS
+ BEGIN
+ RETURN gtb_table( l, r );
+ END ;
+
+ FUNCTION gt ( l,r : STD_ULOGIC_VECTOR ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : STD_ULOGIC_VECTOR ( 1 TO ml );
+ VARIABLE rt : STD_ULOGIC_VECTOR ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF NOT eq( lt(i), rt(i) ) THEN
+ RETURN gt( lt(i), rt(i) );
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION gt ( l,r : STD_LOGIC_VECTOR ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : STD_LOGIC_VECTOR ( 1 TO ml );
+ VARIABLE rt : STD_LOGIC_VECTOR ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF NOT eq( lt(i), rt(i) ) THEN
+ RETURN gt( lt(i), rt(i) );
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION gt ( l,r : UNSIGNED ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : UNSIGNED ( 1 TO ml );
+ VARIABLE rt : UNSIGNED ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF NOT eq( lt(i), rt(i) ) THEN
+ RETURN gt( lt(i), rt(i) );
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION gt ( l,r : SIGNED ) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt, rt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := (OTHERS => l(l'left)) ;
+ lt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rt := (OTHERS => r(r'left)) ;
+ rt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ IF(lt(lt'left) = '1' AND rt(rt'left) = '0') THEN
+ RETURN(FALSE) ;
+ ELSIF(lt(lt'left) = '0' AND rt(rt'left) = '1') THEN
+ RETURN(TRUE) ;
+ ELSE
+ RETURN (gt( lt, rt ));
+ END IF ;
+ END;
+
+ FUNCTION ">" ( l,r : UNSIGNED ) RETURN BOOLEAN IS
+ CONSTANT ml : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt : UNSIGNED ( 1 TO ml );
+ VARIABLE rt : UNSIGNED ( 1 TO ml );
+ BEGIN
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'range LOOP
+ IF NOT eq( lt(i), rt(i) ) THEN
+ RETURN gt( lt(i), rt(i) );
+ END IF;
+ END LOOP;
+ RETURN FALSE;
+ END;
+
+ FUNCTION ">" ( l,r : SIGNED ) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt, rt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := (OTHERS => l(l'left)) ;
+ lt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rt := (OTHERS => r(r'left)) ;
+ rt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ IF(lt(lt'left) = '1' AND rt(rt'left) = '0') THEN
+ RETURN(FALSE) ;
+ ELSIF(lt(lt'left) = '0' AND rt(rt'left) = '1') THEN
+ RETURN(TRUE) ;
+ ELSE
+ RETURN (gt( lt, rt ));
+ END IF ;
+ END;
+
+--
+-- Less Than or Equal to functions.
+--
+ CONSTANT leb_table : stdlogic_boolean_table := (
+ -- ----------------------------------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------------------------------
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | U |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | X |
+ ( TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE ), -- | 0 |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | 1 |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | Z |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | W |
+ ( TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE ), -- | L |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ), -- | H |
+ ( FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE ) -- | D |
+ );
+
+ FUNCTION le ( l, r : std_logic ) RETURN BOOLEAN IS
+ BEGIN
+ RETURN leb_table( l, r );
+ END ;
+
+ TYPE std_ulogic_fuzzy_state IS ('U', 'X', 'T', 'F', 'N');
+ TYPE std_ulogic_fuzzy_state_table IS ARRAY ( std_ulogic, std_ulogic ) OF std_ulogic_fuzzy_state;
+
+ CONSTANT le_fuzzy_table : std_ulogic_fuzzy_state_table := (
+ -- ----------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------
+ ( 'U', 'U', 'U', 'N', 'U', 'U', 'U', 'N', 'U' ), -- | U |
+ ( 'U', 'X', 'X', 'N', 'X', 'X', 'X', 'N', 'X' ), -- | X |
+ ( 'N', 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N' ), -- | 0 |
+ ( 'U', 'X', 'F', 'N', 'X', 'X', 'F', 'N', 'X' ), -- | 1 |
+ ( 'U', 'X', 'X', 'N', 'X', 'X', 'X', 'N', 'X' ), -- | Z |
+ ( 'U', 'X', 'X', 'N', 'X', 'X', 'X', 'N', 'X' ), -- | W |
+ ( 'N', 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N' ), -- | L |
+ ( 'U', 'X', 'F', 'N', 'X', 'X', 'F', 'N', 'X' ), -- | H |
+ ( 'U', 'X', 'X', 'N', 'X', 'X', 'X', 'N', 'X' ) -- | D |
+ );
+
+ FUNCTION le ( L,R : std_ulogic_vector ) RETURN boolean IS
+ CONSTANT ml : integer := maximum( L'LENGTH, R'LENGTH );
+ VARIABLE lt : std_ulogic_vector ( 1 to ml );
+ VARIABLE rt : std_ulogic_vector ( 1 to ml );
+ VARIABLE res : std_ulogic_fuzzy_state;
+ begin
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'RANGE LOOP
+ res := le_fuzzy_table( lt(i), rt(i) );
+ CASE res IS
+ WHEN 'U' => RETURN FALSE;
+ WHEN 'X' => RETURN FALSE;
+ WHEN 'T' => RETURN TRUE;
+ WHEN 'F' => RETURN FALSE;
+ WHEN OTHERS => null;
+ END CASE;
+ END LOOP;
+ RETURN TRUE;
+ end ;
+
+ TYPE std_logic_fuzzy_state IS ('U', 'X', 'T', 'F', 'N');
+ TYPE std_logic_fuzzy_state_table IS ARRAY ( std_logic, std_logic ) OF std_logic_fuzzy_state;
+
+ CONSTANT le_lfuzzy_table : std_logic_fuzzy_state_table := (
+ -- ----------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------
+ ( 'U', 'U', 'U', 'N', 'U', 'U', 'U', 'N', 'U' ), -- | U |
+ ( 'U', 'X', 'X', 'N', 'X', 'X', 'X', 'N', 'X' ), -- | X |
+ ( 'N', 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N' ), -- | 0 |
+ ( 'U', 'X', 'F', 'N', 'X', 'X', 'F', 'N', 'X' ), -- | 1 |
+ ( 'U', 'X', 'X', 'N', 'X', 'X', 'X', 'N', 'X' ), -- | Z |
+ ( 'U', 'X', 'X', 'N', 'X', 'X', 'X', 'N', 'X' ), -- | W |
+ ( 'N', 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N' ), -- | L |
+ ( 'U', 'X', 'F', 'N', 'X', 'X', 'F', 'N', 'X' ), -- | H |
+ ( 'U', 'X', 'X', 'N', 'X', 'X', 'X', 'N', 'X' ) -- | D |
+ );
+
+ FUNCTION le ( L,R : std_logic_vector ) RETURN boolean IS
+ CONSTANT ml : integer := maximum( L'LENGTH, R'LENGTH );
+ VARIABLE lt : std_logic_vector ( 1 to ml );
+ VARIABLE rt : std_logic_vector ( 1 to ml );
+ VARIABLE res : std_logic_fuzzy_state;
+ begin
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'RANGE LOOP
+ res := le_lfuzzy_table( lt(i), rt(i) );
+ CASE res IS
+ WHEN 'U' => RETURN FALSE;
+ WHEN 'X' => RETURN FALSE;
+ WHEN 'T' => RETURN TRUE;
+ WHEN 'F' => RETURN FALSE;
+ WHEN OTHERS => null;
+ END CASE;
+ END LOOP;
+ RETURN TRUE;
+ end ;
+
+ FUNCTION le ( L,R : UNSIGNED ) RETURN boolean IS
+ CONSTANT ml : integer := maximum( L'LENGTH, R'LENGTH );
+ VARIABLE lt : UNSIGNED ( 1 to ml );
+ VARIABLE rt : UNSIGNED ( 1 to ml );
+ VARIABLE res : std_logic_fuzzy_state;
+ begin
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'RANGE LOOP
+ res := le_lfuzzy_table( lt(i), rt(i) );
+ CASE res IS
+ WHEN 'U' => RETURN FALSE;
+ WHEN 'X' => RETURN FALSE;
+ WHEN 'T' => RETURN TRUE;
+ WHEN 'F' => RETURN FALSE;
+ WHEN OTHERS => null;
+ END CASE;
+ END LOOP;
+ RETURN TRUE;
+ end ;
+
+ FUNCTION le (l, r:SIGNED) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt, rt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := (OTHERS => l(l'left)) ;
+ lt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rt := (OTHERS => r(r'left)) ;
+ rt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ IF(lt(lt'left) = '1' AND rt(rt'left) = '0') THEN
+ RETURN(TRUE) ;
+ ELSIF(lt(lt'left) = '0' AND rt(rt'left) = '1') THEN
+ RETURN(FALSE) ;
+ ELSE
+ RETURN (le( lt, rt ));
+ END IF ;
+ END;
+
+ FUNCTION "<=" ( L,R : UNSIGNED ) RETURN boolean IS
+ CONSTANT ml : integer := maximum( L'LENGTH, R'LENGTH );
+ VARIABLE lt : UNSIGNED ( 1 to ml );
+ VARIABLE rt : UNSIGNED ( 1 to ml );
+ VARIABLE res : std_logic_fuzzy_state;
+ begin
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'RANGE LOOP
+ res := le_lfuzzy_table( lt(i), rt(i) );
+ CASE res IS
+ WHEN 'U' => RETURN FALSE;
+ WHEN 'X' => RETURN FALSE;
+ WHEN 'T' => RETURN TRUE;
+ WHEN 'F' => RETURN FALSE;
+ WHEN OTHERS => null;
+ END CASE;
+ END LOOP;
+ RETURN TRUE;
+ end ;
+
+ FUNCTION "<=" (l, r:SIGNED) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt, rt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := (OTHERS => l(l'left)) ;
+ lt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rt := (OTHERS => r(r'left)) ;
+ rt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ IF(lt(lt'left) = '1' AND rt(rt'left) = '0') THEN
+ RETURN(TRUE) ;
+ ELSIF(lt(lt'left) = '0' AND rt(rt'left) = '1') THEN
+ RETURN(FALSE) ;
+ ELSE
+ RETURN (le( lt, rt ));
+ END IF ;
+ END;
+
+--
+-- Greater Than or Equal to functions.
+--
+ CONSTANT geb_table : stdlogic_boolean_table := (
+ -- ----------------------------------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------------------------------
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | U |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | X |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | 0 |
+ ( TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE ), -- | 1 |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | Z |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | W |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ), -- | L |
+ ( TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE ), -- | H |
+ ( FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE ) -- | D |
+ );
+
+ FUNCTION ge ( l, r : std_logic ) RETURN BOOLEAN IS
+ BEGIN
+ RETURN geb_table( l, r );
+ END ;
+
+ CONSTANT ge_fuzzy_table : std_ulogic_fuzzy_state_table := (
+ -- ----------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------
+ ( 'U', 'U', 'N', 'U', 'U', 'U', 'N', 'U', 'U' ), -- | U |
+ ( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | X |
+ ( 'U', 'X', 'N', 'F', 'X', 'X', 'N', 'F', 'X' ), -- | 0 |
+ ( 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N', 'N' ), -- | 1 |
+ ( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | Z |
+ ( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | W |
+ ( 'U', 'X', 'N', 'F', 'X', 'X', 'N', 'F', 'X' ), -- | L |
+ ( 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N', 'N' ), -- | H |
+ ( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ) -- | D |
+ );
+
+ FUNCTION ge ( L,R : std_ulogic_vector ) RETURN boolean IS
+ CONSTANT ml : integer := maximum( L'LENGTH, R'LENGTH );
+ VARIABLE lt : std_ulogic_vector ( 1 to ml );
+ VARIABLE rt : std_ulogic_vector ( 1 to ml );
+ VARIABLE res : std_ulogic_fuzzy_state;
+ begin
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'RANGE LOOP
+ res := ge_fuzzy_table( lt(i), rt(i) );
+ CASE res IS
+ WHEN 'U' => RETURN FALSE;
+ WHEN 'X' => RETURN FALSE;
+ WHEN 'T' => RETURN TRUE;
+ WHEN 'F' => RETURN FALSE;
+ WHEN OTHERS => null;
+ END CASE;
+ END LOOP;
+ RETURN TRUE;
+ end ;
+
+ CONSTANT ge_lfuzzy_table : std_logic_fuzzy_state_table := (
+ -- ----------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------
+ ( 'U', 'U', 'N', 'U', 'U', 'U', 'N', 'U', 'U' ), -- | U |
+ ( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | X |
+ ( 'U', 'X', 'N', 'F', 'X', 'X', 'N', 'F', 'X' ), -- | 0 |
+ ( 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N', 'N' ), -- | 1 |
+ ( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | Z |
+ ( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ), -- | W |
+ ( 'U', 'X', 'N', 'F', 'X', 'X', 'N', 'F', 'X' ), -- | L |
+ ( 'N', 'N', 'T', 'N', 'N', 'N', 'T', 'N', 'N' ), -- | H |
+ ( 'U', 'X', 'N', 'X', 'X', 'X', 'N', 'X', 'X' ) -- | D |
+ );
+
+ FUNCTION ge ( L,R : std_logic_vector ) RETURN boolean IS
+ CONSTANT ml : integer := maximum( L'LENGTH, R'LENGTH );
+ VARIABLE lt : std_logic_vector ( 1 to ml );
+ VARIABLE rt : std_logic_vector ( 1 to ml );
+ VARIABLE res : std_logic_fuzzy_state;
+ begin
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'RANGE LOOP
+ res := ge_lfuzzy_table( lt(i), rt(i) );
+ CASE res IS
+ WHEN 'U' => RETURN FALSE;
+ WHEN 'X' => RETURN FALSE;
+ WHEN 'T' => RETURN TRUE;
+ WHEN 'F' => RETURN FALSE;
+ WHEN OTHERS => null;
+ END CASE;
+ END LOOP;
+ RETURN TRUE;
+ end ;
+
+ FUNCTION ge ( L,R : UNSIGNED ) RETURN boolean IS
+ CONSTANT ml : integer := maximum( L'LENGTH, R'LENGTH );
+ VARIABLE lt : UNSIGNED ( 1 to ml );
+ VARIABLE rt : UNSIGNED ( 1 to ml );
+ VARIABLE res : std_logic_fuzzy_state;
+ begin
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'RANGE LOOP
+ res := ge_lfuzzy_table( lt(i), rt(i) );
+ CASE res IS
+ WHEN 'U' => RETURN FALSE;
+ WHEN 'X' => RETURN FALSE;
+ WHEN 'T' => RETURN TRUE;
+ WHEN 'F' => RETURN FALSE;
+ WHEN OTHERS => null;
+ END CASE;
+ END LOOP;
+ RETURN TRUE;
+ end ;
+
+ FUNCTION ge ( l,r : SIGNED ) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt, rt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := (OTHERS => l(l'left)) ;
+ lt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rt := (OTHERS => r(r'left)) ;
+ rt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ IF(lt(lt'left) = '1' AND rt(rt'left) = '0') THEN
+ RETURN(FALSE) ;
+ ELSIF(lt(lt'left) = '0' AND rt(rt'left) = '1') THEN
+ RETURN(TRUE) ;
+ ELSE
+ RETURN (ge( lt, rt ));
+ END IF ;
+ END;
+
+ FUNCTION ">=" ( L,R : UNSIGNED ) RETURN boolean IS
+ CONSTANT ml : integer := maximum( L'LENGTH, R'LENGTH );
+ VARIABLE lt : UNSIGNED ( 1 to ml );
+ VARIABLE rt : UNSIGNED ( 1 to ml );
+ VARIABLE res : std_logic_fuzzy_state;
+ begin
+ lt := zxt( l, ml );
+ rt := zxt( r, ml );
+ FOR i IN lt'RANGE LOOP
+ res := ge_lfuzzy_table( lt(i), rt(i) );
+ CASE res IS
+ WHEN 'U' => RETURN FALSE;
+ WHEN 'X' => RETURN FALSE;
+ WHEN 'T' => RETURN TRUE;
+ WHEN 'F' => RETURN FALSE;
+ WHEN OTHERS => null;
+ END CASE;
+ END LOOP;
+ RETURN TRUE;
+ end ;
+
+ FUNCTION ">=" ( l,r : SIGNED ) RETURN BOOLEAN IS
+ CONSTANT len : INTEGER := maximum( l'length, r'length );
+ VARIABLE lt, rt : UNSIGNED ( len-1 downto 0 ) := (OTHERS => '0');
+ BEGIN
+ assert l'length > 1 AND r'length > 1
+ report "SIGNED vector must be atleast 2 bits wide"
+ severity ERROR;
+ lt := (OTHERS => l(l'left)) ;
+ lt(l'length - 1 DOWNTO 0) := UNSIGNED(l);
+ rt := (OTHERS => r(r'left)) ;
+ rt(r'length - 1 DOWNTO 0) := UNSIGNED(r);
+ IF(lt(lt'left) = '1' AND rt(rt'left) = '0') THEN
+ RETURN(FALSE) ;
+ ELSIF(lt(lt'left) = '0' AND rt(rt'left) = '1') THEN
+ RETURN(TRUE) ;
+ ELSE
+ RETURN (ge( lt, rt ));
+ END IF ;
+ END;
+
+ -------------------------------------------------------------------------------
+ -- Logical Operations
+ -------------------------------------------------------------------------------
+
+ -- truth table for "and" function
+ CONSTANT and_table : stdlogic_table := (
+ -- ----------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------
+ ( 'U', 'U', '0', 'U', 'U', 'U', '0', 'U', 'U' ), -- | U |
+ ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), -- | X |
+ ( '0', '0', '0', '0', '0', '0', '0', '0', '0' ), -- | 0 |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | 1 |
+ ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), -- | Z |
+ ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ), -- | W |
+ ( '0', '0', '0', '0', '0', '0', '0', '0', '0' ), -- | L |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | H |
+ ( 'U', 'X', '0', 'X', 'X', 'X', '0', 'X', 'X' ) -- | D |
+ );
+
+ -- truth table for "or" function
+ CONSTANT or_table : stdlogic_table := (
+ -- ----------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------
+ ( 'U', 'U', 'U', '1', 'U', 'U', 'U', '1', 'U' ), -- | U |
+ ( 'U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ), -- | X |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | 0 |
+ ( '1', '1', '1', '1', '1', '1', '1', '1', '1' ), -- | 1 |
+ ( 'U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ), -- | Z |
+ ( 'U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ), -- | W |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | L |
+ ( '1', '1', '1', '1', '1', '1', '1', '1', '1' ), -- | H |
+ ( 'U', 'X', 'X', '1', 'X', 'X', 'X', '1', 'X' ) -- | D |
+ );
+
+
+ -- truth table for "xor" function
+ CONSTANT xor_table : stdlogic_table := (
+ -- ----------------------------------------------------
+ -- | U X 0 1 Z W L H D | |
+ -- ----------------------------------------------------
+ ( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- | U |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | 0 |
+ ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' ), -- | 1 |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | Z |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | W |
+ ( 'U', 'X', '0', '1', 'X', 'X', '0', '1', 'X' ), -- | L |
+ ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' ), -- | H |
+ ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ) -- | D |
+ );
+
+ -- truth table for "not" function
+ CONSTANT not_table: stdlogic_1D :=
+ -- -------------------------------------------------
+ -- | U X 0 1 Z W L H D |
+ -- -------------------------------------------------
+ ( 'U', 'X', '1', '0', 'X', 'X', '1', '0', 'X' );
+
+ FUNCTION "and" ( arg1,arg2 : UNSIGNED ) RETURN UNSIGNED IS
+ CONSTANT ml : integer := maximum( arg1'LENGTH, arg2'LENGTH );
+ VARIABLE lt : UNSIGNED ( 1 to ml );
+ VARIABLE rt : UNSIGNED ( 1 to ml );
+ VARIABLE res : UNSIGNED ( 1 to ml );
+ begin
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN res'RANGE LOOP
+ res(i) := and_table( lt(i), rt(i) );
+ END LOOP;
+ RETURN res;
+ end "and";
+
+ FUNCTION "nand" ( arg1,arg2 : UNSIGNED ) RETURN UNSIGNED IS
+ CONSTANT ml : integer := maximum( arg1'LENGTH, arg2'LENGTH );
+ VARIABLE lt : UNSIGNED ( 1 to ml );
+ VARIABLE rt : UNSIGNED ( 1 to ml );
+ VARIABLE res : UNSIGNED ( 1 to ml );
+ begin
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN res'RANGE LOOP
+ res(i) := not_table( and_table( lt(i), rt(i) ) );
+ END LOOP;
+ RETURN res;
+ end "nand";
+
+ FUNCTION "or" ( arg1,arg2 : UNSIGNED ) RETURN UNSIGNED IS
+ CONSTANT ml : integer := maximum( arg1'LENGTH, arg2'LENGTH );
+ VARIABLE lt : UNSIGNED ( 1 to ml );
+ VARIABLE rt : UNSIGNED ( 1 to ml );
+ VARIABLE res : UNSIGNED ( 1 to ml );
+ begin
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN res'RANGE LOOP
+ res(i) := or_table( lt(i), rt(i) );
+ END LOOP;
+ RETURN res;
+ end "or";
+
+ FUNCTION "nor" ( arg1,arg2 : UNSIGNED ) RETURN UNSIGNED IS
+ CONSTANT ml : integer := maximum( arg1'LENGTH, arg2'LENGTH );
+ VARIABLE lt : UNSIGNED ( 1 to ml );
+ VARIABLE rt : UNSIGNED ( 1 to ml );
+ VARIABLE res : UNSIGNED ( 1 to ml );
+ begin
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN res'RANGE LOOP
+ res(i) := not_table( or_table( lt(i), rt(i) ) );
+ END LOOP;
+ RETURN res;
+ end "nor";
+
+ FUNCTION "xor" ( arg1, arg2 : UNSIGNED ) RETURN UNSIGNED IS
+ CONSTANT ml : integer := maximum( arg1'LENGTH, arg2'LENGTH );
+ VARIABLE lt : UNSIGNED ( 1 to ml );
+ VARIABLE rt : UNSIGNED ( 1 to ml );
+ VARIABLE res : UNSIGNED ( 1 to ml );
+ begin
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN res'RANGE LOOP
+ res(i) := xor_table( lt(i), rt(i) );
+ END LOOP;
+ RETURN res;
+ end "xor";
+
+ FUNCTION "not" ( arg1 : UNSIGNED ) RETURN UNSIGNED IS
+ VARIABLE result : UNSIGNED ( arg1'RANGE ) := (Others => 'X');
+ begin
+ for i in result'range loop
+ result(i) := not_table( arg1(i) );
+ end loop;
+ return result;
+ end "not";
+
+ FUNCTION "and" ( arg1,arg2 : SIGNED ) RETURN SIGNED IS
+ CONSTANT len : INTEGER := maximum(arg1'length,arg2'length) ;
+ VARIABLE a,b : UNSIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ VARIABLE answer : SIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ a := (OTHERS => arg1(arg1'left)) ;
+ a(arg1'length - 1 DOWNTO 0) := UNSIGNED(arg1);
+ b := (OTHERS => arg2(arg2'left)) ;
+ b(arg2'length - 1 DOWNTO 0) := UNSIGNED(arg2);
+ answer := SIGNED(a and b);
+ RETURN (answer);
+ end "and";
+
+ FUNCTION "nand" ( arg1,arg2 : SIGNED ) RETURN SIGNED IS
+ CONSTANT len : INTEGER := maximum(arg1'length,arg2'length) ;
+ VARIABLE a,b : UNSIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ VARIABLE answer : SIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ a := (OTHERS => arg1(arg1'left)) ;
+ a(arg1'length - 1 DOWNTO 0) := UNSIGNED(arg1);
+ b := (OTHERS => arg2(arg2'left)) ;
+ b(arg2'length - 1 DOWNTO 0) := UNSIGNED(arg2);
+ answer := SIGNED(a nand b);
+ RETURN (answer);
+ end "nand";
+
+ FUNCTION "or" ( arg1,arg2 : SIGNED ) RETURN SIGNED IS
+ CONSTANT len : INTEGER := maximum(arg1'length,arg2'length) ;
+ VARIABLE a,b : UNSIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ VARIABLE answer : SIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ a := (OTHERS => arg1(arg1'left)) ;
+ a(arg1'length - 1 DOWNTO 0) := UNSIGNED(arg1);
+ b := (OTHERS => arg2(arg2'left)) ;
+ b(arg2'length - 1 DOWNTO 0) := UNSIGNED(arg2);
+ answer := SIGNED(a or b);
+ RETURN (answer);
+ end "or";
+
+ FUNCTION "nor" ( arg1,arg2 : SIGNED ) RETURN SIGNED IS
+ CONSTANT len : INTEGER := maximum(arg1'length,arg2'length) ;
+ VARIABLE a,b : UNSIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ VARIABLE answer : SIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ a := (OTHERS => arg1(arg1'left)) ;
+ a(arg1'length - 1 DOWNTO 0) := UNSIGNED(arg1);
+ b := (OTHERS => arg2(arg2'left)) ;
+ b(arg2'length - 1 DOWNTO 0) := UNSIGNED(arg2);
+ answer := SIGNED(a nor b);
+ RETURN (answer);
+ end "nor";
+
+ FUNCTION "xor" ( arg1, arg2 : SIGNED ) RETURN SIGNED IS
+ CONSTANT len : INTEGER := maximum(arg1'length,arg2'length) ;
+ VARIABLE a,b : UNSIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ VARIABLE answer : SIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ a := (OTHERS => arg1(arg1'left)) ;
+ a(arg1'length - 1 DOWNTO 0) := UNSIGNED(arg1);
+ b := (OTHERS => arg2(arg2'left)) ;
+ b(arg2'length - 1 DOWNTO 0) := UNSIGNED(arg2);
+ answer := SIGNED(a xor b);
+ RETURN (answer);
+ end "xor";
+
+ FUNCTION "not" ( arg1 : SIGNED ) RETURN SIGNED IS
+ VARIABLE result : SIGNED ( arg1'RANGE ) := (Others => 'X');
+ begin
+ for i in result'range loop
+ result(i) := not_table( arg1(i) );
+ end loop;
+ return result;
+ end "not";
+
+ FUNCTION "xnor" ( arg1, arg2 : std_ulogic_vector ) RETURN std_ulogic_vector IS
+ CONSTANT ml : integer := maximum( arg1'LENGTH, arg2'LENGTH );
+ VARIABLE lt : std_ulogic_vector ( 1 to ml );
+ VARIABLE rt : std_ulogic_vector ( 1 to ml );
+ VARIABLE res : std_ulogic_vector ( 1 to ml );
+ begin
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN res'RANGE LOOP
+ res(i) := not_table( xor_table( lt(i), rt(i) ) );
+ END LOOP;
+ RETURN res;
+ end "xnor";
+
+ FUNCTION "xnor" ( arg1, arg2 : std_logic_vector ) RETURN std_logic_vector IS
+ CONSTANT ml : integer := maximum( arg1'LENGTH, arg2'LENGTH );
+ VARIABLE lt : std_logic_vector ( 1 to ml );
+ VARIABLE rt : std_logic_vector ( 1 to ml );
+ VARIABLE res : std_logic_vector ( 1 to ml );
+ begin
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN res'RANGE LOOP
+ res(i) := not_table( xor_table( lt(i), rt(i) ) );
+ END LOOP;
+ RETURN res;
+ end "xnor";
+
+ FUNCTION "xnor" ( arg1, arg2 : UNSIGNED ) RETURN UNSIGNED IS
+ CONSTANT ml : integer := maximum( arg1'LENGTH, arg2'LENGTH );
+ VARIABLE lt : UNSIGNED ( 1 to ml );
+ VARIABLE rt : UNSIGNED ( 1 to ml );
+ VARIABLE res : UNSIGNED ( 1 to ml );
+ begin
+ lt := zxt( arg1, ml );
+ rt := zxt( arg2, ml );
+ FOR i IN res'RANGE LOOP
+ res(i) := not_table( xor_table( lt(i), rt(i) ) );
+ END LOOP;
+ RETURN res;
+ end "xnor";
+
+ FUNCTION "xnor" ( arg1, arg2 : SIGNED ) RETURN SIGNED IS
+ CONSTANT len : INTEGER := maximum(arg1'length,arg2'length) ;
+ VARIABLE a,b : UNSIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ VARIABLE answer : SIGNED(len-1 DOWNTO 0) := (OTHERS => '0') ;
+ BEGIN
+ a := (OTHERS => arg1(arg1'left)) ;
+ a(arg1'length - 1 DOWNTO 0) := UNSIGNED(arg1);
+ b := (OTHERS => arg2(arg2'left)) ;
+ b(arg2'length - 1 DOWNTO 0) := UNSIGNED(arg2);
+ answer := SIGNED(a xnor b);
+ RETURN (answer);
+ end "xnor";
+
+END ;