FPGA状态机学习

2024-02-27 1281阅读

温馨提示:这篇文章已超过410天没有更新,请注意相关的内容是否还可用!

        Verilog 是硬件描述语言,硬件电路是并行执行的,当需要按照流程或者步骤来完成某个功能时,代码中通常会使用很多个 if 嵌套语句来实现,这样就增加了代码的复杂度,以及降低了代码的可读性,这个时候就可以使用状态机来编写代码。状态机相当于一个控制器,它将一项功能的完成分解为若干步,每一步对应于二进制的一个状态,通过预先设计的顺序在各状态之间进行转换,状态转换的过程就是实现逻辑功能的过程。

        状态机,全称是有限状态机(Finite State Machine,缩写为 FSM),是一种在有限个状态之间按一定规律转换的时序电路,可以认为是组合逻辑和时序逻辑的一种组合。状态机通过控制各个状态的跳转来控制流程,使得整个代码看上去更加清晰易懂,在控制复杂流程的时候,状态机优势明显,因此基本上都会用到状态机,如 SDRAM 控制器等。在本手册提供的例程中,会有多个用到状态机设计的例子,希望大家能够慢慢体会和理解,并且能够熟练掌握。

        根据状态机的输出是否与输入条件相关,可将状态机分为两大类,即摩尔(Moore)型状态机和米勒(Mealy)型状态机。
        ➢ Mealy 状态机:组合逻辑的输出不仅取决于当前状态,还取决于输入状态。

        ➢ Moore 状态机:组合逻辑的输出只取决于当前状态。

1、Mealy 状态机

        米勒状态机的模型如下图所示,模型中第一个方框是指产生下一状态的组合逻辑 F,F 是当前状态和输入信号的函数,状态是否改变、如何改变,取决于组合逻辑 F 的输出;第二框图是指状态寄存器,其由一组触发器组成,用来记忆状态机当前所处的状态,状态的改变只发生在时钟的跳边沿;第三个框图是指产生输出的组合逻辑 G,状态机的输出是由输出组合逻辑 G 提供的,G 也是当前状态和输入信号的函数。

FPGA状态机学习

Mealy 状态机模型

2、Moore 状态机

        摩尔状态机的模型如下图所示,对比米勒状态机的模型可以发现,其区别在于米勒状态机的输出由当前状态和输入条件决定的,而摩尔状态机的输出只取决于当前状态。

FPGA状态机学习

Moore 状态机模型

3、三段式状态机

        根据状态机的实际写法,状态机还可以分为一段式、二段式和三段式状态机。

        一段式:整个状态机写到一个 always 模块里面,在该模块中既描述状态转移,又描述状态的输入和输出。不推荐采用这种状态机,因为从代码风格方面来讲,一般都会要求把组合逻辑和时序逻辑分开;从代码维护和升级来说,组合逻辑和时序逻辑混合在一起不利于代码维护和修改,也不利于约束。

        二段式:用两个 always 模块来描述状态机,其中一个 always 模块采用同步时序描述状态转移;另一个模块采用组合逻辑判断状态转移条件,描述状态转移规律以及输出。不同于一段式状态机的是,它需要定义两个状态,现态和次态,然后通过现态和次态的转换来实现时序逻辑。

        三段式:在两个 always 模块描述方法基础上,使用三个 always 模块,一个 always 模块采用同步时序描述状态转移,一个 always 采用组合逻辑判断状态转移条件,描述状态转移规律,另一个 always 模块描述状态输出(可以用组合电路输出,也可以时序电路输出)。

        实际应用中三段式状态机使用最多,因为三段式状态机将组合逻辑和时序分开,有利于综合器分析优化以及程序的维护;并且三段式状态机将状态转移与状态输出分开,使代码看上去更加清晰易懂,提高了代码的可读性,推荐大家使用三段式状态机,本文也着重讲解三段式。
三段式状态机的基本格式是:

第一个 always 语句实现同步状态跳转;

第二个 always 语句采用组合逻辑判断状态转移条件;

第三个 always 语句描述状态输出(可以用组合电路输出,也可以时序电路输出)。

        在开始编写状态机代码之前,一般先画出状态跳转图,这样在编写代码时思路会比较清晰,下面以一个 7 分频为例(对于分频等较简单的功能,可以不使用状态机,这里只是演示状态机编写的方法),状态跳转图如下图所示:

FPGA状态机学习

七分频状态跳转图

        状态跳转图画完之后,接下来通过 parameter 来定义各个不同状态的参数,如下代码所示:

parameter S0 = 7’b0000001; //独热码定义方式
parameter S1 = 7’b0000010;
parameter S2 = 7’b0000100;
parameter S3 = 7’b0001000;
parameter S4 = 7’b0010000;
parameter S5 = 7’b0100000;
parameter S6 = 7’b1000000;

        这里是使用独热码的方式来定义状态机,每个状态只有一位为 1,当然也可以直接定义成十进制的 0,1,2……7。

        因为我们定义成独热码的方式,每一个状态的位宽为 7 位,接下来还需要定义两个 7 位的寄存器,一个用来表示当前状态,另一个用来表示下一个状态,如下所示:

reg [6:0] curr_st ; //当前状态
reg [6:0] next_st ; //下一个状态

        接下来就可以使用三个 always 语句来开始编写状态机的代码,第一个 always 采用同步时序描述状态转移,第二个 always 采用组合逻辑判断状态转移条件,第三个 always 是描述状态输出,一个完整的三段式状态机的例子如下代码所示:

1 module divider7_fsm (
2     //系统时钟与复位
3     input sys_clk ,
4     input sys_rst_n ,
5
6     //输出时钟
7     output reg clk_divide_7
8 );
9
10 //parameter define
11 parameter S0 = 7’b0000001; //独热码定义方式
12 parameter S1 = 7’b0000010;
13 parameter S2 = 7’b0000100;
14 parameter S3 = 7’b0001000;
15 parameter S4 = 7’b0010000;
16 parameter S5 = 7’b0100000;
17 parameter S6 = 7’b1000000;
18
19 //reg define
20 reg [6:0] curr_st ; //当前状态
21 reg [6:0] next_st ; //下一个状态
22
23 //*****************************************************
24 //** main code
25 //*****************************************************
26
27 //状态机的第一段采用同步时序描述状态转移
28 always @(posedge sys_clk or negedge sys_rst_n) begin
29     if (!sys_rst_n)
30         curr_st 
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]