You are on page 1of 58

FPGA Design

Part IV - State Machines & Sequential VHDL

Thomas Lenzi
Objective

• We learned how to use an FPGA to code


combinatorial logic in VHDL.

• We will now focus on sequential logic and learn


how to implement complexer functions in VHDL.

• But first we will have a look at state machines which


are useful to control systems.

2
State Machines
State Machines
• A state machine is a construction in which a system
is described by states in which it can be.

• In every state, the actions taken are clearly defined


and solely depend on the state of the machine.

• The machine can go from one state to another


using clearly defined conditions.

• The transition between state cannot influence the


actions of the machine.
4
Diagrams
• State machines can be illustrated using diagrams.

Otherwise Otherwise

When button A is pushed


State 1 State 2
Wh
en
butto
ns A
and When button B
Always Ba
re p is pushed
ush
ed

Always
State 4 State 3

5
Exercise

• Draw the diagram of a fruit vending machine that


only accepts 1€ and 0.50€ and returns money if the
user gave too much.

6
Solution

Less than 2€
Exactly 2€

Nothing happens
Inserted 1€ More than 2€
Gave 1€
Waiting for money Give fruit
Gave 0.50€
Inserted 0.50€ More than 2€

Less than 2€
More than 2€
Always
Give money back

7
Processes
Processes
• In order to code sequential statements in
VHDL, you need to use processes.

• Statements in a process will not be executed


sequentially, they will simply be interpreted that
way and translated into appropriate logic by the
synthesiser (do not compare this to C code).

• Processes take a sensitivity list as parameter.


Every time one of the signals in the list
changes, the process is fired.

9
Variables & Signals I
• When using processes, you can create
variables at the beginning of the
process.

• The difference between signals and


variables is that signals are
concurrently assigned, while variables
are sequentially assigned.

• The value of the variable is saved


between the various times the process
is fired.

10
Variables & Signals II
• In this example, the process will fire
every time the clock changes, but the
IF statement requires it to be high.

• The variable is first set to ‘0’ and then


inverted. Therefore, the output will
always be ‘1’.

• The signal is first set to ‘0’, but this


instruction is overwritten by the
following one. The signal will thus
oscillate.

11
Variables & Signals III

12
Propagation delays and
variables
• You must use variables with care as they will
produce cascading logic.

• When running at low speed, the delay induced by


this logic is not significant compared to the clock
speed. But when using higher clock speed, you
must ensure that the delay is less than the clock
period.

13
Sequential Statements
If / elsif / else

• The if / elsif / else


statements have a
similar use as in C.

• When encoding
conditions, be sure to
cover all possible cases!

15
Case
• The case statement has a
similar use as in C.

• Each possibility can hold


multiple sequential
statements.

• When encoding conditions,


be sure to cover all possible
cases!

16
For & While

• Processes can use For and While


loops to duplicate logic, similarly to
the For Generate statements.

• Not every piece of code using For


and While statements can be
translated to logic. ISE will issue an
error when this happens.

17
Using the Clock
• To use the clock as timer, you have to
make use of the rising_edge function.
It will ensure that the process is fired
when the clock changes from low to
high.

• Using this function in designs will


result in the use of DFFs to buffer
values.

• This is the proper way to code state


machines.

18
Exercise

• Design a fruit vending machine that only accepts


1€ and 0.50€ (represented by two buttons) and
returns money if the user gave too much. Fruits
cost 2€.

19
Solution

20
Packages
Packages
• Next to regular VHDL entities, you can also create
Packages.

• Packages hold functions, procedures, custom data


types, constants, etc. They are toolboxes that
contain helping tools.

• To create a VHDL package, add a new file and


select “VHDL Package”.

22
Package Structure
• Packages are decomposed in two
parts: header and body.

• The header contains the custom data


types, constants, and the functions
and procedures headers.

• The body contains the logic of the


functions and procedures.

23
Types and Constants
• In VHDL, you can create new types:

• subtype is simply an alias to an


existing type;

• record is similar to a struct in C and


holds multiple signals;

• array defines an array of elements of


a given type;

• enumerate defines a list of values a


signal can hold.

• You can also define constants that can


be used in your design.

24
Functions

• All the parameters of a function are


inputs.

• A function can only return one


value.

• Statements in a function are


sequential.

25
Procedures

• Procedures apply logic to signals.

• The parameters of a procedure can


be in/out signal/constants/
variables.

26
Using Packages
• To use your package
you need to include if
using the use statement.

• Types can then be used


for signals.

• Functions and
procedures can then be
called.

27
Back to State
Machines
A Better State Machine

• To allow for better optimisation and clarity, the state


machine should respect the following rules:

• The code that dictates the transitions between


states and the code that acts depending on the
state the machine is in should be separate.

• The state variable should be an enumerate type.

29
Solution
State transitions State actions

