有限状态机实战设计(Verilog)

有限状态机(FSM)设计实例

有限状态机(Finite State Machine, FSM)是数字系统设计中处理时序逻辑的重要模型,广泛应用于序列检测、控制逻辑、协议处理等场景。以下通过三个典型案例,详细展示 Moore 型和 Mealy 型状态机的设计方法。

一、Moore 型状态机:序列检测(检测 “101” 序列)

功能描述

输入一个串行比特流,当检测到连续输入 “101” 时,输出 detect 信号为高电平(持续 1 个周期)。输出仅依赖于当前状态(Moore 型)。

状态定义(二进制编码)

状态编码含义
S02’b00初始状态(无有效输入)
S12’b01检测到第一个 ‘1’
S22’b10检测到 ‘10’ 序列
S32’b11检测到 ‘101’ 序列(终止状态)

状态转移图

din=1
din=0
din=1
din=1
din=0
din=0
din=1
din=0
S0
S1
S2
S3

Verilog 代码实现

状态的存储和状态转换的逻辑进行分离,实现代码块之间的解耦
存储很简单,而状态的转换其实就是多个组合逻辑电路(多个子神经元)
module sequence_detector (
    input clk,       // 时钟
    input rst_n,     // 复位(低有效)
    input din,       // 输入比特流
    output reg detect // 检测信号(高有效)
);

// 状态定义
parameter S0 = 2'b00, S1 = 2'b01, S2 = 2'b10, S3 = 2'b11;

reg [1:0] current_state, next_state;

// 状态寄存器(时序逻辑)
always @(posedge clk or negedge rst_n) begin
    if (!rst_n)
        current_state <= S0;
    else
        current_state <= next_state;
end

// 状态转移逻辑(组合逻辑)
always @(*) begin
    case (current_state)
        S0: begin
            if (din == 1'b1)
                next_state = S1;
            else
                next_state = S0;
        end
        S1: begin
            if (din == 1'b0)
                next_state = S2;
            else if (din == 1'b1) // 连续'1',保持S1
                next_state = S1;
            else
                next_state = S0; // 非法输入,默认回到S0
        end
        S2: begin
            if (din == 1'b1)
                next_state = S3;
            else if (din == 1'b0) // '10'后接'0',回到S0(无法形成有效序列)
                next_state = S0;
            else
                next_state = S0;
        end
        S3: begin
            if (din == 1'b1) // '101'后接'1',进入S1(新序列开始)
                next_state = S1;
            else if (din == 1'b0) // '101'后接'0',回到S0
                next_state = S0;
            else
                next_state = S0;
        end
        default: next_state = S0;
    endcase
end

// 输出逻辑(仅依赖当前状态,Moore型)
always @(*) begin
    detect = (current_state == S3) ? 1'b1 : 1'b0;
end

endmodule

二、Mealy 型状态机:带使能的模 3 计数器

功能描述

当使能信号 en 为高电平时,计数器在时钟上升沿递增,计数到 2 后回到 0;en 为低电平时保持当前值。输出 cout 在计数值为 2 且 en 为高时产生进位信号(提前一个周期响应输入,Mealy 型)。

状态定义(独热码编码,适合 FPGA)

Verilog

parameter S0 = 3'b001, S1 = 3'b010, S2 = 3'b100; // 3个状态,独热码

状态转移与输出逻辑

当前状态输入 en下一状态输出 cout
S00S00
S01S10
S10S10
S11S20
S20S20
S21S01

状态转移图

en=0
en=1
en=0
en=1
en=0
en=1
S0
S1
S2

Verilog 代码实现

module mod3_counter (
    input clk,    // 时钟
    input rst_n,  // 复位(低有效)
    input en,     // 使能信号(高有效)
    output reg [1:0] q,  // 计数值(0-2)
    output reg cout       // 进位信号(高有效)
);

// 状态定义(独热码)
parameter S0 = 3'b001, S1 = 3'b010, S2 = 3'b100;

reg [2:0] current_state, next_state;

// 状态寄存器
always @(posedge clk or negedge rst_n) begin
    if (!rst_n)
        current_state <= S0;
    else
        current_state <= next_state;
end

// 状态转移与输出逻辑(Mealy型,输出依赖输入en)
always @(*) begin
    case (current_state)
        S0: begin
            q = 2'b00;