A concurrent procedure call is a procedure call used as a concurrent statement; it is used in an architecture or a block, rather than in a process. A concurrent procedure call is equivalent to a process containing a single sequential procedure call. The syntax is the same as that of a sequential procedure call.
procedure_name [ ( [ name => ] expression
{ , [ name => ] expression } ) ] ;
The equivalent process is sensitive to all in and inout parameters of the procedure. The example below shows a procedure declaration, then a concurrent procedure call and its equivalent process.
procedure ADD(signal A, B: in BIT;
signal SUM: out BIT);
...
ADD(A, B, SUM); -- Concurrent procedure call
...
process(A, B) -- The equivalent process
begin
ADD(A, B, SUM); -- Sequential procedure call
end process;
Foundation Express implements procedure and function calls with logic, unless you use the map_to_entity compiler directive. (See the Mapping Subprograms to Components (Entities) section of the Sequential Statements chapter.)
A common use for concurrent procedure calls is to obtain many copies of a procedure. For example, a class of BIT_VECTOR signals must contain only one bit with value 1 and the rest of the bits with value 0. You have several signals of varying widths that you want monitored at the same time. One approach is to write a procedure to detect the error in a BIT_VECTOR signal, then make a concurrent call to that procedure for each signal.
The following example shows a procedure CHECK that determines whether a given bit vector contains exactly one element with value '1'; if this is not the case, CHECK sets its out parameter ERROR to TRUE.
procedure CHECK(signal A: in BIT_VECTOR;
signal ERROR: out Boolean) is
variable FOUND_ONE: Boolean := FALSE;
-- Set TRUE when a '1'
-- is seen
begin
for I in A'range loop -- Loop across all bits
-- in the vector
if A(I) = '1' then -- Found a '1'
if FOUND_ONE then -- Have we already found one?
ERROR <= TRUE; -- Found two '1's
return; -- Terminate procedure
end if;
FOUND_ONE := TRUE; -- Note that we have
end if; -- seen a '1'
end loop;
ERROR <= not FOUND_ONE; -- Error will be TRUE
-- if no '1' found
end;
The example below shows the CHECK procedure called concurrently for four differently sized bit vector signals. The resulting circuit is shown in the figure following the example.
BLK: block
signal S1: BIT_VECTOR(0 to 0);
signal S2: BIT_VECTOR(0 to 1);
signal S3: BIT_VECTOR(0 to 2);
signal S4: BIT_VECTOR(0 to 3);
signal E1, E2, E3, E4: Boolean;
begin
CHECK(S1, E1); -- Concurrent procedure call
CHECK(S2, E2);
CHECK(S3, E3);
CHECK(S4, E4);
end block BLK;
Figure 7.5 Circuit for Concurrent Procedure Calls |