【转】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
电路如图所示:
万变不离其宗,本文到此结束。