VHDL port external names and procedure modes

Viewed 299

Using Modelsim 10.7b (VHDL-2008), I am confused by the behavior of VHDL external names when passed in to a procedure. In particular, I see a wide variety of different behavior depending on whether the external name references a port or a signal, and whether I use mode in or inout.

The only book I have that covers external names (Ashenden, 3rd Ed.) only gives one trivial example of a port, but just implies it's exactly the same as a signal: "This reflects the rule in VHDL that a port is considered to be a signal declared within an entity". It doesn't appear to cover what happens in a procedure.

Therefore, my question is whether someone can provide an explanation for the observed behavior in each of the following 3 simple test cases.

an_entity.vhd:

library ieee;
    use ieee.std_logic_1164.all;

entity an_entity is
    port (
        i   : in std_logic
    );
end;

architecture rtl of an_entity is
    signal s    : std_logic;
begin
    s <= i;
end;

tb.vhd:

library ieee;
    use ieee.std_logic_1164.all;

entity tb is
end entity tb;

architecture rtl of tb is

    procedure procedure_with_mode_in(signal x : in std_logic) is
    begin
        x <= force '1';
    end procedure;

    procedure procedure_with_mode_inout(signal x : inout std_logic) is
    begin
        x <= force '1';
    end procedure;

    signal i    : std_logic := '0';

begin

    uut : entity work.an_entity
    port map(
        i   => i
    );

    process
    begin

        -- ### COPY-PASTE TEST CASE HERE ###

        wait;
    end process;

end architecture rtl;

SANITY CHECK: No procedure call

wait for 10 ns;
<<signal uut.i : std_logic>> <= force '1';
wait for 10 ns;
<<signal uut.i : std_logic>> <= release;

Result: Forces and releases successfully:

Test 1 Result

TEST CASE 1: Procedure called on port, mode in

wait for 10 ns;
procedure_with_mode_in(<<signal uut.i : std_logic>>);
wait for 10 ns;
<<signal uut.i : std_logic>> <= release;

Result: Forces but doesn't release:

(Note: Result is the same if procedure is called on a signal external name).

enter image description here

TEST CASE 2: Procedure called on port, mode inout

wait for 10 ns;
procedure_with_mode_inout(<<signal uut.i : std_logic>>);
wait for 10 ns;
<<signal uut.i : std_logic>> <= release;

Result: Error:

# ** Error: (vsim-8509) The object class "SIGNAL(read/driven)" of "uut.i" is different from the class "VHDL INPUT PORT" of the denoted object.  
#    Time: 0 ns  Iteration: 0  Instance: /tb File: C:/path/tb.vhd Line: 32

TEST CASE 3: Procedure called on signal, mode inout

wait for 10 ns;
procedure_with_mode_inout(<<signal uut.s : std_logic>>);
wait for 10 ns;
<<signal uut.s : std_logic>> <= release;

Result: Signal is undefined, but forces and releases:

enter image description here

0 Answers
Related