FSM Skeleton Generator

Generate a clean finite-state-machine skeleton from a transition list: binary, one-hot or Gray encoded Verilog, an enumerated-type VHDL version, and a Graphviz diagram. Condition signals become input ports automatically.

Results

States / transitions
4 / 5
Encoding
binary, 2 bits
Reset state
IDLE
Condition inputs
start, last, err, clear

Notes

Verilog
// my_fsm: 4-state FSM, binary encoded (2 bits)
// Generated by libfpga.com/tools/fsm-generator
module my_fsm (
    input  wire clk,
    input  wire rst,
    input  wire start,
    input  wire last,
    input  wire err,
    input  wire clear,
    output reg  [1:0] state
);

    localparam [1:0] IDLE = 2'd0;
    localparam [1:0] RUN = 2'd1;
    localparam [1:0] DONE = 2'd2;
    localparam [1:0] ERROR = 2'd3;

    reg [1:0] state_nxt;

    always @(posedge clk) begin
        if (rst) state <= IDLE;
        else     state <= state_nxt;
    end

    always @* begin
        state_nxt = state;  // stay by default: no latches
        case (state)
            IDLE: begin
                if (start) state_nxt = RUN;
            end
            RUN: begin
                if (last) state_nxt = DONE;
                else if (err) state_nxt = ERROR;
            end
            DONE: begin
                state_nxt = IDLE;
            end
            ERROR: begin
                if (clear) state_nxt = IDLE;
            end
            default: state_nxt = IDLE;
        endcase
    end
endmodule
VHDL (2008)
-- my_fsm: 4-state FSM (enumerated; tools choose the encoding)
-- Generated by libfpga.com/tools/fsm-generator
library ieee;
use ieee.std_logic_1164.all;

entity my_fsm is
    port (
        clk : in std_logic;
        rst : in std_logic;
        start : in std_logic;
        last : in std_logic;
        err : in std_logic;
        clear : in std_logic
    );
end entity;

architecture rtl of my_fsm is
    type state_t is (IDLE, RUN, DONE, ERROR);
    signal state, state_nxt : state_t;
begin
    process (clk) begin
        if rising_edge(clk) then
            if rst = '1' then
                state <= IDLE;
            else
                state <= state_nxt;
            end if;
        end if;
    end process;

    process (all) begin
        state_nxt <= state;
        case state is
            when IDLE =>
                if start = '1' then
                    state_nxt <= RUN;
                end if;
            when RUN =>
                if last = '1' then
                    state_nxt <= DONE;
                elsif err = '1' then
                    state_nxt <= ERROR;
                end if;
            when DONE =>
                state_nxt <= IDLE;
            when ERROR =>
                if clear = '1' then
                    state_nxt <= IDLE;
                end if;
        end case;
    end process;
end architecture;
Graphviz DOT
// paste into any Graphviz viewer (e.g. edotor.net)
digraph my_fsm {
    rankdir=LR;
    node [shape=circle, fontname=monospace];
    IDLE [shape=doublecircle];  // reset state
    IDLE -> RUN [label="start"];
    RUN -> DONE [label="last"];
    RUN -> ERROR [label="err"];
    ERROR -> IDLE [label="clear"];
    DONE -> IDLE;
}

This exact result is bookmarkable — the URL contains all your inputs. Need it in a script? Append &format=json (API docs).

About this tool

Every synthesizable FSM is the same two blocks: a register that holds the state and a combinational block that computes the next one. The bugs are always in the boilerplate — a forgotten default assignment that infers a latch, a missing state in the case, an encoding mismatch after adding a state. This generator produces that boilerplate correctly from the part you actually care about (the transition list), with your choice of encoding. Priority between conflicting transitions follows file order, made explicit as an if/else chain. Note that Vivado and Quartus re-encode FSMs by default (fsm_encoding/syn_encoding attributes control it), so the encoding here is a starting point, not a guarantee — one-hot is what FPGA tools usually pick anyway.

Related tools