Design using Standard Description Languages:Sub-programs
Sub-programs
In classical programming languages (e.g., C), functions and procedures are elements building hierarchy. The work flow is divided and each individual task is coded in a sub-program. Calling the sub-program forms the program. In VHDL a hierarchy is not created by sub-programs, but by entity-architecture pairs or components. Functions and procedures are preferably used for collecting frequently used operations (macro), the type conversions at interfaces or the supply of operators for newly defined types.
Functions in signal definitions are mainly located on the right hand side or embedded in conditions of IF or CASE statements, whereas procedures are autonomous statements. Depending on its loca- tion within or outside a process, they represent a sequential or a concurrent statement. Internally, similarly to processes, functions and procedures use sequential statements (fig. 4.59).
The interface of a function consists of submitted parameters and a return value. The return value can be assigned to a signal, to a variable, or can be evaluated in a comparison. The following example shows various applications. The most significant bit has either a value of ’0’ or ’1’, with the purpose that a checksum (XOR operation of all bits in the vector) returns the value ’0’.
It is assumed in the example presented that the function has already been declared. There are several possibilities of how it can be done:
• In the declaration part of the process, in front of BEGIN;
• In the declaration part of the architecture;
• In the declaration part of a package (section 4.11);
• Very seldom in a package body, as it would be only visible there.
Structure of a Function
Using the example presented previously, the struc- ture of a function can be shown. Its structure is similar to a process; however, looking at variables, the function has a different behavior. The function declaration consists of the function name and de- tails of submitted parameters and the return value.
FUNCTION parity (d: IN STD_LOGIC_VECTOR)
RETURN STD_LOGIC IS ...
As submitted parameters are, as a rule, only read- able within the function, they must show the mode IN. IN is the default setting and needs not nec- essarily be specified. The parameter d does not constrain the width of the vector at this point, which allows a universal use of the function. The second part of the function is the declaration part, e.g., for local variables. Thus a variable, e.g., with the name ‘result’ could be provided for returning the result of the function with the RETURN as- signment. Of course, the type of that variable must coincide with the type of the returned value in the function’s declaration.
Differently from processes, in functions the vari- ables are re-initialized at every function call. This is taken into account at synthesis.
Procedures are sub-programs, too, very similar to functions when looking at declarations and structures. The declaration of procedures is legal in each declaration region; however, they are to be found most often in the declaration part of a pack- age. The obvious difference from functions is that parameters in procedures can take the mode IN, OUT or INOUT. However, this direction of data flow must not be mixed up with the specifications in ports of an entity, because data flow direction has a different meaning here. Since parameters of a procedure are capable of transporting data into the procedure (mode IN) or to the world outside the procedure (mode OUT), a separate return value is not necessary. This is another essential difference from functions.
Going back to the examples mentioned before, a procedure is to test for even parity of the input vector d_in and assign a parameter error to ’1’ in the case of an error. At the same time, the
All assignments in this example are assignments to variables. This is because OUT parameters of a procedure are variables, if not stated differently to be otherwise. Hence, having variables, this procedure can only be called in a sequential environment.
The third mode INOUT has a special meaning: it can pass parameters to be modified within the procedure and return the values using the same interface. INOUT does not model a tristate inter- face or bidirectional signals, but allows recursive algorithms. In functions it is simpler to read a signal or a variable and assign a new value to it:
y <= any_function(y);
In a procedure this parameter would have to take the mode INOUT in order to obtain the same behavior:
any_procedure(y);
Parameters of Functions and Procedures
Parameters of sub-programs can be a member of the classes SIGNAL, VARIABLE or CONSTANT. However, not all possible combinations of classes and modes are allowed (table 4.23). IN, OUT, and INOUT define the direction of data flow as seen by the sub-program, and the class defines the way the parameter interfaces to the outside world. Looking at the class membership, function parameters do not have restrictions, but have only the mode IN. Without a class specification a function parameter is a member of the class CONSTANT. Hence it can be an interface to a variable or a signal com- ing from the outside. On principle another class specification (e.g., signal or variable, instead of constant) would be possible, but it would limit a later use of the function.
These thoughts are also valid for the IN parameter at procedures. Procedure parameters having the mode OUT or INOUT can not be a member of the class CONSTANT, because their default class is VARIABLE. The declaration of a parameter to be a variable only permits a sequential use, e.g., in processes located in other procedures or functions.
Wired-Or Resolved with a Resolution Function
❑ Example: Or operation with a wired-or resolu- tion function (fig. 4.60)
Resolution functions are used in cases in which a signal is driven by multiple sources. These func- tions determine which value the multiple driven signal has to take finally. During every cycle of simulation when the signal is active, which means a transaction is pending, the resolution function
is called implicitly. As a parameter the func- tion receives a vector which contains up to date driver values. Amongst those the function’s al- gorithm calculates a return value to resolve the driver’s conflict. This example declares a type MY_LOGIC and MY_LOGIC_VECTOR, plus a function wired-or to combine all drivers involved disjunctively. Finally, this is an application of the resolution function on MY_LOGIC. By then each signal of the type WIRED_LOGIC knows the values of the type MY_LOGIC and has an automatically built in resolution function (see def- inition of STD_LOGIC in appendix C.3).
Comments
Post a Comment