深入理解阻塞和非阻塞赋值的不同

1、阻塞赋值和非阻塞赋值对应着两种不同的电路结构

        (1)阻塞赋值对应的电路结构往往与触发沿没有关系,只与输入电平的变化有关系。

        (2)非阻塞赋值对应的电路结构往往与触发沿有关系,只有在触发沿时才有可能发生赋值的变化。

2、正确使用赋值操作避免在Verlog仿真时出现竞争和冒险的现象

        在编写代码时首先要遵循下面这两个要点:

        (1)在描述组合逻辑的always块中用阻塞赋值,则综合成组合逻辑的电路结构。

        (2)在描述时序逻辑的always块中用非阻塞赋值,则综合成时序逻辑的电路结构。

        为什么要遵循这两个要点呢?这是因为要使综合前仿真和综合后仿真一致的缘故。如果不按照上面这两个要点来编写Verilog代码,也有可能综合出正确的逻辑,但前后仿真的结果就会不一致。

        IEEE Verilog标准定义了有些语句有确定的执行时间,有些语句没有确定的执行时间。若有两条或两条以上语句准备在同一时刻执行,但由于语句的排列顺序不同(而这种排列顺序的不同是IEEE Verilog标准所允许的),却产生的不同的输出结果,这就造成了Verilog模块竞争和冒险现象的原因。为了避免产生竞争,理解阻塞和非阻塞赋值在执行时间上的差别是至关重要的。

3、阻塞赋值和非阻塞赋值详细介绍

3.1、阻塞赋值

        阻塞赋值操作符用等号(即 = )表示。为什么称这种赋值为阻塞赋值呢?这是因为在赋值时先计算等号右手方向(RHS)部分的值,只是赋值语句不允许任何别的Verilog语句的干扰,直到现行的赋值完成时刻,即把RHS赋值给LHS的时刻,它才允许别的赋值语句的执行。一般可综合的阻塞赋值操作在RHS不能设定有延迟的(即使是零延迟也不允许)。从理论上讲,它与后面的阻塞赋值只有概念上的先后,而无实质上的延迟。若在RHS上加延迟,则在延迟期间会阻止赋值语句的执行,延迟后才能执行赋值,这种赋值语句是不可综合的,在需要综合的模块设计中不可使用这种风格的代码。

        阻塞赋值的执行可以认为是只有一个步骤的操作,即计算RHS并更新LHS,此时不能允许有来自任何其他Verilog语句的干扰。所谓阻塞的概念是指同一个always块中,其后面的赋值语句从概念上(即使不设定延迟)是在前一句赋值语句结束后再开始赋值的。

        如果在一个过程块中阻塞赋值的RHS变量正好是另一个过程块中阻塞赋值的LHS变量,这两个过程块又用同一个时钟触发,这时阻塞赋值操作会出现问题,即如果阻塞赋值的顺序安排不好,就会出现竞争。若这两个阻塞赋值操作用同一个时钟沿触发,则执行的顺序是无法确定的。 

举例如下:

module fboscl (y1, y2, clk, rst);
	output y1, y2;
	input clk, rst;
	reg   y1, y2;
	
	always@(posedge clk or posedge rst)
		if(rst) y1 = 0;   //reset
		else    y1 = y2;

	always@(posedge clk or posedge rst)
		if(rst) y2 = 1;   //preset
		else    y2 = y1;

endmodule

        按照 IEEE Verilog的标准,上例中的两个always块是并行执行的,若复位信号已从1到0,且例中上面的always块的有效时钟沿比下面的always块的时钟沿早几个皮秒(由时钟偏差造成)到达,则y1和y2都会取1;而若下面的那个always块的有效时钟沿早几个皮秒到达,则y1和y2都会取0。这清楚的说明这个Verilog模块是不稳定的,必定会产生竞争和冒险的情况。

3.2、非阻塞赋值

        非阻塞赋值操作符用小于等于号(即 <= )表示。为什么称这种赋值为非阻塞赋值?这是因为在赋值操作时刻开始时计算非阻塞赋值符的RHS表达式,赋值操作结束时刻才更新LHS。在计算非阻塞赋值的RHS表达式和更新LHS期间,其他的Verilog语句,包括其他的Verilog非阻塞赋值语句都能同时计算RHS表达式和更新LHS。非阻塞赋值允许其他的Verilog语句同时进行操作。非阻塞赋值的操作过程可以看作两个步骤:

        (1)在赋值开始时刻,计算非阻塞赋值RHS表达式;

        (2)在赋值结束时刻,更新非阻塞赋值LHS表达式。

         非阻塞赋值操作只能用于对寄存器类型变量进行赋值,因此只能用于在“initial”块和“always”块等过程块中,而非阻塞赋值不允许用于连续赋值

举例如下:

module fbosc2 (y1, y2, clk, rst);
	output y1, y2;
	input clk, rst;
	reg   y1, y2;
	
	always@(posedge clk or posedge rst)
		if(rst) y1 <= 0;   //预置值
		else    y1 <= y2;

	always@(posedge clk or posedge rst)
		if(rst) y2 <= 1;   //预置值
		else    y2 <= y1;

endmodule

        同样,按照 IEEE Verilog的标准,上例中两个always块是并行执行的,与先后顺序无关。复位信号回到0后,无论哪一个always块的有效沿先到,两个always块中的非阻塞赋值都在赋值开始时刻计算RHS表达式,而在结束时刻才更新LHS表达式。所以,复位信号从1回到0后,无论哪个always块的有效时钟沿早到几个皮秒,y1为1,而y2为0是确定的,因为实质上y1被赋的y2值是由rst正跳变沿决定的,而y2被赋的y1也是由rst正跳变沿决定的(若以后rst继续保持为0,时钟信号不断重复,则每次被赋值的y1和y2都是由上一个周期的时钟有效沿确定的),从用户的角度看这两个非阻塞赋值好像是并行执行的。

4、Verilog模块编程要点

        在编写Verilog代码时必须牢记这8个要点,才能在综合布局布线后的仿真中避免出现j竞争冒险现象。

        (1)时序电路电路建模时,用非阻塞赋值。

        (2)锁存器电路建模时,用非阻塞赋值。

        (3)用always块建立组合逻辑模型时,用阻塞赋值。

        (4)在同一个always块中建立时序和组合逻辑电路时,用非阻塞赋值。

        (5)在同一个always块中不要既用非阻塞赋值又用阻塞赋值。

        (6)不要在一个以上的always块中为同一个变量赋值。

        (7)用$strobe系统任务来显示用非阻塞赋值的变量值。

        (8)在赋值时不要使用#0延迟。

 5、什么是竞争与冒险

        竞争:在组合电路中,信号经由不同的路径到达某一会合点的时间不一致的现象。

        冒险:由于竞争而引起电路输出发生瞬间错误,表现为输出端出现了理论上没有的窄脉冲。

~OVER~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Panda 皮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值