Download as doc, pdf, or txt
Download as doc, pdf, or txt
You are on page 1of 18

Entity

An entity is used to describe the interface of the VHDL module to other modules. All signals
entering or exiting a vhdl module must be declared in the entity declaration. An example of an
entity describing the interface for a two input AND gate can be found below:
ENTITY and2 IS
PORT(A in : std_logic;
B in : std_logic;
F out : std_logic
);
END and2;

Inside the entity a port declaration can be found. There are the following kinds of ports:

Type Description
Specifies a port that can be read from but not written to. A in port cannot be used on the left side of
in
an assignment.
Specifies a port that can be written to but not read from. A out port can only be used on the left side
out
of an assignment
Specifies a port that can be read and written to. An inout port is commonly used to describe tristate
in/out
buses.
Specifies a out port whose current value can be read from. The same functionality can be achieved
buffer by assigning to an internal signal in the VHDL code, reading from that signal when needed, and
assigning the internal signal to the out port using a concurrent statement.
[edit]Architecture

An architecture in VHDL describes how functionality of the module is implemented. Below is the
architecture for a two input and gate:
ARCHITECTURE and2_rtl OF and2 IS
-- Signal, component, type and constant declarations go here.
...
BEGIN
-- Concurrent statements and processes go here
F <= A and B;
...
END and2_rtl;
[edit]Types of Architecture Implementation
An architecture can be implemented in different ways depending on its purpose.
[edit]Structural

A structural implementation connects and instantiates other modules. It serves to organize and
connect modules together. A strict structural implementation contains only other instantiated
blocks wired together using port maps.
[edit]Behavioral

A behavioral implementation describes how a modules should function using the full array of
VHDL constructs available. Behaviorally designed modules are not necessarily synthesizable, but
are useful for modeling and testing synthesizable modules.
[edit]Register Transfer

A register transfer implementation describes the functionality of a module in terms of registers


and the transformation of the data that flows between the registers. Register transfer
implementations are commonly used to describe modules that are to be synthesized on actual
devices.

[edit]Package

A VHDL package is used to contain a group of reusable data types, functions, procedures, and
other VHDL constructs. The basic syntax for a package is as follows:
PACKAGE package_name IS
...
END package_name;

PACKAGE BODY package_name IS


...
END package_name;

The package header is for the declaration of VHDL constructs. The package body is for their
implementation. Not all constructs (such as data types) need an entry in the body. The body is
commonly used for function and procedure implementation.

[edit]Libraries

A library establishes a namespace for the modules to exist in. When compiled by a simulator or
synthesis tool, every package and entity is compiled into a library. There is no way for a VHDL file
to specify which library it is compiled into. This is determined by the tool used to compile the
VHDL code. The default library that tools compile VHDL objects into is called work. This means
the following statement is assumed when creating VHDL models:
library work;

VHDL models can use the library keyword to make libraries visible to a module and use objects
from them. This is needed to include packages from other libraries and to directly instantiate
entities from other libraries.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

The library keyword makes a library visible to a VHDL design. After the library is made visible,
packages inside the the library can be used. The next line states to make everything declared in
the ieee.std_logic_1164 namespace declared in the current namespace. For example, this allows
us to use the statement:
signal sQ: std_logic;

instead of
signal sQ: ieee.std_logic_1164.std_logic;
[edit]Instantiation of a VHDL Module
There are two ways a VHDL modules can be instantiated. The original way, specified in VHDL
'87, uses a component, port map, and corresponding entity declaration. The newer way, specified
in VHDL '93, uses just the port map and corresponding entity declaration. Each one is useful
under certain circumstances. For each method the following entity will be instantiated:
entity D_FF is
port(
clk : out std_logic;
rst : out std_logic;
D : in std_logic;
Q : in std_logic
);
end entity D_FF;

architecture rtl of D_FF is


...
begin
...
end architecture rtl;
[edit]With Components
architecture rtl of uses_d_ff is
...
component D_FF is
port(
clk : out std_logic;
rst : out std_logic;
D : in std_logic;
Q : in std_logic
);
end component D_FF;
...
signal sClk: std_logic;
signal sRst: std_logic;
signal sD: std_logic;
signal sQ: std_logic;
...
begin
u_D_FF: component D_FF
port map(
clk => sClk,
rst => sRst,
D => sD,
Q => sQ
);

