EEE515
VHDL
Notes from
“Digital System Design with VHDL” Mark Zwolinski, Pearson/Prentice Hall, 2nd Edition
See also
“The Student’s Guide to VHDL” Peter Ashenden, 2nd edition Morgan Kaufman (under £20)
Ian McCrum
Room 5B16
Tel: 90 366364 voice mail on 6th ring
Email: IJ.McCrum@Ulster.ac.uk
Web site: http://www.eej.ulst.ac.uk
www.eej.ulst.ac.uk/~ian/modules/EEE515
1/48
VHDL: Resources
• “The Student’s Guide to VHDL” Peter Ashenden, 2nd
edition Morgan Kaufman (under £20)
His online guides
• VHDL Cookbook (dated, older version of VHDL)
• VHDL-quick-start.pdf (42 slides)
• VHDL_Tutorial, (84 Pages) online - check copyright status
Do the quick start then come back here – this highlights
usage instead of reference/understanding.
www.eej.ulst.ac.uk/~ian/modules/EEE515
2
Combinational logic
using VHDL gate models
entity And2 is
port (x, y
end entity And2;
architecture ex1
begin
z <= x and
end architecture
BIT is a predefined
type with two
values: ‘0’ and ‘1’.
: in BIT; z: out BIT);
of And2 is
y;
ex1;
We can also use
inout or buffer or
omit the in
keyword
The entity name
at the end is
optional,
The entity part describes a black box. We can see the inputs and outputs of the black
box, together with their types, but we know nothing of the internals of the circuit.
www.eej.ulst.ac.uk/~ian/modules/EEE515
3
The architecture describes the function and/or
structure of the circuit. In this example, the
functionality of the circuit is described in terms of
Boolean operations. The reason for having this split
is that it is possible to have more than one
architecture for each entity, perhaps describing
alternative implementations or different levels of
description. For instance, we can describe an AND
gate in terms of a Boolean operator, as shown, but
we could also write a truth table. In either case, the
entity, i.e. the ‘black box’, is the same, but there
would be two architectures, one for each model.
VHDL has the following operators defined for type BIT:
not, and, or, nand,
nor,
xor and xnor
www.eej.ulst.ac.uk/~ian/modules/EEE515
4
Structural VHDL
-- in addition to the AND gate
entity Or2 is
port (x, y : in BIT; z: out BIT);
end entity Or2;
architecture ex1 of Or2 is
begin
z <= x or y;
end architecture ex1;
entity Not1 is
port (x : in BIT; z: out BIT);
end entity Not1;
architecture ex1 of Not1 is
begin
z <= not x;
end architecture ex1;
architecture netlist of comb_function is
signal p, q, r : BIT;
begin
g1: entity WORK.Not1(ex1) port map (a, p);
g2: entity WORK.And2(ex1) port map (p, b, q);
g3: entity WORK.And2(ex1) port map (a, c, r);
g4: entity WORK.Or2(ex1) port map (q, r, z);
end architecture netlist;
Note several styles exist for structural VHDL.
We will not use structural except for
testbenches if not using the simple simulator.
Note the signal keyword
Also work is the current working library –
more tool and system independent than
specifying folder location!
www.eej.ulst.ac.uk/~ian/modules/EEE515
5
Structural VHDL 2
architecture netlist2 of comb_function is
component And2 is
port (x, y : in BIT; z: out BIT);
end component And2;
component Or2 is
port (x, y : in BIT; z: out BIT);
end component Or2;
component Not1 is
port (x : in BIT; z: out BIT);
end component Not1;
signal p, q, r : BIT;
begin
g1: Not1 port map (a, p);
g2: And2 port map (p, b, q);
g3: And2 port map (a, c, r);
g4: Or2 port map (q, r, z);
end architecture netlist2;
www.eej.ulst.ac.uk/~ian/modules/EEE515
6
Signal assignments
z <= x and y;
z <= not ((x and y) or (a and b));
z <= x after 4 NS;
This is an inertial delay. In other words, the signal is delayed by 4
ns, and in addition, any pulse that is less than 4 ns wide is
suppressed, as shown below.
www.eej.ulst.ac.uk/~ian/modules/EEE515
A pure or transport delay is
modelled with:
z <= transport x after 4 NS;
(Note the space between 4
and NS.) Any pulse is now
transmitted. We can include
the
keyword inertial if we want to
be very specific about the
delay model.
7
Generics
z <= x and y after 5 ns; -- better to be general…
z <= x and y after delay;
To define delay as a parameter to the VHDL
model using a generic:
entity And2 is
generic (delay : DELAY_LENGTH);
port (x, y : in BIT; z: out BIT);
end entity And2;
www.eej.ulst.ac.uk/~ian/modules/EEE515
8
Testbenches
If we wish to simulate our circuit to verify that it really does work as expected,
we need to apply some test stimuli. We could, of course, write out some test
vectors and apply them, or, more conveniently, write the test data in VHDL.
This type of VHDL model isoften known as a testbench. Testbenches have a
distinctive style. Below is a testbench for a two-input AND gate.
entity TestAnd2 is
end entity TestAnd2;
architecture io of TestAnd2 is
signal a,b,c : BIT;
begin
g1: entity WORK.And2(ex2) port map (x=>a, y=>b, z=>c);
a<= '0', '1' after 100 NS;
b<= '0', '1' after 150 NS;
end architecture io;
Because this is a testbench, i.e. a description of the entire world that affects
the model we are testing, there are no inputs or outputs in the entity. This is
characteristic of testbenches.
www.eej.ulst.ac.uk/~ian/modules/EEE515
9
Three-state buffers
A buffer with input and output that has an additional
input called EN or ENABLE. When active it switched
the output off, (both pullup and pulldown transistors)
Usually called the high impedance state ‘Z’
BIT is no longer adequate to represent logic signal
values. We can define a new type to represent logic
signals in VHDL:
type tri is ('0', '1', 'Z'); -- can declare signals & ports..
www.eej.ulst.ac.uk/~ian/modules/EEE515
10
In VHDL, functions and operators can be
overloaded.
For example, the and operator normally takes two operands of
type bit and returns the Boolean AND of the two operands. We
can write a new AND operator to take two operands of type tri
and return the values shown in the truth table. The syntax of
this function will become clear later.
function "and" (Left, Right: tri) return tri is
type tri_array is array (tri, tri) of tri;
constant and_table : tri_array := (('0', '0', '0'),('0', '1', '1'),('0', '1', '1'));
begin
return and_table(Left, Right);
end function "and";
www.eej.ulst.ac.uk/~ian/modules/EEE515
11
Standard logic package
Having defined a new type with values ‘0’, ‘1’ and ‘Z’, we would
have to write VHDL functions for the various logical operations.
Moreover, we might wonder whether three states are sufficient
for everything we might wish to model. IEEE standard 1164
defines an enumerated type with nine values:
‘U’ Uninitialized
‘X’ Forcing (i.e. strong) unknown
‘0’ Forcing 0
‘1’ Forcing 1
‘Z’ High impedance
‘W’Weak unknown
‘L’Weak 0
‘H’Weak 1
‘–’ Don’t care
www.eej.ulst.ac.uk/~ian/modules/EEE515
12
std_ulogic
The standard logic type is defined by:
type std_ulogic is ('U', 'X', '0', '1', 'Z', 'W', 'L', 'H', '–');
The and function for std_ulogic is given by the following truth
table. The two inputs are given by the first row and column.
www.eej.ulst.ac.uk/~ian/modules/EEE515
13
std_ulogic
If we write a model using signals of type BIT or std_ulogic, we must
ensure that two models do not attempt to put a value onto the same
signal. In VHDL terms, a signal may have one or more sources.
A source may be an out, inout or buffer port of an instantiated
component or a driver. In simple terms, a driver is the righthand side of
a signal assignment. The one occasion when we do try to connect two
or more outputs together is when we use three-state buffers.
We still have to be careful that no more than one output generates a
logic 1 or 0 and the rest of the outputs are in the high-impedance state,
but we want the simulator to tell us if there is a design mistake. This
cannot be done with std_ulogic – a VHDL simulator does not treat ‘Z’
as a special case.
www.eej.ulst.ac.uk/~ian/modules/EEE515
14
std_logic
The IEEE 1164 standard defines std_logic, which allows more
than one output to be connected to the same signal. Std_logic is
defined as a subtype of std_ulogic, for which a resolution
function is declared. The resolved function defines the state of a
signal if, for example, a ‘Z’ and a ‘1’ are driven onto the same
signal.
Because VHDL is strongly typed, operations involving two or
more types must be explicitly defined. A subtype may, however,
be used in place of the type from which it is derived, without
causing an error.
subtype std_logic is resolved std_ulogic;
www.eej.ulst.ac.uk/~ian/modules/EEE515
15
Ideally, we should use std_ulogic for all signals unless we intend that
any contention should be resolved. If we were to do this, the simulator
would immediately tell us (by halting) if we were erroneously trying to
force two conflicting values onto the same piece of wire.
1
In practice, however, some synthesis tools have difficulties with
std_ulogic.
The use of std_logic now seems to be the accepted industry standard, so
in the rest of this book we will use std_logic as the types of all Boolean
signals.
Contention can be recognized by the unexpected appearance of ‘X’
values in a simulation.
Use std_logic_1164 for all real signals!
www.eej.ulst.ac.uk/~ian/modules/EEE515
16
library IEEE;
use IEEE.std_logic_1164.all;
-- The various standard logic types and the
-- functions needed to use them are gathered
-- together in a package. The various standard
-- logic types and the functions needed to use
-- them are gathered together in a package.
every VHDL model that uses the standard logic
package must be prefixed with the 2 lines above
www.eej.ulst.ac.uk/~ian/modules/EEE515
17
VHDL Concurrent statements
When . . . else
library IEEE;
use IEEE.std_logic_1164.all;
entity three_state is
port (a, enable : in std_logic;
z : out std_logic);
end entity three_state;
architecture when_else of three_state is
begin
z <= a when enable = '1' else 'Z'; -- a tri state
-- if you want a delay use z <= a after 4 NS when enable = '1' else 'Z';
end architecture when_else;
www.eej.ulst.ac.uk/~ian/modules/EEE515
18
Decoders
•
type std_logic_vector is array (NATURAL range <>) of std_logic;
library IEEE;
use IEEE.std_logic_1164.all;
entity decoder is
port (a : in std_logic_vector(1 downto 0); -- could use to if you
want
z : out std_logic_vector(3 downto 0));
end entity decoder;
architecture when_else of decoder is
begin
z <=
"0001" when a = "00" else
"0010" when a = "01" else
"0100" when a = "10" else
"1000" when a = "11" else
"XXXX";
end architecture when_else;
www.eej.ulst.ac.uk/~ian/modules/EEE515
If the final
else is
omitted, z
continues to
take the last
value
assigned to it.
In
VHDL, a signal
takes a value
until a new
value is
assigned. This
may be
interpreted as
z holding its
value in a
latch.
19
With . . . select statement
An alternative to the when . . . else statement is the
with . . . select statement. Another model of the 2 to 4 decoder is shown below.
architecture with_select of decoder is
begin
with a select
z <= "0001" when "00",
"0010" when "01",
"0100" when "10",
"1000" when "11",
"XXXX" when others;
end architecture with_select;
-- all tests done in parallel
-- a can have non 0 or 1 values
-- so must have others just in case
www.eej.ulst.ac.uk/~ian/modules/EEE515
20
Seven segment decoder
library IEEE;
use IEEE.std_logic_1164.all;
entity seven_seg is
port (a : in std_logic_vector(3 downto 0);
z : out std_logic_vector(6 downto 0));
end entity seven_seg;
architecture with_select of seven_seg is
begin
with a select
z <= "1110111" when "0000",
"0010010" when "0001",
"1011101" when "0010",
"1011011" when "0011",
"0111010" when "0100",
"1101011" when "0101",
"1101111" when "0110",
"1010010" when "0111",
"1111111" when "1000",
"1111011" when "1001",
"1101101" when
"1010"|"1011"|"1100"|
"1101"|"1110"|"1111",
"0000000" when others;
end architecture with_select;
www.eej.ulst.ac.uk/~ian/modules/EEE515
21
n to 2n decoder – shift operators
We have seen two ways to describe a 2 to 4 decoder. The same structures could
easily be adapted to model a 3 to 8 decoder or a 4 to 16 decoder. Although these
devices are clearly more complex than the 2 to 4 decoder, conceptually there is
little difference. It would be convenient to have a general n to 2n decoder that
could be described once but used for any application. We saw in the previous
chapter that generics can be used to pass parameters, such as delays, to VHDL
models. We can similarly use a generic to define the size of a structure.
library IEEE;
use IEEE.std_logic_1164.all;
entity decoder is
generic (n : POSITIVE);
port (a : in std_logic_vector(n-1 downto 0);
z : out std_logic_vector(2**n-1 downto 0));
end entity decoder;
We can also define constants:
constant z_out : std_logic_vector(2**n-1 downto 0) := (0 => '1', others => '0');
www.eej.ulst.ac.uk/~ian/modules/EEE515
22
VHDL shift operators
• sll, sla, rol, srl, sra, and ror
www.eej.ulst.ac.uk/~ian/modules/EEE515
23
VHDL’s strong typing
These operators are defined, by default, to shift a BIT_VECTOR by an
integer number of places. We will want to shift a std_logic_vector by a
number of places given by the integer interpretation of another
std_logic_vector. Therefore, it would be easier to declare z_out as a
BIT_VECTOR, to convert a to an INTEGER and to convert the final result to
a std_logic_vector.
This last conversion can be done by a function in the std_logic_1164
package. The other conversion function is not, however, provided. To do
this we need to use another package, numeric_std, that provides a set of
numeric operators for vectors of std_logic – but not std_logic_vectors!
Because vectors of bits can be interpreted to be either signed (two’s
complement) or unsigned integers, we need to distinguish the operations
performed on such vectors. Therefore the numeric_std package defines
two new types: signed and unsigned. VHDL’s strong typing means that
we cannot mix signed, unsigned and std_logic_vector by accident, but
because all three types consist of arrays of std_logic,
www.eej.ulst.ac.uk/~ian/modules/EEE515
24
we can explicitly convert from one to the other using statements of the
kind
x <= unsigned(y);
y <= std_logic_vector(x);
where x is of type unsigned and y is of type std_logic_vector. Although
these look like function calls, no such function has been defined. These are
known as type conversions (sometimes such a conversion is known as a
cast).
On the other hand, to convert from an unsigned to an INTEGER does
require a function call because the possible values (‘X’, ‘Z’, etc.) of the
std_logic type need to be interpreted.
The function to_integer is provided in numeric_std to achieve this.
To convert from an INTEGER to an unsigned type, the to_unsigned(i, n)
function should be used, where i is the integer and n is the number of bits
in the result.
www.eej.ulst.ac.uk/~ian/modules/EEE515
25
Complete Model for Generic decoder
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity decoder is
generic (n : POSITIVE);
port ( a : in std_logic_vector(n-1 downto 0);
z : out std_logic_vector(2**n-1 downto 0));
end entity decoder;
architecture rotate of decoder is
constant z_out : BIT_VECTOR(2**n-1 downto 0) := (0 => '1', others => '0');
begin
z <= to_StdLogicVector (z_out sll to_integer(unsigned(a)));
end architecture rotate;
www.eej.ulst.ac.uk/~ian/modules/EEE515
26
Multiplexers
library IEEE;
use IEEE.std_logic_1164.all;
entity mux is
port (a, b, c, d : in std_logic;
s: in std_logic_vector(1
downto 0);
end entity mux;
architecture mux1 of mux is
begin
with s select
y <= a when "00",
b when "01",
c when "10",
d when "11",
'X' when others;
end architecture mux1;
Can use either architecture,
or tristates to implement a
multiplexor
architecture mux2 of mux is
begin
y <= a when s = "00" else
b when s = "01" else
c when s = "10" else
d when s = "11" else
'X';
end architecture mux2;
www.eej.ulst.ac.uk/~ian/modules/EEE515
27
Using three-state logic to build a
multiplexer
library IEEE;
use IEEE.std_logic_1164.all;
entity mux is
port (a, b, c, d: in std_logic;
s: in std_logic_vector(1 downto 0);
y: out std_logic);
end entity mux;
architecture three_state of mux is
begin
y <= a when s = "00" else 'Z';
y <= b when s = "01" else 'Z';
y <= c when s = "10" else 'Z';
y <= d when s = "11" else 'Z';
end architecture three_state;
www.eej.ulst.ac.uk/~ian/modules/EEE515
28
Priority encoder
library IEEE;
use IEEE.std_logic_1164.all;
entity priority is
port (a: in std_logic_vector(3 downto 0);
y: out std_logic_vector(1 downto 0);
valid: out std_logic);
end entity priority;
architecture DontCare of priority is
begin
with a select
y <= "00" when "0001",
"01" when "001-",
"10" when "01--",
"11" when "1---",
"00" when others;
valid <= '1' when a(0) = '1' or a(1) = '1' or a(2) = '1'
or a(3) = '1' else '0';
end architecture DontCare;
www.eej.ulst.ac.uk/~ian/modules/EEE515
DOES NOT
WORK –
the don’t
know value
‘-’ is just
treated as a
specific
value
29
Note how to get at bits of a vector
architecture Ordered of priority is
begin
y <= "11" when a(3) = '1' else
"10" when a(2) = '1' else
"01" when a(1) = '1' else
"00" when a(0) = '1' else
"00";
valid <= '1' when a(0) = '1' or a(1) = '1' or a(2) = '1'
or a(3) = '1' else '0';
end architecture Ordered;
www.eej.ulst.ac.uk/~ian/modules/EEE515
30
The numeric_std package includes a function, std_match, that treats the
don’t care value as a real don’t care condition. We can’t use std_match in a
with . . . select statement because the choices must be constant. We can
write instead:
use IEEE.numeric_std.all; -- can out this here – only applies to this arch
architecture Match of priority is
begin
y <= "00" when std_match(a, "0001") else
"01" when std_match(a, "001-") else
"10" when std_match(a, "01--") else
"11" when std_match(a, "1---") else
"00";
valid <= '1' when a(0) = '1' or a(1) = '1' or a(2) = '1'
or a(3) = '1' else '0';
end architecture Match;
www.eej.ulst.ac.uk/~ian/modules/EEE515
31
Sequential VHDL
There are three styles of VHDL:
structural,
dataflow and
sequential.
All the examples in this chapter have used the dataflow
style. Dataflow statements are concurrent signal
assignment statements.
Structural VHDL consists of component instantiations.
Sequential VHDL resembles a conventional programming
language. Sequential VHDL statements can be used only in
subprograms (procedures and functions) or processes.
www.eej.ulst.ac.uk/~ian/modules/EEE515
32
Sequential VHDL
architecture Sequential of priority is
The process has a sensitivity list
begin
process (a) is
with one signal, a. The process is
begin
evaluated only when the signals
if a(3) = '1' then
in the sensitivity list change. Thus
y <= "11";
valid <= '1';
it is important that the sensitivity
elsif a(2) = '1' then
list includes all signals that might
y <= "10";
cause an output to change. In
valid <= '1';
elsif a(1) = '1' then
this case, a is a vector and the
y <= "01";
process is evaluated when any
valid <= '1';
bit of a changes.
elsif a(0) = '1' then
y <= "00";
valid <= '1';
the following rule should be observed: if
else
an assignment is made to a signal in one
y <= "00";
valid <= '0';
path through a process, an assignment
end if;
should be made to that signal in all paths.
end process;
33
end architecture Sequential; www.eej.ulst.ac.uk/~ian/modules/EEE515
Adders
library IEEE;
use IEEE.std_logic_1164.all, IEEE.numeric_std.all;
entity NBitAdder is
generic (n: NATURAL :=4);
port ( A, B: in std_logic_vector(n-1 downto 0);
Cin : in std_logic;
Sum : out std_logic_vector(n-1 downto 0);
Cout : out std_logic);
end entity NBitAdder;
www.eej.ulst.ac.uk/~ian/modules/EEE515
34
Addition
We can use the arithmetic operator, +, defined in numeric_std to
perform the adding operation.
This operator takes two vectors, of type signed or unsigned, and returns
a result of the same length as the longest operand.
The addition of two n-bit integers produces a result of length n 1,
where the most significant bit is the carry out bit.
Therefore within the VHDL description we must convert Cin from a
single bit to a vector of length n 1, convert A and B to vectors of length
n1 and separate the result into an n-bit sum and a carry out bit.
The code below performs these actions for unsigned addition.
www.eej.ulst.ac.uk/~ian/modules/EEE515
35
Conatenation
The ampersand, ‘&’, is the concatenation operator.
Thus '0' & unsigned(A) concatenates a single bit and an n-bit vector to give a
vector of length n +1.
So A and B are converted to type unsigned.
After addition of three n 1 bit vectors,
the lowest n bits of the result are converted back to a std_logic_vector and the
most significant bit is taken as the carry out.
www.eej.ulst.ac.uk/~ian/modules/EEE515
36
Adder for positive numbers
architecture unsgned of NBitAdder is
signal result : unsigned(n downto 0);
signal carry : unsigned(n downto 0);
constant zeros : unsigned(n-1 downto 0) := (others =>'0');
begin
carry <= (zeros & Cin);
result <= ('0' & unsigned(A)) + ('0' & unsigned(B)) + carry;
Sum <= std_logic_vector(result(n-1 downto 0));
Cout <= result(n);
end architecture unsgned;
www.eej.ulst.ac.uk/~ian/modules/EEE515
37
Adder for signed numbers
The major difference here is that the most significant bits of the A and B vectors
are used to extend those vectors to the left. If A or B is negative, its most
significant bit would be ‘1’ and this must be preserved.
architecture sgned of NBitAdder is
signal result : signed(n downto 0);
signal carry : signed(n downto 0);
constant zeros : signed(n-1 downto 0) := (others => '0');
begin
carry <= (zeros & Cin);
result <= (A(n-1) & signed(A)) + (B(n-1) & signed(B)) + carry;
Sum <= std_logic_vector(result(n-1 downto 0));
Cout <= result(n);
end architecture sgned;
www.eej.ulst.ac.uk/~ian/modules/EEE515
38
Ripple adder
library IEEE;
use IEEE.std_logic_1164.all;
This model contains two
assignments, to Sum and
Cout. Note that in VHDL,
entity FullAdder is
these two
port (a, b, Cin : in std_logic;
assignments are concurrent
Sum, Cout: out std_logic);
– it does not matter in which
end entity FullAdder;
order statements are written.
The simple rule to
architecture concurrent of FullAdder is
remember is that unless
begin
otherwise stated, all
Sum <= a xor b xor Cin;
Cout <= (a and b) or (a and Cin) or (b and Cin); statements in VHDL
are concurrent.
end architecture concurrent;
www.eej.ulst.ac.uk/~ian/modules/EEE515
39
Parity checker
library IEEE;
use IEEE.std_logic_1164.all;
entity parity is
port (a : in std_logic_vector;
y : out std_logic);
end entity parity;
architecture iterative of parity is
begin
process (a) is
variable even : std_logic;
begin
even := '0';
for i in a'RANGE loop
If a(i) = '1' then
even := not even;
end if;
end loop;
y <= even;
end process;
end architecture iterative
Note the loop structure here and the
use of attributes, put after an object
with a tick symbol. Various attributes
exist. Also the use of a variable:
A variable can only be declared inside
a process (a signal may not be
declared in a process) and an
assignment to a variable (denoted by
‘:=’) takes immediate effect. A signal
assignment does not take effect until
the process restarts.
www.eej.ulst.ac.uk/~ian/modules/EEE515
40
State machines in VHDL
Although state machines can be described using concurrent VHDL
constructs, the task is far easier using sequential VHDL. We have seen
that a VHDL process is evaluated when a signal in its sensitivity list
changes.
A process may alternatively contain one or more wait statements.
A process cannot have both a sensitivity list and wait statements. A sensitivity
list is equivalent to putting a wait statement with the signals listed at the end
of the process. A state machine changes state at a clock edge. Therefore, the
sensitivity list of a process modelling a state machine must include the clock,
or the clock must be included in a wait statement. A decision to change state
then has to be made on the appropriate clock edge.
The state of the system must be held in an internal variable. The state can be
represented by an enumerated type. The possible values of this type are the state
names, e.g.
type state_type is (G, R); -- e.g for traffic lights
www.eej.ulst.ac.uk/~ian/modules/EEE515
41
Traffic lights
If a car is detected on the minor road, the
signals change to red for the major road and
green for the minor road. When the lights
change, a timer is started. Once that timer
completes, a ‘TIMED’ signal is asserted,
which causes the lights to change back to
their default state.
library IEEE;
use IEEE.std_logic_1164.all;
entity traffic is
port (
clock, timed, car : in std_logic;
start_timer, major_green, minor_green : out std_logic);
end entity traffic;
www.eej.ulst.ac.uk/~ian/modules/EEE515
42
Traffic Light Problem
There are two graphical
design tools commonly used:
State diagrams (above) or
ASM charts as on the left
www.eej.ulst.ac.uk/~ian/modules/EEE515
43
process (clock) is
type state_type is (G, R);
variable state : state_type;
begin
start_timer <= '0';
wait until clock = '1'
case state is
when G =>
major_green <= '1';
minor_green <= '0';
if (car = '1') then
start_timer <= '1';
state := R;
end if;
when R =>
major_green <= '0';
minor_green <= '1';
if (timed = '1') then
state := G;
end if;
end case;
end process;
www.eej.ulst.ac.uk/~ian/modules/EEE515
44
Synthesis Tools
As most synthesis tools and the 1076.6 RTL Synthesis standard
expect there to be one edge-sensitive statement in a process, it is
not possible to correctly model state machines with Mealy outputs
using a single VHDL process.
A common modelling style for state machines therefore uses two
processes.
One process is used to model the state registers, while the second
process models the next state and output logic.
Communication between the
two processes is achieved using the present and next values of the
state registers.
www.eej.ulst.ac.uk/~ian/modules/EEE515
45
Classical two process FSM – USE this!!!
architecture asm2 of traffic is
type state_type is (G, R);
signal present_state, next_state : state_type;
begin
-- First of two processes…
seq:
process (clock) is
begin
if(rising_edge(clock)) then
present_state <= next_state;
end if;
end process seq;
www.eej.ulst.ac.uk/~ian/modules/EEE515
46
com: process (car, timed, present_state) is
begin
start_timer <= '0';
case present_state is
when G =>
major_green <= '1';
minor_green <= '0';
if (car = '1') then
start_timer <= '1'; -- note this is a Mealy machine.
next_state <= R;
else
next_state <= G;
end if;
when R =>
major_green <= '0';
minor_green <= '1';
if (timed = '1') then
next_state <= G;
else
next_state <= R;
end if;
end case;
end process com;
www.eej.ulst.ac.uk/~ian/modules/EEE515
end architecture asm2;
47
VHDL models of
sequential logic blocks
Latches
Flip-flops
JK and T flip-flops
Registers and shift registers
Counters
Memory
Sequential multiplier
Testbenches for sequential building blocks
www.eej.ulst.ac.uk/~ian/modules/EEE515
48