【技巧分享】MDY关于阻塞赋值与非阻塞赋值的讨论
阻塞与非阻塞作者:小黑同学【总结1】规范用法:时序逻辑使用非阻塞赋值,组合逻辑使用阻塞赋值。【总结2】按照规范用法,不会产生任何问题。【总结3】非规范用法,纯粹是为了学术探讨的目的,而不是应用目的。 为学术探讨,可以看下面的内容。关于阻塞赋值和非阻塞赋值的讨论1. FPGA里只要总结出一个规范用法:时序逻辑使用非阻塞赋值,组合逻辑使用阻塞赋值,就不会产生任何问题,即使你不懂阻塞和非阻塞的区别都可以。2. 有关于阻塞赋值和非阻塞赋值,纯粹是国内的学者,无聊、咬文嚼字、卖弄语法才整出来的问题,更多地去解析语法,玩不同语法情况下的理解。3. 经常会问到:不按“规范用法”去做,会产生什么样现象的问题!这种问题实在是太多太多,各种角度提问的方式都有,防不胜防。为此,特提供一个思路,请按这个思路来去理解。 a. 首先一定要理解,VERILOG是硬件描述语言这个大前提!请深刻理解!VERILOG就是用来描述功能,然后综合器按照功能描述,去产生一个电路,来跟这个功能对应! b. 阻塞赋值是一行一行“执行”,非阻塞赋值是“同时执行”。这是第二前提。请仔细思考在这前提下,这个功能会如何变,必要时结合CLK一起理解!!!(如果实在理解不了,那就用MODELSIM仿真,仿真结果就是功能) c. 综合器根据“描述的功能”来生成电路,这是第三前提。综合器生成的电路,一定是与“功能描述一样”,即使这个电路看起来跟设想的完全不一样。 d. 请按上面三步,逐个确认。参考的视频:https://www.bilibili.com/video/BV1yf4y1R7gH?p=26
一、 概述
1、阻塞赋值对应的电路往往与触发沿没有关系,只与电平的变化有关系。阻塞赋值符号“=”。
2、非阻塞赋值对应的电路结构往往与边沿触发有关系,只有在触发沿时才有可能发生赋值的情况。非阻塞赋值符号“<=”。
二、 赋值方式
1、阻塞赋值
阻塞赋值操作符用等号(即 = )表示。阻塞赋值时先计算等号右手方向(RHS)部分的值,这时赋值语句不允许任何别的语句的干扰,直到现行的赋值完成时刻,即把RHS赋值给 LHS的时刻,它才允许别的赋值语句的执行。 一般可综合的阻塞赋值操作在RHS不能设定有延迟,(即使是零延迟也不允许)。若在RHS 加上延迟,则在延迟期间会阻止赋值语句的执行, 延迟后才执行赋值,这种赋值语句是不可综合的,在需要综合的模块设计中不可使用这种风格的代码。
阻塞赋值的执行可以认为是只有一个步骤的操作:
所谓阻塞的概念是指在同一个always块中,其后面的赋值语句从概念上(即使不设定延迟)是在前一句赋值语句结束后再开始赋值的。
如果在一个过程块中阻塞赋值的RHS变量正好是另一个过程块中阻塞赋值的LHS变量,这两个过程块又用同一个时钟沿触发,这时阻塞赋值操作会出现问题,即如果阻塞赋值的次序安排不好,就会出现竞争。若这两个阻塞赋值操作用同一个时钟沿触发,则执行的次序是无法确定的。
2、非阻塞赋值
非阻塞赋值操作符用小于等于号 (即 <= )表示。在赋值操作时刻开始时计算非阻塞赋值符的RHS表达式,赋值操作时刻结束时更新LHS。在计算非阻塞赋值的RHS表达式和更新LHS期间,其他的Verilog语句,包括其他的Verilog非阻塞赋值语句都能同时计算RHS表达式和更新LHS。非阻塞赋值允许其他的Verilog语句同时进行操作。非阻塞赋值的操作可以看作为两个步骤的过程:
1)在赋值时刻开始时,计算非阻塞赋值RHS表达式。
2)在赋值时刻结束时,更新非阻塞赋值LHS表达式。
非阻塞赋值操作只能用于对寄存器类型变量进行赋值,因此只能用在“initial”块和“always”块等过程块中。非阻塞赋值不允许用于连续赋值。
三、 举例
1、 阻塞赋值
项目例 1 例 2
描述wire ck;
reg a, b, c, d;
always @( posedge ck ) begin
c = b;
b = a;
a = d;
end
[代入前的初始值]
a = 5; c = 10;
b = 3; d = 2;wire ck;
reg a, b, c,
always @( posedge ck ) begin
a = d; //不同处 c = b;
b = a;
end
[代入前的初始值]
a = 5; c = 10;
b = 3; d = 2;
运算结果a = 2; c = 3;
b = 5; d= 2;a = 2; c = 3;
b = 2; d= 2;
2、 非阻塞赋值
项目例 1 例 2
描述wire ck;
reg a, b, c, d;
always @( posedge ck ) begin
c〈 = b;
b 〈= a;
a 〈= d;
end
[代入前的初始值]
a = 5; c = 10;
b = 3; d = 2;wire ck;
reg a, b, c,
always @( posedge ck ) begin
a 〈= d; //不同处 c 〈= b;
b 〈= a;
end
[代入前的初始值]
a = 5; c = 10;
b = 3; d = 2;
运算结果a = 2; c = 3;
b = 5; d= 2;a = 2; c = 3;
b = 5; d= 2;
四、 总结
综上所述,明德扬至简设计法提出这样的规则:时序逻辑用非阻塞赋值,组合逻辑用阻塞赋值。
页:
[1]