...
end architecture rtl;
[edit]Without Components
Not using a component shortens the syntax quite bit. To instantiate D_FF above, the following
code is used:
architecture rtl of uses_d_ff is
...
signal sClk: std_logic;
signal sRst: std_logic;
signal sD: std_logic;
signal sQ: std_logic;
...
begin
u_D_FF: entity work.D_FF(rtl)
port map(
clk => sClk,
rst => sRst,
D => sD,
Q => sQ
);

...
end architecture rtl;

As long as the tools used support this syntax, not using a component is recommended because it
improves code maintainability. When signals are added/removed and removed from entities, they
only need to be added or removed from the entity declaration and the port map. Components are
useful when what is being instantiated does not have a VHDL module. When instantiating Verilog
designs in VHDL or using IP cores, this is sometimes necessary. This allows the VHDL compiler
to create a "black box" when compiling the VHDL and connect the actual model to the black box
later.

Tutorial: Using Xilinx ISE 10.1 for VHDL


Based Design
In this tutorial, you will learn to create a design module from VHDL
code. With
Xilinx ISE, you can easily create modules from VHDL code using the
ISE Text Editor
tool. The VHDL code may then be connected to your top-level VHDL
design through
instantiation and compiled with the rest of the design.
In this tutorial, you will author a new VHDL module. This program
converts a
hexadecimal number to a 7-segment LED display format. If
necessary, review the steps
in Practice-project to create a new project, generate a test bench, and
perform a functional
simulation.
Using the New Source Wizard and ISE Text Editor
In order to create the module, in the New Source Wizard, create a file
and specify
the name and ports of the component. The resulting “skeleton” VHDL
file is then
modified further in the ISE Text Editor.
To create the source file:
1. Select Project → New Source. A dialog box opens in which you
specify the
type of source you want to create.
2. Select VHDL Module in New Source Wizard – Select Source Type
window.
3. In the File Name field, type ‘hex2led’. Click Next.
The hex2led component has a 4-bit input port named HEX and a 7-bit
output port
named LED.
To enter these ports:
1. In New Source Wizard – Define Module window, click in the Port
Name field
and type HEX.
2. Click in the Direction field, set the direction to in, and select the
Bus field.
3. In the MSB field enter 3, and in the LSB field enter 0.
4. Refer to Figure 1. Repeat the previous steps for the LED[6:0]
output bus. Be sure
that the direction is set to out.
Winter 2009 1Tutorial: Using Xilinx ISE 10.1 for VHDL Based Design
Figure 1: New Source Wizard for VHDL
5. Click Next to complete the Wizard session. A description of the
module displays.
6. Click Finish to open the empty VHDL file in the ISE Text Editor. See
Figure 2.
Figure 2: Skeleton VHDL File in the ISE Text Editor
Winter 2009 2Tutorial: Using Xilinx ISE 10.1 for VHDL Based Design
In the ISE Text Editor, the ports are already declared in the VHDL file,
and some
of the basic file structure is already in place. Keywords are displayed
in blue, data types
in red, comments in green, and values in black. This color-coding
enhances readability
and recognition of typographical errors.
Using the Language Templates
The ISE Language Templates include VHDL constructs and
synthesis templates
which represent commonly used logic components, such as
counters, D flip-flops,
multiplexers, and primitives. You will use the 7-Segment Display Hex
Conversion
template for this exercise. This template provides source code to
convert a 4-bit value to a
7-segment LED display format.
Note: You can add your own templates to the Language Templates
for components or
constructs you use often.
To invoke the Language Templates and select the template for this
tutorial:
1. From Project Navigator, select Edit → Language Templates.
2. To expand the view of any of these sections, click the (+) next to
the topic. Click
any of the listed templates to view the template contents in the right-
hand pane.
3. Under the VHDL hierarchy, expand the Synthesis Constructs,
Coding Examples,
Misc hierarchy and select the template called 7-Segment Display Hex
Conversion.
The contents display in the right-hand pane. Refer to Figure 3.
Figure 3: Language Templates
Winter 2009 3Tutorial: Using Xilinx ISE 10.1 for VHDL Based Design
Adding the Language Template to Your File
You will now use the Use in file method for adding templates to your
VHDL file.
(Note: a copy and paste function is also available from the Language
Templates Edit
Menu and the right click menu.)
1. Before you add the template to the hex2led.vhd, move the cursor
under the
architecture begin statement (line number 38 in Figure 4).
2. In the Language Templates, right click the 7-Segment Display Hex
Conversion
name and select Use in file. This will add the template into the
hex2led.vhd file.
3. Close the Language Templates window. You now have complete
and functional
VHDL code.
4. Save the file by selecting File → Save.
5. Select hex2led in the Sources window. In the Processes window,
expand the
selection of Implement Design, Synthesize-XST, and double click on
Check Syntax
to test your VHDL code.
Figure 4: Check Syntax
6. To create a schematic symbol, click (+) under Design Utilities and
double click
on Create Schematic Symbol. The schematic symbol of hex2led will
appear under
Symbols in a Schematic Editor window in the same project.
7. To simulate, open new Test Bench Waveform file and select
hex2led as a source
code.
Reference: ISE In-Depth Tutorial, www.xilinx.com
VHDL was originally developed at the behest of the U.S Department of Defense in order to
document the behavior of the ASICs that supplier companies were including in equipment. That is
to say, VHDL was developed as an alternative to huge, complex manuals which were subject to
implementation-specific details.

