良好的代碼風格推薦:
1.組合邏輯儘量採用阻塞邏輯
2.時序邏輯儘量採用非阻塞賦值
3.同一個always模塊中儘量不要混用組合邏輯和時序邏輯。
4.阻塞邏輯是 = ,語句按順序執行,後一語句等待前一語句執行完之後才執行,所以稱之爲阻塞
5.非阻塞邏輯是 <= ,語句同時執行,所以通常稱之爲非阻塞
下面給出兩個例子說明:
1.對於組合邏輯
用阻塞賦值得到如下程序:
module non_blocking(
input a,
input b,
input c,
input d,
output out
);
reg t1,t2,out;
always@(a or b or c or d) begin
t1=a & b;
t2=c & d;
out=t1 | t2;
end
endmodule
當a,b,c,d同時由0變爲1時,out變爲1,按順序執行,沒有延時。
用非阻塞賦值得到如下程序:
module non_blocking(
input a,
input b,
input c,
input d,
output out
);
reg t1,t2,out;
always@(a or b or c or d or t1 or t2) begin
t1<=a & b;
t2<=c & d;
out<=t1 | t2;
end
endmodule
用非阻塞賦值,敏感列表中必須添加t1和t2,因爲這三句語句同時執行,第三句並不是等前兩句執行完才執行。
上面兩行代碼得到的仿真圖形都如下所示:
2.對於時序邏輯
實現移位寄存器,用阻塞邏輯得到如下程序:
module block1(q0,q1,q2,q3,din,clk);
input clk,din;
output reg q0,q1,q2,q3;
always @(posedge clk)
begin
q3=q2; //注意賦值語句的順序
q2=q1;
q1=q0;
q0=din;
end
endmodule
對於阻塞邏輯,只要顛倒上面賦值順序,便不能按照我們的想法實現移位寄存器。
對於非阻塞邏輯得到如下程序:
module block4(q0,q1,q2,q3,din,clk);
input clk,din;
output reg q0,q1,q2,q3;
always @(posedge clk)
begin
q3<=q2;
q1<=q0;
q2<=q1;
q0<=din;
end
endmodule
顛倒順序不影響結果。
重要!!!!!!!
阻塞賦值和非阻塞賦值是指一個begin...end中的語句是按順序執行還是同時執行,與延時沒有關係!!
組合邏輯和時序邏輯的重要區別是時鐘信號在不在敏感列表中!!