Style #2

This style has one process (4), and uses synthesiser-determined state encodings. The two outputs are generated combinatorially by decoding the state register. Style #3 and Style #4 instead use two different methods to generate the outputs sequentially.

Allowing the synthesiser to determine the state codings is easier and more concise than Style #1, since it is not necessary to manually derive the codings for each state; it also allows the synthesiser to optimise the FSM.

The VHDL code uses an enumerated type (5) for the state register, while the Verilog code uses parameter encoding. The two versions of this code are therefore not directly equivalent, since parameter encoding requires the designer to explicitly specify the state encodings (which will later be recoded by the synthesiser). The VHDL code is 'symbolic' and does not require the designer to specify state encodings. XST does, in fact, synthesise the Verilog and VHDL versions differently.

The specific Verilog parameter encodings are, in principle, not important, since the designer's intent is that they should be recoded by the synthesiser. As it turns out, however, the initial encoding is significant; see the discussion of Style #3.



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

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

   assign SCK  = (STATEREG == st2) | (STATEREG == st3);
   assign BUSY = (STATEREG == st1) | (STATEREG == st2);

   always @(posedge CLK)
       STATEREG <= st3;
         st3: STATEREG <= st1;
         st0: if(LOAD)
                STATEREG <= st1;
         st1: STATEREG <= st2;
                STATEREG <= st0;
                STATEREG <= st1;


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);

  SCK  <= '1' when STATEREG = st2 or STATEREG = st3 else
  BUSY <= '1' when STATEREG = st1 or STATEREG = st2 else

  FSM : process (CLK) is
    if rising_edge(CLK) then
      if SRST = '1' then
        STATEREG <= st3;
        case STATEREG is
          when st3 => STATEREG <= st1;
          when st0 =>
            if LOAD = '1' then
              STATEREG <= st1;
            end if;
          when st1 => STATEREG <= st2;
          when st2 =>
            if TC = '1' then
              STATEREG <= st0;
            else STATEREG <= st1;
            end if;
        end case;
      end if;
    end if;
  end process FSM;
end architecture RTL;

This FSM has two combinatorial outputs (SCK and BUSY). It might be expected, then, that the default output from XST (with "auto" FSM encoding) would be a one-hot FSM (with 4 flip-flops and 2 LUTs), and two additional combinatorial LUTs to generate the SCK and BSY outputs. In fact, XST produced a much better solution:

Style 2 synthesis results
Mode SCK/BUSY Period LUT2 LUT4 FDR FDS Total
fsm2.v Auto Reg/Comb 0.926 2 1 2 5
fsm2.vhd Auto Reg/Reg 0.926 1 1 1 1 4

The VHDL output is esentially the optimal solution, while the Verilog output adds a LUT2 to combinatorially drive BUSY. For the VHDL output, at least, XST recoded the enumerated FSM into the equivalent of the manually coded Style #1 FSMs, absorbing the combinatorial outputs into the two state registers. The state encodings of the VHDL Style #1 and Style #2 outputs differed:

st0 st1 st2 st3
user style #1 00 01 11 10
auto style #2 00 10 11 01

However, the synthesised output was identical, except that the contents of the LUT2 differed between the two FSMs.