Friday, July 31, 2015

VHDL Functions and Procedures

Function
Procedure
Functions are used to describe frequently used sequential algorithms that return a single value that is returned to the calling program using a return statement.
These are used to partition large behavioral descriptions into modular sections.
Eg., resolution functions, type conversion functions.
Eg., Arithmetic Unit, Memories, Control Unit, etc  
These are usually used for computing a single value.
Procedures can return zero or more values using parameters of mode out and inout.
Functions are used to compute values that are available instantaneously.
A process that calls a procedure with a wait statement cannot have a sensitivity list. This follows from the fact that a process cannot be sensitive to signals and also be made to wait simultaneously.
A function cannot be made to wait.
A procedure body can have a wait statement. Hence any variables declared in the procedure retain their values through this wait period and cease to exist only when the procedure terminates.
The general syntax of a subprogram specification for a function body is

function function-name (parameter-list) return return-type

The parameter-list describes the list of formal parameters for the function. The only mode allowed for the parameters is mode in. Also, only constants and signal objects can be passed in as parameters.
Syntax for a procedure body

procedure procedure-name ( parameter-list )

The parameter-list specifies the list of formal parameters for the procedure. Parameters may be constants, variables, or signals and their modes may be in, out, or inout.
The default object class is constant and its value cannot be modified within the function body.
If the object class of a parameter is not explicitly specified, then the object class is by default a constant if the parameter is of mode in, else it is a variable if the parameter is of mode out or inout.
Eg., function body

function LARGEST (TOTAL_NO: INTEGER; SET: PATTERN)
return REAL is
-- PATTERN is defined to be atype of 1-D array of
-- floating-point values, elsewhere.
variable RETURN_VALUE: REAL := 0.0;
begin
for K in 1 to TOTAL_NO loop
if SET(K) > RETURN_VALUE then
RETURN_VALUE := SET(K);
end if;
end loop;
return RETURN_VALUE;
end LARGEST;

Variable RETURN_VALUE comes into existence with an initial value of 0.0 every time the function is called. It ceases to exist after the function returns back to the calling program.
Eg., procedure body that describes the behavior of an arithmetic logic unit.

type OP_CODE is (ADD, SUB, MUL, DIV, LT, LE, EQ);
procedure ARITH_UNIT (A, B: in INTEGER; OP: in OP_CODE;
Z: out INTEGER; ZCOMP: out BOOLEAN) is
begin
case OP is
when ADD=>Z:=A+B;
when SUB=>Z:=A-B;
when MUL=>Z:=A*B;
when DIV => Z := A/B;
when LT => ZCOMP := A < B;
when LE => ZCOMP := A <= B;
when EQ => ZCOMP := A = B;
end case;
end ARITH_UNIT;
A function call can be used within an expression.
A procedure call may be a sequential or a concurrent statement, which is based on where the actual procedure call statement is present.
Functions are invoked by function call.

A function call is an expression and can, therefore, be used in expressions.

Eg.,

SUM := SUM + LARGEST(MAX_COINS, COLLECTION);
Procedures are invoked by using procedure calls.

If the call is inside a process statement or inside another subprogram, then it is a sequential procedure call statement, else it is a concurrent procedure call statement.

A procedure can normally be used simultaneously as a concurrent and a sequential statement. But, if any of the procedure parameters are of the variable class, the procedure would be restricted to be used as a sequential procedural call, since variables can only be defined inside of a process.

Concurrent procedure calls are useful in representing frequently used processes.

A sequential procedure call statement is executed sequentially with respect to the sequential statements surrounding it inside a process or a subprogram.

A concurrent procedure call statement is executed whenever an event occurs on one of the parameters which is a signal of mode in or inout.

Semantically, a concurrent procedure call is equivalent to a process with a sequential procedure call and a wait statement that waits for an event on the signal parameters of mode in or inout.

Eg., A concurrent procedure call and its equivalent process statement.

architecture DUMMY_ARCH of DUMMY is
-- Following is a procedure body:
procedure INT_2_VEC (signal D: out BIT_VECTOR;
START_BIT, STOP_BIT: in INTEGER;
signal VALUE: in INTEGER)
begin
-- Procedure behavior here.
end INT_2_VEC;
begin
-- This is an example of a concurrent procedure call:
INT_2_VEC (D_ARRAY, START, STOP, SIGNAL.VALUE);
end DUMMY_ARCH;

- is equivalent to:
architecture DUMMY_ARCH of DUMMY is
procedure INT_2_VEC (signal D: out BIT_VECTOR;
START_BIT, STOP_BIT: in INTEGER;
signal VALUE: in INTEGER)
begin
-- Procedure behavior here.
end INT_2_VEC;
begin
process
begin
INT_2_VEC (D_ARRAY, START, STOP, SIGNAL_VALUE);
-- This is now a sequential procedure call.
wait on SIGNAL_VALUE;
-- Since SIGNAL_VALUE is an input signal.
end process;
end DUMMY_ARCH;
A function call has the form

function-name ( list-of-actual-values )

The actual values may be associated by position (the first actual value corresponds to the first formal parameter, the second actual value corresponds to the second parameter, and so on) or they may be associated using named association (the association of actual values and formal parameters are explicitly specified). The function call in the last example used positional association.
Syntax of a procedure call statement is

procedure-name (list-of-actual-parameters);

The actual parameters specify the expressions that are to be passed into the procedure and the names of objects that are to receive the computed values from the procedure.

Actual parameters may be specified using positional association or named association.
Function call using position association

LARGEST(MAX_COINS, COLLECTION);

ARITH_UNIT (D1, D2, ADD, SUM, COMP); -- Positional association.

Function call using named association

LARGEST (SET=> COLLECTION, TOTAL_NO => MAX_COINS)

ARITH_UNIT (Z=>SUM, B=>D2, A=>D1, OP=>ADD, ZCOMP=>COMP);
-- Named association.

2 comments: