I am trying to understand the concurrent procedure call with different parameters' class. Assuming I have the procedure test and it is called concurrently like below:
ENTITY tb IS
END ENTITY tb;
ARCHITECTURE sim OF tb IS
SIGNAL cnt : integer RANGE 0 TO 3 := 0;
SIGNAL str : string(1 TO 5) := (OTHERS => ' ');
PROCEDURE test (CONSTANT number : IN integer RANGE 0 TO 3 := 0;
SIGNAL num_str : OUT string(1 TO 5)) IS
BEGIN
REPORT "here";
CASE number IS
WHEN 0 => num_str <= "zero ";
WHEN OTHERS => num_str <= "one ";
END CASE;
END PROCEDURE;
BEGIN
test(cnt, str); -- CONCURRENT CALL TO PROCEDURE TEST
PROCESS
BEGIN
FOR i IN 0 TO 3 LOOP
WAIT FOR 10 ns;
cnt <= i;
END LOOP;
WAIT;
END PROCESS;
END ARCHITECTURE sim;
In THE VHDL DESIGNER GUIED
Another point to note about concurrent procedure calls is that if there are no signals associated with in-mode or inout-mode parameters, the wait statement in the equivalent process does not have a sensitivity clause. If the procedure ever returns, the process suspends indefinitely. This may be useful if we want the procedure to be called only once at startup time.
As procedure test has no signals associated with in-mode or inout-mode, it supposes to be executed once and then suspends indefinitely. But with this example, the procedure is executed 4 times.
Can someone explain to me what is happening or what I am missing?
Section 11.4 of the 2008 LRM (IEEE Std 1076-2008):
For any concurrent procedure call statement, there is an equivalent process statement [...] The equivalent process statement also has no sensitivity list, an empty declarative part, and a statement part that consists of a procedure call statement followed by a wait statement. The procedure call statement consists of the same procedure name and actual parameter part that appear in the concurrent procedure call statement.
If there exists a name that denotes a signal in the actual part of any association element in the concurrent procedure call statement, and that actual is associated with a formal parameter of mode in or inout, then the equivalent process statement includes a final wait statement with a sensitivity clause that is constructed by taking the union of the sets constructed by applying the rule of 10.2 to each actual part associated with a formal parameter.
Forget about the last part, in your case things are super simple and your equivalent process is:
process
begin
test(cnt, str);
wait on cnt;
end process;
The CONSTANT
class declaration of your procedure's declaration only indicates that (section 4.2.2.2):
For parameters of class constant or variable, only the values of the actual or formal are transferred into or out of the subprogram call.
It somehow forces you to manipulate this value as if it was a constant and nothing else... inside the procedure's body. It forbids you, for instance, to use signal attributes (e.g. number'EVENT
). But it doesn't say anything about the actual parameter that you will associate to this formal parameter when instantiating the procedure.
And the result is, logically, what you observe: your procedure is called 4 times in the equivalent process. Each time the value of the actual parameter, that is, the signal cnt
is passed through the formal parameter number
.
And your book is right:
[...] if there are no signals associated with in-mode or inout-mode parameters, the wait statement in the equivalent process does not have a sensitivity clause.
Indeed, you have a signal (cnt
) associated with an in-mode parameter (number
).