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), orprocess(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
| 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.