next up previous contents
Next: 7. Signals Up: 6. Sequential Modeling Previous: 6.1 Assignments

   
6.2 Subprograms

In VHDL, procedures (one or more return parameters) and functions (only one return value) are available as subprograms. Functions are often used for type conversions or as resolution functions (see Section 7.3, page [*]).

Local variables can be declared within subprograms and their values are defined only until the return from a subprogram occurs. In contrast, variables of a process correspond to the local memory locations.

A subprogram must be declared prior to its call. Therefore, if it is called within a process, it must be declared in its respective architecture, entity or package.

During the subprogram call, passing of parameters is done by either the proper position in the parameter list or by the name, such that declaration_name => actual_parameter.

Function:
may have several parameters but produces only one return value (analogous to the VHDL expression).

Syntax:
function func_name (parameter_list)
return type_name is
  
[variable_declaration]
  
[constant_declaration]
  
[type_declaration]
  
[use_clause]
begin
  
[sequential_statements]
  return expression;
  
[sequential_statements]
end
[func_name];

In the following example, function VEC2INT converts a bit-vector into an integer value.

Example:
architecture ...
  ...
  function VEC2INT (S: bit_vector range 1 to 8)
  return integer is
    variable RES: integer := 0;       
local variable
  begin
    for I in 1 to 8 loop
      RES := RES * 2;
      if S(I) = '1'  then RES := RES + 1;
      end if;
    end loop;
    return RES;
  end VEC2INT;
  ...
begin
  ...
  process ...
    ...
    XVAL := VEC2INT (XBUS);            
function call
    ...
  end process;
  ...
end ...

Procedure:
can have zero or more parameters with the following modes:


in :readable only within the procedure
out :writable only; the use of these parameter is allowed only on the left side of an assignment.
inout :read/write paramenter, which can be universally used within a procedure.

Procedure parameters can be both variables and signals (after their explicit declaration). In VHDL code procedures are handled similarly to the assignments.

Syntax:
procedure proc_name (parameter_list) is
  
[variable_declaration]
  
[constant_declaration]
  
[type_declaration]
  
[use_clause]
begin
  sequential_statements
end
[proc_name];

parameter_list:
[variable]name_list [in|out|inout] type_name
   
[:= expression];|
signal        name_list
[in|out|inout] type_name;
The example below shows a procedure which performs the same bit-vector conversion into an integer value as the function of the previous example. In addition, the procedure also sets a Flag.

Example:
architecture ...
  ...
  procedure VEC2INT                      
Declaration
    ( S: in bit_vector;
      ZFLAG: out boolean;
      Q: inout integer ) is         
mode assignments
  begin
    Q := 0;
    ZFLAG := true;
    for I in 1 to 8 loop
      Q := Q * 2;        Q
allowed on the right side
      if S(I) = '1' then
        Q := Q + 1;     
$ \Rightarrow$ Mode is: inout
        ZFLAG := false;
      end if;
    end loop;
  end VEC2INT;

begin   - architecture statement part
  ...
  process ...
    ...
    VEC2INT (XBUS, XFLG, XVAL);       
procedure call
    ...
  end process;
  ...
end ...

Overloading
VHDL, similarly to other programming languages, allows Overloading of prodecures and functions. Overloading means that two or more subprograms have the same name but differ in the number of parameters and base types. When an overloaded subprogram is called its name, number of actual parameters, order of arguments and their types, are used to determine which function/procedure should be invoked. Overloading overcomes strong typing and allows a more general use of operators and functions.
Argument-Type:
overloaded subprograms are distiguished through the different types of their arguments (parameters).

Example:
function DECR (X: integer) return integer is
begin
  ...
end DECR;

function DECR (X: real) return real is
begin
  ...
end DECR;
...
variable A, B: integer;
...
B := DECR(A);      
call the first (integer) function

Argument-Number:
overloaded subprograms are distinguished based on the different number of parameters.

Example:
function CONV_ADDR (A0, A1: bit) return integer is
begin                                    
2 arguments
  ...
end;
function CONV_ADDR (A0, A1, A2: bit) return integer is
begin                                    
3 arguments
  ...
end;

In general, overloading permits extension of already existing operators found in the default package STANDARD. This is particularly useful for writing vendor/ user-specific packages. Some of the most commonly used extended packages are n-value logic packages MVL7, MVL9 and STD_LOGIC_1164. They define logic values 'X' (unknown), 'Z' (high-impedance), etc., as well as drivers of different strengths, in addition to the conventional '0' und '1'. Logical (and, or, not, xor...), arithmetic (+, -, *...) and comparison operators (=, / =, >, <...) for the new types are also provided. For the often used STD_LOGIC_1164 package an extension exists which defines operators for unsigned and signed (2's complement) binary representations. The user can then take advantage of overloading and conveniently use these types with their respective operators. For functions with only two arguments it is possible to use the infix-Notation.

In the following example, a new addition function for a 4-bit bit_vector is defined.7

Example:
function "+" (A, B: bit_vector (3 downto 0))
                                     return bit_vector is
  variable SUM: bit_vector (3 downto 0);
  variable CARRY: bit;
begin
  CARRY := '0';
  for I in 0 to 3 loop
    SUM(I)  := A(I) xor B(I) xor CARRY;
    CARRY   := ((A(I) and B(I)) or (A(I) and CARRY)
   or (B(I) and CARRY));
  end loop;
  return SUM;
end;


next up previous contents
Next: 7. Signals Up: 6. Sequential Modeling Previous: 6.1 Assignments
Richard Geissler
1998-10-07