FPGA状态机设计思想

时间:2025-09-16  作者:Diven  阅读:0

01

FPGA状态机设计思想

状态机设计概述

硬件电路设计通常以并行方式实现,但是在实际工程中经常会存在系统按照顺序逻辑执行的需求。如果希望分多个时间步骤完成一个任务,同时减少使用大量使能信号衔接多个模块造成的麻烦,就需要引出状态机的概念。

状态机(State Machine)由输入、输出和状态三要素构成,输入是指一些引发状态变化的条件,输出是指状态改变后引起的变化,状态是指顺序逻辑执行的步骤,通常利用一些逻辑值进行表示。

以NAND FALSH控制过程的状态机为例,NAND FALSH操作通常需要按顺序依次执行擦除、坏块检测和读写操作:NAND FLASH在系统复位信号rst = 1后进入空闲状态IDLE;当指令使能信号i_cmd_en = 1且指令选择信号i_cmd_sel = h18时,NAND FLASH 进入擦除状态ERASE;当指令结束信号i_cmd_finish = 1时,NAND FLASH进入擦除状态读取状态......NAND FLASH根据不同的输入条件和当前状态实现状态跳转,通过在不同状态实现不同功能,完成NAND FLASH读写等操作。

状态机设计按照不同的标准分类:

1. 输出与输入是否相关:

Moore型状态机:输出只与状态相关,与输入无关;

Mealy型状态机:输出与状态和输入都相关。

2. 状态转移与输出是否依赖时钟信号:

同步状态机:状态转移和输出都发生在时钟沿;

异步状态机:状态转移和输出不依赖时钟信号,而是依赖于输入信号的变化。

3. 输出与状态是否相关:

顺序逻辑状态机:输出与输入和状态都相关,当前时刻的输出会影响下一个时刻的状态;

组合逻辑状态机:输出只与输入相关,与状态无关,当前时刻的输出不会影响下一个时刻的状态。

4. 状态数目是否有限:

有限状态机:状态数目是有限的,可以用状态转移图来表示状态和状态之间的转移关系;

无限状态机:状态数目是无限的,一般用差分方程或状态转移函数来表示状态转移关系。

在FPGA设计过程中,通常考虑的状态机是有限状态机(FSM, Finite State Machine)。FPGA有限状态机根据写法不同可以分为一段式、两段式和三段式,不同状态机写法在代码可读性和速度面积平衡性方面有所优劣,本文将以不同写法下状态机的Verilog代码为例,对三种状态机写法的效果进行对比分析。

02

一段式状态机设计分析

一段式状态机将状态机的三要素(输入、输出和状态)逻辑实现在同一个always内,示例代码如下:

`timescale 1ns / 1ps

//////////////////////////////////////////////////////////////////////////////////

// Company: Cascatrix

// Engineer: Carson

// 

// Create Date: 2023/07/16

// Design Name: FSM

// Module Name: FSM

// Tool Versions: v1.0

// Description: Finite State Machine 

//////////////////////////////////////////////////////////////////////////////////

Module FSM(

    clk,

    rst_n,

    condition1,

    condition2,

    result

    );

    input           clk;

    input           rst_n;

    input           condition1;

    input           condition2;

    output  [3:0]   result;

    wire            clk;

    wire            rst_n;

    wire            condition1;

    wire            condition2;

    reg     [3:0]   result;

    parameter IDLE = 1;

    parameter STATE_S11 = 2;

    parameter STATE_S12 = 3;

    parameter STATE_S21 = 4;

    parameter STATE_S22 = 4;

    reg [3:0] current_state;   

    always@(posedge clk or negedge rst_n)

    begin

        if(!rst_n)

        begin

            current_state <= IDLE;

            result <= 4'b0101;

        end

        else

        begin

            case(current_state)

            IDLE:

            begin

                if(condition1)

                begin

                    current_state <= STATE_S11;

                    result <= 4'b1110;

                end

                else if(condition2)

                begin

                    current_state <= STATE_S21;

                    result <= 4'b1111;

                end

                else

                begin

                    current_state <= IDLE;

                    result <= 4'b0101;

                end

            end

            STATE_S11:

            begin

                current_state <= STATE_S12;

                result <= 4'b0010;

            end

            STATE_S12:

            begin

                current_state <= IDLE;

                result <= 4'b0101;

            end

            STATE_S21:

            begin

                current_state <= STATE_S22;

                result <= 4'b1000;

            end

            STATE_S22:

            begin

                current_state <= IDLE;

                result <= 4'b0101;

            end

            default:current_state <= IDLE;

            endcase

        end

    end

endmodule

上述代码所实现的一段式状态机RTL视图如下: 

通过分析一段式状态机代码可以发现,状态current_state、输入condition1/2和输出result在同一个always内,整体而言代码编写较为简单。从代码可读性和可维护性的角度而言,一段式状态机的这种代码格式并不利于后期的阅读与维护,当状态机较为复杂时,一段式状态机更容易出现错误。

03

两段式状态机设计分析

两段式状态机将状态机的时序逻辑和组合逻辑划分为两个always,时序逻辑内进行当前状态和下一状态的切换,组合逻辑里实现各个输入、输出和状态的判断,示例代码如下:

`timescale 1ns / 1ps

