HDL Synthesis Coding Guidelines
Lattice Semiconductor
for Lattice Semiconductor FPGAs
15-5
Coding Styles for FSM
A finite state machine (FSM) is a hardware component that advances from the current state to the next state at the
clock edge. As mentioned in the Encoding Methodologies for State Machines section, the preferable scheme for
FPGA architectures is one-hot encoding. This section discusses some common issues encountered when con-
structing state machines, such as initialization and state coverage, and special case statements in Verilog.
General State Machine Description
Generally, there are two approaches to describe a state machine. One is to use one process/block to handle both
state transitions and state outputs. The other is to separate the state transition and the state outputs into two differ-
ent process/blocks. The latter approach is more straightforward because it separates the synchronous state regis-
ters from the decoding logic used in the computation of the next state and the outputs. This will make the code
easier to read and modify, and makes the documentation more efficient. If the outputs of the state machine are
combinatorial signals, the second approach is almost always necessary because it will prevent the accidental reg-
istering of the state machine outputs.
The following examples describe a simple state machine in VHDL and Verilog. In the VHDL example, a sequential
process is separated from the combinatorial process. In Verilog code, two always blocks are used to describe the
state machine in a similar way.
VHDL Example for State Machine
. . .
architecture lattice_fpga of dram_refresh is
type state_typ is (s0, s1, s2, s3, s4);
signal present_state, next_state : state_typ;
begin
-- process to update the present state
registers: process (clk, reset)
begin
if (reset='1') then
present_state <= s0;
elsif clk'event and clk='1' then
present_state <= next_state;
end if;
end process registers;
-- process to calculate the next state & output
transitions: process (present_state, refresh, cs)
begin
ras <= '0'; cas <= '0'; ready <= '0';
case present_state is
when s0 =>
ras <= '1'; cas <= '1'; ready <= '1';
if (refresh = '1') then next_state <= s3;
elsif (cs = '1') then next_state <= s1;
else next_state <= s0;
end if;
when s1 =>
ras <= '0'; cas <= '1'; ready <= '0';
next_state <= s2;
when s2 =>
ras <= '0'; cas <= '0'; ready <= '0';
if (cs = '0') then next_state <= s0;
else next_state <= s2;
end if;
when s3 =>
ras <= '1'; cas <= '0'; ready <= '0';
next_state <= s4;
when s4 =>
ras <= '0'; cas <= '0'; ready <= '0';
next_state <= s0;
when others =>
ras <= '0'; cas <= '0'; ready <= '0';
next_state <= s0;
end case;
end process transitions;
. . .
Verilog Example for State Machine
. . .
parameter s0 = 0, s1 = 1, s2 = 2, s3 = 3, s4 = 4;
reg [2:0] present_state, next_state;
reg ras, cas, ready;
// always block to update the present state
always @ (posedge clk or posedge reset)
begin
if (reset) present_state = s0;
else present_state = next_state;
end
// always block to calculate the next state & outputs
always @ (present_state or refresh or cs)
begin
next_state = s0;
ras = 1'bX; cas = 1'bX; ready = 1'bX;
case (present_state)
s0 : if (refresh) begin
next_state = s3;
ras = 1'b1; cas = 1'b0; ready = 1'b0;
end
else if (cs) begin
next_state = s1; ras = 1'b0; cas = 1'b1; ready = 1'b0;
end
else begin
next_state = s0; ras = 1'b1; cas = 1'b1; ready = 1'b1;
end
s1 : begin
next_state = s2; ras = 1'b0; cas = 1'b0; ready = 1'b0;
end
s2 : if (~cs) begin
next_state = s0; ras = 1'b1; cas = 1'b1; ready = 1'b1;
end
else begin
next_state = s2; ras = 1'b0; cas = 1'b0; ready = 1'b0;
end
s3 : begin
next_state = s4; ras = 1'b1; cas = 1'b0; ready = 1'b0;
end
s4 : begin
next_state = s0; ras = 1'b0; cas = 1'b0; ready = 1'b0;
end
endcase
end
. . .