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 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).
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:


