Introduction to FSM State machines or FSM are the heart of any digital design; of course a counter is a simple form of FSM. When I was learning Verilog, I used to wonder "How do I code FSM in Verilog" and "What is the best way to code it". I will try to answer the first part of the question below and second part of the question can be found in the tidbits section. State machine Types There are two types of state machines as classified by the types of outputs generated from each. The first is the Moore State Machine where the outputs are only a function of the present state, the second is the Mealy State Machine where one or more of the outputs are a function of the present state and one or more of the inputs. Mealy Model Moore Model State machines can also be classified according to the state encoding used. Encoding style is also a critical factor which decides speed and gate complexity of the FSM. Binary, gray, one hot, one cold, and almost one hot are the different types of encoding styles used in coding FSM states. Modeling State machines. One thing that need to be kept in mind when coding FSM is that combinational logic and sequence logic should be in two different always blocks. In the above two figures, next state logic is always the combinational logic. State Registers and Output logic are sequential logic. It is very important that any asynchronous signal to the next state logic be synchronized before being fed to the FSM. Always try to keep FSM in a separate Verilog file. Using constants declaration like parameter or `define to define states of the FSM makes code more readable and easy to manage. Example - Arbiter We will be using the arbiter FSM to study FSM coding styles in Verilog. Verilog Code FSM code should have three sections: Encoding style. Combinational part. Sequential part. Encoding Style There are many encoding styles around, some of which are: Binary Encoding One Hot Encoding One Cold Encoding Almost One Hot Encoding Almost One Cold Encoding Gray Encoding Of all the above types we normally use one hot and binary encoding. One Hot Encoding ``` 1 parameter [4:0] IDLE = 5'b0_0001; 2 parameter [4:0] GNT0 = 5'b0_0010; 3 parameter [4:0] GNT1 = 5'b0_0100; 4 parameter [4:0] GNT2 = 5'b0_1000; 5 parameter [4:0] GNT3 = 5'b1_0000; ``` You could download file fsm_one_hot_params.v here Binary Encoding ``` 1 parameter [2:0] IDLE = 3'b000; 2 parameter [2:0] GNT0 = 3'b001; 3 parameter [2:0] GNT1 = 3'b010; 4 parameter [2:0] GNT2 = 3'b011; 5 parameter [2:0] GNT3 = 3'b100; ``` You could download file fsm_binary_params.v here Gray Encoding ``` 1 parameter [2:0] IDLE = 3'b000; 2 parameter [2:0] GNT0 = 3'b001; 3 parameter [2:0] GNT1 = 3'b011; 4 parameter [2:0] GNT2 = 3'b010; 5 parameter [2:0] GNT3 = 3'b110; ``` You could download file fsm_gray_params.v here