阻塞赋值——“=” <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
非阻塞赋值——“〈=”
为了说明方便引入 RHS——表赋值符号右边的变量或者表达式
LHS——表赋值符号左边的变量或者表达式
1、入门以后始终搞不清楚的名词“阻塞”“非阻塞”?
正解:对于阻塞赋值(“=”)来说,一旦出现该语句,在赋值时先计算RHS的值,且不允许(阻塞)其他赋值语句执行(我们知道Verilog语句执行的最大特点是“并行性”,如果这点不知道,请不要在往下看了,很费眼的!O(∩_∩)O~)。现行的赋值RHS完成,立即赋值给LHS(同一时刻,立即更新),然后才允许别的赋值语句执行。
用书本上的有点“矛盾的话”一句话讲:“存在概念上的先后,而无实质上的延迟”。。。
而对于非阻塞赋值(“<=”)来说,则是出现以后,赋值是也计算RHS的值,但其允许其他Verilog语句(也包括其他赋值非阻塞语句)进行操作,所有同时钟下的并行语句都操作结束以后,才更新LHS。
我的理解是,“=”,RHS完成后马上赋值给LHS,优先权是最大的,别的都要退让。
“<=”RHS完成后要等会才能赋值LHS,优先级是最小的,同级别的其他语句,可以都进行操作,不会阻塞!
2、两种赋值各有各的妙处,使用中要具体情况具体分析。不加区分的乱用,出现的麻烦会意想不到,请看:
上面是一个采用阻塞语句实现的反馈振荡器,其主要的逻辑含义,很简单咯,两个always块理论上并行执行的,若rst(复位信号)由高变低(以后不再发生变化),那么初始值y1为0,y2为1。在同一有效时钟作用,进行相互赋值。(我一开始认为不就是简单的y1从0变1,同时y2从1变0,随着时钟上升沿,再同步反向变化一次。。。。。。。。。)
情况1:编写ModelSim进行RTL仿真,其结果如下:
在复位初始化后,y1=y2=0;(好像块2失效了!)
情况2:若将2块放在1块前,在编译一次,进行RTL仿真:
在复位初始化后,y1=y2=1;(好像块2失效了!)
为什么会造成这两种仿真情况呢?
正解:理论上的块1和块2都应该是同时刻执行,但是实际上,有效时钟沿到达两个块是有一定的时钟偏差的(毕竟使用的不是同一个逻辑单元构成的),皮秒级的延时使得触发时间就有先有后,比如:情况1,可能是先触发了块1,执行了块1中的y2=y1(y1初始化值为0),赋值期间不能进行y1=y2,那么y2为1,等块1完成阻塞赋值后在进行的y1=y2就使得y1一直为1了。情况2,便是先触发了块2造成的结果。
这种调换顺序,会不稳定的情况,实际上在综合以后会造成传说中的“冒险和竞争”。那么采用非阻塞赋值去实现,情况是怎么样的呢?
无论块1和块2的位置如何,其RTL结果都是这样:
从仿真中可以,无论哪一个块先到,y1和y2的更新赋值都是由上一个周期的时钟的有效沿确定的。
进一步可以得出 原则1:时序电路建模,尽可能采样用非阻塞赋值,减少仿真时可能出现的冒险和竞争。
待续。。。。。。。。。。
zaocaokun_970486327 2015-1-15 16:49
用户403664 2015-1-14 17:16
用户603678 2012-10-28 10:19
用户603678 2012-10-28 10:16