Professional Documents
Culture Documents
WITH VHDL
Introduction
VHDL is used to:
document circuits
simulate circuits
synthesize design descriptions
Synthesis is the reduction of a design description to a lower-
level representation (such as a netlist or a set of equations).
The lecture will at times draw upon the concepts of VHDL as a
simulation language
Why Use VHDL?
Quick Time-to-Market
Allows designers to quickly develop designs requiring
tens of thousands of logic gates
Provides powerful high-level constructs for describing
complex logic
Supports modular design methodology and multiple levels
of hierarchy
One language for design and simulation
Allows creation of device-independent designs that are
portable to multiple vendors. Good for ASIC Migration
Allows user to pick any synthesis tool, vendor, or device
VHDL Design Descriptions
VHDL design descriptions consist of an ENTITY
declaration and an ARCHITECTURE body
A “BLACK BOX”
The ENTITY describes the periphery of the
black box (i.e., the design I/O)
BLACK_BOX
rst
q[7:0]
d[7:0]
co
clk
Example Entity declaration
ENTITY black_box IS PORT (
clk, rst: IN std_logic;
d: IN std_logic_vector(7 DOWNTO 0);
q: OUT std_logic_vector(7 DOWNTO 0);
co: OUT std_logic);
END black_box;
BLACK_BOX
rst
q[7:0]
d[7:0]
co
clk
The Entity Declaration
ENTITY entity_name IS
-- optional generics
PORT (
name : mode type ;
...
) ;
END entity_name;
OUT Data goes out of the entity only (and is not used
internally)
INTEGER
• useful as index holders for loops, constants, generics,
or high-level modeling
BOOLEAN
• can take values ‘TRUE’ or ‘FALSE’
ENUMERATED
• has user defined set of possible values, e.g.,
• TYPE traffic_light IS (green, yellow, red);
IEEE 1164
A package created to solve the limitations of the BIT type
Nine values instead of just two ('0' and '1')
Allows increased flexibility in VHDL coding, synthesis, and
simulation
STD_LOGIC and STD_LOGIC_VECTOR are used instead of
BIT and BIT_VECTOR when a multi-valued logic system is
required
STD_LOGIC and STD_LOGIC _VECTOR must be used
when tri-state logic (Z) is required
To be able to use this new type, you need to add 2 lines to
your code:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
1164 Types
std_logic and std_logic_vector are the industry
standard logic type for digital design
Values for Simulation & Synthesis
‘0’ -- Forcing ‘0’
‘1’ -- Forcing ‘1’
‘Z’ -- High Impedance
‘L’ -- Weak ‘0’
‘H’ -- Weak ‘1’
‘-’ -- Don’t care
Values for Simulation only (std_ulogic):
‘U’ -- Uninitialized
‘X’ -- Forcing Unknown
‘W’ -- Weak Unknown
Entity Declaration Example
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY black_box IS PORT (
clk, rst: IN std_logic;
d: IN std_logic_vector(7 DOWNTO 0);
q: OUT std_logic_vector(7 DOWNTO 0);
co: OUT std_logic);
END black_box;
BLACK_BOX
MODE rst
TYPE q[7:0]
d[7:0]
co
clk
Exercise #1: The Entity - A Walk through
Write an entity declaration for the following:
Port D is a 12-bit bus, input only
Port OE and CLK are each input bits
Port AD is a 12-bit, three-state bi-directional bus
Port A is a 12-bit bus, output only
Port INT is a three-state output
Port AS is an output also used internally
my_design
d[11:0] ad[11:0]
oe a[11:0]
clk int
as
Exercise #1: Solution
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY my_design IS PORT (
d: IN std_logic_vector(11 DOWNTO 0);
oe, clk: IN std_logic;
ad: INOUT std_logic_vector(11 DOWNTO 0);
a: OUT std_logic_vector(11 DOWNTO 0);
int: OUT std_logic;
my_design
as: BUFFER std_logic);
END my_design; d[11:0] ad[11:0]
-- In this presentation, VHDL keywords oe a[11:0]
-- are highlighted in bold, CAPITALS; clk int
-- however, VHDL is not case sensitive: as
-- clock, Clock, CLOCK all refer to the
-- same signal, -- means a comment
The Architecture
Architectures describe what is in the black box (i.e., the
structure or behavior of entities)
Descriptions can be either a combination of
Structural descriptions
• Instantiations (placements of logicmuch like in a
schematicand their connections) of building blocks
referred to as components
Behavioral/Dataflow descriptions
• Algorithmic (or “high-level”) descriptions:
IF a = b THEN state <= state5;
• Boolean equations (also referred to as dataflow):
x <= a OR (b AND c);
The Architecture Declaration
ARCHITECTURE arch_name OF entity_name IS
-- optional signal declarations, etc.
BEGIN
--VHDL statements
END arch_name;
f
USE WORK.gatespkg.ALL; c g1
ARCHITECTURE archlogic OF logic IS
SIGNAL d: std_logic;
BEGIN
d <= a AND b; Behavioral/Dataflow
g1: nor2 PORT MAP (c, d, f); Structural
END archlogic;
Comparing Architecture Styles
At the end of the process, all outputs are assigned and the
process goes back to sleep until the next time a signal
changes in the sensitivity list
The Process (contd.)
with s select s
x <= a when “00” , 2
b when “01” , a
c when “10” , b x
mux
c
d when others ;
d
More on with-select-when
clock
clock
Signal Assignment in Processes
Inside processes, signals are not updated immediately.
Instead, they are scheduled to be updated
The signals are not actually updated until the END
PROCESS statement is reached
Therefore, on the previous slide, two registers will be
synthesized (c <= b will be the old b)
In some cases, the use of a concurrent statement outside
the process will fix the problem, but this is not always
possible
So how else can we fix this problem ?
Variables
When a concurrent signal assignment outside the
process cannot be used, the previous problem can be
avoided using a variable
Variables are like signals, BUT they can only be
used inside a PROCESS. They cannot be used to
communicate information between processes
Variables can be of any valid VHDL data type
The value assigned to a variable is available
immediately
Assignment of variables is done using a colon (:),
like this:
c := a AND b;
Using Variables vs. Signals
if rising_edge(clk) then
q <= d;
end if;
A Registered Process (1)
A 4-bit counter with synchronous reset
USE WORK.std_arith.ALL;
... count
upcount: PROCESS (clk) clk
BEGIN
IF rising_edge(clk) THEN rst
IF reset = '1'
THEN count <= "0000"; -- or x"0" instead
ELSE count <= count + 1;
END IF;
END IF;
END PROCESS upcount;
BEGIN clk
IF clk = '1'
THEN q <= d;
END IF;
END PROCESS latch;
Instantiating a registered component
Example: Using LPM library
LIBRARY ieee; d q
USE ieee.std_logic_1164.ALL;
clk
USE WORK.lpmpkg.all ;
ENTITY registered IS PORT (
d: IN std_logic;
clk: IN std_logic_vector(3 DOWNTO 0);
q: OUT std_logic _vector(3 DOWNTO 0));
END registered;
ENC
COUNTER
DATA
4
DIN
LD COUNT
LD Q 4
ENC COMPARATOR
CLOCK P
RST
RESET (sync) P=Q
Q
REGISTER
DIN
Q
ENR 4
ENR
Exercise #4: Solution
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY ex4 IS PORT (
clock, reset, enc, enr, ld: IN std_logic;
data: IN std_logic_vector (3 DOWNTO 0);
count: BUFFER std_logic_vector(3 DOWNTO 0));
END ex4;
USE WORK.std_arith.ALL; -- for counter and Ultragen
ARCHITECTURE archex4 OF ex4 IS
SIGNAL comp: std_logic;
SIGNAL regout: std_logic_vector (3 DOWNTO 0);
BEGIN
reg: PROCESS (clock)
BEGIN
IF RISING_EDGE(clock)
THEN
IF enr = '1' THEN
regout <= data;
END IF;
END IF;
END PROCESS reg;
Exercise #4: Solution (contd.)
cntr: PROCESS (clock)
BEGIN
IF RISING_EDGE(clock) THEN
IF reset = '1'
THEN count <= "0000";
ELSIF ld = '1'
THEN count <= data;
ELSIF enc = '1' AND comp = '0'
THEN count <= count + 1;
END IF;
END IF;
END PROCESS cntr;
comp <= '1' WHEN regout = count ELSE '0';
END archex4;
State machines
Moore Machines
A finite state machine in which the outputs
change due to a change of state
Mealy Machines
A finite state machine in which the outputs can
change asynchronously i.e., an input can cause
an output to change immediately
Moore machines
RESET
(asynchronous)
TIMER1 TIMER2
RED GREEN YELLOW
TIMER1
R='1' G='1' Y='1'
TIMER3
Moore state machine implementations (1)
Outputs decoded from state bits COMBINATORIALLY
combinatorial output logic is in series with state registers
outputs are a function of the present state only
time from clock to output (tco) is long
Present State
Tco + tpd
Example: The Entity Declaration
END arch_1;
Moore state machine implementations (2)
Outputs decoded from state bits using REGISTERS
registered output logic is in parallel with state registers
outputs are a function of the previous state and the inputs
tco is shorter, but you need more registers
tco
Example: Solution 2
Registered outputs decoded from the state registers
ARCHITECTURE arch_2 OF state_machine IS
TYPE traffic_states IS (red, yellow, green);
SIGNAL sm: traffic_states;
BEGIN
fsm: PROCESS (clock, reset) -- the process describes the
BEGIN -- state machine AND the outputs
IF reset = '1' THEN
sm <= red;
r<=‘1’; g<=‘0’; y<=‘0’;
ELSIF rising_edge(clock) THEN
CASE sm IS
WHEN red => IF timer1=‘1’
THEN sm <= green;
r<=‘0’; g<=‘1’; y=‘0’;
ELSE sm <= red;
r<=‘1’; g<=‘0’; y=‘0’;
END IF;
Example: Solution 2 (contd.)
WHEN green => IF timer2=’1'
THEN sm <= yellow;
r<=‘0’; g<=‘0’; y<=‘1’;
ELSE sm <= green;
r<=‘0’; g<=‘1’; y<=‘0’;
END IF;
WHEN yellow => IF timer3=’1'
THEN sm <= red;
r<=‘1’; g<=‘0’; y<=‘0’;
ELSE sm <= yellow;
r<=‘0’; g<=‘0’; y<=‘1’;
END IF;
WHEN others => sm <= red;
END CASE;
END IF;
END PROCESS fsm;
END arch_2;
Moore State Machine Implementations (3)
We encoded the outputs within the state registers
Logic
State Outputs
Inputs Registers
Tco
Example: Solution 3
Outputs encoded inside the state registers
ARCHITECTURE arch_3 OF state_machine IS
SIGNAL sm: std_logic_vector(2 DOWNTO 0) ;
CONSTANT red: std_logic_vector(2 DOWNTO 0) := ”100" ;
CONSTANT green: std_logic_vector(2 DOWNTO 0) := "010" ;
CONSTANT yellow: std_logic_vector(2 DOWNTO 0) := "001" ;
BEGIN
fsm: PROCESS (clock, reset) -- the process describes the
BEGIN -- state machine only
IF reset = '1' THEN
sm <= red;
ELSIF rising_edge(clock) THEN
CASE sm IS
WHEN red => IF timer1=‘1’
THEN sm <= green;
ELSE sm <= red;
END IF;
Example: Solution 3 (contd.)
WHEN green => IF timer2=’1'
THEN sm <= yellow;
ELSE sm <= green;
END IF;
END arch_3;
Mealy Machines
State
Registers
Logic Outputs
Inputs
Example: The Wait State Generator
State diagram:
PWAIT
RESET
(async)
REQ
RETRY_OUT='1'
IDLE RETRY
if, ENABLE='0'
REQ
PWAIT
Example: Mealy Machine Solution
ARCHITECTURE archmealy1 OF mealy1 IS
TYPE fsm_states IS (idle, retry);
SIGNAL wait_gen: fsm_states;
BEGIN
fsm: PROCESS (clock, reset)
BEGIN
IF reset = '1' THEN
wait_gen <= idle;
ELSIF FALLING_EDGE(clock) THEN
CASE wait_gen IS
WHEN idle => IF req = '0' THEN wait_gen <= retry;
ELSE wait_gen <= idle;
END IF;
WHEN retry => IF pwait = '1' THEN wait_gen <= idle;
ELSE wait_gen <= retry;
END IF;
WHEN OTHERS => wait_gen <= idle;
END CASE;
END IF;
END PROCESS fsm;
retry_out <= '1' WHEN (wait_gen = retry AND enable='0') ELSE '0';
END archmealy1;
Exercise #5
Design a state machine to implement the function
shown below:
RESET
(sync)
POS
hold sample extend
POS
clear='0' track='1'
track='1'
Hierarchical (Modular) Designs
c i c
t
b r b
sel
s
sel toplevel
mux2to1
• schematic • schematic
• entity/architecture mux2to1 • entity/architecture
a
• library
c • package
b • symbol
sel • component
Hierarchy Management
Libraries are used to store re-usable components, type definitions,
overloaded operators etc. You add the ‘LIBRARY’ and ‘USE’
clauses to your code to get access to them
Your Design (VHDL) Library (Compiled) Packages (VHDL) Others (VHDL)
LIBRARY ieee; ieee
std_logic_1164 std_logic
USE ieee.std_logic_1164..
type
USE work.std_arith.all
definitions
mux2to1 t(0)
mux2to1 t(1)
mux2to1 t(2)
i(2) a i(1) a i(0) a
m0 c
m1 c
m2 c
r(0) b r(1) b r(2) b
sel sel sel
s
Exercise #6
Making use of exercise #4, we will use a separate
entity/architecture for each block and use VHDL hierarchy
ENC
COUNTER
DATA
4
DIN
LD COUNT
LD Q 4
ENC COMPARATOR
CLOCK P
RST
RESET (sync) P=Q
Q
REGISTER
DIN
Q
ENR 4
ENR
Exercise 6 Solution: package.vhd
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
PACKAGE ex6_pkg IS
END ex6_pkg;
Exercise 6 Solution: Top Level File - ex6.vhd
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
BEGIN
END ex6_arch;
Exercise 6: Summary
We created entity/architectures for each component. We stored those
components in a package so that we could RE-USE them
We included ALL “components” in the “ex6_pkg” package which
was compiled into the “work” library
Your Design (VHDL) Library (Compiled) Packages (VHDL) Others (VHDL)
LIBRARY ieee; ieee std_logic_1164
std_logic
USE ieee.std_logic_1164..
type
USE work.ex6_pkg.all
definitions
reset
q(31) q(30) q(29) q(1) q(0)
si
•••
clock
Output
DRAM
Enable
Controller
Controller
Exercise #7: The FSM chart
Use the following FSM chart:
RAM RESET
IDLE
OE=1111
/RAM
CHOOSE
OE=1111
/EOC
EOC
Exercise #7: Solution
ENTITY ex7 IS PORT (
clk, reset: IN std_logic;
ram, eoc: IN std_logic;
a3a2: IN std_logic_vector(1 DOWNTO 0) ;
oe: OUT std_logic_vector(3 DOWNTO 0));
END ex7;
BEGIN
Exercise #7: Solution (contd.)
fsm: PROCESS (clk)
BEGIN
IF RISING_EDGE(clock) THEN
IF reset = '1' THEN
next_state <= idle;
ELSE
CASE present_state IS
WHEN idle => IF ram = '0'
THEN next_state <= choose ;
ELSE next_state <= idle ;
END IF ;
WHEN choose =>
CASE a3a2 IS
WHEN "00" => next_state <= banka ;
WHEN "01" => next_state <= bankb ;
WHEN "10" => next_state <= bankc ;
WHEN "11" => next_state <= bankd ;
WHEN OTHERS => next_state <= banka ;
END CASE ;
WHEN banka => IF eoc = '1'
THEN next_state <= bankb ;
ELSE next_state <= idle ;
END IF ;
Exercise #7: Solution (contd.)
END archex7;