|Summary |Design Units |Sequential Statements |Concurrent Statements |Predefined Types |Declarations |
|Resolution and Signatures |Reserved Words |Operators |Predefined Attributes |Standard Packages |
A resolution function defines how values from multiple sources,
multiple drivers, are resolved into a single value.
A type may be defined to have a resolution function. Every signal
object of this type uses the resolution function when there are
multiple drivers.
A signal may be defined to use a specific resolution function.
This signal uses the resolution function when there are multiple
drivers.
A resolution function must be a pure function that has a single
input parameter of class constant that is a one dimensional
unconstrained array of the type of the resolved signal.
An example is from the package  std_logic_1164 :
    type std_ulogic is ( 'U',  -- Uninitialized
                         'X',  -- Forcing  Unknown
                         '0',  -- Forcing  0
                         '1',  -- Forcing  1
                         'Z',  -- High Impedance   
                         'W',  -- Weak     Unknown
                         'L',  -- Weak     0       
                         'H',  -- Weak     1       
                         '-'   -- Don't care
                       );
    type std_ulogic_vector is array ( natural range <> ) of std_ulogic;
                                    
    -- resolution function
    function resolved ( s : std_ulogic_vector ) return std_ulogic;
        variable result : std_ulogic := 'Z';  -- weakest state default
    begin
        -- the test for a single driver is essential otherwise the
        -- loop would return 'X' for a single driver of '-' and that
        -- would conflict with the value of a single driver unresolved
        -- signal.
        if  s'length = 1 then
            return s(s'low);
        else
            for i in s'range loop
                result := resolution_table(result, s(i));
            end loop;
        end if;
        return result;
    end resolved;
    constant resolution_table : stdlogic_table := (
    --      ---------------------------------------------------------
    --      |  U    X    0    1    Z    W    L    H    -        |   |  
    --      ---------------------------------------------------------
            ( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- | U |
            ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X |
            ( 'U', 'X', '0', 'X', '0', '0', '0', '0', 'X' ), -- | 0 |
            ( 'U', 'X', 'X', '1', '1', '1', '1', '1', 'X' ), -- | 1 |
            ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', 'X' ), -- | Z |
            ( 'U', 'X', '0', '1', 'W', 'W', 'W', 'W', 'X' ), -- | W |
            ( 'U', 'X', '0', '1', 'L', 'W', 'L', 'W', 'X' ), -- | L |
            ( 'U', 'X', '0', '1', 'H', 'W', 'W', 'H', 'X' ), -- | H |
            ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' )  -- | - |
        );
    
    subtype std_logic is resolved std_ulogic;
    type std_logic_vector is array ( natural range <>) of std_logic;
    signal xyz : std_logic_vector(0 to 3);
    xyz <= -- some expression ;
    xyz <= -- some other expression ; -- a second driver
                           -- each bit of  xyz  comes from function "resolved"
A signature distinguishes between overloaded subprograms and enumeration
literals based on their parameter and result type profiles.
A signature may be used in an attribute name, entity designator,
or alias declaration.
The syntax of the signature is
  [ type_mark, type_mark, ... , type_mark return type_mark ]
A signature used in an alias statement to give a shorthand to
a textio procedure is:
    alias swrite is write [line, string, side, width] ;
allowing   swrite(output, "some text");  in place of
           write(output, string'("some text"));
The "[line, string, side, width]" is the signature to choose which
of the overloaded  'write'  procedures to alias to 'swrite'.
No return is used for procedures.
The type marks are the parameter types in their defined order.
The square brackets at beginning and end are part of the signature.
The signature is used immediately after the subprogram or
enumeration literal name.
This is just a specific example to help understand 'to' vs 'downto'
and how the values of attributes such as 'left 'right and 'high 'low
are determined.
A : std_logic_vector(31 downto 0) := x"FEDCBA98"; -- 'downto'
B : std_logic_vector( 4 to    27) := x"654321";   -- 'to'
C       a literal constant                  x"321"
Name  bitstring (attributes on following lines)
 A    11111110110111001011101010011000
      A'left=31     A'right=0      A'low=0      A'high=31
      A(A'left)=1   A(A'right)=0   A(A'low)=0   A(A'high)=1
      A'range=(31 downto 0)        A'reverse_range=(0 to 31) 
      A'length=32                  A'ascending=false
 B    011001010100001100100001                  B'ascending=true
      B'left=4      B'right=27     B'low=4      B'high=27
      B(B'left)=0   B(B'right)=1   B(B'low)=0   B(B'high)=1
      B'range=(4 to 27)            B'reverse_range=(27 downto 4) 
      B'length=24                  B'ascending=true
 C    001100100001
      C'left=0      C'right=11     C'low=0      C'high=11
      C(C'left)=0   C(C'right)=1   C(C'low)=0   C(C'high)=1
      C'range=(0 to 11)            C'reverse_range=(11 downto 0) 
      C'length=12                  C'ascending=true
      Notice the default values of attributes on literal constants.
      Always a range of (0 to 'length-1)  'left  = 'low  = 0
                                          'right = 'high = 'length-1