米联客-FPGA程序设计Verilog语法入门篇连载-24 FPGA知识_认识FPGA中的状态机

软件版本:无

操作系统:WIN10 64bit

硬件平台:适用所有系列FPGA

板卡获取平台:https://milianke.tmall.com/

登录"米联客"FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!

1概述

让FPGA电路,有序执行任务,我们需要状态机电路。所有的时序电路都是随着时间的流逝发生各种状态,在FPGA中,基于时序编写状态机,可以完成几乎所有的逻辑控制任务。状态机就是用来管理电路的逻辑状态。如果你学习过C语言,你可能主要用switch case进行条件判断,但是学习了FPGA的状态机后,你可以考虑下改进下你的C语言设计,利用C语言的switch case来实现状态机,对于很多基于时间的逻辑类控制,状态机是非常好的管理方案,适合于一切的编程。

状态机的描述通常有三种方:一段式状态机、二段式状态机、三段式状态机,当然你可以写出四段式,五段式,但是一般来说,常用的不超过三段式。如果选用是一段、二段还是三段根据实际情况,一般原则,很简单的状态机一段式搞定,稍微复杂的用二段式,很复杂的用三段式。大部分情况我们都是面对的简单的状态机。

2一段式状态机

cpp 复制代码
module detect_1(

    input clk_i,

    input rst_n_i,

    output out_o

    );



reg out_r;

//状态声明和状态编码

reg [1:0] state;

parameter [1:0] S0=2'b00;

parameter [1:0] S1=2'b01;

parameter [1:0] S2=2'b10;

parameter [1:0] S3=2'b11;



always@(posedge clk_i)

begin

    if(!rst_n_i)begin

        state<=0;

       out_r<=1'b0;

    end

    else 

        case(state)

            S0 :

            begin

               out_r<=1'b0;

               state<= S1;

            end

            S1 :

            begin

                out_r<=1'b1;

                state<= S2;

            end 

            S2 :

            begin

                 out_r<=1'b0;

                 state<= S3;

            end

            S3 :

            begin

                 out_r<=1'b1;

            end

        endcase

end

assign out_o=out_r;

endmodule

通常来说一段式状态机是不推荐使用的,但是实际情况是对于简单的代码没必要严格去比较采用一段式或者二段式状态机,而且一段式的状态机,写起来比较顺手,所以规模不大的简单状态机放心用吧。

3两段式状态机

cpp 复制代码
module detect_2(

     input clk_i,

     input rst_n_i,

     output out_o

);

    reg out_r;

    //状态声明和状态编码

    reg [1:0] Current_state;

    reg [1:0] Next_state;

    parameter [1:0] S0=2'b00;

    parameter [1:0] S1=2'b01;

    parameter [1:0] S2=2'b10;

    parameter [1:0] S3=2'b11;

   

    //时序逻辑:描述状态转换

    always@(posedge clk_i)

    begin

        if(!rst_n_i)

           Current_state<=0;

        else

            Current_state<=Next_state;

    end

   

    //组合逻辑:描述下一状态和输出

    always@(*)

    begin

        case(Current_state)

            S0 :

                begin

                 out_r=1'b0;

                 Next_state= S1;

                end

            S1 :

                begin

                 out_r=1'b1;

                 Next_state= S2;

                end

            S2 :

                begin

                 out_r=1'b0;

                 Next_state= S3;

                end

            S3 :

                 begin

                 out_r=1'b1;

                 Next_state=Next_state;

                 end

            endcase

    end

    assign out_o=out_r;    

endmodule

两段式状态机采用两个always模块实现状态机的功能,其中一个always采用同步时序逻辑描述状态转移,另一个always采用组合逻辑来判断状态条件转移。虽然对于简单的代码我们没必要去比较一段式好还是两段式好,但是如果推荐肯定还是使用两段式的状态机,不过很多时候笔者也偷懒,使用一段式的状态机。但是如果对于时序要求和状态机机有一定的规模的电路,还是用两段式的吧。

代码翻译的电路原理图:

总之两段式状态机是推荐的状态机设计方法。

4三段式状态机

cpp 复制代码
module detect_3(

        input clk_i,

        input rst_n_i,

        output out_o

        );

    reg out_r;

    //状态声明和状态编码

    reg [1:0] Current_state;

    reg [1:0] Next_state;

    parameter [1:0] S0=2'b00;

    parameter [1:0] S1=2'b01;

    parameter [1:0] S2=2'b10;

    parameter [1:0] S3=2'b11;

   

    //时序逻辑:描述状态转换

    always@(posedge clk_i)

    begin

        if(!rst_n_i)

            Current_state<=0;

        else

            Current_state<=Next_state;

    end

   

    //组合逻辑:描述下一状态

    always@(*)

    begin

        case(Current_state)

            S0:

                Next_state = S1;

            S1:

                Next_state = S2;

            S2:

                Next_state = S3;

            S3:

                Next_state = Next_state;

         default :

            Next_state = S0;

          endcase

    end

    //输出逻辑:让输出out,经过寄存器out_r锁存后输出,消除毛刺

    always@(*)

    begin

        case(Current_state)

               S0,S2:

                   out_r<=1'b0;

               S1,S3:

                   out_r<=1'b1;

           default :

              out_r<=out_r;

            endcase

    end    assign out_o=out_r;    

三段式状态机在第一个always模块采用同步时序逻辑方式描述状态转移,第二个always模块采用组合逻辑方式描述状态转移规律,第三个always描述电路的输出。通常让输出信号经过寄存器缓存之后再输出,消除电路毛刺。这种状态机也是比较推崇的,主要是由于维护方便,组合逻辑与时序逻辑完全独立。

代码翻译的电路原理图:

5总结

通过对比三种状态机的写法,可以发现,三段式的状态机翻译出来的原理图是最简洁最高效的编写方式,两段式也是很简洁的,但是比三段式差了一点点,而一段式是最差的表现。所以推荐是使用两段式以上的状态机。

相关推荐
S&Z34635 小时前
[FPGA基础] UART篇
fpga开发
szxinmai主板定制专家14 小时前
国产RK3568+FPGA以 ‌“实时控制+高精度采集+灵活扩展”‌ 为核心的解决方案
大数据·运维·网络·人工智能·fpga开发·机器人
FPGA_ADDA14 小时前
基于FPGA 和DSP 的高性能6U VPX 采集处理板
fpga开发·dsp·6u vpx·8通道采集
__pop_16 小时前
system verilog 语句 耗时规则
verilog
FakeOccupational17 小时前
fpga系列 HDL:跨时钟域同步 脉冲展宽同步 Pulse Synchronization
fpga开发
丶七年先生18 小时前
牛客 verilog入门 VIP
fpga开发
hahaha601621 小时前
ARINC818协议(六)
网络·fpga开发
深圳信迈科技DSP+ARM+FPGA21 小时前
基于ARM+FPGA+DSP的储能协调控制器解决方案,支持国产化
arm开发·fpga开发·信号处理
承接电子控制相关项目1 天前
单片机与FPGA的核心差异、优缺点、编程差异、典型应用场景、选型等对比分析
单片机·嵌入式硬件·fpga开发
XINVRY-FPGA1 天前
XCZU19EG-2FFVC1760I Xilinx赛灵思FPGA Zynq UltraScale+MPSoC
c++·嵌入式硬件·阿里云·fpga开发·云计算·硬件工程·fpga