【FPGA】状态机模板-分别对比一段式状态机、二段式状态机以及三段式状态机

状态机模板

  • 1、一段式状态机
    • [1.1 一段式状态机模板代码](#1.1 一段式状态机模板代码)
    • [1.2 一段式状态机结构特点说明](#1.2 一段式状态机结构特点说明)
  • 2、二段式状态机
    • [2.1 二段式状态机模板代码](#2.1 二段式状态机模板代码)
    • [2.2 二段式状态机结构特点说明](#2.2 二段式状态机结构特点说明)
  • 3、三段式状态机
    • [3.1 三段式状态机模板代码](#3.1 三段式状态机模板代码)
    • [3.2 三段式结构特点说明](#3.2 三段式结构特点说明)
  • 4、总结区分
    • [4.1 三种架构对比表](#4.1 三种架构对比表)
    • [4.2 设计建议](#4.2 设计建议)

1、一段式状态机

1.1 一段式状态机模板代码

bash 复制代码
module fsm_one_segment (
    input               clk,
    input               rst_n,
    input               [输入信号],
    output reg          [输出信号]
);

parameter [1:0] 
    IDLE   = 2'b00,
    STATE1 = 2'b01,
    STATE2 = 2'b10;

reg [1:0] current_state;

always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        current_state <= IDLE;
        [输出信号]    <= 默认值;
    end else begin
        case (current_state)
            IDLE: begin
                [输出信号] <= 值1;
                if (转移条件) begin
                    current_state <= STATE1;
                end
            end

            STATE1: begin
                [输出信号] <= 值2;
                if (条件1) begin
                    current_state <= STATE2;
                end
            end

            default: begin
                current_state <= IDLE;
                [输出信号] <= 默认值;
            end
        endcase
    end
end

endmodule

1.2 一段式状态机结构特点说明

  • 特点:所有逻辑在一个时序块中完成,代码结构简单,代码量小。
  • 缺点:代码可读性差,易产生锁存器,不推荐复杂设计。

2、二段式状态机

2.1 二段式状态机模板代码

bash 复制代码
module fsm_two_segment (
    input               clk,
    input               rst_n,
    input               [输入信号],
    output reg          [输出信号]
);

// ================== 状态定义 ==================
parameter [1:0] 
    IDLE   = 2'b00,
    STATE1 = 2'b01,
    STATE2 = 2'b10;

reg [1:0] current_state;
reg [1:0] next_state;

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

// ============== 状态转移+输出逻辑(第二段)==============
always @(*) begin
    // 默认值和状态转移初始化
    next_state = current_state;
    [输出信号] = 默认值;

    case (current_state)
        IDLE: begin
            [输出信号] = 值1;  // 输出逻辑
            if (转移条件) begin
                next_state = STATE1;
            end
        end

        STATE1: begin
            [输出信号] = 值2;
            if (条件1) begin
                next_state = STATE2;
            end else if (条件2) begin
                next_state = IDLE;
            end
        end

        default: begin
            next_state = IDLE;
            [输出信号] = 默认值;
        end
    endcase
end

endmodule

2.2 二段式状态机结构特点说明

特点:将状态转移逻辑与输出逻辑合并(输出在时序逻辑中)

优点:规避组合逻辑输出的毛刺,代码结构更简洁

3、三段式状态机

3.1 三段式状态机模板代码

bash 复制代码
module fsm_three_segment (
    input               clk,        // 时钟
    input               rst_n,      // 异步复位(低有效)
    input               [输入信号声明],
    output reg          [输出信号声明]
);
// ========================= 状态定义 =========================
// 建议使用独热码(one-hot)或二进制编码
parameter [STATE_WIDTH-1:0] 
    IDLE    = 0,
    STATE1  = 1,
    STATE2  = 2;
    
reg [STATE_WIDTH-1:0] current_state;
reg [STATE_WIDTH-1:0] next_state;

// ===================== 状态寄存器(第一段)=====================
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        current_state <= IDLE;      // 复位初始状态
    end else begin
        current_state <= next_state; // 状态更新
    end
end

// ===================== 状态转移逻辑(第二段)=====================
always @(*) begin
    // 默认保持当前状态
    next_state = current_state; 
    
    case (current_state)
        IDLE: begin
            if (触发条件) begin
                next_state = STATE1;
            end
        end
        
        STATE1: begin
            if (状态转移条件1) begin
                next_state = STATE2;
            end else if (状态转移条件2) begin
                next_state = IDLE;
            end
        end
        
        STATE2: begin
            if (状态转移条件) begin
                next_state = IDLE;
            end
        end
        
        default: next_state = IDLE; // 避免锁存
    endcase
end

// ===================== 输出逻辑(第三段)=====================
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        // 复位输出初始化
        [输出信号] <= 默认值;
    end else begin
        case (current_state)
            IDLE: begin
                // 状态对应输出
                [输出信号] <= 值1;
            end
            
            STATE1: begin
                [输出信号] <= 值2;
            end
            
            STATE2: begin
                [输出信号] <= 值3;
            end
            
            default: [输出信号] <= 默认值;
        endcase
    end
end

endmodule

3.2 三段式结构特点说明

  • 特点:逻辑分层明确,代码简洁且符合同步设计规范。
  • 优点:规避毛刺问题,综合优化友好,模块化设计,易扩展性好。

4、总结区分

一段式:所有逻辑混在一个 always 块中,代码臃肿且难以维护。易因条件覆盖不全产生锁存器,但其代码量少易于构建使用,简单状态逻辑可以使用。

两段式(组合输出型):两段式一般将状态转移和输出逻辑合并,或者将状态寄存器和转移逻辑分开,输出逻辑为组合电路,其可能产生毛刺,需额外同步电路处理,状态转移和输出逻辑混合,代码可读性降低。

三段式:三段式状态机通常分为三个部分,状态寄存器(时序)、状态转移逻辑(组合)和输出逻辑(时序或组合),输出逻辑用时序电路,直接规避毛刺问题,逻辑分层明确,代码简洁且符合同步设计规范。

4.1 三种架构对比表

类型 代码结构 毛刺风险 可维护性 推荐场景
三段式 状态寄存 + 转移 + 输出 时序/组合
两段式 状态寄存 + (转移+输出) 时序或组合
一段式 单时序块完成所有逻辑 时序

4.2 设计建议

  • 推荐使用 parameter 定义状态(而非 define)
  • FPGA 建议使用独热码(one-hot),ASIC 建议用二进制编码
  • 每个状态对应独立的输出逻辑
  • 所有条件分支必须覆盖所有可能性
  • 必须包含 default 处理未定义状态
  • 建议对状态机做容错处理(例如添加看门狗)
相关推荐
LabVIEW开发9 小时前
LabVIEW与FPGA超声探伤
fpga开发·labview·labview功能
cycf11 小时前
FPGA设计中的数据存储
fpga开发
FPGA之旅1 天前
FPGA从零到一实现FOC(一)之PWM模块设计
fpga开发·dubbo
XMAIPC_Robot2 天前
基于ARM+FPGA的光栅尺精密位移加速度测试解决方案
arm开发·人工智能·fpga开发·自动化·边缘计算
cycf2 天前
状态机的设计
fpga开发
szxinmai主板定制专家2 天前
【精密测量】基于ARM+FPGA的多路光栅信号采集方案
服务器·arm开发·人工智能·嵌入式硬件·fpga开发
千宇宙航2 天前
闲庭信步使用SV搭建图像测试平台:第三十二课——系列结篇语
fpga开发
千宇宙航2 天前
闲庭信步使用SV搭建图像测试平台:第三十一课——基于神经网络的手写数字识别
图像处理·人工智能·深度学习·神经网络·计算机视觉·fpga开发
小眼睛FPGA3 天前
【RK3568+PG2L50H开发板实验例程】FPGA部分/紫光同创 IP core 的使用及添加
科技·嵌入式硬件·ai·fpga开发·gpu算力
forgeda3 天前
如何将FPGA设计验证效率提升1000倍以上(2)
fpga开发·前沿技术·在线调试·硬件断点·时钟断点·事件断点