//////////////////////////////////////////////////////////////////////////////////

// Company: Cascatrix

// Engineer: Carson

// 

// Create Date: 2023/07/16

// Design Name: FSM

// Module Name: FSM

// Tool Versions: v1.0

// Description: Finite State Machine 

//////////////////////////////////////////////////////////////////////////////////

module FSM(

    clk,

    rst_n,

    condition1,

    condition2,

    result

    );

    input           clk;

    input           rst_n;

    input           condition1;

    input           condition2;

    output  [3:0]   result;

    wire            clk;

    wire            rst_n;

    wire            condition1;

    wire            condition2;

    reg     [3:0]   result;

    parameter IDLE = 1;

    parameter STATE_S11 = 2;

    parameter STATE_S12 = 3;

    parameter STATE_S21 = 4;

    parameter STATE_S22 = 4;

    reg [3:0] next_state;   

    reg [3:0] current_state;   

    always@(posedge clk or negedge rst_n)

    begin

        if(!rst_n)

            current_state <= IDLE;

        else

            current_state <= next_state;

    end

    always@(current_state or condition1 or condition2)

    begin

        if(!rst_n)

        begin

            next_state = IDLE;

            result = 4'b0101;

        end

        else

        begin

            case(next_state)

            IDLE:

            begin

                if(condition1)

                begin

                    next_state = STATE_S11;

                    result = 4'b1110;

                end

                else if(condition2)

                begin

                    next_state = STATE_S21;

                    result = 4'b1111;

                end

                else

                begin

                    next_state = IDLE;

                    result = 4'b0101;

                end

            end

            STATE_S11:

            begin

                next_state = STATE_S12;

                result = 4'b0010;

            end

            STATE_S12:

            begin

                next_state = IDLE;

                result = 4'b0101;

            end

            STATE_S21:

            begin

                next_state = STATE_S22;

                result = 4'b1000;

            end

            STATE_S22:

            begin

                next_state = IDLE;

                result = 4'b0101;

            end

            default:next_state = IDLE;

            endcase

        end

    end

endmodule

上述代码所实现的两段式状态机RTL视图如下: 

相比于一段式状态机,两段式状态机通过划分组合逻辑和时序逻辑提高代码的可读性和可维护性,对组合逻辑内容更改即可提高。两段式状态机的组合逻辑输出在同一个模块中可能会出现竞争冒险,因此较为容易出现毛刺等问题。

04

三段式状态机设计分析

三段式状态机将两段式状态机组合逻辑的状态和输出划分为两部分,状态转换使用组合逻辑、逻辑输出使用时序逻辑,示例代码如下:

