VHDL Lecture
CP323L1
Advanced Logic Circuit
Engr. Rommel A. Manalo,
CpE Department
Introduction to VHDL
VHDL is a language for describing digital
hardware used by industry worldwide
VHDL is an acronym for VHSIC (Very High
Speed Integrated Circuit) Hardware
Description Language
A VHDL description of a digital system can
be transformed into a gate level
implementation. This process is know as
synthesis.
A Brief History of VHDL
June 1981: Woods Hole Workshop
July 1983: contract awarded to develop VHDL
Intermetrics
IBM
Texas Instruments
August 1985: VHDL Version 7.2 released
December 1987: VHDL became IEEE Standard 1076-
1987 and in 1988 an ANSI standard
Four versions of VHDL:
IEEE-1076 1987
IEEE-1076 1993 most commonly supported by CAD tools
IEEE-1076 2000 (minor changes)
IEEE-1076 2002 (minor changes)
Verilog
Essentially identical in function to VHDL
No generate statement
Simpler and syntactically different
C-like
Gateway Design Automation Co., 1983
Early de facto standard for ASIC
programming
Open Verilog International Standard
VHDL vs. Verilog
Example Code:
VHDL Design Flows
ASIC versus FPGA
What is an FPGA Chip ?
VHDL Design Styles
VHDL Design
Styles
dataflow
Concurrent
statements
structural
behavioral
(sequential)
Components and Sequential statements
interconnects
Registers
State machines
Instruction decoders
Testbenches
Levels of VHDL Design
Levels of Design
Description
Register Transfer Logic (RTL)
Design Description
VHDL Fundamentals
Fundamental parts of a
LIBRARY
VHDL - Basic Terminology
VHDL is a hardware description language that can be
used to model a digital system
Entity: A hardware abstraction of a digital system
Component:An entity used by another entity
Example: when an entity X used in another entity Y, then X
become a component for the entity Y.
Design units: VHDL provides five different types
of primary constructs to describe an entity
1. Entity declaration
2. Architecture body
3. Configuration declaration
4. Package declaration
5. Package body
VHDL - Basic Terminology
Entity declaration: describes the external
view of the entity.
Example: input and output signal names
Architecture body: contains the internal
description of the entity
Example:
a set of interconnected components that represents the
structure of the entity or
a set of concurrent or sequential statements that
represents the behavior of the entity
Each architecture body can be represented by
- one style or
- mixed style of representation
Case Sensitivity
VHDL is not case sensitive
Example:
Names or labels
databus
Databus
DataBus
DATABUS
are all equivalent
Naming and Labeling
General rules of thumb (according to VHDL-87)
1. All names should start with an alphabet character
(a-z or A-Z)
2. Use only alphabet characters (a-z or A-Z) digits (09) and underscore (_)
3. Do not use any punctuation or reserved
characters within a name (!, ?, ., &, +, -, etc.)
4. Do not use two or more consecutive underscore
characters (__) within a name (e.g., Sel__A is
invalid)
5. All names and labels in a given entity and
architecture must be unique
Identifiers
Basic identifiers are made up of alphabetic,
numeric and/or underscore characters.
The first character must be a letter.
The last character can not be an underscore.
Two underscores in succession are not allowed.
VHDL reserved words such as entity, is,
architecture should not be used as identifiers.
Upper and lower case letters are equivalent
when used in identifiers. The following are
equivalent:
Clk, clk, CLK, clK
Reserved Keywords:
Examples:
Identify the legal identifiers
_tx_clk?
No. must start with a letter.
Tx_clk?
Yes. A legal identifier.
6A15X?
No. can not start with a number.
Big#buffer?
No. Can not have # in identifier.
Examples:
Select?
No. Reserved word.
tx_clk_?
No. The last character can not be an
underscore.
ABC_456?
Yes. A legal identifier.
Tx__clk
No. Two underscores in succession not
allowed.
VHDL is a Free Format
VHDL is a free format language
No formatting conventions, such as spacing or indentation
imposed by VHDL compilers. Space and carriage return
treated the same way.
Example:
if (a=b) then
or
if (a=b) then
or
if (a =
b) then
are all equivalent
VHDL Comments
Comments in VHDL are indicated with a double
dash, i.e., --
Comment indicator can be placed anywhere in the
line
Any text that follows in the same line is treated as a
comment
Carriage return terminates a comment
No method for commenting a block extending over a
couple of lines
Examples:
-- main subcircuit
Data_in <= Data_bus;
FIFO
-- reading data from the input
VHDL Comments
Explain function of module to other
designers
Explanatory, not just restatement of code
Locate close to code described
Put near executable code, not just in a
header
Logic Operators
Logic operators
and
or
nand
nor
xor
not
xnor
Logic operators precedence
only in VHDL-93
Highest
and
Lowest
or
not
nand
nor
xor
xnor
No Implied Precedence
Wanted: y = ab + cd
Incorrect
y <= a and b or c and d ;
equivalent to
y <= ((a and b) or c) and d ;
equivalent to
y = (ab + c)d
Correct
y <= (a and b) or (c and d) ;
VHDL operators
VHDL Code
Example: NAND Gate
VHDL Code
3 sections to a piece of VHDL code
File extension for a VHDL file is .vhd
Name of the file is usually the entity name
(nand_gate.vhd)
Fundamental Part Of A
Library
Library is a collection of commonly used
pieces of code, grouped for reuse.
Use all definitions from the package
std_logic_1164
Library Declarations
Commonly Used Libraries
Design Entity
Entity Declaration
Entity Declaration describes the interface
of the component, i.e. input and output
ports.
Entity declaration simplified
syntax
Port Mode IN
Port Mode OUT
Port Mode OUT (with
extra signal)
Port Mode BUFFER
Port Mode INOUT
Port Modes: Summary
The Port Mode of the interface describes the direction
in which data travels with respect to the component
In: Data comes in this port and can only be read within the entity.
It can appear only on the right side of a signal or variable
assignment.
Out: The value of an output port can only be updated within the
entity. It cannot be read. It can only appear on the left side of a
signal assignment.
Inout: The value of a bi-directional port can be read and updated
within the entity model. It can appear on both sides of a signal
assignment.
Buffer: Used for a signal that is an output from an entity. The
value of the signal can be used inside the entity, which means
that in an assignment statement the signal can appear on the
left and right sides of the <= operator
Architecture
Entity describes the ports of the module
Architecture describes the functionality of
the module (i.e. what does the module do)
Architecture example:
Architecture Simplified
Syntax
Entity Declaration &
Architecture
Every VHDL model is composed of an
entity and at least one architecture .
Entity describes the interface to the model
(inputs, outputs)
Architecture describes the behavior of the
model
Can have multiple architectures for one
entity
Entity Declaration &
Architecture
nand_gate.vhd
STD_LOGIC
BIT versus STD_LOGIC
BIT type can only have a value of 0 or 1
STD_LOGIC can have eight values
0,1,X,Z,W,L,H,-
Useful mainly for simulation
0,1, and Z are synthesizable
use std_logic or std_logic_vector for all
entity input or output ports
Modeling Wires and Buses
SIGNAL a : STD_LOGIC;
a
1
wire
SIGNAL b : STD_LOGIC_VECTOR(7 DOWNTO
0);
b
8
bus
Merging wires and buses
a
4
10
SIGNAL
SIGNAL
SIGNAL
SIGNAL
a:
b:
c:
d:
STD_LOGIC_VECTOR(3 DOWNTO 0);
STD_LOGIC_VECTOR(4 DOWNTO 0);
STD_LOGIC;
STD_LOGIC_VECTOR(9 DOWNTO 0);
d <= a & b & c;
Splitting buses
a
4
10
5
b
c
SIGNAL
SIGNAL
SIGNAL
SIGNAL
a:
b:
c:
d:
STD_LOGIC_VECTOR(3 DOWNTO 0);
STD_LOGIC_VECTOR(4 DOWNTO 0);
STD_LOGIC;
STD_LOGIC_VECTOR(9 DOWNTO 0);
a <= d(9 downto 6);
b <= d(5 downto 1);
c <= d(0);
Single versus Double
Quote
Use single quote to hold a single bit signal
a <= 0, a <=Z
Use double quote to hold a multi-bit signal
b <= 00, b <= 11
The Design Proper
A Sample Model(1)
Description
Implementation
A Sample Model(2)
Description
Implementation
LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY xor IS
PORT(
A : IN STD_LOGIC;
B : IN STD_LOGIC;
C : IN STD_LOGIC;
Result : OUT STD_LOGIC
);
END xor3;
VHDL Statements
VHDL has a reputation as a complex
language (it is!)
We will use a small subset of the language
for our purposes
Some VHDL constructs:
Signal Assignment: A <= B;
Comparisons = (equal), > (greater than), <
(less than), etc.
Boolean operations AND, OR, NOT, XOR
Sequential statements (CASE, IF, FOR)
Concurrent statements (when-else)
XOR (Signal Assignment)
ARCHITECTURE dataflow OF xor3 IS
SIGNAL U1_out: STD_LOGIC;
BEGIN
U1_out <= A XOR B;
Result <= U1_out XOR C;
END dataflow;
Majority Gate Example
The following is an example of a three input
XOR gate (majority gate) implemented in
VHDL
Majority Gate with Temporary
Signals
The following version of the majority gate uses some
temporary signals (entity has been left out, is same).
Note that temporary signals are declared between
architecture statement and begin statement.
Majority Gate with when-else
statement
The following version of the majority gate
uses a 'when-else' statement:
You will find that there are many different
ways to accomplish the same result in
VHDL. There is usually no best way; just
use one that you feel most comfortable
with.
Concurrent Versus Sequential
Statement
The statements we have looked at so far are called
concurrent statements.
Each concurrent statement will synthesize to a block
of logic.
Another class of VHDL statements are called
sequential statements.
Sequential statements can ONLY appear inside of a
process block.
A process block is considered to be a single
concurrent statement.
Can have multiple process blocks in an architecture.
Usually use process blocks to describe complex
combinational or sequential logic.
Majority Gate using process
block and if statement
The entity declaration has been left out
(same as before).
Analysis on process block
model
The first line in the process "main: process (A, B, C)" has the
name of the process (main) and the sensitivity list of the
process.
The process name is user defined, can also be left out (unnamed
process).
The sensitivity list should contain any signals that appear on the
right hand side of an assignment (inputs) or in any boolean for a
sequential control statement.
The if statement condition must return a boolean value (TRUE
or FALSE) so that is why the conditional is written as:
( (A='1') and (B= '1') )
Cannot write it as:
( A and B)
because this will return a 'std_logic' type (more on types
later)
if-else statement
ARCHITECTURE behavioral OF xor IS
BEGIN
PROCESS (A,B,C)
BEGIN
IF ((A XOR B XOR C) = '1') THEN
Result <= '1';
ELSE
Result <= '0';
END IF;
END PROCESS;
END behavioral;
if-else statement
Unassigned outputs in Process
blocks
Analysis on Unassigned
Output
In the above process, the ELSE clause was left out. If the
'if statement condition is false, then the output Y is not
assigned a value.
In synthesis terms, this means the output Y should have a
LATCH placed on it!
The synthesized logic will have a latch placed on the Y
output; once Y goes to a '1', it can NEVER return to a '0'!!!!!
This is probably the #1 student mistake in writing
processes. To avoid this problem do one of the following
things:
ALL signal outputs of the process should have DEFAULT
assignments right at the beginning of the process.
OR, all 'if' statements that affect a signal must have ELSE
clauses that assign the signal a value if the 'if' test is false.
if-elsif-else statement
Example: Priority circuit
Priority circuit has 7 inputs; Y7 is highest
priority, Y0 is lowest priority.
Three bit output should indicate the highest
priority input that is a '1' (ie. if Y6 ='1' , Y4
= '1', then output should be "101"). If no
input is asserted, output should be "000".
Priority
Circuit
using if-elsifelse
statement
Analysis on Priority
Example
This is the first example that used a bus. The DOUT signal is
a 3 bit output bus.
std_logic_vector(2 downto 0) describes a 3 bit bus where
dout(2) is most significant bit, dout(0) is least significant bit.
std_logic_vector (0 to 2) is also a 3 bit bus, but dout(0) is MSB,
dout(2) is LSB. We will always use 'downto' in this class.
A bus assignment can be done in many ways:
dout <= "110"; assigns all three bits
dout(2) <= '1'; assigns only bit #2
dout(1 downto 0) <= "10"; assigns two bits of the bus.
This architecture used the 'elsif' form of the 'if' statement
Note that it is 'elsif', NOT 'elseif'.
This called an elsif chain.
Priority Circuit with just IF
statements
By reversing the
order of the
assignments, we
can
accomplish the
same as the elsif
priority chain.
In a process, the
LAST
assignment to the
output is what
counts.
Priority Circuit with when-else
architecture whenelse of priority is
begin
-- priority circuit, Y7 highest priority input
-- Y1 is lowest priority input
-- uses just one when-else concurrent statement.
dout <= "111" when (y7 = '1') else
"110" when (y6 = '1') else
"101" when (y5 = '1') else
"100" when (y4 = '1') else
"011" when (y3 = '1') else
"010" when (y2 = '1') else
"001" when (y1 = '1') else
"000";
end process;
end whenelse;
2-to-1 Multiplexer
s
w
0
w
1
(a) Graphical symbol
w
0
w
1
(b) Truth table
VHDL code for a 2-to-1
Multiplexer
LIBRARY ieee ;
USE ieee.std_logic_1164.all ;
ENTITY mux2to1 IS
PORT ( w0, w1, s
f
END mux2to1 ;
: IN
: OUT
STD_LOGIC ;
STD_LOGIC ) ;
ARCHITECTURE dataflow OF mux2to1 IS
BEGIN
f <= w0 WHEN s = '0' ELSE w1 ;
END dataflow ;
Cascade of two multiplexers
w
3
w
2
0
w
1
y
1
s2
s1
VHDL code for a cascade of two multiplexers
LIBRARY ieee ;
USE ieee.std_logic_1164.all ;
ENTITY mux_cascade IS
PORT ( w1, w2, w3: IN STD_LOGIC ;
s1, s2
: IN STD_LOGIC ;
f
: OUT STD_LOGIC ) ;
END mux_cascade ;
ARCHITECTURE dataflow OF mux2to1 IS
BEGIN
f <= w1 WHEN s1 = 1' ELSE
w2 WHEN s2 = 1 ELSE
w3 ;
END dataflow ;
4 x 1 Multiplexer
s
0
s
1
w
w
w
w
s s
1 0
00
01
10
11
(a) Graphic symbol
(b) Truth table
0
1
2
3
4-to-1 Mux using Select Concurrent
LIBRARY ieee ;
USE ieee.std_logic_1164.all ;
ENTITY mux4to1 IS
PORT ( w0, w1, w2, w3
s
f
END mux4to1 ;
: IN
: IN
: OUT
ARCHITECTURE dataflow OF mux4to1 IS
BEGIN
WITH s SELECT
f <= w0 WHEN "00",
w1 WHEN "01",
w2 WHEN "10",
w3 WHEN OTHERS ;
END dataflow ;
STD_LOGIC ;
STD_LOGIC_VECTOR(1 DOWNTO 0) ;
STD_LOGIC ) ;
4-to-1 Mux using Select
Concurrent
Some synthesis tools will automatically
recognize this structure as a mux and will
find a more efficient implementation than
using a whenelse or if statement structure
(when-else and if structures define a
priority structure). The others case must be
specified.
This is a concurrent statement; the
sequential version of the select statement
is the case statement.
4-to-1 Mux using Case
Sequential
There can be multiple statements for each case; only one
statement is needed for each case in this example.
architecture select_statement of mux4to1_8 is
begin
process (a, b, c, d, sel)
begin
case sel is
when "01" => dout <= b ;
when "10" => dout <= c;
when "11" => dout <= d;
when others => dout <= a;
end case;
end process;
end select_statement;
4-to-1 mux with 8 bit
Datapaths
Analysis on Mux example
This is one way to write a mux, but is not
the best way. The when-else structure is
actually a priority structure.
A mux has no priority between inputs, just a
simple selection.
The synthesis tool has to work harder than
necessary to understand that all possible
choices for sel are specified and that no
priority is necessary.
Just want a simple selection mechanism.
4 Bit Ripple Carry Adder
Write a VHDL model for a 4 bit ripple carry
adder.
Logic equation for each full adder is:
sum <= a xor b xor ci;
co <= (a and b) or (ci and (a or b));
library ieee;
use ieee.std_logic_1164.all;
entity adder4bit is
port ( a,b: in std_logic_vector(3 downto 0);
cin : in std_logic;
cout: out std_logic;
sum: out std_logic_vector(3 downto 0)
);
end adder4bit;
architecture bruteforce of adder4bit is
-- temporary signals for internal carries
signal c : std_logic_vector(4 downto 0); .
begin
process (a, b, cin, c)
begin
c(0) <= cin;
-- full adder 0
sum(0) <= a(0) xor b(0) xor c(0);
c(1) <= (a(0) and b(0)) or (c(0) and (a(0) or b(0)));
-- full adder 1
sum(1) <= a(1) xor b(1) xor c(1);
c(2) <= (a(1) and b(1)) or (c(1) and (a(1) or b(1)));
-- full adder 2
sum(2) <= a(2) xor b(2) xor c(2);
c(3) <= (a(2) and b(2)) or (c(2) and (a(2) or b(2)));
-- full adder 3
sum(3) <= a(3) xor b(3) xor c(3);
c(4) <= (a(3) and b(3)) or (c(3) and (a(3) or b(3)));
cout <= c(4);
end process;
end bruteforce;
Straight forward implementation. Nothing wrong with
this. However, is there an easier way?
4 Bit Ripple Carry Model using
For
Analysis on for-loop
statement
The for-loop can be used to repeat blocks of
logic
The loop variable i is implicity declared for
this loop; does not have to be declared
anywhere else.
To visualize what logic is created, 'unroll'
the loop by writing down each loop
iteration with loop indices replaced hard
numbers.
Summary
There are many different ways to write
VHDL synthesizable models for
combinational logic.
There is no 'best' way to write a model; for
now, just use the statements/style that you
feel most comfortable with and can get to
work (of course!)
READ THE BOOK!!!!!!!!
There is NO WAY that we can cover all
possible examples in class.
The book has many other VHDL examples.
Summary (Cont.)
This course is about Digital System DESIGN, not
VHDL. As such, we will only have 3-4 lectures
about VHDL, the rest will be on design topics.
VHDL is only a means for efficiently implementing
your design it is not interesting by itself.
You will probably learn multiple synthesis
languages in your design career - it is the digital
design techniques that you use that will be
common to your designs, not the synthesis
language.
Next Meeting: Registers and Counters