在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 1762|回复: 3

[原创] 孩子都能学会的FPGA:第八课——状态机

[复制链接]
发表于 2023-11-22 17:06:33 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
本帖最后由 chdaj58 于 2023-11-22 17:07 编辑

原创声明:该文是作者的原创,面向对象是FPGA入门者,后续会有进阶的高级教程。宗旨是让每个想做FPGA的人轻松入门作者不光让大家知其然,还要让大家知其所以然!每个工程作者都搭建了全自动化的仿真环境,只需要双击top_tb.bat文件就可以完成整个的仿真(前提是安装了modelsim),降低了初学者的门槛。如果需要整个工程请留言索要(微信15092150280索要也可以),不收任何费用,但是仅供参考,不建议大家获得资料后从事一些商业活动!

前面几课的时间都是在讲计数器模块,相信大家掌握的都差不多了,那这节课我们开启一个新的模块——状态机。为什么要用状态机呢?这要从硬件设计的并行思维讲起,FPGA芯片只要一上电,内部的所有always模块开始开始并行执行。但是对于实际的工程应用中,往往需要设计硬件来实现一些具有顺序的工作,必须一些算法的实现,在比如一些寄存器的配置,就需要用到状态机的思想。

状态机是一种用于处理具有前后顺序的事件的计算机模型,包含现态、条件、动作和次态四个要素,它可以将一个复杂的控制流程分解成多个互相独立的状态,从而简化设计过程并提高了系统的可靠性和性能。

现态:系统当前所处的状态。比如早晨起来你还在家里,这就是你当前的状态;                                                                                                                     

输入:一般指外部事件,当一个外部事件发生后,状态机便会根据状态转移函数发生响应。 比如早晨7点30分是每天出门上班的时间。输入条件满足,状态就要开始转变。

次态:根据现态、输入、状态转移条件所得到的状态机将要跳转至的新状态。其中,“次态”是相对于“现态”而言的,一旦被跳转后,“次态”就转变成新的“现态”了。比如早晨7点30分去上班,去上班就是次态。但是7点30分后,你在上班的路上,此时去上班就变成了现态。

输出:由现态或现态和输入共同决定的,但是有时某一状态或者某一输入改变,输出并不一定会发生变化,带来的仅仅是状态迁移而已。比如输出是在公司工作,状态从家里变成去上班的路上,都没有达到输出的结果,此时输入不变。等到了公司开始工作,那输出就有变化了。

状态机有两种类型,一种是摩尔(Moore)型状态机:下一状态只由当前状态决定 ;另一种是米勒(Mealy) 型状态机:下一状态不但与当前状态有关,还与当前输入值有关 。

如下所示Moore型状态机,        最左侧是次态组合逻辑电路,通过将状态输出反馈到次态组合逻辑电路,在和输入信号决定,下一状态是什么状态。中间部分是时序电路,就是一个触发器,将下一状态的值给到现在的状态。最右侧是组合输出逻辑,通过判断当前的状态,得到输出。


v2-57936639952cfd2c2269fdcf0e5517a8_720w.png

如下所示Mealy型状态机,结构和Moore型状态机类似,只是最右侧的输出逻辑不仅与当前的状态有关,还有输入有关。


v2-0df2376084846dc3dee0fa9aad713d32_720w.png

在实际的应用中,Mealy型状态机的输出与输入有关,输出信号很容易出现毛刺,所以工程设计一般采用Moore型状态机。但是Moore型状态机最终的输出是组合逻辑,还是有产生毛刺的风险,目前输出逻辑大多采用时序逻辑进行实现。

一般来说,在FPGA中状态机有多种写法,常见的有一段式、两段式和三段式状态机

一段式状态机:所有的状态变化以及输出变化都写在一个always块中,在该always块中既描述状态的同步转移,又描述状态的输入条件和输出。采用一段式状态机会让结构和逻辑看起来比较混乱,不推荐使用。

