VHDL Notes
VHDL Notes
Description language.)
VHDL stands for VHSIC (Very High Speed Integrated Circuits) Hardware Description
Language.
The other widely used hardware description language is Verilog. A third HDL language
is ABEL (Advanced Boolean Equation Language) which was specifically designed for
Programmable Logic Devices (PLD).
The highest level of abstraction is the behavioral level that describes a system in
terms of what it does (or how it behaves) rather than in terms of its components and
interconnection between them. A behavioral description specifies the relationship
between the input and output signals
The behavioral level can be further divided into two kinds of styles: Data flow and
Algorithmic.
The structural level, on the other hand, describes a system as a collection of gates and
components that are interconnected to perform a desired function. A structural
description could be compared to a schematic of interconnected logic gates. It is a
representation that is usually closer to the physical realization of a system
entity
One can consider the entity declaration as the interface to the outside world that defines
the input and output signals
Entity Declaration
The entity declaration defines the NAME of the entity and lists the input and output
ports. The general form is as follows,
entity NAME_OF_ENTITY is [ generic generic_declarations);]
generic : generic declarations are optional and determine the local constants used for
timing and sizing (e.g. bus widths) the entity. A generic can have a default value. The
syntax for a generic follows,
generic (
constant_name: type [:=value] ;
Architecture body
The architecture body specifies how the circuit operates and how it is implemented. As
discussed earlier, an entity or circuit can be specified in a variety of ways, such as
behavioral, structural (interconnected components), or a combination of the above.
The main body of the architecture starts with the keyword begin
The statements after the begin keyword gives the instantiations of the components and
describes how these are interconnected. A component instantiation statement creates a
new level of hierarchy. Each line starts with an instance name (e.g. U0) followed by a
colon and a component name and the keyword port map. This keyword defines how
the components are connected.
To express a number in a base different from the base “10”, one uses the following
convention: base#number#. A few examples follow.
To make the readability of large numbers easier, one can insert underscores in the
numbers as long as the underscore is not used at the beginning or the end.
Data Objects: Signals, Variables and Constants
Constant
A constant can have a single value of a given type and cannot be changed during the
simulation. A constant is declared as follows,
constant list_of_name_of_constant: type [ := initial value] ;
where the initial value is optional. Constants can be declared at the start of an
architecture and can then be used anywhere within the architecture. Constants declared
within a process can only be used inside that specific process.
constant RISE_FALL_TME: time := 2 ns;
Variable
A variable assignment statement. The variable is updated without any delay as soon as
the statement is executed. Variables must be declared inside a process. The variable
declaration is as follows A variable can have a single value, as with a constant, but a
variable can be updated using:
variable list_of_variable_names: type [ := initial value] ;
The variable SUM, in the example above, is an integer that has a range from 0 to 256
with initial value of 16 at the start of the simulation. The fourth example defines a bit
vector or 8 elements: STS_BIT(7), STS_BIT(6),… STS_BIT(0).
Variable_name := expression;
Signal
Signals are declared with the following statement:
signal list_of_signal_names: type [ := initial value] ;
signal SUM, CARRY: std_logic;
signal CLOCK: bit;
signal TRIGGER: integer :=0;
signal DATA_BUS: bit_vector (0 to 7);
signal VALUE: integer range 0 to 100;
Signals are updated when their signal assignment statement is executed, after a certain
delay, as illustrated below,
SUM <= (A xor B) after 2 ns;
It is important to understand the difference between variables and signals, particularly
how it relates to when their value changes. A variable changes instantaneously when the
variable assignment is executed. On the other hand, a signal changes a delay after the
assignment expression is evaluated. If no delay is specified, the signal will change after a
delay delay. This has important consequences for the updated values of variables and
signals.
Data types.
Enumerated Types
If one does not initialize the signal, the default initialization is the leftmost element of the
list.
Enumerated types have to be defined in the architecture body or inside a package as
shown in the section above
Sometimes it is more convenient not to specify the dimension of the array when the array
type is declared. This is called an unconstrained array type. The syntax for the array
declaration is,
The range is now specified when one declares the array object,
variable MATRIX8: MATRIX (2 downto -8) := (3, 5, 1, 4, 7, 9, 12, 14, 20, 18);
variable ARRAY3x2: VECTOR2 (1 to 4, 1 to 3)) := ((‘1’,’0’), (‘0’,’-‘), (1, ‘Z’));
Operators
VHDL supports different classes of operators that operate on signals, variables and
constants. The different classes of operators are summarized below.
Class
1. Logical operators and or nand nor xor xnor
2. Relational operators = /= < <= > >=
3. Shift operators sll srl sla sra rol ror
4.Addition operators + = &
5. Unary operators + -
6. Multiplying op. * / mod rem
7. Miscellaneous op. ** abs not
The order of precedence is the highest for the operators of class 7, followed by class 6
with the lowest precedence for class 1. Unless parentheses are used, the operators with
the highest precedence are applied first. Operators of the same class have the same
precedence and are applied from left to right in an expression.
Shift operators
These operators perform a bit-wise shift or rotate operation on a one-dimensional
array of elements of the type bit (or std_logic) or Boolean.
The multiplying operators are used to perform mathematical functions on numeric types (integer
or floating point).
The result of the rem operator has the sign of its first operand while the result of the mod
operators has the sign of the second operand.
Some examples of these operators are given below.
11 rem 4 results in 3
(-11) rem 4 results in -3
9 mod 4 results in 1
7 mod (-4) results in –1 (7 – 4*2 = -1).
Miscellaneous operators
These are the absolute value and exponentation operators that can be applied to numeric
types. The logical negation (not) results in the inverse polarity but the same type.
Labels are optional but are useful when writing nested loops. The next and exit statement
are sequential statements that can only be used inside a loop.
• The next statement terminates the rest of the current loop iteration and execution
will proceed to the next loop iteration.
• The exit statement skips the rest of the statements, terminating the loop entirely,
and continues with the next statement after the exited loop.
There are three types of iteration schemes:
• • basic loop
• • while … loop
• • for … loop
Notice that this construct is simpler than the If-then-else construct using the process
statement or the case statement. An alternative way to define the multiplexer is the case
construct inside a process statement, as discussed earlier
. Selected Signal assignments
The selected signal assignment is similar to the conditional one described above. The
syntax is as follows,
with choice_expression select
target_name <= expression when choices,
target_name <= expression when choices,
:
target_name <= expression when choices;
The target is a signal that will receive the value of an expression whose choice includes
the value of the choice_expression. The expression selected is the first with a matching
choice. The choice can be a static expression (e.g. 5) or a range expression (e.g. 4 to 9).
The following rules must be followed for the choices:
• No two choices can overlap
• All possible values of choice_expression must be covered by the set of choices,
unless an others choice is present.
entity MUX_4_1_Conc2 is
port (A, B, C, D: in std_logic;
SEL: in std_logic_vector(1 downto 0);
Z: out std_logic);
end MUX_4_1_Conc2;
architecture concurr_MUX41b of MUX_4_1_Conc2 is
begin
with SEL select
Z <= A when “00”,
B when “01”,
C when “10”,
D when “11”;
end concurr_MUX41b;
Notice that the Xilinx Foundation Express does not allow a vector as
choice_expression such as std_logic_vector’(A,B,C).
As an example, lets consider a full adder with inputs A, B and C and outputs sum
and cout,
entity FullAdd_Conc is
port (A, B, C: in std_logic;
sum, cout: out std_logic);
end FullAdd_Conc;
architecture FullAdd_Conc of FullAdd_Conc is
--define internal signal: vector INS of the input signals
signal INS: std_logic_vector (2 downto 0);
begin
--define the components of vector INS of the input signals
INS(2) <= A;
INS(1) <= B;
INS(0) <= C;
with INS select
(sum, cout) <= std_logic_vector’(“00”) when “000”,
std_logic_vector’(“10”) when “001”,
end FullAdd_Conc; ]
Structural modeling was described briefly in the section Structural Modeling in “Basic
Structure of a VHDL file”. A structural way of modeling describes a circuit in terms of
components and its interconnection. Each component is supposed to be defined earlier
(e.g. in package) and can be described as structural, a behavioral or dataflow model. At
the lowest hierarchy each component is described as a behavioral model, using the basic
logic operators defined in VHDL. In general structural modeling is very good to describe
complex digital systems, though a set of components in a hierarchical fashion.
A structural description can best be compared to a schematic block diagram that can be
described by the components and the interconnections. VHDL provides a formal way to
do this by
The components and signals are declared within the architecture body,
architecture architecture_name of NAME_OF_ENTITY is
-- Declarations
component declarations
signal declarations
begin
-- Statements
component instantiation and connections
:
end architecture_name;
a. Component declaration
The component name refers to either the name of an entity defined in a library or an
entity explicitly defined in the VHDL file (see example of the four bit adder).
The list of interface ports gives the name, mode and type of each port, similarly as is
done in the entity declaration.
component OR2
port (in1, in2: in std_logic;
out1: out std_logic);
end component;
component PROC
port (CLK, RST, RW, STP: in std_logic;
ADDRBUS: out std_logic_vector (31 downto 0);
DATA: inout integer range 0 to 1024);
component FULLADDER
port(a, b, c: in std_logic;
sum, carry: out std_logic);
end component;
The instance name or label can be any legal identifier and is the name of this particular
instance. The component name is the name of the component declared earlier using the
component declaration statement. The port name is the name of the port and signal is the
name of the signal to which the specific port is connected. The above port map associates
the ports to the signals through named association. An alternative method is the positional
association shown below,
in which the first port in the component declaration corresponds to the first signal, the
second port to the second signal, etc. The signal position must be in the same order as the
declared component’s ports. One can mix named and positional associations as long as
one puts all positional associations before the named ones. The following examples
illustrates this,
component NAND2
port (in1, in2: in std_logic;
out1: out std_logic);
end component;
signal int1, int2, int3: std_logic;
architecture struct of EXAMPLE is
U1: NAND2 port map (A,B,int1);
U2: NAND2 port map (in2=>C, in2=>D, out1=>int2);
U3: NAND3 port map (in1=>int1, int2, Z);
…..
1. D. Gajski and R. Khun, “Introduction: New VLSI Tools,” IEEE Computer, Vol.
16, No. 12, pp. 11-14, Dec. 1983.
2. M. Mano and C. Kime, “Logic and Computer Design Fundamentals,” 2nd Edition,
Prentice Hall, Upper Saddle River, 2001.
3. S. Yalamanchili, “VHDL Starter’s Guide,” Prentice Hall, Upper Saddle River,
1998.
4. J. Bhasker, “VHDL Primer,” 3rd Edition, Prentice Hall, Upper Saddle River, 1998.
5. P. J. Ashenden, “The Student’s Guide to VHDL,” Morgan Kaufmann Publishers,
Inc, San Francisco, 1998.
6. A. Dewey, “Analysis and Design of Digital Systems,” PWS Publishing Company,
New York, 1997.
7. C. H. Roth, “Digital System Design using VHDL”, PWS Publishing Company,
New York, 1998.
8. D. Pellerin and D. Taylor, “VHDL Made Easy!”, ,” Prentice Hall, Upper Saddle
River, 1997.
9. VHDL Reference Guide, Xilinx, Inc., 1999 (available on line:
http://toolbox.xilinx.com/docsan/data/fndtn/vhd/vhd.htm
or, http://toolbox.xilinx.com/docsan/ (select Foundation Series)
Copyright 2001; Created by Jan Van der Spiegel, Sept. 28, 2001; Updated November
18, 2001
Go to EE201