You are on page 1of 30

Finite State Machines

Introduction

• All programmable logic designs can be


specified in Boolean form. However some
designs are easier to conceptualize and
implement using non-Boolean models. The
State Machine model is one such model.
Simple Example: State Transition
Diagram
• FSM that Recognizes Sequence 10
0/0 1/0 1/0

S0 S1

reset 0/1
S0: No S1: “1”
Meaning elements observed
of states: of the
sequence
observed
Pseudo Code
always @ (posedge clk)
if (rst) cst <= s0;
else cst <= nst;

always @ *
case(cst)
so: if(inp == 1) { nst <= s1;}
out <= 0;
s1: if(inp == 0) {nst <= s0; out <= 1}
else out <= 0;
endcase
FSM Consists of….
• State Space: so,s1
• Inputs: Inp
• Output: out
• Next State Function:
case(cst)
so: if(inp == 1) { nst <= s1;}
s1: if(inp == 0) {nst <= s0;}

• Output Function:
case(cst)
so: out <= 0;
s1: out = !inp

• Reset State: so
• An FSM is defined in terms of:
1. S : Finite State Space
2. I : Input vectors
3. O : Output vectors
4. T : Transition function
5. F : Output Function

reset

current_state

Next next_state State Output outputs


State
Register Function
Function
inputs

clk
Definition of a State Machine
• A state machine represents a system as a
set of states, the transitions between
them, along with the associated inputs and
outputs.
• An FSM is a discrete dynamic system that
translates sequences of input vectors into
sequences of output vectors
Definition of a State Machine
(Contd.)
• So, a state machine is a particular
conceptualization of a particular sequential
circuit. State machines can be used for
many other things beyond logic design
and computer architecture.
• FSMs form the core sequential units of a
hardware design
Finite State Machines
• Any Circuit with Memory Is a Finite State
Machine
– Even computers can be viewed as huge FSMs
• Design of FSMs Involves
– Defining states
– Defining transitions between states
– Optimization / minimization:
• Advanced EDA tools do this automatically. We’ll touch upon
some important optimizations and transformations in this
training
Implicit State Machines
-- Explicit FSM -- --Implicit FSM--

always @ clk always @ clk


case(cst) {
so: out <= in1;
out <= in1; always @ clk
cst <= s1; {
s1: out <= in2;
out <= in2; }
cst <= s0; }
endcase
• This points to a very interesting fact that
-- State variables are internal to state
machines and they are required only for
easy description and visualization

reset

current_state

Next next_state State Output outputs


State
Register Function
Function
inputs

clk
Example: FSM using enum variable
Choosing Sequential Encoding to
Original Design represent enum literals

State: enum (START = “00”, MIDDLE=“01”,


State: enum (START,MIDDLE,STOP); STOP=“10”);
CMB: process (A,B,STATE) begin CMB: process (A,B,STATE) begin
     
        case STATE is         case STATE is
          when START =>           when “00” =>
if (A or B)=`0` then if (A or B)=`0` then
                     NEXTSTATE <= MIDDLE ;                      NEXTSTATE <= “01” ;
out <= in1; out <= in1;
                    end if ;                     end if ;
          when MIDDLE =>           when “01” =>
if (A and B)=`1` then if (A and B)=`1` then
                        NEXTSTATE <= STOP ;                         NEXTSTATE <= “10”;
out <= in2; out <= in2;
                  end if ;                   end if ;
          when STOP =>           when “10” => `
if (A xor B)=`1` then if (A xor B)=`1` then
                        NEXTSTATE <= START ;                         NEXTSTATE <= “00” ;
out <= in3; out <= in3;
                  end if ;                   end if ;
          when others =>           when others =>
NEXTSTATE <= START ; NEXTSTATE <= “00” ;
  end case ;       end case ;    
end process CMB ; end process CMB ;
One-Hot Encoding
Choosing One-Hot Encoding to
Original Design represent enum literals

State: enum (START = “001”, MIDDLE=“010”,


State: enum (START,MIDDLE,STOP); STOP=“100”);
CMB: process (A,B,STATE) begin CMB: process (A,B,STATE) begin
     
        case STATE is         case STATE is
          when START =>           when “001” =>
if (A or B)=`0` then if (A or B)=`0` then
                     NEXTSTATE <= MIDDLE ;                      NEXTSTATE <= “010” ;
out <= in1; out <= in1;
                    end if ;                     end if ;
          when MIDDLE =>           when “010” =>
if (A and B)=`1` then if (A and B)=`1` then
                        NEXTSTATE <= STOP ;                         NEXTSTATE <= “100”;
out <= in2; out <= in2;
                  end if ;                   end if ;
          when STOP =>           when “100” => `