`timescale 1ns / 1ps

//////////////////////////////////////////////////////////////////////////////////

// Company: Cascatrix

// Engineer: Carson

// 

// Create Date: 2023/07/16

// Design Name: FSM

// Module Name: FSM

// Tool Versions: v1.0

// Description: Finite State Machine 

//////////////////////////////////////////////////////////////////////////////////

module FSM(

    clk,

    rst_n,

    condition1,

    condition2,

    result

    );

    input           clk;

    input           rst_n;

    input           condition1;

    input           condition2;

    output  [3:0]   result;

    wire            clk;

    wire            rst_n;

    wire            condition1;

    wire            condition2;

    reg     [3:0]   result;

    parameter IDLE = 1;

    parameter STATE_S11 = 2;

    parameter STATE_S12 = 3;

    parameter STATE_S21 = 4;

    parameter STATE_S22 = 4;

    reg [3:0] next_state;   

    reg [3:0] current_state;   

    always@(posedge clk or negedge rst_n)

    begin

        if(!rst_n)

            current_state <= IDLE;

        else

            current_state <= next_state;

    end

    always@(current_state or condition1 or condition2)

    begin

        case(current_state)

        IDLE:

        begin

            if(condition1)

                next_state = STATE_S11;

            else if(condition2)

                next_state = STATE_S21;

            else

                next_state = IDLE;

        end

        STATE_S11: next_state = STATE_S12;

        STATE_S12: next_state = IDLE;

        STATE_S21: next_state = STATE_S22;

        STATE_S22: next_state = IDLE;

        default:next_state = IDLE;

        endcase

    end

    always@(posedge clk or negedge rst_n)

    begin

        if(!rst_n)

            result <= 4'b0101;

        else

        case(current_state)

        IDLE:

        begin

            if(condition1)

                result <= 4'b1110;

            else if(condition2)

                result <= 4'b1111;

            else

                result <= 4'b0101;

        end

        STATE_S11: result <= 4'b0010;

        STATE_S12: result <= 4'b0101;

        STATE_S21: result <= 4'b1000;

        STATE_S22: result <= 4'b0101;

        default:result <= 4'b0101;

        endcase

    end

endmodule

上述代码所实现的三段式状态机RTL视图如下: 

三段式状态机通过时序逻辑解决了两段式写法中组合逻辑产生毛刺的问题,同时保证代码的可读性和可维护性。从资源消耗方面而言,相比于一段式和两段式状态机,三段式状态机会占用更多资源,同时从输入到输出会延迟一个时钟周期。

05

状态机设计

状态机三种写法可以如下:

一段式状态机:一个always块,既描述状态转移,又描述状态的输入输出,当前状态用寄存器输出;

二段式:两个always块,时序逻辑与组合逻辑分开,一个always块采用同步时序描述状态转移;另一个always块采用组合逻辑判断状态转移条件,描述状态转移规律以及输出,当前状态用组合逻辑输出,可能出现竞争冒险,产生毛刺,而且不利于约束,不利于综合器和布局布线器实现高性能的设计;

三段式:三个always块,一个always模块采用同步时序描述状态转移;一个always采用组合逻辑判断状态转移条件,描述状态转移规律;第三个always块使用同步时序描述状态输出,寄存器输出。

注:需要注意的是,状态机三种不同写法的本质区别是状态机三要素(状态、输入和输出)的逻辑功能,而非always块的数量。


审核编辑:刘清

猜您喜欢

检测贴片电阻好坏,主要有以下几种方法:目视检查: 这是最简单直接的方法。观察电阻表面是否有烧焦、裂纹、变形等明显的损坏痕迹。如果有,基本可以判断电阻已坏。万用表...
2024-11-29 10:26:24

电池是能够将化学能转化为电能的装置,应用于各类电子设备中。其电池,通常指除了常见的铅酸电池和锂电池之外的其类型电池,如镍氢电池、镍镉电池、锂聚合物电池等。这些电...
2022-04-12 00:00:00

电子元件的世界中,封装类型的选择对于电路设计和性能非常重要。HTSSOP-24(7.8X4.4MM-EP)是应用的封装类型,因其出色的性能和紧凑的设计而受到众多...
2025-04-25 04:30:46

贴片电阻R005,别看它身材微小,却是电子电路中不可或缺的关键元件。它采用005封装尺寸,仅有0.4mm x 0.2mm大小,却能有效地限制电流,起到稳压、分流...
2024-11-26 11:30:00

理解贴片电阻的命名规则对于选择合适的元件很重要。常见的命名方法主要有三位数法和四位数法。三位数法用三位数字表示电阻值,前两位数字表示有效数字,第三位数字表示10...
2024-11-29 10:26:31

开口型扁圆头抽芯铆钉是常见的连接件,其设计和功能具有独特的特点。开口型铆钉的结构使其在安装过程中更加便捷,适合快速组装的场景。与传统铆钉相比,开口型设计能够有效...
2008-03-27 00:00:00


线对板针座是重要的连接器件,应用于电子设备和电路板的组装中。主要功能是提供可靠的电气连接,确保信号的稳定传输。线对板针座通常由高强度塑料和金属材料制成,具有良好...
2018-10-20 00:00:00

尖头半圆锉是常见的手工工具,应用于金属、木材和塑料的加工与修整。其主要参数包括锉的长度、宽度、齿形和材料等。一般而言,尖头半圆锉的长度通常在200mm到300m...
2013-05-08 00:00:00

在数字化时代,智能手机摄影已经成为人们记录生活、分享瞬间的重要工具。为了满足用户对更高质量影像的渴望,知名CMOS图像传感器供应商思特威(SmartSens,股...
2024-06-27 14:30:00