阻塞和非阻塞的差别直观上表现在<= 和=的差别.但要表现出这个差别是有条件的.
看一下三个测试模块:
module test1(
input clk,
input [7:0] din,
output reg [7:0] dout
);
reg [7:0] a,b,c;
always @ (posedge clk)a=din;
always @ (posedge clk)b=a;
always @ (posedge clk)c=b;
always @ (posedge clk)dout=c;
endmodule
module test2(
input clk,
input [7:0] din,
output reg [7:0] dout
);
reg [7:0] a,b,c;
always @ (posedge clk)
begin
a<=din;
b<=a;
c<=b;
dout<=c;
end
endmodule
module test3(
input clk,
input [7:0] din,
output reg [7:0] dout
);
reg [7:0] a,b,c;
always @ (posedge clk)
begin
a=din;
b=a;
c=b;
dout=c;
end
endmodule
1,test1,test2模块产生了正确的流水寄存器.而test3没有,只产生了一个8位register.
2,test3是该非阻塞的时候没有正确非阻塞.应该使用<=;
3,在test1时候虽然是阻塞赋值但是由于是采用单独的always进行边缘赋值,因此产生了正确的结果.
4,形式服从于内容,只有在内容一样的时候,形式的作用才体现出来(test2和test3就是通过形式区别内容的).要对形式和内容的辨证关系有明确的意识.抓住内容实质,重视形式表现.
5,其实完全没有必要去死记阻塞(=)与非阻塞(<=)的差别,知道到什么样的电路需要用什么样的HDL去表达就可以,是去理解。我每次在说阻塞非阻塞对应符号时候都有点胆战心惊,生怕对应错,但是我知道什么时候要区别<=和=这两个符号,什么时候不需要区别以及区别的时候用<=还是=,这应该理解了实质,就够了。
6,另外千万不要认为只要是带有<=都生成了寄存器,还要看触发条件是否为边缘触发。always@* outp<=inp; 这句就相当于直接连通inp到outp而没有生成寄存器。
test1 test2模块生成的RTL原理图 (原文件名:test12.JPG)
test3模块生成的RTL原理图 (原文件名:test3.JPG) |
|