if (A xor B)=`1` then if (A xor B)=`1` then
                        NEXTSTATE <= START ;                         NEXTSTATE <= “001” ;
out <= in3; out <= in3;
                  end if ;                   end if ;
  end case ;       end case ;    
end process CMB ; end process CMB ;
Optimal Representation One-Hot
Encoding

State: enum (START = “001”, MIDDLE=“010”, State: enum (START = “001”, MIDDLE=“010”,
STOP=“100”); STOP=“100”);

CMB: process (A,B,STATE) begin CMB: process (A,B,STATE) begin


     
        case STATE is         case STATE is
          when “001” =>           when “xx1” =>
if (A or B)=`0` then if (A or B)=`0` then
                     NEXTSTATE <= “010” ;                      NEXTSTATE <= “010” ;
out <= in1; out <= in1;
                    end if ;                     end if ;
          when “010” =>           when “x1x” =>
if (A and B)=`1` then if (A and B)=`1` then
                        NEXTSTATE <= “100”;                         NEXTSTATE <= “100”;
out <= in2; out <= in2;
                  end if ;                   end if ;
          when “100” => `           when “1xx” => `
if (A xor B)=`1` then if (A xor B)=`1` then
                        NEXTSTATE <= “001” ;                         NEXTSTATE <= “001” ;
out <= in3; out <= in3;
                  end if ;                   end if ;
  end case ;       end case ;    

end process CMB ; end process CMB ;


