Previous

std_logic_arith Package

Functions defined in the std_logic_arith package provide conversion to and from the predefined VHDL data type INTEGER and arithmetic, comparison, and Boolean operations. With this package, you can perform arithmetic operations and numeric comparisons on array data types. The package defines some arithmetic operators (+, -, *, and abs) and the relational operators (<, >, <=, >=, =, and /=).


NOTE

IEEE VHDL does not define arithmetic operators for arrays and defines the comparison operators in a manner inconsistent with an arithmetic interpretation of array values.


The package also defines two major data types of its own; UNSIGNED and SIGNED. Find details in the “Data Types” section of this chapter. The std_logic_arith package is legal VHDL; you can use it for both synthesis and simulation.

The std_logic_arith package can be configured to work on any array of single-bit types. You encode single-bit types in one bit with the ENUM_ENCODING attribute.

You can make the vector type (for example, std_logic_vector) synonymous with either SIGNED or UNSIGNED. This way, if you plan to use mostly UNSIGNED numbers, you do not need to convert your vector type to call UNSIGNED functions. The disadvantage of making your vector type synonymous with either UNSIGNED or SIGNED is that it causes the standard VHDL comparison functions (=, /=, <, >, <=, and >=) to be redefined.

The table below shows that the standard comparison functions for BIT_VECTOR do not match the SIGNED and UNSIGNED functions.

Table 10_1 UNSIGNED, SIGNED, AND BIT_VECTOR

ARG1
op
ARG2
UNSIGNED
SIGNED
BIT_VECTOR
"000"
=
"000"
TRUE
TRUE
TRUE
"00"
=
"000"
TRUE
TRUE
FALSE
"100"
=
"0100"
TRUE
FALSE
FALSE
"000"
<
"000"
FALSE
FALSE
FALSE
"00"
<
"000"
FALSE
FALSE
TRUE
"100"
<
"0100"
FALSE
TRUE
FALSE

Using the Package

The std_logic_arith package has been added to the IEEE package and does not have to be compiled into a separate VHDL library.

This package is in the synth/lib/packages/IEEE/src/std_logic_arith.vhd subdirectory of the Xilinx root directory. To use this package in a VHDL source file, include the following lines at the top of the source file.

   library IEEE;
use IEEE.std_logic_arith.all;

These packages are preanalyzed, and you do not need to further analyze them.

Modifying the Package

The std_logic_arith package is written in standard VHDL. You can modify or add to it. The appropriate hardware is then synthesized.

