【转】VeriLog HDL 阻塞性过程赋值与非阻塞性过程赋值

VeriLog HDL 阻塞性过程赋值 与 非阻塞性过程赋值

首先来看一下定义:

阻塞性过程赋值 “=” : 即,在下一条语句执行前,完成当前语句执行。

非阻塞性过程赋值 “<=”: 即,在当前输出时间同步结束后,或者任意输出被调度时,完成该语句执行。

下面解释一下上面的说法,根据以上说法与实际综合来看,即:阻塞赋值 “=” 为同一个时钟时刻内赋值完成所有操作。如果模块比较大,则会增加逻辑速度延迟开销。非阻塞赋值 “<=” 为当且仅当下一个时钟到来时候,或者本次触发完毕,进行赋值操作。如果模块比较大,则插入寄存器,增大逻辑模块数量开销。

 

下面我们看一段代码来通过综合比较上面的说法:

1:“=”阻塞性赋值:

`default_nettype wand
`timescale 1ns/100ps
module top(clk,rst,d,q,qout);
input clk,rst,d;
output q,qout;
reg q,qout;
/*********************************/
always @(posedge clk or negedge rst)
begin
if(!rst)
begin
   q = 0;
   qout = 0;
end
else
begin
   q = d;
   qout = ~q;
end
end
endmodule
通过以上代码生成电路如图所示:


此图表明,在同一个时钟周期到来的时候,即完成 q 与qout 的完全赋值。

2:“<=”非阻塞性赋值:

`default_nettype wand
`timescale 1ns/100ps
module top(clk,rst,d,q,qout);
input clk,rst,d;
output q,qout;
reg q,qout;
/*********************************/
always @(posedge clk or negedge rst)
begin
if(!rst)
begin
   q <= 0;
   qout <= 0;
end
else
begin
   q <= d;
   qout <= ~q;
end
end
endmodule
通过以上代码生成电路如图所示:

此图表明,在下一个时钟周期或者本次时钟周期结束时才进行赋值操作。

 

下面我们再来分析一下什么情况下才会插入寄存器。

我们在以上代码的基础上再定义 s0 和 s1 两个寄存器。

3:“=”阻塞性赋值:

`default_nettype wand
`timescale 1ns/100ps
module top(clk,rst,d,q,qout);
input clk,rst,d;
output q,qout;
reg q,qout;
reg s0,s1;
/*********************************/
always @(posedge clk or negedge rst)
begin
if(!rst)
begin
   q = 0;
   qout = 0;
end
else
begin
   s0 = d;
   q = s0;
   s1 = ~q;
   qout <= s1;
end
end
endmodule
通过以上代码综合产生的电路如图所示:


通过图所示,没有插入寄存器。

4:“<=”非阻塞性赋值:

`default_nettype wand
`timescale 1ns/100ps
module top(clk,rst,d,q,qout);
input clk,rst,d;
output q,qout;
reg q,qout;
reg s0,s1;
/*********************************/
always @(posedge clk or negedge rst)
begin
if(!rst)
begin
   q <= 0;
   qout <= 0;
end
else
begin
   s0 <= d;
   q <= s0;
   s1 <= ~q;
   qout <= s1;
end
end
endmodule
通过以上代码综合分析如图所示:


即:插入寄存器。

我们再看一下底层电路:

通过以上分析,我们可以得出结论:

“=”阻塞性赋值:不会插入寄存器,在always顺序语句中不起到顺序作用,而是得到always的触发条件在同一个时钟周期内完成所有逻辑运算。

“<=”非阻塞赋值:插入寄存器,在always顺序语句中明显顺序运行,在always触发条件下,在时钟完成时刻或者下一个时钟到来时完成赋值运算。

 

 

最后我们来改变以上代码,通过一个阻塞与非阻塞混用来控制寄存器的插入与逻辑同步控制:

`default_nettype wand
`timescale 1ns/100ps
module top(clk,rst,d,q,qout);
input clk,rst,d;
output q,qout;
reg q,qout;
reg s0,s1;
/*********************************/
always @(posedge clk or negedge rst)
begin
if(!rst)
begin
   q = 0;
   qout = 0;
end
else
begin
   s0 <= d;
   q = s0;
   s1 <= ~q;
   qout = s1;
end
end
endmodule

电路如图所示:


万变不离其宗,本文到此结束。

posted @ 2014-06-26 16:00  luckybag  阅读(1183)  评论(0编辑  收藏  举报