The idea of being able to simulate this documentation was so obviously attractive that logic
simulators were developed that could read the VHDL files. The next step was the development
of logic synthesis tools that read the VHDL, and output a definition of the physical implementation
of the circuit.

Because the Department of Defense required as much of the syntax as possible to be based on
Ada, in order to avoid re-inventing concepts that had already been thoroughly tested in the
development of Ada,[citation needed] VHDL borrows heavily from the Ada programming language in
both concepts and syntax.

The initial version of VHDL, designed to IEEE standard 1076-1987, included a wide range of data
types, including numerical (integerand real), logical (bit and boolean), character and time,
plus arrays of bit called bit_vector and of character called string.

A problem not solved by this edition, however, was "multi-valued logic", where a signal's drive
strength (none, weak or strong) and unknown values are also considered. This required IEEE
standard 1164, which defined the 9-value logic types: scalar std_ulogicand its vector
version std_ulogic_vector.

The an updated IEEE 1076, in 1993, made the syntax more consistent, allowed more flexibility in
naming, extended the charactertype to allow ISO-8859-1 printable characters, added
the xnor operator, etc.[specify]

Minor changes in the standard (2000 and 2002) added the idea of protected types (similar to the
concept of class in C++) and removed some restrictions from port mapping rules.

In addition to IEEE standard 1164, several child standards were introduced to extend functionality
of the language. IEEE standard 1076.2 added better handling of real and complex data types.
IEEE standard 1076.3 introduced signed and unsigned types to facilitate arithmetical operations
on vectors. IEEE standard 1076.1 (known as VHDL-AMS) provided analog and mixed-signal
circuit design extensions.

Some other standards support wider use of VHDL, notably VITAL (VHDL Initiative Towards ASIC
Libraries) and microwave circuit design extensions.

In June 2006, VHDL Technical Committee of Accellera (delegated by IEEE to work on next
update of the standard) approved so called Draft 3.0 of VHDL-2006. While maintaining full
compatibility with older versions, this proposed standard provides numerous extensions that
make writing and managing VHDL code easier. Key changes include incorporation of child
standards (1164, 1076.2, 1076.3) into the main 1076 standard, an extended set of operators,
more flexible syntax of case and generate statements, incorporation of VHPI (interface to C/C++
languages) and a subset of PSL (Property Specification Language). These changes should
improve quality of synthesizable VHDL code, make testbenches more flexible, and allow wider
use of VHDL for system-level descriptions.

In February 2008, Accellera approved VHDL 4.0 also informally known as VHDL 2008, which
addressed more than 90 issues discovered during the trial period for version 3.0 and includes
enhanced generic types. In 2008, Accellera released VHDL 4.0 to the IEEE for balloting for
inclusion in IEEE 1076-2008. The VHDL standard IEEE 1076-2008 was published in September
2008.

