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