Está en la página 1de 9

Unit 4

Contents:

1. VHDL subprogram parameters


1.1. Functions
1.2. Procedures
2. Overloading
2.1. Operator Overloading
3. Predefined attributes ----(From RTU ashirwad)
3.1. Array attributes
3.2. Type attributes
3.3. Signal attributes
3.4. Entity attributes
3.5. Range attributes
4. User defined attributes
5. Packaging basic utilities. (not good)
6. VHDL as a modeling language-----(From RTU ashirwad)
6.1. Bi-directional component modeling
6.1.1. Load Dependent Timing
6.1.2. Models for Controllability and Observability
6.2. Multi mode component modeling
6.2.1. Cone modeling
6.2.2. Cone Modeling Utilities
6.2.3. Cone Gate Models
6.2.4. Simulation and Code identification

1. VHDL subprogram parameters


A subprogram defines a sequential algorithm that performs a certain computation and executes
in zero simulation time. There are two kinds of subprograms:
Functions: These are usually used for computing a single value.
Procedures: These are used to partition large behavioral descriptions. Procedures can return
zero or more values.
A subprogram is defined using a subprogram body.
The typical format for a subprogram body is
subprogram-specification is
subprogram-item-declarations
begin
subprogram-statements -- Same as sequential-statements.
end [ subprogram-name ];

The subprogram-specification specifies the name of a subprogram and defines its interface, that
is, it defines the formal parameter names, their class (i.e., signal, variable, or constant), their type,
and their mode (whether they are in, out, or inout).
Parameters of mode in are read-only parameters; these cannot be updated within a subprogram
body. Parameters of mode out are write-only parameters; their values cannot be used but can only
be updated within a subprogram body. Parameters of mode inout can be read as well as updated.
Actual values are passed to and from a subprogram via a subprogram call.
Actual values are passed to and from a subprogram via a subprogram call.
Only a signal object may be used to pass a value to a parameter of the signal class.
Only a variable object may be used to pass a value to a parameter of the variable class.
A constant or an expression may be used to pass a value to a parameter of constant class.
When parameters are of a variable or constant class, values are passed to the subprogram by value.
Arrays may or may not be passed by reference.
For a signal of any mode, the signal-valued attributes, STABLE, QUIET, DELAYED, and
TRANSACTION cannot be used in a subprogram body.
The type of an actual value in a subprogram call must match that of its corresponding formal
parameter. If the formal parameter belongs to an unconstrained type, the size of this parameter is
determined from the actual value that is passed in.
The subprogram-item-declarations part contains a set of declarations (e.g., type and object
declarations) that are accessible for use locally within the subprogram. These declarations come
into effect every time the subprogram is called. Variables are also created and initialized every
time the subprogram is called. They remain in existence until the subprogram completes. This is
in contrast with declarations in a process statement that get initialized only once, that is at start of
simulation, and any declared variables persist throughout the entire simulation run.
The subprogram-statements part contains sequential statements that define the computation to
be performed by the subprogram. A return statement, which is also a sequential statement, is a
special statement that is allowed only within subprograms.
The format of a return statement is :
return { expression];
The return statement causes the subprogram to terminate and control is returned back to the
calling object. All functions must have a return statement and the value of the expression in the
return statement is returned to the calling program. For procedures, objects of mode out and
inout return their values to the calling program.

1.1. Functions

Functions are used to describe frequently used sequential algorithms that return a single value.
This value is returned to the calling program using a return statement. Some of their common
uses are as resolution functions, and as type conversion functions.
The syntax for calling a function:
function-name (ACT_PAR1, ACT_PAR2, ACT_PAR3);
The following is an example of a 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.
The only mode allowed for the parameters is mode in. Also, only constants and signal objects
can be passed in as parameters. The default object class is constant For example, in function
LARGEST, TOTAL_NO is a constant and its value cannot be modified within the function body.
A function call is an expression and can, therefore, be used in expressions. For example,
SUM := SUM + LARGEST(MAX_COINS, COLLECTION);
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. An equivalent function call
using named association is
LARGEST (SET=> COLLECTION, TOTAL_NO => MAX_COINS)
1.2. Procedures