For example, to convert a vector of multivalued logic to an INTEGER, you can write the function shown in the following example. This MVL_TO_INTEGER function returns the integer value corresponding to the vector when the vector is interpreted as an unsigned (natural) number. If unknown values are in the vector, the return value is -1.

   library IEEE;
   use IEEE.std_logic_1164.all;
   
   function MVL_TO_INTEGER(ARG : MVL_VECTOR) 
      return INTEGER is
      -- pragma built_in SYN_FEED_THRU
      variable uns: UNSIGNED (ARG'range);
   begin
      for i in ARG'range loop
         case ARG(i) is
            when '0' | 'L' => uns(i) := '0';
            when '1' | 'H' => uns(i) := '1';
            when others    => return -1;
         end case;
      end loop;
      return CONV_INTEGER(uns);
   end;

Notice how the CONV_INTEGER function is used in the above example.

Foundation Express performs almost all synthesis directly from the VHDL descriptions. However, several functions are hard wired for efficiency. These functions can be identified by the following comment in their declarations.

- - pragma built_in

This statement marks functions as special, causing the body to be ignored. Modifying the body does not change the synthesized logic unless you remove the built_in comment. If you want new functionality, use the built_in functions; this is more efficient than removing the built_in and modifying the body.

Data Types

The std_logic_arith package defines two data types, UNSIGNED and SIGNED.

   type UNSIGNED is array (natural range <>) of std_logic;
   type SIGNED is array (natural range <>) of std_logic;

These data types are similar to the predefined VHDL type BIT_VECTOR, but the std_logic_arith package defines the interpretation of variables and signals of these types as numeric values. With the install_vhdl conversion script, you can change these data types to arrays of other one-bit types.

UNSIGNED

The UNSIGNED data type represents an unsigned numeric value. Foundation Express interprets the number as a binary representation, with the farthest left bit being most significant. For example, the decimal number 8 can be represented by the following.

UNSIGNED'("1000")

When you declare variables or signals of type UNSIGNED, a larger vector holds a larger number. A four-bit variable holds values up to decimal 15; an eight-bit variable holds values up to 255 and so on. By definition, negative numbers cannot be represented in an UNSIGNED variable. Zero is the smallest value that can be represented.

In the example below, the most significant bit is the farthest left array bound, rather than the high or low range value.

   variable VAR: UNSIGNED (1 to 10);
      -- 11-bit number
      -- VAR(VAR'left) = VAR(1) is the most significant bit
   
   signal SIG: UNSIGNED (5 downto 0); 
      -- 6-bit number
      -- SIG(SIG'left) = SIG(5) is the most significant bit

SIGNED

The SIGNED data type represents a signed numeric value. Foundation Express interprets the number as a 2s complement binary representation, with the farthest left bit as the sign bit. For example, you can represent decimal 5 and -5 by the following.

   SIGNED'("0101")  -- represents +5
   SIGNED'("1011")  -- represents -5

When you declare SIGNED variables or signals, a larger vector holds a larger number. A four-bit variable holds values from -8 to 7; an eight-bit variable holds values from -128 to 127. Notice that a SIGNED value cannot hold as large a value as an UNSIGNED value with the same bit width.


NOTE

The sign bit is the farthest left bit, rather than the highest or lowest in the following example.


   variable S_VAR: SIGNED (1 to 10);  
      -- 11-bit number
      -- S_VAR(S_VAR'left) = S_VAR(1) is the sign bit
   
   signal S_SIG: SIGNED (5 downto 0); 
      -- 6-bit number
      -- S_SIG(S_SIG'left) = S_SIG(5) is the sign bit

Conversion Functions

The std_logic_arith package provides three sets of functions to convert values between its UNSIGNED and SIGNED types and the predefined type INTEGER. This package also provides the std_logic_vector.

The example below shows the declarations of these conversion functions. BIT and BIT_VECTOR types are shown.

   subtype SMALL_INT is INTEGER range 0 to 1;
   
   function CONV_INTEGER(ARG: INTEGER)  return INTEGER;
   function CONV_INTEGER(ARG: UNSIGNED) return INTEGER;
   function CONV_INTEGER(ARG: SIGNED)   return INTEGER;
   function CONV_INTEGER(ARG: STD_ULOGIC) return SMALL_INT;
   
   function CONV_UNSIGNED(ARG: INTEGER;SIZE: INTEGER) return UNSIGNED;
   function CONV_UNSIGNED(ARG: UNSIGNED;SIZE: INTEGER) return UNSIGNED;
   function CONV_UNSIGNED(ARG: SIGNED;         SIZE: INTEGER) return UNSIGNED;
   function CONV_UNSIGNED(ARG: STD_ULOGIC;                       SIZE: INTEGER) return UNSIGNED;
   
   function CONV_SIGNED(ARG: INTEGER; SIZE: INTEGER)   return SIGNED;
   function CONV_SIGNED(ARG: UNSIGNED;SIZE: INTEGER)   return SIGNED;
   function CONV_SIGNED(ARG: SIGNED;SIZE: INTEGER)   return SIGNED;
   function CONV_SIGNED(ARG: STD_ULOGIC;SIZE: INTEGER)   return SIGNED;
   
   function CONV_STD_LOGIC_VECTOR(ARG: INTEGER;SIZE: INTEGER) return STD_LOGIC_VECTOR;
   function CONV_STD_LOGIC_VECTOR(ARG: UNSIGNED;                      SIZE: INTEGER)   return STD_LOGIC_VECTOR;
   function CONV_STD_LOGIC_VECTOR(ARG: SIGNED;                     SIZE: INTEGER)   return STD_LOGIC_VECTOR;
   function CONV_STD_LOGIC_VECTOR(ARG: STD_ULOGIC;SIZE: INTEGER)   return STD_LOGIC_VECTOR;

NOTE

There are four versions of each conversion function.


The operator overloading mechanism of VHDL determines the correct version from the function call's argument types.

The CONV_INTEGER functions convert an argument of type INTEGER, UNSIGNED, SIGNED, or STD_ULOGIC to an INTEGER return value. The CONV_UNSIGNED and CONV_SIGNED functions convert an argument of type INTEGER, UNSIGNED, SIGNED, or STD_ULOGIC to an UNSIGNED or SIGNED return value whose bit width is SIZE.

The CONV_INTEGER functions have a limitation on the size of operands. VHDL defines INTEGER values as between -2147483647 and 2147483647. This range corresponds to a 31-bit UNSIGNED value or a 32-bit SIGNED value. You cannot convert an argument outside this range to an INTEGER.

The CONV_UNSIGNED and CONV_SIGNED functions require two operands. The first operand is the value converted. The second operand is an INTEGER that specifies the expected size of the converted result. For example, the following function call returns a 10-bit UNSIGNED value representing the value in sig.

   ten_unsigned_bits := CONV_UNSIGNED(sig, 10);

If the value passed to CONV_UNSIGNED or CONV_SIGNED is smaller than the expected bit width (such as representing the value 2 in a 24-bit number), the value is bit-extended appropriately. Foundation Express places zeros in the more significant (left) bits for an UNSIGNED return value and uses sign extension for a SIGNED return value.

You can use the conversion functions to extend a number's bit width even if conversion is not required. An example follows.

   CONV_SIGNED(SIGNED'("110"), 8) % "11111110"

An UNSIGNED or SIGNED return value is truncated when its bit width is too small to hold the ARG value. An exampl follows.

   CONV_SIGNED(UNSIGNED'("1101010"), 3) % "010"

Arithmetic Functions

The std_logic_arith package provides arithmetic functions for use with combinations of Xilinx's UNSIGNED and SIGNED data types and the predefined types STD_ULOGIC and INTEGER. These functions produce adders and subtracters.

There are two sets of arithmetic functions; binary functions with two arguments, such as A+B or A*B, and unary functions with one argument, such as -A. The declarations for these functions are shown in the following examples.

Example 10-1: Binary Arithmetic Functions

   function "+"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED;
   function "+"(L: SIGNED;   R: SIGNED)   return SIGNED;
   function "+"(L: UNSIGNED; R: SIGNED)   return SIGNED;
   function "+"(L: SIGNED;   R: UNSIGNED) return SIGNED;
   function "+"(L: UNSIGNED; R: INTEGER)  return UNSIGNED;
   function "+"(L: INTEGER;  R: UNSIGNED) return UNSIGNED;
   function "+"(L: SIGNED;   R: INTEGER)  return SIGNED;
   function "+"(L: INTEGER;  R: SIGNED)   return SIGNED;
   function "+"(L: UNSIGNED; R: STD_ULOGIC) return UNSIGNED;
   function "+"(L: STD_ULOGIC; R: UNSIGNED) return UNSIGNED;
   function "+"(L: SIGNED;   R: STD_ULOGIC) return SIGNED;
   function "+"(L: STD_ULOGIC; R: SIGNED)   return SIGNED;
   
   function "+"(L: UNSIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR;
   function "+"(L: SIGNED; R: SIGNED) return STD_LOGIC_VECTOR;
   function "+"(L: UNSIGNED; R: SIGNED) return STD_LOGIC_VECTOR;
   function "+"(L: SIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR;
   function "+"(L: UNSIGNED; R: INTEGER) return STD_LOGIC_VECTOR;
   function "+"(L: INTEGER; R: UNSIGNED) return STD_LOGIC_VECTOR;
   function "+"(L: SIGNED; R: INTEGER) return STD_LOGIC_VECTOR;
   function "+"(L: INTEGER; R: SIGNED) return STD_LOGIC_VECTOR;
   function "+"(L: UNSIGNED; R: STD_ULOGIC) return
    STD_LOGIC_VECTOR;
   function "+"(L: STD_ULOGIC; R: UNSIGNED) return STD_LOGIC_VECTOR;
   function "+"(L: SIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR;
   function "+"(L: STD_ULOGIC; R: SIGNED) return STD_LOGIC_VECTOR;
   function "-"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED;
   function "-"(L: SIGNED;   R: SIGNED)   return SIGNED;
   function "-"(L: UNSIGNED; R: SIGNED)   return SIGNED;
   function "-"(L: SIGNED;   R: UNSIGNED) return SIGNED;
   function "-"(L: UNSIGNED; R: INTEGER)  return UNSIGNED;
   function "-"(L: INTEGER;  R: UNSIGNED) return UNSIGNED;
   function "-"(L: SIGNED;   R: INTEGER)  return SIGNED;
   function "-"(L: INTEGER;  R: SIGNED)   return SIGNED;
   function "-"(L: UNSIGNED; R: STD_ULOGIC) return UNSIGNED;
   function "-"(L: STD_ULOGIC; R: UNSIGNED) return UNSIGNED;
   function "-"(L: SIGNED;   R: STD_ULOGIC) return SIGNED;
   function "-"(L: STD_ULOGIC; R: SIGNED)   return SIGNED;
   
   function "-"(L: UNSIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR;
   function "-"(L: SIGNED; R: SIGNED) return STD_LOGIC_VECTOR;
   function "-"(L: UNSIGNED; R: SIGNED) return STD_LOGIC_VECTOR;
   function "-"(L: SIGNED; R: UNSIGNED) return STD_LOGIC_VECTOR;
   function "-"(L: UNSIGNED; R: INTEGER) return STD_LOGIC_VECTOR;
   function "-"(L: INTEGER; R: UNSIGNED) return STD_LOGIC_VECTOR;
   function "-"(L: SIGNED; R: INTEGER) return STD_LOGIC_VECTOR;
   function "-"(L: INTEGER; R: SIGNED) return STD_LOGIC_VECTOR;
   function "-"(L: UNSIGNED; R: STD_ULOGIC) return
    STD_LOGIC_VECTOR;
   function "-"(L: STD_ULOGIC; R: UNSIGNED) return
    STD_LOGIC_VECTOR;
   function "-"(L: SIGNED; R: STD_ULOGIC) return STD_LOGIC_VECTOR;
   function "-"(L: STD_ULOGIC; R: SIGNED) return STD_LOGIC_VECTOR;
   
   function "*"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED;
   function "*"(L: SIGNED;   R: SIGNED)   return SIGNED;
   function "*"(L: SIGNED;   R: UNSIGNED) return SIGNED;
   function "*"(L: UNSIGNED; R: SIGNED)   return SIGNED;

Example 10-2: Unary Arithmetic Functions

   function "+"(L: UNSIGNED) return UNSIGNED;
   function "+"(L: SIGNED)   return SIGNED;
   function "-"(L: SIGNED)   return SIGNED;
   function "ABS"(L: SIGNED) return SIGNED;

These functions determine the width of their return values as follows.

The number of bits returned by + and - is illustrated in the following table.

   signal U4: UNSIGNED (3 downto 0);
   signal U8: UNSIGNED (7 downto 0);
   signal S4: SIGNED (3 downto 0);
   signal S8: SIGNED (7 downto 0);

Table 10_2 Number of Bits Returned by + and -

+ or -
U4
U8
S4
S8
U4
4
8
5
8
U8
8
8
9
9
S4
5
9
4
8
S8
8
9
8
8

In some circumstances, you might need to obtain a carry-out bit from the + or - operation. To do this, extend the larger operand by one bit. The high bit of the return value is the carry-out bit, as illustrated in the example below.


   process
      variable a, b, sum: UNSIGNED (7 downto 0);
      variable temp: UNSIGNED (8 downto 0);
      variable carry: BIT;
   begin
      temp  := CONV_UNSIGNED(a,9) + b;
      sum   := temp(7 downto 0);
      carry := temp(8);
   end process;

Comparison Functions

The std_logic_arith package provides functions to compare UNSIGNED and SIGNED data types to each other and to the predefined type INTEGER. Foundation Express compares the numeric values of the arguments, returning a Boolean value. For example, the following expression evaluates to TRUE.

UNSIGNED'("001") > SIGNED'("111")

The std_logic_arith comparison functions are similar to the built-in VHDL comparison functions. The only difference is that the std_logic_arith functions accommodate signed numbers and varying bit widths. The predefined VHDL comparison functions perform bit-wise comparisons and so do not have the correct semantics for comparing numeric values. (See the “Relational Operators” section of the “Expressions” chapter.)

These functions produce comparators. The function declarations are listed in two groups, ordering functions (<, <=, >, and >=) and equality functions (= and /=) in the following examples.

Example 10-3: Ordering Functions

   function "<"(L: UNSIGNED; R: UNSIGNED) return Boolean;
   function "<"(L: SIGNED;   R: SIGNED)   return Boolean;
   function "<"(L: UNSIGNED; R: SIGNED)   return Boolean;
   function "<"(L: SIGNED;   R: UNSIGNED) return Boolean;
   function "<"(L: UNSIGNED; R: INTEGER)  return Boolean;
   function "<"(L: INTEGER;  R: UNSIGNED) return Boolean;
   function "<"(L: SIGNED;   R: INTEGER)  return Boolean;
   function "<"(L: INTEGER;  R: SIGNED)   return Boolean;
   
   function "<="(L: UNSIGNED; R: UNSIGNED) return Boolean;
   function "<="(L: SIGNED;   R: SIGNED)   return Boolean;
   function "<="(L: UNSIGNED; R: SIGNED)   return Boolean;
   function "<="(L: SIGNED;   R: UNSIGNED) return Boolean;
   function "<="(L: UNSIGNED; R: INTEGER)  return Boolean;
   function "<="(L: INTEGER;  R: UNSIGNED) return Boolean;
   function "<="(L: SIGNED;   R: INTEGER)  return Boolean;
   function "<="(L: INTEGER;  R: SIGNED)   return Boolean;
   
   function "" functions">">"(L: UNSIGNED; R: UNSIGNED) return Boolean;
   function ">"(L: SIGNED;   R: SIGNED)   return Boolean;
   function ">"(L: UNSIGNED; R: SIGNED)   return Boolean;
   function ">"(L: SIGNED;   R: UNSIGNED) return Boolean;
   function ">"(L: UNSIGNED; R: INTEGER)  return Boolean;
   function ">"(L: INTEGER;  R: UNSIGNED) return Boolean;
   function ">"(L: SIGNED;   R: INTEGER)  return Boolean;
   function ">"(L: INTEGER;  R: SIGNED)   return Boolean;
   
   function ="" functions">">="(L: UNSIGNED; R: UNSIGNED) return Boolean;
   function ">="(L: SIGNED;   R: SIGNED)   return Boolean;
   function ">="(L: UNSIGNED; R: SIGNED)   return Boolean;
   function ">="(L: SIGNED;   R: UNSIGNED) return Boolean;
   function ">="(L: UNSIGNED; R: INTEGER)  return Boolean;
   function ">="(L: INTEGER;  R: UNSIGNED) return Boolean;
   function ">="(L: SIGNED;   R: INTEGER)  return Boolean;
   function ">="(L: INTEGER;  R: SIGNED)   return Boolean;

Example 10-4: Equality Functions

   function "="(L: UNSIGNED; R: UNSIGNED) return Boolean;
   function "="(L: SIGNED;   R: SIGNED)   return Boolean;
   function "="(L: UNSIGNED; R: SIGNED)   return Boolean;
   function "="(L: SIGNED;   R: UNSIGNED) return Boolean;
   function "="(L: UNSIGNED; R: INTEGER)  return Boolean;
   function "="(L: INTEGER;  R: UNSIGNED) return Boolean;
   function "="(L: SIGNED;   R: INTEGER)  return Boolean;
   function "="(L: INTEGER;  R: SIGNED)   return Boolean;
   
   function "/="(L: UNSIGNED; R: UNSIGNED) return Boolean;
   function "/="(L: SIGNED;   R: SIGNED)   return Boolean;
   function "/="(L: UNSIGNED; R: SIGNED)   return Boolean;
   function "/="(L: SIGNED;   R: UNSIGNED) return Boolean;
   function "/="(L: UNSIGNED; R: INTEGER)  return Boolean;
   function "/="(L: INTEGER;  R: UNSIGNED) return Boolean;
   function "/="(L: SIGNED;   R: INTEGER)  return Boolean;
   function "/="(L: INTEGER;  R: SIGNED)   return Boolean;

Shift Functions

The std_logic_arith package provides functions for shifting the bits in SIGNED and UNSIGNED numbers. These functions produce shifters. See the following example for shift function declarations.

   COUNT: UNSIGNED)  return UNSIGNED;
   function SHL(ARG: SIGNED;COUNT: UNSIGNED)  return SIGNED;
   
   function SHR(ARG: UNSIGNED;COUNT: UNSIGNED)  return UNSIGNED;
   function SHR(ARG: SIGNED;COUNT: UNSIGNED)  return SIGNED;

The SHL function shifts the bits of its argument ARG to the left by COUNT bits. The SHR function shifts the bits of its argument ARG to the right by COUNT bits.

The SHL functions work the same for both UNSIGNED and SIGNED values of ARG, shifting in zero bits as necessary. The SHR functions treat UNSIGNED and SIGNED values differently. If ARG is an UNSIGNED number, vacated bits are filled with zeros; if ARG is a SIGNED number, the vacated bits are copied from the sign bit of ARG.

The example below shows some shift function calls and their return values.

   variable U1, U2: UNSIGNED (7 downto 0);
   variable S1, S2: SIGNED   (7 downto 0);
   variable COUNT:  UNSIGNED (1 downto 0);
   . . .
   U1 := "01101011";   
   U2 := "11101011";
   
   S1 := "01101011";   
   S2 := "11101011";
   
   COUNT := CONV_UNSIGNED(ARG => 3, SIZE => 2);
   . . .
   SHL(U1, COUNT) = "01011000"
   SHL(S1, COUNT) = "01011000"
   SHL(U2, COUNT) = "01011000"
   SHL(S2, COUNT) = "01011000"
   
   SHR(U1, COUNT) = "00001101"
   SHR(S1, COUNT) = "00001101"
   SHR(U2, COUNT) = "00011101"
   SHR(S2, COUNT) = "11111101"

You can use shift operations for simple multiplication and division of UNSIGNED numbers, if you multiply or divide by a power of two.

For example, to divide the following UNSIGNED variable U by 4, see the following.

   variable U: UNSIGNED (7 downto 0) := "11010101";
   variable quarter_U: UNSIGNED (5 downto 0);
   
   quarter_U := SHR(U, "01");

ENUM_ENCODING Attribute

Place the synthesis attribute ENUM_ENCODING on your primary logic type. (See the “Enumeration Encoding” section of the “Data Types” chapter.) This attribute allows Foundation Express to interpret your logic correctly.

pragma built_in

Label your primary logic functions with the built_in pragma. This pragma allows Foundation Express to interpret your logic functions easily. When you use a built_in pragma, Foundation Express parses but ignores the body of the function. Instead, Foundation Express directly substitutes the appropriate logic for the function. You are not required to use built_in pragmas; however, using these pragmas can result in run times that are ten times faster.

Use built_in pragmas by placing a comment in the declaration part of a function. Foundation Express interprets a comment as a directive if the first word of the comment is pragma.

The following example shows how to use a built_in pragma.

   function "XOR" (L, R: STD_LOGIC_VECTOR) return
   STD_LOGIC_VECTOR is
      -- pragma built_in SYN_XOR
      begin
         if (L = '1') xor (R = '1') then
            return '1';
         else 
            return '0';
         end if;
      end "XOR";

Two-Argument Logic Functions

Xilinx provides six built-in functions to perform two-argument logic functions.

You can use these functions on single-bit arguments or equal-length arrays of single bits.

The following example shows a function that generates the logical AND of two equal-size arrays.


   function "AND" (L, R: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
        -- pragma built_in SYN_AND
      variable MY_L: STD_LOGIC_VECTOR (L'length-1 downto 0);
      variable MY_R: STD_LOGIC_VECTOR (L'length-1 downto 0);
      variable RESULT: STD_LOGIC_VECTOR (L'length-1 downto 0);
   begin
      assert L'length = R'length;
      MY_L := L;
      MY_R := R;
      for i in RESULT'range loop
         if (MY_L(i) = '1') and (MY_R(i) = '1') then
            RESULT(i) := '1';
         else
            RESULT(i) := '0';
         end if;
      end loop;
      return RESULT;
   end "AND";

One-Argument Logic Functions

Xilinx provides two built-in functions to perform one-argument logic functions.

You can use these functions on single-bit arguments or equal-length arrays of single bits. The example below shows a function that generates the logical NOT of an array.

   function "NOT" (L: STD_LOGIC_VECTOR) return STD_LOGIC_VECTOR is
        -- pragma built_in SYN_NOT
      variable MY_L: STD_LOGIC_VECTOR (L'length-1 downto 0);
      variable RESULT: STD_LOGIC_VECTOR (L'length-1 downto 0);
   begin
      MY_L := L;
      for i in result'range loop
         if (MY_L(i) = '0' or MY_L(i) = 'L') then
            RESULT(i) := '1';
          elsif (MY_L(i) = '1' or MY_L(i) = 'H') then
             RESULT(i) := '0';
         else
            RESULT(i) := 'X';
          end if;
      end loop;
      return RESULT;
   end "NOT";
   end;

Type Conversion

The built-in function SYN_FEED_THRU performs fast type conversion between unrelated types. The synthesized logic from SYN_FEED_THRU wires the single input of a function to the return value. This connection can save the CPU time required to process a complicated conversion function, as shown in the following example.

   type COLOR is (RED, GREEN, BLUE);
   attribute ENUM_ENCODING : STRING;
   attribute ENUM_ENCODING of COLOR : type is "01 10 11";
   ...
   
   function COLOR_TO_BV (L: COLOR) return BIT_VECTOR is
        -- pragma built_in SYN_FEED_THRU
   begin
      case L is
         when RED   => return "01";
          when GREEN => return "10";
         when BLUE  => return "11";
      end case;
   end COLOR_TO_BV;

translate_off Directive

If there are constructs in your “types” package that are not supported for synthesis or that produce warning messages, you may need to use the Foundation Express directive -- synopsys translate_off. You can make liberal use of the translate_off directive when you use built_in pragmas because Foundation Express ignores the body of built_in functions. For examples showing how to use the translate_off directive, see the std_logic_arith.vhd package.

Next