[edit]Design

VHDL is commonly used to write text models that describe a logic circuit. Such a model is
processed by a synthesis program, only if it is part of the logic design. A simulation program is
used to test the logic design using simulation models to represent the logic circuits that interface
to the design. This collection of simulation models is commonly called a testbench.

VHDL has constructs to handle the parallelism inherent in hardware designs, but these constructs
(processes) differ in syntax from the parallel constructs in Ada (tasks). Like Ada, VHDL is strongly
typed and is not case sensitive. In order to directly represent operations which are common in
hardware, there are many features of VHDL which are not found in Ada, such as an extended set
of Boolean operators including nand and nor. VHDL also allows arrays to be indexed in either
ascending or descending direction; Both conventions are used in hardware, whereas in Ada and
most programming languages only ascending indexing is available.

VHDL has file input and output capabilities, and can be used as a general-purpose language for
text processing, but files are more commonly used by a simulation testbench for stimulus or
verification data. There are some VHDL compilers which build executable binaries. In this case, it
might be possible to use VHDL to write a testbench to verify the functionality of the design using
files on the host computer to define stimuli, to interact with the user, and to compare results with
those expected. However, most designers leave this job to the simulator.

It is relatively easy for an inexperienced developer to produce code that simulates successfully
but that cannot be synthesized into a real device, or is too large to be practical. One particular
pitfall is the accidental production of transparent latches rather than D-type flip-flops as storage
elements.[original research?]

One can design hardware in a VHDL IDE (for FPGA implementation such as Xilinx ISE, Altera
Quartus, Synopsys Synplify or Mentor Graphics HDL Designer) to produce the RTL schematic of
the desired circuit. After that, the generated schematic can be verified using simulation software
which shows the waveforms of inputs and outputs of the circuit after generating the appropriate
testbench. To generate an appropriate testbench for a particular circuit or VHDL code, the inputs
have to be defined correctly. For example, for clock input, a loop process or an iterative statement
is required.[original research?]

A final point is that when a VHDL model is translated into the "gates and wires" that are mapped
onto a programmable logic device such as a CPLD or FPGA, then it is the actual hardware being
configured, rather than the VHDL code being "executed" as if on some form of a processor chip.

[edit]Advantages

The key advantage of VHDL when used for systems design is that it allows the behavior of the
required system to be described (modeled) and verified (simulated) before synthesis tools
translate the design into real hardware (gates and wires).

Another benefit is that VHDL allows the description of a concurrent system. VHDL is a Dataflow
language, unlike procedural computing languages such as BASIC, C, and assembly code, which
all run sequentially, one instruction at a time.

VHDL project is multipurpose. Being created once, a calculation block can be used in many other
projects. However, many formational and functional block parameters can be tuned (capacity
parameters, memory size, element base, block composition and interconnection structure).

VHDL project is portable. Being created for one element base, a computing device project can be
ported on another element base, for example VLSI with various technologies.

[edit]Design examples
In VHDL, a design consists at a minimum of an entity which describes the interface and
an architecture which contains the actual implementation. In addition, most designs import library
modules. Some designs also contain multiple architectures andconfigurations.

A simple AND gate in VHDL would look something like this:


-- (this is a VHDL comment)

-- import std_logic from the IEEE library


library IEEE;
use IEEE.std_logic_1164.all;

-- this is the entity


entity ANDGATE is
port (
IN1 : in std_logic;
IN2 : in std_logic;
OUT1: out std_logic);
end ANDGATE;

architecture RTL of ANDGATE is


begin

OUT1 <= IN1 and IN2;

end RTL;

While the example above may seem very verbose to HDL beginners, many parts are either
optional or need to be written only once. Generally simple functions like this are part of a larger
behavioral module, instead of having a separate module for something so simple. In addition, use
of elements such as the std_logic type might at first seem to be an overkill. One could easily
use the built-in bit type and avoid the library import in the beginning. However, using this 9-
valued logic (U,X,0,1,Z,W,H,L,-) instead of simple bits (0,1) offers a very powerful simulation and
debugging tool to the designer which currently does not exist in any other HDL.