Procedures allow decomposition of large behaviors into modular sections. In contrast to a


function, a procedure can return zero or more values using parameters of mode out and
inout.
A procedure is invoked by a procedure call either a sequential body or a concurrent body. If
the call is placed inside a sequential body, it is executed in its natural sequence, If the call is
placed inside a concurrent body, the procedure is invoked when an event occurs on any of
the signal parameters in in or out mode.
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.
The syntax for calling is:
PROC_NAME (ACT_PAR1, ACT_PAR2, ACT_PAR3); using positional association.

PROC_NAME (FORMAL_PAR1=>ACT_PAR1, FORMAL_PAR2=>ACT_PAR2 ); using a named


association.
A procedure can normally be used simultaneously as a concurrent and a sequential
statement. However, 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.
Defining procedures and functions
The procedure or function body should be placed in the signal declaration zone of
entity or architecture design units.
The sub program prototype can be declared in a PACKAGE declaration and its
definition can be placed in the package body.
The syntax for defining a procedure is as follows:
Procedure PROC_NAME
(IN_SIG_NAME1, IN_SIG_NAME2.. : in DATA_TYPE1;
OUT_SIG_NAME1, OUT_SIG_NAME2.. : out DATA_TYPE2;
INOUT_SIG_NAME1, INOUT_SIG_NAME2.. : inout DATA_TYPE3); is
[local variable declarations]
Begin
Statement(s);
End PROC_NAME;
The syntax for defining a function is as follows:
Function FUNC_NAME (SIG_NAME1, SIG_NAME2.. : DATA_TYPE1)
Return DATA_TYPE2;
Begin
Statement(s);
End FUNC_NAME;
2. Overloading

Sometimes it is possible to have two or more subprograms with the same name but differing
in number or type of parameters. The function is said to be overloaded in this case.
The simulator or synthesizer automatically selects the correct subprogram by looking at the
parameters in the call statement. Overloading is a very convenient mechanism for defining a
set of function that performs the same operation on the different data types.
function COUNT (ORANGES: INTEGER) return INTEGER;
function COUNT (APPLES: BIT) return INTEGER;

Both functions are overloaded since they have the same name, COUNT, and have different
parameter types. When a call to either function is made, it is easily possible to identify the
exact function to which the call was made from the type of the actual parameters passed.
For example, the function call
COUNT(20)
refers to the first function since 20 is of type INTEGER, while the function call
COUNT('1')
refers to the second function, since the type of actual parameter is BIT.
Example:
Function ADD (A, B : BIT_VECTOR) return BIT_VECTOR is
Variable SUM: integer;
Begin
SUM:= BYTE_TO_INT(A) + BYTE_TO_INT(B);
Return INT_TO_BYTE(SUM);
End ADD;

Function ADD(A, B : integer) return BIT_VECTOR is


Variable SUM: integer;
Begin
SUM:= A+B;
Return INT_TO_BYTE(SUM);
End ADD;
If two overloaded subprograms have the same parameter types and result types, then it is
possible for one subprogram to hide the other subprogram.
for example, if a subprogram is declared within another subprogram's scope. Here is an
example.
architecture HIDING of DUMMY_ENTITY is
function ADD (A, B: BIT_VECTOR) return BIT_VECTOR is
begin
-- Body of function here.
end ADD:
begin
SUM_IN_ARCH<=ADD(IN1, IN2);
process
function ADD (C, D: BIT_VECTOR) return BIT_VECTOR is
begin
-- Body of function here.
end ADD;
begin
SUM_IN_PROCESS <= ADD (IN1, IN2);
SUM_IN_ARCH <= HIDING.ADD(IN1, IN2);
end process;
end HIDING;
The function ADD declared in the architecture body is hidden within the process because of
the second function ADD that is declared within the declarative part of the process. This
function can still be accessed by qualifying the function name with the architecture name as
shown in the second statement in the process.
It is also possible for two overloaded subprograms to be directly visible within a region, for
example, caused by using use clauses. In such a case, a subprogram call may be ambiguous,
and hence an error, if it is not possible to determine which of the overloaded subprograms is
being called. Here is an example.
package P1 is
function ADD (A, B: BIT_VECTOR) return BIT_VECTOR;
end P1;

