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.
Verilog
fsm2.v
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) if(SRST) STATEREG <= st3; else case(STATEREG) st3: STATEREG <= st1; st0: if(LOAD) STATEREG <= st1; st1: STATEREG <= st2; default: if(TC) STATEREG <= st0; else STATEREG <= st1; endcase endmodule
VHDL
fsm2.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 STATEREG : FSMTYPE; begin SCK <= '1' when STATEREG = st2 or STATEREG = st3 else '0'; BUSY <= '1' when STATEREG = st1 or STATEREG = st2 else '0'; FSM : process (CLK) is begin if rising_edge(CLK) then if SRST = '1' then STATEREG <= st3; else 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;
Synthesis
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:
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.