In the examples that follow, you will see that VHDL code can be written in a very compact form.
However, the experienced designers usually avoid these compact forms and use a more verbose
coding style for the sake of readability and maintainability. Another advantage to the verbose
coding style is the smaller amount of resources used when programming to a Programmable
Logic Device such as a CPLD[citation needed].

[edit]Synthesizeable constructs and VHDL templates


VHDL is frequently used for two different goals: simulation of electronic designs and synthesis of
such designs. Synthesis is a process where a VHDL is compiled and mapped into an
implementation technology such as an FPGA or an ASIC. Many FPGA vendors have free (or
inexpensive) tools to synthesize VHDL for use with their chips, where ASIC tools are often very
expensive.

Not all constructs in VHDL are suitable for synthesis. For example, most constructs that explicitly
deal with timing such as wait for 10 ns; are not synthesizable despite being valid for
simulation. While different synthesis tools have different capabilities, there exists a
common synthesizable subset of VHDL that defines what language constructs and idioms map
into common hardware for many synthesis tools. IEEE 1076.6 defines a subset of the language
that is considered the official synthesis subset. It is generally considered a "best practice" to write
very idiomatic code for synthesis as results can be incorrect or suboptimal for non-standard
constructs.

Some examples of code that map into hardware multiplexers in common tools follow:

[edit]MUX templates
The multiplexer, or 'MUX' as it is usually called, is a simple construct very common in hardware
design. The example below demonstrates a simple two to one MUX, with inputs A and B,
selector S and output X:

-- template 1:
X <= A when S = '1' else B;

-- template 2:
with S select
X <= A when '1',
B when others;

-- template 3:
process(A,B,S)
begin
case S is
when '1' => X <= A;
when others => X <= B;
end case;
end process;

-- template 4:
process(A,B,S)
begin
if S = '1' then
X <= A;
else
X <= B;
end if;
end process;

-- template 5 - 4:1 MUX, where S is a 2-bit std_logic_vector :


process(A,B,C,D,S)
begin
case S is
when "00" => X <= A;
when "01" => X <= B;
when "10" => X <= C;
when others => X <= D;
end case;
end process;

The three last templates make use of what VHDL calls 'sequential' code. The sequential sections
are always placed inside a processand have a slightly different syntax which may resemble more
traditional programming languages.

[edit]Latch templates
A transparent latch is basically one bit of memory which is updated when an enable signal is
raised:
-- latch template 1:
Q <= D when Enable = '1' else Q;

-- latch template 2:
process(D,Enable)
begin
if Enable = '1' then
Q <= D;
end if;
end process;

A SR-latch uses a set and reset signal instead:


-- SR-latch template 1:
Q <= '1' when S = '1' else
'0' when R = '1' else Q;

-- SR-latch template 2:
process(S,R)
begin
if S = '1' then
Q <= '1';
elsif R = '1' then
Q <= '0';
end if;
end process;

Template 2 has an implicit "else Q <= Q;" which may be explicitly added if desired.

-- This one is a RS-latch (i.e. reset dominates)


process(S,R)
begin
if R = '1' then
Q <= '0';
elsif S = '1' then
Q <= '1';
end if;
end process;
[edit]D-type flip-flops
The D-type flip-flop samples an incoming signal at the rising or falling edge of a clock. The DFF is
the basis for all synchronous logic.
-- simplest DFF template (not recommended)
Q <= D when rising_edge(CLK);

-- recommended DFF template:


process(CLK)
begin
-- use falling_edge(CLK) to sample at the falling edge instead
if rising_edge(CLK) then
Q <= D;
end if;
end process;

-- alternative DFF template:


process
begin
wait until CLK='1';
Q <= D;
end process;

-- alternative template expands the ''rising_edge'' function above:


process(CLK)
begin
if CLK = '1' and CLK'event then--use rising edge, use "if CLK = '0'
and CLK'event" instead for falling edge
Q <= D;
end if;
end process;

