Style #5

This style has two processes, and uses synthesiser-determined state encodings. A sequential process is used for the state register, and a combinatorial process is used to derive the next state. The two outputs are generated combinatorially by decoding the current state.

This style is shown as a "three-process" style in the XST documentation, but is normally referred to as a "two-process" style. There are two things that should be noted about this style:

  • the sequential state register process has a synchronous reset. In principle, the reset could actually be rolled into the combinatorial next state process, and the sequential process would then not need a reset branch. However, XST requires the state register to have a reset in order for an FSM to be recognised and extracted, and removing the reset would probably result in a sub-optimal solution. This may or may not be true of other synthesisers.
  • the next-state process is combinatorial, and some care must therefore be taken with it. NEXTSTATE should be given a default value to avoid latch creation, and the sensitivity list must be correct. The examples below show explicit sensitivity lists. However, wildcard sensitivity lists are more convenient (always @* for Verilog (8), or process(all) for VHDL).
Verilog

fsm5.v

module FSM (
    input  CLK, SRST, LOAD, TC,
    output SCK, BUSY);

   parameter[1:0] 
           st0 = 0,
           st1 = 1,
           st2 = 2,
           st3 = 3;
   reg [1:0] NEXTSTATE, STATEREG;

   // outputs
   assign SCK  = (STATEREG == st2) | (STATEREG == st3);
   assign BUSY = (STATEREG == st1) | (STATEREG == st2);
   
   // state register
   always @(posedge CLK)
     if(SRST)
       STATEREG <= st3;
     else
       STATEREG <= NEXTSTATE;

   // next state derivation
   always @(LOAD or TC or STATEREG) begin
     NEXTSTATE = STATEREG;    // default: state unchanged
     case(STATEREG)
       st3: NEXTSTATE = st1;
       st0:
         if(LOAD)
            NEXTSTATE = st1;
       st1: NEXTSTATE = st2;
       default:
         if(TC)
              NEXTSTATE = st0;
         else NEXTSTATE = st1;
     endcase
   end
endmodule
VHDL

fsm5.vhd

library IEEE;
use IEEE.std_logic_1164.all;

entity FSM is
  port (
    CLK, SRST, LOAD, TC : in  std_logic;
    SCK, BUSY           : out std_logic);
end entity FSM;

architecture RTL of FSM is
  type   FSMTYPE is (st0, st1, st2, st3);
  signal NEXTSTATE, STATEREG : FSMTYPE;
begin

  -- outputs
  SCK  <= '1' when STATEREG = st2 or STATEREG = st3 else
          '0';

  BUSY <= '1' when STATEREG = st1 or STATEREG = st2 else
          '0';

  -- state register
  process (CLK) is
  begin
    if rising_edge(CLK) then
      if SRST = '1' then
        STATEREG <= st3;
      else
        STATEREG <= NEXTSTATE;
      end if;
    end if;
  end process;

  -- next state derivation
  process (LOAD, TC, STATEREG) is
  begin
    NEXTSTATE <= STATEREG;              -- default: state unchanged
    case STATEREG is
      when st3 => NEXTSTATE <= st1;
      when st0 =>
        if LOAD = '1' then
          NEXTSTATE <= st1;
        end if;
      when st1 => NEXTSTATE <= st2;
      when st2 =>
        if TC = '1' then
             NEXTSTATE <= st0;
        else NEXTSTATE <= st1;
        end if;
    end case;
  end process;
end architecture RTL;
Synthesis
Style 5 synthesis results
Mode SCK/BUSY Period LUT2 LUT4 FDR FDS FDRS Total
fsm5.v Auto Comb/Comb 1.103 2 2 2 1 1 8
fsm5.vhd Auto Reg/Reg 0.926 1 1 1 1 4
fsm5.v User Reg/Comb 0.926 2 1 2 5
fsm5.vhd User Reg/Comb 0.926 2 1 2 5

The Verilog code, with 'auto' encoding selected, produced the expected one-hot FSM, with 4 flip-flops, and the SCK and BUSY outputs driven combinatorially from LUTs. The auto-encoded VHDL code, however, produced an optimal solution with only 2 flip-flops, and the SCK and BUSY bits driven directly from the state register bits. This is the same as the Style #2 output.

With 'user' encoding selected, both the Verilog and VHDL sources produced a 2 flip-flop solution, with one of the state register bits directly driving SCK. The BUSY output was combinatorially driven from a LUT2.