Converting a Finite State Machine to VHDL Dr. Philip Brisk Department of Computer Science and Engineering University of California, Riverside CS 223
Feb 24, 2016
Converting a Finite State Machine to VHDL
Dr. Philip BriskDepartment of Computer Science and Engineering
University of California, Riverside
CS 223
Entity
• Name of the system and I/O Interface
LIBRARY ieee;USE ieee.std_logic_1164.ALL;
ENTITY MainSystem ISPORT(
A_i: IN std_logic_vector(7 DOWNTO 0);B_o: OUT std_logic_vector(7 DOWNTO 0);clk_i: IN std_logic;rst_i: IN std_logic
);
END MainSystem;
Architecture
• Internal circuit of the entity
• The internal circuits of an entity
ARCHITECTURE beh OF MainSystem ISBEGIN
BlinkLed: PROCESS(clk_i)TYPE states IS (LedOff, LedOn);VARIABLE state : states :=
LedOff;VARIABLE B0_v : std_logic := ‘0’;
BEGIN…
END PROCESS;
END beh;
IF (clk_i=’1’ AND clk_i’EVENT) THENIF (rst_i=’1’) THEN
state := LedOff;B0_v := ‘0’;
ELSE -- SM case stmts go hereCASE state IS --
TransitionsWHEN
LedOff =>
state := LedOn;WHEN
LedOn =>
state := LedOff;WHEN
OTHERS =>
state := LedOff;END CASE;
CASE state IS -- Actions
WHEN LedOff =>
B0_v := ‘0’;WHEN
LedOn =>
B0_v := ‘1’;END CASE;
END IF;B_o(0) <= B0_v; -- update port signalEND IF;
PROCESS statement
PROCESS(clk_i)– The “process” executes every time there is an
event on clk_i
– Typically, this means that clk_i will be a clock, so the event is a rising/fall edge
– Details to come…
TYPE and VARIABLE statements
• TYPE states IS (LedOff, LedOn);– Two possible system states
• VARIABLE state : states := LedOff;– Creates an initializes a variable to maintain the current
state
• VARIABLE B0_v : std_logic := ‘0’;– Creates and initializes an intermediate value
Clock Events
IF (clk_i=’1’ AND clk_i’EVENT) THEN
– EVENT means a transition from 0 to 1 or 1 to 0– clk_i=’1’ means to take the action on the rising edge (0 to 1)– Can create complex circuits with different actions on
rising/falling edges• Careful with the timing…
– Can create asynchronous circuits by using logic to generate signals that are used for events, rather than connecting to a clock
Conditions
IF (rst_i=’1’) THENstate := LedOff;B0_v := ‘0’;
ELSE…
state
rst_i
BO_v
rst_i
LedOff
0
0
0
1
1
ELSE
More MuxesELSE -- SM case stmts go here
CASE state IS -- TransitionsWHEN LedOff =>
state := LedOn;WHEN LedOn =>
state := LedOff;WHEN OTHERS =>
state := LedOff;END CASE;
CASE state IS -- ActionsWHEN LedOff =>
B0_v := ‘0’;WHEN LedOn =>
B0_v := ‘1’;END CASE;
END IF;
state
rst_i
BO_v
rst_i
LedOff
0
0
0
1
1
state
LedOff
LedOn
Others
LedOn
LedOff
1
LedOff
LedOn
0
LedOff
Comments
-- This is a comment
Examples from the code…
ELSE -- SM case stmts go hereCASE state IS -- Transitions
Signals and Variables
• Ports are signals– Output ports cannot be read
• Variables hold values– e.g., output of a gate– A wire (bus) or flip-flop (register)
<= writes a signal:= writes a variable
Model vs. Architecture
Wires vs. RegistersELSE -- SM case stmts go here
CASE state IS -- TransitionsWHEN LedOff =>
state := LedOn;WHEN LedOn =>
state := LedOff;WHEN OTHERS =>
state := LedOff;END CASE;
CASE state IS -- ActionsWHEN LedOff =>
B0_v := ‘0’;WHEN LedOn =>
B0_v := ‘1’;END CASE;
END IF;
• The value of state must be stored so that it can be read by the next process execution
• B0_v is not read by the next process execution
How do we get a 500ms Clock Period?
• The FPGA will provide its own internal clock that you can use– You can’t speed it up, but you can slow it down. E.g.,
you don’t necessarily want your LED blinking at 400 MHz
Clock Divider
ARCHITECTURE beh OF MainSystem ISSIGNAL BLclk_s: std_logic;
BEGIN
BlinkLed: PROCESS(BLclk_s)...IF (BLclk_s=’1’ AND BLclk_s’EVENT)
THEN...
END PROCESS;
BlinkLedClk: PROCESS(clk_i) -- Suppose 1 MHzVARIABLE cnt: INTEGER := 0;
BEGIN-- 1 MHz means 1 microsecond(us)
per tick-- 500 ms * 1000us/ms = 500,000usIF (clk_i=’1’ AND clk_i’EVENT) THEN
IF (rst_i=’1’) THENcnt := 0;
ELSEcnt := cnt + 1;IF (cnt = 500000)
THENBLclk_s
<= ‘1’;cnt := 0;
ELSEBLclk_s
<= ‘0’;END IF;
END IF;END IF;
END PROCESS;
-- Note: above process is shorthand -- for 1-state synchSM
END beh;
Next Example: Uneven Blinking LEDs
ARCHITECTURE beh OF MainSystem ISSIGNAL BL2clk_s: std_logic;
BEGIN
BlinkingLed2: PROCESS(BL2clk_s)TYPE states IS (Init, LedOn, LedOff);VARIABLE state : states := Init;VARIABLE X_v : std_logic_vector(7 DOWNTO
0);VARIABLE B0_v : std_logic;
BEGINIF (BL2clk_s=’1’ AND BL2clk_s’EVENT) THEN
IF (rst_i=’1’) THENstate := Init;
ELSE…
END IF;B_o(0) <= B0_v;
END IF;END PROCESS;
CASE state IS -- TransitionsWHEN Init=>
state := LedOn;WHEN LedOn =>
IF (X_v < “00000011”) THENstate := LedOn;
ELSIF (NOT(X_v < “00000011”)) THENstate := LedOff;
END IF;WHEN LedOff => …WHEN OTHERS =>
state := Init;END CASE;CASE state IS -- Actions
WHEN Init =>X_v := “00000000”;B0_v := ‘0’;
WHEN LedOn =>X_v := X_v + “00000001”;B0_v := ‘1’;
...END CASE;
Uneven Blinking LEDs (VHDL)
Multiple SynchronousState Machines
ARCHITECTURE beh OF MainSystem ISSIGNAL BLclk_s, TLclk_s: std_logic;
BEGIN
BlinkLed: PROCESS(BLclk_s)...
END PROCESS;
BlinkLedClk: PROCESS(clk_i) -- gen 300 ms BLclk_s...
END PROCESS;
ThreeLeds: PROCESS(TLclk_s)...
END PROCESS;
ThreeLedsClk: PROCESS(clk_i) -- gen 200 ms TLclk_s...
END PROCESS;
END beh;
BlinkLED Period = 300ms
ThreeLEDs Period = 200ms
Shared Variable Communication
IlluminateLampClk: PROCESS(clk_i) --gen 200 ms ILclk_s...
END PROCESS;
END beh;
ARCHITECTURE beh OF MainSystem ISSIGNAL DMclk_s, ILclk_s: std_logic;SHARED VARIABLE mtn_sv: std_logic;
BEGIN
DetectMotion: PROCESS(DMclk_s)...mtn_sv := ‘1’;...
END PROCESS;
DetectMotionClk: PROCESS(clk_i) --gen 200 ms DMclk_s...
END PROCESS;
IlluminateLamp: PROCESS(TLclk_s)...IF (mtn_sv = ‘1’) THEN...
END PROCESS;
Shared Variable Communication
(VHDL)