Some flip-flops also have asynchronous or synchronous Set and Reset signals:
-- "Textbook" template for asynchronous reset.
-- This style is prone to error if some signals assigned under the
rising_edge
-- condition are omitted (either intentionally or mistakenly) under the
reset
-- condition. Such signals will synthesize as flip-flops having
feedback MUXes
-- or clock enables (see below), which was probably not intended.
-- This is very similar to the 'transparent latch' mistake mentioned
earlier.
process(CLK, RESET)
begin
if RESET = '1' then -- or '0' if RESET is active low...
Q <= '0';
elsif rising_edge(CLK) then
Q <= D;
end if;
end process;

-- A safer description of reset uses overwrite rather than


-- if-else semantics and avoids the gotcha described above:
process(CLK, RESET)
begin
if rising_edge(CLK) then
Q <= D;
end if;
if RESET = '1' then -- or '0' if RESET is active low...
Q <= '0';
end if;
end process;

-- template for synchronous reset:


process(CLK)
begin
if rising_edge(CLK) then
Q <= D;
if RESET = '1' then -- or '0' if RESET is active low...
Q <= '0';
end if;
end if;
end process;

Another common feature for flip-flops is an Enable signal:


-- template for flip-flop with clock enable:
process(CLK)
begin
if rising_edge(CLK) then
if Enable = '1' then -- or '0' if Enable is active low...
Q <= D;
end if;
end if;
end process;

Flip-flops can also be described with a combination of features:


-- template with clock enable and asynchronous reset combined:
process(CLK, RESET)
begin
if rising_edge(CLK) then
if Enable = '1' then -- or '0' if Enable is active low...
Q <= D;
end if;
end if;
if RESET = '1' then -- or '0' if RESET is active low...
Q <= '0';
end if;
end process;
[edit]Example: a counter
The following example is an up-counter with asynchronous reset, parallel load and configurable
width. It demonstrates the use of the 'unsigned' type and VHDL generics. The generics are very
close to arguments or templates in other traditional programming languages like C or C++.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all; -- for the unsigned type

entity counter_example is
generic ( WIDTH : integer := 32);
port (
CLK, RESET, LOAD : in std_logic;
DATA : in unsigned(WIDTH-1 downto 0);
Q : out unsigned(WIDTH-1 downto 0));
end entity counter_example;

architecture counter_example_a of counter_example is


signal cnt : unsigned(WIDTH-1 downto 0);
begin
process(RESET, CLK) is
begin
if RESET = '1' then
cnt <= (others => '0');
elsif rising_edge(CLK) then
if LOAD = '1' then
cnt <= DATA;
else
cnt <= cnt + 1;
end if;
end if;
end process;

Q <= cnt;

end architecture counter_example_a;

More complex counters may add if/then/else statements within the rising_edge(CLK)
elsif to add other functions, such as count enables, stopping or rolling over at some count
value, generating output signals like terminal count signals, etc. Care must be taken with the
ordering and nesting of such controls if used together, in order to produce the desired priorities
and minimize the number of logic levels needed.

[edit]Simulation-only constructs
A large subset of VHDL cannot be translated into hardware. This subset is known as the non-
synthesizable or the simulation-only subset of VHDL and can only be used for prototyping,
simulation and debugging. For example, the following code will generate a clock with the
frequency of 50 MHz. It can, for example, be used to drive a clock input in a design during
simulation. It is, however, a simulation-only construct and cannot be implemented in hardware. In
actual hardware, the clock is generated externally; it can be scaled down internally by user logic
or dedicated hardware.
process
begin
CLK <= '1'; wait for 10 ns;
CLK <= '0'; wait for 10 ns;
end process;

The simulation-only constructs can be used to build complex waveforms in very short time. Such
waveform can be used, for example, as test vectors for a complex design or as a prototype of
some synthesizable logic that will be implemented in future.
process
begin
wait until START = '1'; -- wait until START is high

for i in 1 to 10 loop -- then wait for a few clock periods...


wait until rising_edge(CLK);
end loop;
for i in 1 to 10 loop -- write numbers 1 to 10 to DATA, 1 every
cycle
DATA <= to_unsigned(i, 8);
wait until rising_edge(CLK);
end loop;

-- wait until the output changes


wait on RESULT;

-- now raise ACK for clock period


ACK <= '1';
wait until rising_edge(CLK);
ACK <= '0';

-- and so on...
end process;

You might also like