状态机,从细节出发(一段式、两段式、三段式,moore型、mealy型)
目录
前言
一、状态机要素
二、状态机描述方法
1、一段式描述方法
2、两段式描述方法
3、三段式描述方法
三、关系
1、一段式与三段式
2、两段式与三段式
3、三种FSM描述方法比较表
四、状态机的种类
1、Moore型状态机
2、Mealy型状态机
3、注意点
五、举例
1、三种描述风格
一段式描述风格
两段式描述风格
三段式描述风格
说明
2、两种状态机
moore型状态机
mealy型状态机
说明
总结
前言
今天更新一篇状态机的总结,可以说万物基于状态机了,哈哈。本篇博主将会用自己的经历为大家总结一下状态机的设计,同时也会提出一些其他博客都没有讲到的点,希望能给大家分享这些经验。
一、状态机要素
什么是RTL级好的状态机(Finite State Machine,FSM)描述?
1、FSM要安全,稳定性高(最重要,优先级最高),即FSM不会进入死循环,特别是不会进入非预知的状态,即要求FSM的综合实现结果无毛刺等扰动,要求状态机要完备;
2、FSM速度快,满足设计的频率要求;
3、FSM面积小,满足设计的面积要求;
4、FSM设计要清晰易懂,易维护。
二、状态机描述方法
1、一段式描述方法
概述:整个电路用一个进程描述,包含状态转移条件判断、状态输出和状态寄存器转移。
缺点:A、不符合时序和组合逻辑分开描述的代码风格;B、不利于修改、维护;C、不利于附加约束;D、不利于综合器和布局布线器对设计的优化;E、代码冗长。
2、两段式描述方法
概述:从左往右:第二个进程(纯组合逻辑always模块),描述状态转移条件的判断;第一个进程(同步时序always模块),格式化描述次态到现态的转移;一般情况下是组合逻辑输出,如果时序允许,尽量寄存器输出。
缺点:其输出一般使用组合逻辑描述,而组合逻辑易产生毛刺等不稳定因素。
3、三段式描述方法
概述:从左往右:第二个进程和第一个进程同两段式状态机的描述方法一样;第三个进程(同步时序always),格式化描述状态的寄存器输出。这里的第三个进程是使用next_state做判断的,所以不会消耗多余的时钟周期。
优点:A、FSM做到了同步寄存器输出;B、消除了组合逻辑输出的不稳定与毛刺的隐患;C、更利于时序路径分组;D、在FPGA/CPLD等可编程逻辑器件上的综合与布局布线效果更佳。
三、关系
1、一段式与三段式
一段式建模:必须考虑现态在何种状态转移条件下会进入哪些次态,然后在每个现态的case分支下分别描述每个次态的输出。
三段式建模:只需指定case敏感列表为次态寄存器,然后在每个次态的case分支中描述该状态的输出即可(根本不用考虑状态转移条件)。
2、两段式与三段式
两段式建模:状态寄存器分割了两部分组合逻辑(状态转移条件组合逻辑)(输出组合逻辑),电路时序路径较短,可以获得更高的性能。
三段式建模:从输入到寄存器的输出路径上,要经过两部分组合逻辑(状态转移条件组合逻辑)(输出组合逻辑),从时序上,这两部分组合逻辑完全可以看为一体,因此这条路径的组合逻辑就比较复杂,该路径的时序相对紧张。但其优点也很突出:可以改善输出的时序条件;还能避免组合电路的毛刺,因此更为推荐这种写法。
3、三种FSM描述方法比较表
比较项目 | 一段式 | 两段式 | 三段式 |
推荐等级 | 不推荐 | 推荐 | 最优推荐 |
代码简洁程度 | 冗长 | 最简洁 | 简洁 |
always模块个数 | 1 | 2 | 3 |
是否有利于时序约束 | 不利于 | 利于 | 利于 |
是否有组合逻辑输出 | 可以无组合逻辑输出 | 多数情况下有组合逻辑输出 | 无组合逻辑输出 |
是否有利于综合与布局布线 | 不利于 | 利于 | 利于 |
代码的可靠性与可维护性 | 低 | 高 | 最高 |
代码风格的规范性 | 低,任意度较大 | 格式化,规范 | 格式化,规范 |
四、状态机的种类
1、Moore型状态机
状态机的输出至于当前的状态有关,如下图所示。
2、Mealy型状态机
状态机的输出不仅与当前的状态有关,还与当前的输入有关,如下图所示。
3、注意点
以上说明moore型状态机和mealy型状态机的区别所用的是两段式状态机,也就是状态输出都是采用组合逻辑输出。如果状态输出采用寄存器输出,则需要在输出端加一个寄存器,这样会多消耗一个时钟周期,但是功能不会发生错误。
三段式状态机中为了不消耗一个额外的时钟周期,采用next_state作为判断条件,但是如果采用mealy型状态机,则此时的输入将会和next_state一起作为判断条件来判断输出,这样就会发生功能错误,如下图所示。
正确的做法是将输出_temp与当前输入再用组合逻辑输出,如下图所示,这样功能不会发生错误。但是其实这种做法是多此一举的,因为这样做输出还是组合逻辑,没有采用寄存器输出,并且这条通路的时序相对紧张。博主这样的画法只是想说明保证三段式mealy状态机功能正确的做法。
五、举例
本节中,博主选择了两道HDLbits中的题目,来为大家更好的描述三种状态机写法以及moore、mealy状态机之间的差异。
1、三种描述风格
状态转移图如上图所示,下面是一段式、两段式、三段式的描述风格。
一段式描述风格
module top_module(input clk,input areset, // Asynchronous reset to state Binput in,output reg out);// parameter A=1'b0, B=1'b1; reg state;always@(posedge clk or posedge areset)beginif(areset)beginstate <= B;out <= 1'b1;endelse begincase(state)B:beginif(in == 1'b1)beginstate <= B;out <= 1'b1;endelse beginstate <= A;out <= 1'b0;endendA:beginif(in == 1'b1)beginstate <= A;out <= 1'b0;endelse beginstate <= B;out <= 1'b1;endenddefault:beginstate <= B;out <= 1'b1;endendcaseendendendmodule
两段式描述风格
输出写在下一状态转移组合逻辑中。
module top_module(input clk,input areset, // Asynchronous reset to state Binput in,output reg out);// parameter A=1'b0, B=1'b1; reg current_state, next_state;always@(posedge clk or posedge areset)beginif(areset)begincurrent_state <= B;endelse begincurrent_state <= next_state;endendalways@(*)begincase(current_state)B:beginif(in == 1'b1)beginnext_state = B;endelse beginnext_state = A;endout = 1'b1;endA:beginout = 1'b0;if(in == 1'b1)beginnext_state = A;endelse beginnext_state = B;endout = 1'b0;endendcaseendendmodule
输出与下一状态转移组合逻辑分开。
module top_module(input clk,input areset, // Asynchronous reset to state Binput in,output reg out);// parameter A=1'b0, B=1'b1; reg current_state, next_state;always@(posedge clk or posedge areset)beginif(areset)begincurrent_state <= B;endelse begincurrent_state <= next_state;endendalways@(*)begincase(current_state)B:beginif(in == 1'b1)beginnext_state = B;endelse beginnext_state = A;endendA:beginif(in == 1'b1)beginnext_state = A;endelse beginnext_state = B;endendendcaseendalways@(*)begin if(current_state == B)beginout = 1'b1;endelse beginout = 1'b0;endend/*//second way//assign out = (current_state == B);*//*//third wayalways@(*)begincase(current_state)B:beginout = 1'b1;endA:beginout = 1'b0;endendcaseend*/endmodule
三段式描述风格
module top_module(input clk,input areset, // Asynchronous reset to state Binput in,output reg out);// parameter A=1'b0, B=1'b1; reg current_state, next_state;always@(posedge clk or posedge areset)beginif(areset)begincurrent_state <= B;endelse begincurrent_state <= next_state;endendalways@(*)begincase(current_state)B:beginif(in == 1'b1)beginnext_state = B;endelse beginnext_state = A;endendA:beginif(in == 1'b1)beginnext_state = A;endelse beginnext_state = B;endendendcaseendalways@(posedge clk or posedge areset)beginif(areset)beginout <= 1'b1;endelse if(next_state == B)beginout <= 1'b1;endelse beginout <= 1'b0;endendendmodule
说明
一段式状态机描述中没有区分current_state和next_state,将所有的状态转移和输出逻辑写在一个always时序模块中,代码相对冗长,不利于分析电路结构。
两段式状态机描述中采用组合逻辑描述输出,其中两种大的写法,第一种是将输出逻辑融合到下一状态转移组合逻辑中,第二种是将输出和下一状态转移组合逻辑分开。大家要注意,这两种写法映射到电路中没有任何区别。有一点困扰的地方是大家通常将第二种写法叫做三段式状态机的第三段。从广义上来讲,这种叫法没有错,因为毕竟这三段分割明显,每一段做什么事情都很好理解,但是更细化,从电路结构来讲,这种写法只能称为两段式状态机,next_state到current_state采用时序逻辑,状态转移和输出采用组合逻辑,这是两段式状态机的标志。
三段式状态机描述中采用时序逻辑描述输出,为了节省一拍,采用next_state作为判断条件。
特别注意,这里只有A和B两个状态,只需要1bit,所以博主两段式和三段式的case中省略了default,这里建议不论条件是否列全,都应该加上default,博主没有加default的做法不值得提倡。
2、两种状态机
检测“101”序列,题目要求重叠检测(比如对于序列“101010”,重叠检测会输出两次高电平,不重叠检测会输出一次高电平)。
moore型状态机
状态转移图如下。
module top_module (input clk,input aresetn, // Asynchronous active-low resetinput x,output reg z ); parameter S0 = 2'd0, S1 = 2'd1, S2 = 2'd2, S3 = 2'd3;reg [1:0] current_state;reg [1:0] next_state;always@(posedge clk or negedge aresetn)beginif(aresetn == 1'b0)begincurrent_state <= S0;endelse begincurrent_state <= next_state;endendalways@(*)begincase(current_state)S0:beginnext_state = x ? S1 : S0;endS1:beginnext_state = x ? S1 : S2;endS2:beginnext_state = x ? S3 : S0;endS3:beginnext_state = x ? S1 : S2;enddefault:beginnext_state = S0;endendcaseendalways@(posedge clk or negedge aresetn)beginif(aresetn == 1'b0)beginz <= 1'b0;endelse beginif(next_state == S3)beginz <= 1'b1;endelse beginz <= 1'b0;endendendendmodule
mealy型状态机
状态转移图如下。
module top_module (input clk,input aresetn, // Asynchronous active-low resetinput x,output z ); parameter S0 = 2'd0, S1 = 2'd1, S2 = 2'd2;reg [1:0] current_state;reg [1:0] next_state;always@(posedge clk or negedge aresetn)beginif(aresetn == 1'b0)begincurrent_state <= S0;endelse begincurrent_state <= next_state;endendalways@(*)begincase(current_state)S0:beginnext_state = x ? S1 : S0;endS1:beginnext_state = x ? S1 : S2;endS2:beginnext_state = x ? S1 : S0;enddefault:beginnext_state = S0;endendcaseendassign z = ((current_state == S2) && (x == 1'b1)) ? 1'b1 : 1'b0;/*//second wayalways@(*)begincase(current_state)S0:beginz = 1'b0;endS1:beginz = 1'b0;endS2:beginz = x;endendcaseend*/endmodule
module top_module (input clk,input aresetn, // Asynchronous active-low resetinput x,output z ); parameter S0 = 2'd0, S1 = 2'd1, S2 = 2'd2;reg [1:0] current_state;reg [1:0] next_state;reg z_temp;always@(posedge clk or negedge aresetn)beginif(aresetn == 1'b0)begincurrent_state <= S0;endelse begincurrent_state <= next_state;endendalways@(*)begincase(current_state)S0:beginnext_state = x ? S1 : S0;endS1:beginnext_state = x ? S1 : S2;endS2:beginnext_state = x ? S1 : S0;enddefault:beginnext_state = S0;endendcaseendalways@(posedge clk or negedge aresetn)beginif(aresetn == 1'b0)beginz_temp <= 1'b0;endelse beginif(next_state == S2)beginz_temp <= 1'b1;endelse beginz_temp <= 1'b0;endendendassign z = z_temp == 1'b1 && x == 1'b1;endmodule
上面两组代码就是mealy型状态机分别使用“两段式状态机”和“三段式状态机”完成的写法,这里加了引号,因为不是标准的两段式和三段式,我们最常用的两段式和三段式主要都是针对moore型状态机所说。
说明
我们从上面的状态转移图可以看出,moore型状态机要比mealy型状态机多一个状态,也就意味着mealy型状态机要比moore型状态机快一个周期,因为mealy型状态机使用当前输入和当前状态共同判断,moore型状态机不需要当前输入。
总结
今天的这篇博客,基于博主自己对状态机的理解所写,包括博主曾经踩过的一些坑。博客中对三种状态机写法,两类状态机都有一些直观的描述,其中三种状态机的写法那部分参考了邸志雄老师在慕课的课程《芯动力——硬件加速设计方法》,感兴趣的同学可以去慕课观看,希望能给大家带来帮助。
状态机,从细节出发(一段式、两段式、三段式,moore型、mealy型)相关推荐
- Verilog 实现111序列检测器——Moore和Mealy型状态机实现
111序列检测器 有限状态机简介 电路结构 '111'序列检测器 Moore状态机 代码实现 Mealy状态机 代码实现 有关三段式和两段式的对比 有关可重叠和不可重叠序列的对比 有限状态机简介 电路 ...
- html三段式布局,运用三段式框架,教你轻松应对10分钟即兴演讲!
即兴演讲不宜篇幅过长,一般人在很短的时间也不可能构思出内容复杂的宏篇巨论.因此,即兴演讲宜简短精炼,结构简单,一般为单线条式的结构,或横向的以事物的几个方面为纲,或纵向的以事物的发展过程为目,按逻辑思 ...
- 彻底搞懂状态机(一段式、两段式、三段式)
转自:https://blog.csdn.net/wordwarwordwar/article/details/78509445 实例:FSM实现10010串的检测 状态转移图:初始状态S0,a = ...
- mooremealy状态机区分(附例子代码)三段式描述方式
在状态机部分,moore和mealy也算是老生常谈了吧. 什么是状态? 说白了就是通过时钟信号不断改变当前的状态,可能是根据输入的数据,也可能是自身发生改变(比如一些计时器),所以少不了触发器,虽然我 ...
- 以爱情规律为例,浅谈三段式描述状态机
目录 基础概念介绍 状态机的要素 FSM的分类 Verilog描述状态机的方法 一段式描述 两段式描述 三段式描述 结语 基础概念介绍 今夜闲来无事,忽然想到最近准备复习一下Verilog语法,所以就 ...
- DSP嵌入式C语言状态机,三段式状态机描述及模版
三段式状态机描述及模版 [复制链接] 本帖最后由 Aguilera 于 2018-11-10 20:23 编辑 时序电路的状态是一个状态变量集合,这些状态变量在任意时刻的值都包含了为确定电路的未来行为 ...
- FPGA状态机(一段式、二段式、三段式)、摩尔型(Moore)和米勒型(Mealy)
1.状态机 1.1.理论 FPGA不同于CPU的一点特点就是CPU是顺序执行的,而FPGA是同步执行(并行)的.那么FPGA如何处理明显具有时间上先后顺序的事件呢?这个时候我们就需要使用到状态机了. ...
- Verilog有限状态机三段式描述方法【原创*改进】
1.好的状态机标准 好的状态机的标准很多,最重要的几个方面如下: 第一,状态机要安全,是指FSM不会进入死循环,特别是不会进入非预知的状态,而且由于某些扰动进入非设计状态,也能很快的恢复到正常的状态循 ...
- 2022-05-18——视频拍摄小记 ——三段式思维让短片更具有氛围感
分镜三段式拍摄,三段式思维让短片更具有氛围感 每次拍摄一个动作的时候,把它拆分成三个镜头 远景 中景 特写 特写镜头也可以换成风景,或者静物 顺序可以自己来考量,一般按照这个顺序拍摄,后期可以调整顺序 ...
- 【 FPGA 】状态机的模型之Mealy型状态机
上篇博文讲了:Moore型状态机,这篇博文和上篇博文思路一致,如果读懂了上篇博文,这篇博文就很容易理解了. 如果一个状态机的输出是由现态和输入共同决定的,那么它就是一个Mealy型的状态机.而按照驱动 ...
最新文章
- 哈佛的凌晨4点。。。
- 容器源码解析之LinkedHashSet(六)
- 光子浏览器_烟台招聘信息烟台光子信息科技有限公司招聘(五险一金,餐补)...
- asp sql 导出 excel_Mysql数据导出到excel基于python
- Apache下的FileUtils.listFiles方法简单使用技巧
- 懒人也能变美,AR试妆会让你剁手到停不下来吗?
- npm stripts 使用指南
- 计算机网络子网斜杠后面的含义,ip地址后面的斜杠24是什么意思
- html表格上只有竖边框,html中画表格让表格只有横边框没有竖边框.doc
- 关于使用腾讯乐固加固,涉及的签名及其他问题
- Linux下CGroup进行CPU、内存等资源控制
- git 强制同步远端仓库
- 22222222222
- 实用小工具:加密软件
- 电动汽车简化设计,“减重瘦身”不再难
- 华为服务器硬件图,华为RH2288 V3硬件简介_华为 FusionServer RH2288 V3_服务器评测与技术-中关村在线...
- Django REST 框架详解 06 | 视图家族 Generics 与 Viewsets
- 利用python爬取京东华为旗舰店手机信息(价格、型号、颜色、链接等)
- unity 开发游戏 认识_认识明天鼓舞人心的Unity开发人员
- 通配符SSL证书 通配符HTTPS证书特点 泛域名SSL证书是什么