package P2 is
function ADD (X, Y: BIT_VECTOR) return BIT_VECTOR;
end P2;

use WORK.P1. all, WORK.P2.all;


architecture OVERLOADED of DUMMY_ENTITY is
begin
SUM_CORRECT <= ADD (X => IN1, Y => IN2);
SUM_ERROR <= ADD (IN1, IN2); -- An error.
end OVERLOADED;
The function call in the first signal assignment statement is not an error since it
refers to the function declared in package P2, while the call in the second signal
assignment statement is ambiguous and hence an error.

2.1. Operator Overloading

When a standard operator symbol is made to behave differently based on the type of its
operands, the operator is said to be overloaded.
The need for operator overloading arises from the fact that the predefined operators in the
language are defined for operands of certain predefined types.
The operators can also be made to behave differently depending on the type of the
operands they are acting on. This is achieved by operator overloading.
The operators have been overloaded to define the operations on the user defined data
types.
Operator overloading is defined by defining a function having the same name as the
operator. The name should be enclosed in double quote marks since all operator names are
reserved words.
Function for binary operators have two parameters and functions for unary operators have
one parameter.
Here are some examples of function declarations for such function bodies.
type MVL is ('U', '0', '1', 'Z);
function "and" (L, R: MVL) return MVL;
function "or" (L, R: MVL) return MVL;
function "not" (R: MVL) return MVL;
Since the and, or, and not operators are predefined operator symbols, they have to be
enclosed within double quotes when used as overloaded operator function names. Having
declared the overloaded functions, the operators can now be called using two different
types of notations:
1. standard operator notation,
2. standard function call notation.
some examples of these two types of notations based on the overloaded operator function
declarations:
signal A, B, C: MVL;
signal X, Y, Z: BIT;
A <= 'Z' or '1'; -- #1: standard operator notation.
B <= "or" ('0', 'Z); -- #2: function call notation.
The or operator in the first statement refers to the overloaded operator because the type
of the left operand is MVL. This is the standard operator notation since the overloaded
operator symbol appears just like the standard operator symbol. An example of the function
call notation is shown in the second statement in which the overloaded function, or, is
explicitly called.
The below statement would be an error assuming that there are no other overloaded or
operators defined with the first parameter type of BIT and the second parameter type of
MVL.
Z<= ( X and Y) or A;
In overloaded operator functions, it is not necessary for both operands to have the same
type. In the previous case, if another or overloaded function with a declaration such as
function "or" (L: BIT; R: MVL) return BIT:
were defined, the sixth assignment statement would not be an error.

3. Predefined attributes (From RTY ashirwad)

4. User defined attributes

User-defined attributes are constants of any type. They are declared using attribute
declarations. The User-defined attribute has to be defined two steps. In the first one, an
attribute declaration declares an attribute name and its type and has the following form:
Attribute ATTR_NAME: ATTR_DATA_TYPE;
Example:
Type DATE is record
MM: integer;
DD: integer;
YYYY: integer;
Attribute AUTHOR_NAME: String;
Attribute UPDATE_DATE: DATE;
In the second step, the attribute is associated with the desired object as follows:
Attribute ATTR_NAME of OBJ_NAME: OBJ_CLASS is ATTR_val;
Example: Entity CPU is
Port (-);
Attribute AUTHOR_NAME of CPU: entity is Dr. S. S. Limaye;
Attribute UPDATE_DATE of CPU: entity is (5, 12, 2011 );
End CPU;
After having created an attribute and then having associated it with a name, the value of the
attribute can then be used in an expression by referring to
OBJ_NAME ' ATTR_NAME -- The single quote is often read as "tick".

También podría gustarte