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

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

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
查看: 518|回复: 0

[原创] 孩子都能学会的FPGA:第四课——组合逻辑和时序逻辑

[复制链接]
发表于 2023-11-20 16:23:56 | 显示全部楼层 |阅读模式

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

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

x

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


上课讲了阻塞赋值和非阻塞赋值,很多人可能会有疑问,为什么要分阻塞赋值和非阻塞赋值,合并成一种赋值不可以吗?这不是增加了开发的难度吗?说实话,还真的的不能合并,因为学习过数字电路的人都知道,数字电路的根据触发器有没有时钟可以分为组合电路和时序电路,那对应到FPGA开发上就是组合逻辑时序逻辑,说白了FPGA的开发就是组合逻辑和时序逻辑的开发,大家去看看所有的FPGA工程,都是组合逻辑和时序逻辑的有机组合。下面详细的介绍这两种逻辑。


组合逻辑,反应在硬件电路上就是没有时钟的锁存和控制组合电路任意时刻的输出仅仅取决于当前时刻的输入,与电路原本的状态无关,就是组合电路没有任何的记忆功能。可以把组合电路想象成《水浒传》中的李逵,无组织无纪律,李逵的行为(输出)只与当前的环境(输入)有关,根本不去管出发前宋江大哥的命令(以前时刻的输入),所以李逵才会惹出来那么多的麻烦来。组合逻辑的这种性质,注定了要用阻塞赋值来实现,因为阻塞赋值不消耗仿真时间,当前输入的变化马上反应到输出的变化,所以阻塞赋值就是为组合逻辑量身定制的!


时序逻辑,反应在硬件电路上就是有时钟可以进行锁存和控制,时序电路任意时刻的输出不仅取决于当前时刻的输入,而且还和电路原来的状态有关,就是时序电路是有记忆功能的。可以把时序电路想象成《水浒传》中的108将,上梁山前大家各自为战,但是上了梁山就要统一行动听指挥,不能私自行动,就像李逵私自下山就要受到惩罚。时序逻辑的性质,决定要用非阻塞赋值来实现,因为非阻塞赋值是让所有的寄存器在特定的时刻统一变化,其它时刻大家保持当前的状态即可。


大家常用照镜子来比喻用阻塞赋值实现组合逻辑,只要你站在镜子前面,镜子里面马上就可以出现你的样貌,但是只要你离开镜子,镜子里面马上就没有了你的样貌。常用手机拍照来比喻用非阻塞赋值实现时序逻辑,比如自拍,只有按了拍照按钮,你的样貌才会被保存成图片,当前图片可以保存到下一次按动拍照按钮为止,图片就会更新为新的一副图片,在这期间,无论你的表情和动作如何变化,图片上的内容都不会变化。


下面我们用实例来说明,还是用第二课的流水灯为例说明,当时我们把one_second_done信号定义成了wire,然后用assign进行赋值(为了快速仿真SYS_CLK设置为10),这就是阻塞赋值,实现的就是组合逻辑

31.png

看看仿真结果,one_second_cnt由8变化成9的时刻one_second_done拉高,在one_second_cnt由9变化成0的时刻one_second_done拉低,就是one_second_cnt的变化马上会引起one_second_done的变化。


32.png


阻塞赋值的信号一定要定义成wire类型吗?其实不是的,也可以定义成reg类型,不过实现组合逻辑的方式要改变一下,如下所示。@(*)的意思是模块中所有信号的变化都是同时引起one_second_done的变化

33.png


仿真结果和用assign的仿真结果是一样的,如下所示。

34.png


one_second_done可不可以用时序逻辑来实现,在本例中是可以的,修改FPGA程序如下:

35.png

然后再看看仿真解决,比较一下和组合逻辑实现的有什么不同。如下所示,结果很明显,计数器one_second_cnt多计数了一次,计数器one_second_cnt是10的时候one_second_done才拉高具体分析一下,时序逻辑的计数器one_second_cnt8变成9是在clk上升沿再往后Δt的时间,就是在clk上升沿的时候计数器的值还是8,所以此时one_second_done不会拉高。计数器one_second_cnt9变成10是在clk上升沿再往后Δt的时间,就是在clk上升沿的时候计数器的值还是9,所以此时one_second_done才会被拉高!one_second_done拉低也是相同的分析思路。

36.png

从功能上分析,上面的FPGA程序其实是错误的,本来预期的是每计数10one_second_done拉高一次,现在变成了每计数11one_second_done拉高一次,所以在时序逻辑中,要把修改计数的值,才能保证功能的正确,如下所示。

37.png

在看看仿真结果,功能就是正确的了。

38.png

大家可能会说,你口口声声说要大家尽快入门FPGA,但是连续几课只讲计数器和流水灯,要是别人早就讲到各个IP的设计了。我想说的是:开始慢一点,是为了后面的快一些!下课让大家看看仅仅使用计数器就可以实现UART的协议!


您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

×

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

GMT+8, 2024-5-13 16:35 , Processed in 0.026360 second(s), 9 queries , Gzip On, Redis On.

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