1. Finite state machine
- Basic concepts
Finite State Machine (FSM) is a classic method of circuit design. It can usually be considered as a combination of combinational logic and register logic. Combinational logic uses For status decoding and output signal generation, registers are used to store status.
- Moore and Mealy state machines
Moore state machine: The output is only a function of the current state
Mealy state Machine: The output is a function of the current state and the current input
It doesn’t seem to be easy to understand. Let’s take a look at it based on the state machine model.
It can be seen that the output of the Moore type state machine is only related to the current state (current CS)
It can be seen from the figure that compared to the Moore-type state machine, the output logic of the Mealy-type state machine has one more input terminal. That is, the output of the Mealy-type state machine mentioned in the above definition is determined by the current state (current state CS) and the current input. .
- The difference between the two state machines
Due to the difference between the two models, it is not difficult to see that the output of the Mealy type state machine will change immediately when the input changes, without relying on the clock. When the input state of the Moore-type state machine changes, the output needs to be changed after clock synchronization. That is, the output of the Moore-type state machine takes one more clock cycle than the Mealy-type state machine. Practical state machines are generally designed in synchronous timing mode.
2. Verilog description of finite state machine
-The design of the state machine mainly includes the following three objects:
- Current State, or CS (Current State, CS)
- Next State, or NS (Next State, NS)
- Out Logic (OL)
-Verilog description method
- Three-paragraph description (CS, NS, OL)
- Two-paragraph description (CS+NS, OL) or (CS, NS+OL)
- Single paragraph description (CS+NS+OL)
-Example (Coke machine: 2.5¥ produces Coke, you can invest 0.5¥, 1¥)
1. First draw the state transition diagram, it is ugly, but it is probably like this, For the sake of simplicity, change is not considered, and no coin input is counted as input.
2.Verilog description
2.1 Three-paragraph description
//三段式描述(CS、NS、OL)
module Coke_Machine //模块名
(
input wire sys_clk , //输入时钟
input wire sys_rst_n , //输入复位
input wire pi_money_half , //输入0.5
input wire pi_money_one , //输入1.0
output reg po_cola
);
parameter IDLE = 5'b00001, //状态编码,独热码
HALF = 5'b00010,
ONE = 5'b00100,
ONE_HALF = 5'b01000,
TWO = 5'b10000;
wire [1:0] pi_money;
reg [4:0] state,next_state;
assign pi_money = {pi_money_one,pi_money_half}; //合并输入,即输入0.5为01,输入1为10
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
state <= IDLE; //定义起始状态
else
state <= next_state;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
state <= IDLE; //定义起始状态
else case(state)
IDLE: if(pi_money == 2'b01)
next_state <= HALF;
else if(pi_money == 2'b10)
next_state <= ONE;
else
next_state <= IDLE;
HALF: if(pi_money == 2'b01)
next_state <= ONE;
else if(pi_money == 2'b10)
next_state <= ONE_HALF;
else
next_state <= HALF;
ONE: if(pi_money == 2'b01)
next_state <= ONE_HALF;
else if(pi_money == 2'b10)
next_state <= TWO;
else
next_state <= ONE;
ONE_HALF: if(pi_money == 2'b01)
next_state <= TWO;
else if(pi_money == 2'b10)
next_state <= IDLE;
else
next_state <= ONE_HALF;
TWO: if(pi_money == 2'b01)
next_state <= IDLE;
else if(pi_money == 2'b10)
next_state <= HALF;
else
next_state <= TWO;
default: next_state <= IDLE;
endcase
always@(posedge sys_clk or negedge sys_rst_n) //输出逻辑
if(sys_rst_n == 1'b0)
po_cola <= 1'b0;
else if(((state == ONE_HALF) && (pi_money == 2'b10))
|| ((state == TWO) && (pi_money == 2'b01))
|| ((state == TWO) && (pi_money == 2'b10)))
po_cola <= 1'b1;
else
po_cola <= 1'b0;
endmodule
2.2 Two-paragraph description (CS+NS, OL)
//两段式描述(CS+NS、OL)
module Coke_Machine //模块名
(
input wire sys_clk , //输入时钟
input wire sys_rst_n , //输入复位
input wire pi_money_half , //输入01
input wire pi_money_one , //输入10
output reg po_cola
);
parameter IDLE = 5'b00001, //状态编码,独热码
HALF = 5'b00010,
ONE = 5'b00100,
ONE_HALF = 5'b01000,
TWO = 5'b10000;
wire [1:0] pi_money;
reg [4:0] state;
assign pi_money = {pi_money_one,pi_money_half}; //合并输入,即输入0.5为01,输入1为10
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
state <= IDLE; //定义起始状态
else case(state)
IDLE: if(pi_money == 2'b01)
state <= HALF;
else if(pi_money == 2'b10)
state <= ONE;
else
state <= IDLE;
HALF: if(pi_money == 2'b01)
state <= ONE;
else if(pi_money == 2'b10)
state <= ONE_HALF;
else
state <= HALF;
ONE: if(pi_money == 2'b01)
state <= ONE_HALF;
else if(pi_money == 2'b10)
state <= TWO;
else
state <= ONE;
ONE_HALF: if(pi_money == 2'b01)
state <= TWO;
else if(pi_money == 2'b10)
state <= IDLE;
else
state <= ONE_HALF;
TWO: if(pi_money == 2'b01)
state <= IDLE;
else if(pi_money == 2'b10)
state <= HALF;
else
state <= TWO;
default: state <= IDLE;
endcase
always@(posedge sys_clk or negedge sys_rst_n) //输出逻辑
if(sys_rst_n == 1'b0)
po_cola <= 1'b0;
else if(((state == ONE_HALF) && (pi_money == 2'b10))
|| ((state == TWO) && (pi_money == 2'b01))
|| ((state == TWO) && (pi_money == 2'b10)))
po_cola <= 1'b1;
else
po_cola <= 1'b0;
endmodule
2.3 Single process description
//单段式描述
module Coke_Machine //模块名
(
input wire sys_clk , //输入时钟
input wire sys_rst_n , //输入复位
input wire pi_money_half , //输入01
input wire pi_money_one , //输入10
output reg po_cola
);
parameter IDLE = 5'b00001, //状态编码,独热码
HALF = 5'b00010,
ONE = 5'b00100,
ONE_HALF = 5'b01000,
TWO = 5'b10000;
wire [1:0] pi_money;
reg [4:0] state;
assign pi_money = {pi_money_one,pi_money_half}; //合并输入,即输入0.5为01,输入1为10
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
state <= IDLE; //定义起始状态
else case(state)
IDLE: if(pi_money == 2'b01)
begin
state <= HALF;
po_cola <= 1'b0;
end
else if(pi_money == 2'b10)
begin
state <= ONE;
po_cola <= 1'b0;
end
else
begin
state <= IDLE;
po_cola <= 1'b0;
end
HALF: if(pi_money == 2'b01)
begin
state <= ONE;
po_cola <= 1'b0;
end
else if(pi_money == 2'b10)
begin
state <= ONE_HALF;
po_cola <= 1'b0;
end
else
begin
state <= HALF;
po_cola <= 1'b0;
end
ONE: if(pi_money == 2'b01)
begin
state <= ONE_HALF;
po_cola <= 1'b0;
end
else if(pi_money == 2'b10)
begin
state <= TWO;
po_cola <= 1'b0;
end
else
begin
state <= ONE;
po_cola <= 1'b0;
end
ONE_HALF: if(pi_money == 2'b01)
begin
state <= TWO;
po_cola <= 1'b0;
end
else if(pi_money == 2'b10)
begin
state <= IDLE;
po_cola <= 1'b1;
end
else
begin
state <= ONE_HALF;
po_cola <= 1'b0;
end
TWO: if(pi_money == 2'b01)
begin
state <= IDLE;
po_cola <= 1'b1;
end
else if(pi_money == 2'b10)
begin
state <= HALF;
po_cola <= 1'b1;
end
else
begin
state <= TWO;
po_cola <= 1'b0;
end
default:
begin
state <= IDLE;
po_cola <= 1'b0;
end
endcase
endmodule
3. Status coding
Common encoding methods:
- Sequential encoding Use sequential binary numbers to encode each state. For example, there are 4 states: 00, 01, 10, 11. The advantage is that it occupies less bits. The disadvantage is that when transitioning from one state to an adjacent state, multiple bits may change at the same time, which can easily cause glitches and cause logic errors.
- Gray coding Use Gray code to encode each state. For example, there are 4 states: 00, 01, 11, 10. The advantage is that fewer digits save logical units. Because adjacent state transitions only change one bit, the number of transients and the possibility of glitches are also reduced.
- Johnson coding The Johnson code is derived based on the Johnson counter, and the highest bit of the output is inverted and then fed back to the lowest bit. For example, there are 6 states: 000, 001, 011, 111, 110, 100, the same two adjacent states are only different in one bit, but the occupied bit width is much wider.
- 1-bit hot code encoding (one-hot code) Use n flip-flops to encode n states. For example, there are 4 states: 0001, 0010, 0100, 1000. The one-hot code occupies the most digits, but it can effectively save and simplify the decoding circuit and is used more.
**Reference materials:
Wang Jinming. "FPGA Design and Verilog HDL Implementation". Beijing: Electronic Industry Press, 2021.** a>