两段式状态机:用两个always块来描述状态机。其中一个模块采用同步时序逻辑描述状态转移,另一个模块采用组合逻辑判断状态转移条件。它需要两个状态——现态和次态,然后通过现态和次态的转换来实现时序逻辑。输出采用组合逻辑。也不太推荐使用。

三段式状态机:用三个always块来描述状态机。其中一个模块采用同步时序逻辑描述状态转移,另一个模块采用组合逻辑判断状态转移条件(注意和两段式的区别)。第三个模块描述状态的输出(既可以用组合逻辑也可以用时序逻辑,建议使用时序逻辑)。

所以对于比较复杂的状态机建议采用三段式状态机的设计,比较简单的状态机采用改进的一段式状态机,即用一个always块描述状态的同步转移,但是用一个模块单独描述状态的输出(建议使用时序逻辑)。

下面通过一个简单的工程让大家在直观上理解一下状态机的运行。工程要求:系统时钟是100MHz,低电平复位,一根输入线上的电平会随机跳动,请检测出数字序列1011001。需求很明确,就是把线上特定的序列检测出来,线上的状态是串行变化的,所以用状态机实现是比较合适的。

那怎么定义状态呢?一般都会有一个IDLE状态,就是系统的初始状态,还有就是S1,S10,S101,S1011,S10110,S101100,S101101这几个状态,根据输入信号进行切换。比如开始检测上线的信号是1,那状态就由IDLE转变成S1,如果下一个时刻检测到的线上的信号是0,那状态就有S1转变成S10,如果这个时刻检测到的线上的信号是1,那状态就有S1转变成IDEL,以此类推。一般用状态转移图来表示,很直观明了。如下所示,pi输入,po是输出,根据输入确定状态机的跳转,并标明输出的值。


v2-cd0d9ec4c6922f64980deceb51cecdc8_720w.png

有了状态转移图,那FPGA代码的设计就很简单了,由于本状态机很简单,我们采用改进的一段状态机进行设计,下面讲解一下。pi是输入的随机电平信号,po是检测到数字序列1011001后的输出信号,po拉高表明检测到了期望的序列。定义了7bit的状态寄存器state,用来进行7个状态的切换,状态参数用的独热码进行定义,独热码的好处就是任意状态的切换指挥有一位变化,降低了数据变化出错的机率。


v2-148aaff63173cca7308977c804f77131_720w.png

然后根据状态图,通过输入pi的变化设计状态机的跳转即可,这儿需要注意一点,用了case语句一定要有default,就是一个默认的状态。目前的状态机简单,可以穷尽所有的状态,如果对于复杂的状态机,如果某些状态跳转没有描述,没有default语句,状态机可能就会卡死;而有了default语句,遇到未知的跳转条件就会跳转到这个默认的状态。


v2-b1e5d8f38aecfde19cf6090f36607685_720w.png

最后用时序逻辑设计了输出po,po拉高,就说明检测到了期望的序列。


v2-7143b1d66115dd1f511703c046b81813_720w.png

最后看一下仿真结果,如下所示:下图是检测到期望的1011001序列的一段仿真图,设计的功能是正确的。


v2-3fb825a7e3bb3d5dcf83f598d0273d39_720w.png

今天又熟悉了一个新的模块——状态机。如果能把状态机和计数器合理的组合,那就能设计出来更多的功能。前期的uart模块只能发送和接收单byte的数据,那如果发送和接收多byte的数据呢?那就要用上状态机了,我们下节课好好讲解。  


发表于 2023-12-25 17:18:37 | 显示全部楼层
楼主有这个系列的所有资料吗,麻烦发一下学习学习
发表于 2024-6-25 13:41:39 | 显示全部楼层
感谢分享
发表于 2024-10-11 15:27:43 | 显示全部楼层
感谢分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条


小黑屋| 手机版| 关于我们| 联系我们| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-12-26 03:14 , Processed in 0.018269 second(s), 7 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表