`define IDLE==“000”, WAIT==“001”, EVEN=“010”, ODD=“011”, PAD=“100”

//Combinational block for Transition and Output Functions


always @(state) begin
// Synchronous block for register
next_out_err = out_err; inference
next_state = state; always @(posedge clk)
case (state) if (reset) begin
IDLE: next_out_err = ls;
if (horz_init) next_state = WAIT;
state <= IDLE;
WAIT: next_out_err = ws; out_err <= 1'b0;
if(in_data_valid) next_state = EVEN; end else begin
EVEN: if (horz_init)begin state <= next_state;
next_out_err = hs;
next_state = WAIT;
out_err <= next_out_err;
end end
else if (hs_valid)
if (eol) next_state = PAD; state
else next_state = ODD;
ODD: if (horz_init) begin
next_out_err = 1'b0; reset
next_o
next_state = WAIT; Next ut_err
next_state State Output
end State
else if (hs_valid) inputs Register Function
Function
if (eol) next_state = IDLE; clk
else next_state = EVEN;
PAD: if (horz_init) next_out_err = 1'b1;
else next_state = IDLE; Inputs: horz_init, in_data_valid, eol, hs_valid, ls, ws, hs
default: next_state = IDLE;
endcase
end
Sequential to One-Hot encoding state

Sequential
reset State IDLE One-Hot

State== State==
PAD
State Encoding Next next_state
Register
N
Table inputs
State
State[2:0]
Functionlog N log N
2 2 State[4:0]
clk bit wide Output
State Original One-Hot
Literal Literal
State[2:0]==IDLE State[0]==1
Output Function
IDLE 000 00001 Sequentially Enumerated FSM
WAIT 001 00010 N: Number of States
state
EVEN 010 00100
reset State
Register
N
ODD 011 01000 Next next_state
State
PAD 100 10000 inputs Function N N Output
clk bit wide
Output
Function
One-Hot Encoded FSM
One-Hot Encoding Contd.
• Result in reduced combinational area and
increased sequential logic.
• Good for large state machines.
• Other common encoding styles:
– Gray
– One-cold
– Two-Hot
FSM Re-encoding Heuristics
• Re-encoding may not always improve results
• Example:
– 64 states
– Sequentially encoded
– 6 bit wide state vector
– State space: {6’d0,6’d1, .... , 6’d63}

• Decisions should be based on cost calculation

Sequential current_state > 31 => current_state[6]

One-Hot current_state > 31 => current_state[32] || current_state[33] || … || current_state[63]


Default Expansion
Original Design

State: enum (START,MIDDLE,STOP,STUCK); State: enum (START,MIDDLE,STOP,STUCK);

CMB: process (A,B,STATE) begin CMB: process (A,B,STATE) begin


     
        case STATE is         case STATE is
          when START =>           when START =>
if (A or B)=`0` then if (A or B)=`0` then
                     NEXTSTATE <= MIDDLE ;                      NEXTSTATE <= MIDDLE ;
out <= in1; out <= in1;
                    end if ;                     end if ;
          when MIDDLE =>           when MIDDLE =>
if (A and B)=`1` then if (A and B)=`1` then
                        NEXTSTATE <= STOP ;                         NEXTSTATE <= STOP ;
out <= in2; out <= in2;
                  end if ;                   end if ;
          when STOP =>           when STOP =>
if (A xor B)=`1` then if (A xor B)=`1` then
                        NEXTSTATE <= START ;                         NEXTSTATE <= START ;
out <= in3; out <= in3;
                  end if ;                   end if ;
          when others =>           when STUCK =>
NEXTSTATE <= START ; NEXTSTATE <= START ;
  end case ;       end case ;    

end process CMB ; end process CMB ;


Unreachable State
Removing Unreachable State(s)

State: enum (START,MIDDLE,STOP,STUCK); State: enum (START,MIDDLE,STOP,STUCK);

CMB: process (A,B,STATE) begin CMB: process (A,B,STATE) begin


     
        case STATE is         case STATE is
          when START =>           when START =>
if (A or B)=`0` then if (A or B)=`0` then
                     NEXTSTATE <= MIDDLE ;                      NEXTSTATE <= MIDDLE ;
out <= in1; out <= in1;
                    end if ;                     end if ;
          when MIDDLE =>           when MIDDLE =>
if (A and B)=`1` then if (A and B)=`1` then
                        NEXTSTATE <= STOP ;                         NEXTSTATE <= STOP ;
out <= in2; out <= in2;
                  end if ;                   end if ;
          when STOP =>           when STOP =>
if (A xor B)=`1` then if (A xor B)=`1` then
                        NEXTSTATE <= START ;                         NEXTSTATE <= START ;
out <= in3; out <= in3;
                  end if ;                   end if ;
          when STUCK =>  end case ;    
NEXTSTATE <= START ;
  end case ;    
end process CMB ;
end process CMB ;
Pruning Unreachable States: Example
process(RSTB,CLK,A,B)
begin Unreachable
Assignment process(RSTB,CLK,A,B)
if(RSTB = '0') then
begin
C_STATE <= STATE1;
if(RSTB = '0') then
elsif(CLK'event and CLK = '1') then
C_STATE <= STATE1;
case C_STATE is
Unreachable when STATE1 => C <= A; C_STATE <= STATE4; elsif(CLK'event and CLK = '1') then
State case C_STATE is
when STATE4 => C <= B; C_STATE <= STATE5;
when STATE1 => C <= A; C_STATE <= STATE2;
when STATE3 => C <= B; C_STATE <= STATE6;
when STATE4 => C <= B; C_STATE <= STATE5;
when STATE2 => C <= B; C_STATE <= STATE4;
when STATE5 => C <= B; C_STATE <= STATE1;
when STATE5 => C <= B; C_STATE <= STATE1;
end case;
when STATE7 => C <= B; C_STATE <= STATE1;
end if;
when STATE6 => C <= B; C_STATE <= STATE1;
end process;
when others => C <= A; C_STATE <= STATE1;
end case;
end if;
end process;
State REACHABILITY STATE Reachable
STATE1 Starting State

STATE2 NIL X
STATE3 NIL X
STATE4 STATE1, STATE2
STATE5 STATE4
STATE6 STATE3 X
STATE7 NIL X
Missing Choices Optimization
Removing Unreachable State(s)

State: enum (START = “00”, MIDDLE=“01”, State: enum (START = “00”, MIDDLE=“01”,
STOP=“10”); STOP=“10”);

CMB: process (A,B,STATE) begin CMB: process (A,B,STATE) begin


     
        case STATE is         case STATE is
          when “00” =>           when “00” =>
if (A or B)=`0` then if (A or B)=`0` then
                     NEXTSTATE <= “01” ;                      NEXTSTATE <= “01” ;
out <= in1; out <= in1;
                    end if ;                     end if ;
          when “01” =>           when “x1” =>
if (A and B)=`1` then if (A and B)=`1` then
                        NEXTSTATE <= “10”;                         NEXTSTATE <= “10”;
out <= in2; out <= in2;
                  end if ;                   end if ;
          when “10” => `           when “1x” => `
if (A xor B)=`1` then if (A xor B)=`1` then
                        NEXTSTATE <= “00” ;                         NEXTSTATE <= “00” ;
out <= in3; out <= in3;
                  end if ;                   end if ;
  end case ;       end case ;    

end process CMB ; end process CMB ;


SAFE FSMs
• Most applications require an FSM to be minimal and free
from unreachable states for best Results. However,
there are occasions where the circuit may go into a state
other than that described in the design, such as in harsh
operating environments in aerospace or military
applications, where high levels of alpha particle radiation
may cause registers to change to an invalid state.
Recovery from invalid states may be impossible if the
associated transition logic had been optimized away.
• Such applications demand “safe” FSMs implemented
such that the generated logic has a defined behaviour for
each possible value of the state variable, irrespective of
its reachability (unreachable states are therefore never
pruned).
Safe FSM: User Specified Recovery Logic
Default = STATE != START &&
STATE!= MIDDLE && Default = STATE==STUCK
STATE!=STOP

State: enum (START,MIDDLE,STOP,STUCK); State: enum (START,MIDDLE,STOP,STUCK);

CMB: process (A,B,STATE) begin CMB: process (A,B,STATE) begin


     
        case STATE is         case STATE is
          when START =>           when START =>
if (A or B)=`0` then if (A or B)=`0` then
                     NEXTSTATE <= MIDDLE ;                      NEXTSTATE <= MIDDLE ;
out <= in1; out <= in1;
                    end if ;                     end if ;
          when MIDDLE =>           when MIDDLE =>
if (A and B)=`1` then if (A and B)=`1` then
                        NEXTSTATE <= STOP ;                         NEXTSTATE <= STOP ;
out <= in2; out <= in2;
                  end if ;                   end if ;
          when STOP =>           when STOP =>
if (A xor B)=`1` then if (A xor B)=`1` then
                        NEXTSTATE <= START ;                         NEXTSTATE <= START ;
out <= in3; out <= in3;
                  end if ;                   end if ;
          when Default =>           when STUCK =>
NEXTSTATE <= START ; NEXTSTATE <= START ;
  end case ;      end case ;    

end process CMB ; end process CMB ;


Safe FSM: Binary/One-Hot
State: enum
(START,MIDDLE,STOP,STUCK);
Sequential Enc: SAFE One-Hot Enc: UNSAFE
CMB: process (A,B,STATE) begin
  
        case STATE is State: enum State: enum
    when START => (START,MIDDLE,STOP,STUCK); (START,MIDDLE,STOP,STUCK);
if (A or B)=`0` then
               NEXTSTATE <=
CMB: process (A,B,STATE) begin CMB: process (A,B,STATE) begin
MIDDLE ;      
out <= in1;         case STATE is         case STATE is
              end if ;     when 00 =>    when xxx1 =>
    when MIDDLE => if (A or B)=`0` then if (A or B)=`0` then
if (A and B)=`1` then                NEXTSTATE <= 01;                NEXTSTATE <= 0010;
                  NEXTSTATE <= out <= in1; out <= in1;
STOP ;               end if ;               end if ;
out <= in2;      when 01 =>    when xx1x =>
            end if ; if (A and B)=`1` then if (A and B)=`1` then
    when STOP =>                   NEXTSTATE <= 10;                   NEXTSTATE <= 0100;
if (A xor B)=`1` then out <= in2; out <= in2;
                  NEXTSTATE <=             end if ;             end if ;
    when 10 =>     when x1xx =>
START ; if (A xor B)=`1` then
out <= in3; if (A xor B)=`1` then                   NEXTSTATE <= 0001;
            end if ;                   NEXTSTATE <= 00
out <= in3;
    when STUCK => out <= in3;             end if ;
NEXTSTATE <=             end if ;     when 1xxx =>
    when 11 =>
START ; NEXTSTATE <= 0001;
NEXTSTATE <= 00
 end case ;      end case ;    
 end case ;    
end process CMB ; end process CMB ;
end process CMB ;
Safe FSM
Making case “FULL”

State: enum (START = “00”, MIDDLE=“01”, State: enum (START = “00”, MIDDLE=“01”,
STOP=“10”); STOP=“10”);

CMB: process (A,B,STATE) begin CMB: process (A,B,STATE) begin


     
        case STATE is         case STATE is
          when “00” =>           when “00” =>
if (A or B)=`0` then if (A or B)=`0` then
                     NEXTSTATE <= “01” ;                      NEXTSTATE <= “01” ;
out <= in1; out <= in1;
                    end if ;                     end if ;
          when “01” =>           when “x1” =>
if (A and B)=`1` then if (A and B)=`1` then
                        NEXTSTATE <= “10”;                         NEXTSTATE <= “10”;
out <= in2; out <= in2;
                  end if ;                   end if ;
          when “10” => `           when “10” => `
if (A xor B)=`1` then if (A xor B)=`1` then
                        NEXTSTATE <= “00” ;                         NEXTSTATE <= “00” ;
out <= in3; out <= in3;
                  end if ;                   end if ;
  end case ;       end case ;    

end process CMB ; end process CMB ;


Safe FSMs
process(RSTB,CLK,A,B) process(RSTB,CLK,A,B)
begin begin
if(RSTB = '0') then process(RSTB,CLK,A,B) if(RSTB = '0') then
C_STATE <= STATE1; begin C_STATE <= STATE1;
elsif(CLK'event and CLK = '1') if(RSTB = '0') then elsif(CLK'event and CLK = '1')
then C_STATE <= 5’b00001; then
case C_STATE is elsif(CLK'event and CLK = '1') case C_STATE is
when 3’b000 => C <= A; then when 3’b000 => C <= A;
C_STATE <= 3’b001; casex C_STATE is C_STATE <= 3’b001;
when 3’b001 => C <= B; when 5’bxxxx1 => C <= A; when 3’b001 => C <= B;
C_STATE <= 3’b010; C_STATE <= 5’b00001; C_STATE <= 3’b010;
when 3’b010=> C <= B; when 5’bxxx1x => C <= B; when 3’b010=> C <= B;
C_STATE <= 3’b101; C_STATE <= 5’b00010; C_STATE <= 3’b101;
when 3’b011=> C <= B; when 5’bxx1xx=> C <= B; when 3’bx11=> C <= B;
C_STATE <= 3’b010; C_STATE <= 5’b00100; C_STATE <= 3’b010;
when 3’b100 => C <= B; when 5’bx1xxx => C <= B; when 3’b100 => C <= B;
C_STATE <=3’b000; C_STATE <= 5’b01000; C_STATE <=3’b000;
when 3’b101=> C <= B; when 5’b1xxxx=> C <= B; when 3’b101=> C <= B;
C_STATE <= 3’b110; C_STATE <= 5’b10000; C_STATE <= 3’b110;
when 3’b110 => C <= B; end case; when 3’b110 => C <= B;
C_STATE <=3’b000; end end if; C_STATE <=3’b000;
case; end process; end case;
end if; end if;
end process; end process;

Original FSM Normal Implementation SAFE Implementation


FSM in ROM
• Improved resource utilization
• Faster FSMs
state

reset reset
Next
next_state State Output Output
State
inputs Function Register Function Register outputs
clk clk

state

A
D
D
A
inputs D
T
R
A outputs

clk
ROM
reset
FSM in ROM: Example
• Block RAMs are used to implement ROMs

state

ADDR[8:5] DO[7:4]
• 16 states
inputs
ADDR[4:0]
• 4 outputs
Tied to GND

Tied to GND
WE
DO[3:0]
outputs
• 5 inputs
DI[7:0]

clk RAMB4_S8 • Enable


(512x8 primative)
reset • Synchronous Reset

• 32 states, 3 outputs, 4 inputs, Enable, Synchronous Reset


Assignment
State: enum (START,MIDDLE,STOP,STUCK);

CMB: process (A,B,STATE) begin


  
        case STATE is
          when START =>
if (A or B)=`0` then What is the SAFE
                     NEXTSTATE <= MIDDLE ;
out <= in1; implementation of this FSM
                    end if ;
          when MIDDLE =>
with One-Hot Encoding?
if (A and B)=`1` then
                        NEXTSTATE <= STOP ;
out <= in2;
                  end if ;
          when STOP =>
if (A xor B)=`1` then
                        NEXTSTATE <= START ;
out <= in3;
                  end if ;
          when Default =>
NEXTSTATE <= START ;
  end case ;    

end process CMB ;

You might also like