Transcript L3_VHDL
EEE515 VHDL
Notes from “Digital System Design with VHDL” Mark Zwolinski, Pearson/Prentice Hall, 2 nd See also “The Student’s Guide to VHDL” Peter Ashenden, 2 nd Edition edition Morgan Kaufman (under £20)
Ian McCrum Room 5B16 Tel: 90 366364 voice mail on 6 th ring Email: [email protected]
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, 2 nd 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
BIT is a predefined type with two values: ‘0’ and ‘1’.
port
(x, y :
in
BIT; z:
out
BIT);
end entity
And2;
architecture
ex1
of
And2
is begin
We can also use inout or buffer or omit the in keyword z <= x
and
y;
end architecture
ex1; 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; 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 ; 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; 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);
begin
end component Not1; signal p, q, r : BIT; 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
want 0); -- could use
to
if you z :
out
std_logic_vector(3
downto end entity
decoder; 0));
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; 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.
www.eej.ulst.ac.uk/~ian/modules/EEE515 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
z :
out
std_logic_vector(6
downto
0); 0));
end entity
seven_seg;
architecture
with_select
begin of
seven_seg
is 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 in the result.
to_unsigned(i, n)
function should be used, where i is the integer and n is the number of bits 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 end architecture
rotate; to_integer(unsigned(a))); www.eej.ulst.ac.uk/~ian/modules/EEE515 26
library IEEE; use IEEE.std_logic_1164.all;
Multiplexers
entity mux is port (a, b, c, d : in std_logic; s: in std_logic_vector(1 downto 0); end entity mux; Can use either architecture, or tristates to implement a multiplexor 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; 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
;
DOES NOT
entity
priority
is port
(a:
in
std_logic_vector(3
downto
y:
out
std_logic_vector(1
downto
0); 0); valid:
out
std_logic);
end entity
priority;
WORK – the don’t
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
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
begin
process (a) is
begin
if a(3) = '1' then y <= "11"; valid <= '1'; elsif a(2) = '1' then y <= "10"; valid <= '1'; elsif a(1) = '1' then y <= "01"; valid <= '1'; elsif a(0) = '1' then y <= "00"; valid <= '1';
else
y <= "00"; valid <= '0';
end if; end process;
end architecture Sequential; The process has a sensitivity list with one signal, a. The process is evaluated only when the signals in the sensitivity list change. Thus it is important that the sensitivity list includes all signals that might cause an output to change. In this case, a is a vector and the process is evaluated when any bit of a changes.
the following rule should be observed:
an assignment is made to a signal in one path through a process, an assignment
should be made to that signal in all paths.
www.eej.ulst.ac.uk/~ian/modules/EEE515
if
33
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
where the most significant bit is the carry out bit. 1, 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
n
1 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; entity FullAdder is port (a, b, Cin : in std_logic; Sum, Cout: out std_logic); end entity FullAdder; architecture concurrent of FullAdder is
begin
Sum <= a xor b xor Cin; Cout <= (a and b) or (a and Cin) or (b and Cin); end architecture concurrent; This model contains two assignments, to Sum and Cout. Note that in VHDL, these two assignments are
concurrent
– it does not matter in which order statements are written.
The simple rule to remember is that unless otherwise stated, all statements in VHDL are concurrent.
www.eej.ulst.ac.uk/~ian/modules/EEE515 39
library
IEEE;
use
IEEE.std_logic_1164.
all
;
Parity checker
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
If
a(i) = '1'
then loop
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 => end case; end process; major_green <= '1'; minor_green <= '0';
if
(car = '1')
then
start_timer <= '1'; state := R; when R =>
end if
; major_green <= '0'; minor_green <= '1'; if (timed = '1') then state := G; end if; 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))
end if
;
then
present_state <= next_state;
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; when R => end if; major_green <= '0'; minor_green <= '1'; if (timed = '1') then next_state <= G;
else
next_state <= R; end if; end case; end process com; end architecture asm2; www.eej.ulst.ac.uk/~ian/modules/EEE515 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