30
Simulations
Test Benches
• Test Benches are VHDL entities that drive signals
into a Unit Under Test (UUT).

• They simulate components that are not in the FPGA


or that are not yet implemented (clocks,
communication protocols, …).

• Test benches can only be used in simulation and


cannot be synthesised.

32
Create a Test Bench
• Go to “Project > New Source…”

• Select “VHDL Test Bench” and give it a name with a .vhd extension, then click
“Next”

• On the next window, select the file for which you want to create a test bench
and click “Next” and then “Finish”

33
ISE Simulation Environment
• To use the test bench, you need to
switch to the simulation environment
by selecting the Simulation view.

• In this environment, you will see that


a new file is present and that it
includes the entity you previously
selected.

• The tools on the bottom of the


screen also changed.
34
Structure of a Test Bench
• The logic inside a test bench uses the
statements we previously reviewed, but it
adds the possibility to use the wait for
statement to wait for a given amount of
time.

• In this example, the clock will be generated


by the clk_i_process process which
changes the value of the clock every 5 ns.

• Test benches recognise clock signals when


their name start with clk and automatically
create a process to generate them.

35
Code to Analyse

• The previous test bench will be


used to analyse the following
code.

36
Generating Signals
• To analyse our logic, we will use the following
code:

• reset_i will be held high during 100 ns and then


put low;

• a_i will then go high for 6 ns;

• b_i will be high for 6 ns;

• both a_i and b_i are put back low.

• The final wait statement without a specific duration


insures that the process will never be ran again.

37
Running the Simulation

• To run the simulation, select the test bench in the


top left menu, and double-click on “Simulate
Behavioural Model”.

• A new window appears from the ISim program.

• ISim plots the input and output signals of the top


level.

38
Simulation Result

• Using the controls to zoom out, you can observe


the results of the simulation.

• As expected, c_o is high only when both a_i and


b_i are high at the rising edge of clk_i.

39
Exercise

• Re-write the code of a the vending machine using


types and create a test bench for it.

40
Best Practice VHDL
Common
• The file’s name is the entity’s name

• Use test benches whenever possible

• Use named signal mapping for entities

• When using case, when, … cover all the possible


conditions

• Use constants when possible

• Avoid variables and use signals


42
IOs

• Only use IN and OUT modes

• Add sufixes _i or _o to inputs and outputs

• Only use std_logic, std_logic_vector, or (un)signed


signals or records using them as IOs

43
Vectors

• Vectors always start at 0

• Vectors are always going downwards

44
Clocks and Resets
• Use synchronous resets

• Resets are active high

• Initialise all the signals at reset

• Use the rising edge of the clock

• Synchronous processes only have the clock in their


sensitivity list

45
Communication
Protocols
UART
• The Universal Asynchronous Receiver/Transmitter (UART)
is a protocol that uses two wires: one to receive and one to
transmit data.

• The clock is not transmitted thus both parties must agree


on the sampling frequency of the signal (9600 Hz is the
most common).

47
I2C
• In I2C, a master controls multiple slave by addressing them.

• The master and slaves use the same data line (sda) to
transmit information that is synchronised to a clock line (sck).

• When a module is not using the lines to transmit data, they


should pull it to high impedance in order to avoid shorts.

48
SPI
• SPI uses a Chip Select SS# bus
to allow the master to select the
slave it wishes to address.

• The master sends the clock


SCLK and data MOSI (Master
Out Slave In) to the slaves which
respond using a separate wire
MISO (Master In Slave Out).

49
Exercise
Using the 7-segments
display
Exercise

• Develop a VHDL entity that will control the 7-


segment display.

• It should take four 4-bit busses as input and


represent their hexadecimal value on the four digits
of the display.
7-segments Display
• We want to control the
7-segments display and
be able to display
hexadecimal characters
on it.

• The only thing the user


has to do is set 4 buses
(one per digit) which
hold the values he
wants to display.
52
Questions
What IOs do we need to add to our design?

Is this a sequential or combinatorial design?

What inputs drive the design?

Do we need a state machine? If so, what are


the states?

53
Step 1: IOs
• clk_50MHz_i : input clock

• reset_i : input reset

• x0_i, x1_i, x2_i, x3_i : values to print


on the segments

• seg_o : output data that will be sent


to the display

• dp_o : status of the point LED

• an_o : select the active segment

54
Step 2: Clock

• Divide the input clock


from 50 MHz to 1 kHz.

• Using a counter, we
generate a 1 kHz “clock”.

55
Step 3: States

• We will use 4 states, one for


each active anode.

• The transition between states


will be done every 1 ms.

56
Step 4 : Data Translation
• The 7-segments
display uses a data
bus of 7 bits while
the user uses 4 bits
representing a
number.

• We have to convert
the number to the
display.

57
Step 5 : Data Signalling

• Finally we need to transfer the


data to the display.

58

You might also like