对于阻塞赋值与非阻塞赋值的理解
前言
笔者初次接触阻塞赋值与非阻塞赋值是在数电课上,初次接触这个概念不由自主的和多线程的一系列概念联系在一起。
在这不妨多说几句(可以不看🤤),单核CPU的多线程是通过中断的形式来实现的,那么多线程本质就是一条线程运行多个任务,快速切换,所形成的“多线程假象“。
而对比到FPGA,如果把他的非阻塞赋值理解成多线程,那么我们惊喜的发现,FPGA能够实现真正的多线程,这无疑使得一些可以并行执行的任务在一个时间段内完成,而不是用CPU的形式不断终端开始增加时间复杂度。
当然,这一切只是无端联想。作者接下来也会以这个联想位暗线,开启FPGA之旅。
为什么会有阻塞赋值与非阻塞赋值
- 为什么C语言只有一种赋值?
- 为什么有两种赋值方式,而不是三种?
- 这种设计因为什么而产生?
一言以蔽之,因为时序逻辑和组合逻辑的存在,所以有了阻塞与非阻塞赋值。
这句话可能初听起来咋咋呼呼,且听我细表。
我第一次听到的这句话的说法是
时序逻辑推荐用<=赋值,组合逻辑推荐用=赋值
但我却用了相反的逻辑,即因为时序逻辑和组合逻辑的存在, 才有了这两种赋值语句,也必须有且只有这两种赋值方式。
对于时序逻辑来说,每一次操作都需要一个时钟信号来激发。假设传播没有延时,形象的来讲,一次上升沿来临,就推动我们的电路向前流一格,电路在一格一格的向前推动,而不是光速传播。
而对于组合逻辑来说,我们在理想情况下不考虑传输延迟,也就是说,赋值是立刻的。
因此,在组合逻辑中对于下面这条语句
a=b+c
对应出来的组合逻辑就是一个或门(三根电线,一个或门)。
而对于下面这条语句,
a<=b+c
在时序逻辑中,对应出来的应该是一个寄存器,因为要等待时钟的来临,才能进行赋值,等待的过程就是记忆的过程,就是需要寄存器的过程。
而对于组合逻辑,光速导通,无需记忆。
再换个方向思考一下
- 如果时序逻辑用=来赋值,会出现什么样的RTL电路图
- 如果组合逻辑用<=来赋值,会出现什么样的RTL
作者无法用语言给出合乎逻辑的解释,这个问题似乎只可意会了。
我们应该如何不假思索的使用他们
答案是简单的
时序逻辑推荐用<=赋值,组合逻辑推荐用=赋值
当然还有一些详细的规范,这里给出(摘录野火教程
(1)在编写时序逻辑的代码时采用非阻塞赋值的方式
计算赋值号右手边的信号时,所有的变量值均是触发沿到来前的值,更新的赋值号左手边的信号作为触发沿后的值,并且保持到下一个触发沿到来时候,等待更新。这样,就可以使得在同一个块中非阻塞赋值语句不必要求出现的顺序,都是在全部进行赋值号右手边的信号计算后同时更新赋值号左手边的信号的值。非阻塞赋值可以简单的认为 是赋予下一状态的值。
(2)使用always块来编写组合逻辑的代码时要用阻塞赋值的方式
使用always块建立组合逻辑电路模型时不要忘记always块中的敏感列表一定要使用电平触发的方式,然后在always块中使用阻塞赋值语句就可以实现组合逻辑,这样做既简单且方针又快又好,这样的风格是值得推荐的。
(3)在同一个always块中不要既要用非阻塞赋值又用阻塞方式赋值
在同一个always块中对同一个变量既进行阻塞赋值又进行非阻塞赋值会产生综合不可预测的结果,不是可综合的Verilog风格。
(4)虽然锁存器电路建模是我们不推荐的,但是如果使用到要采用非阻塞赋值的方式。
使用非阻塞赋值实现时序逻辑,实现锁存器是最为安全的。
(5)一个always块只一个变量进行赋值
[野火教程]([10. 阻塞赋值与非阻塞赋值 — 野火]FPGA Verilog开发实战指南——基于Altera EP4CE10 征途Pro开发板 文档 (embedfire.com))
下期预告
挖的坑越多越有动力学习
- 锁存器latch
- 由FPGA硬件资源所决定的设计思想(从高级语言到门电路语言的思想转换)
- FPGA图像识别之路
争取在下期学会配精美配图
期待你的关注
恳请各位大神指教FPGA学习之路,也欢迎一起学习探讨
作者邮箱:1302599315@qq.com
电路语言的思想转换)
- FPGA图像识别之路
争取在下期学会配精美配图
期待你的关注
恳请各位大神指教FPGA学习之路,也欢迎一起学习探讨
作者邮箱:1302599315@qq.com