**
阻塞指派與非阻塞指派的比較(RTL,時序圖分析)
**
1、阻塞指派(“=”)指在程序語句(initial 和 always)中,目前的指派語句會阻斷其後語句的正常執行,後面的語句必須等到目前的指派語句執行完畢才能執行。
2、非阻塞指派(“<=”)指在程序語句(initial 和 always)中,目前的指派語句不會阻斷其後語句的正常執行。
3、下列幾個代碼風格,可以為解決在綜合後仿真中出現絕大多數的冒險競争問題。
- 時序電路模組化時,用非阻塞指派;
- 鎖存器電路模組化時,用非阻塞指派;
- 用 always 塊建立組合邏輯模型時,用阻塞指派;
- 在同一個 always 塊中建立時序群組合邏輯電路時,用非阻塞指派;
- 在同一個 always 塊中不要既用非阻塞指派又用阻塞指派;
- 不要在一個以上的 always 塊中為同一個變量指派。
具體例子:
一、
【1】非阻塞:
code:
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
out <= 2'b0;
else begin
d <= a + b;
out <= d + c;
end
end
RTL:
值得注意的是,這裡RTL有兩個觸發器。
RTL行為級仿真(功能仿真):
詳細圖:
為了更清楚分析時序問題,加入d的時序圖:
tip:時序圖中紅圈部分。在黃線時刻上升沿前現态 d=0 c=0 則次态out=0+0=0;現态a=0 b=1 則次态d=a+b=1
門級仿真(綜合後仿真):
【2】阻塞:
code:
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
out <= 2'b0;
else begin
d = a + b;
out = d + c;
end
end
RTL:
與阻塞指派比,這裡隻有1個觸發器,其中兩個加法器直接相連。
RTL行為級仿真(功能仿真):
如圖6,a,b,c一旦有變化,out在clk上升沿時立即變化。
門級仿真(綜合後仿真):
在變化後out有時延。
【3】另一種非阻塞:
code:
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
out <= 2'b0;
else begin
out = a + b + c;
end
end
RTL:
如圖8可知和阻塞指派的RTL圖5一樣,均隻有1個觸發器。
RTL行為級仿真(功能仿真):
門級仿真(綜合後仿真):
上述是在看小梅哥的筆記後,自己做的仿真加上個人了解。
下面經過學長指點,做的另一種簡潔的例子,這個例子也可以更好的了解時序概念。
二、
【1】非阻塞:
code:
//計數
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt <= 0;
else if(cnt == 4'd9)
cnt <= 0;
else
cnt <= cnt + 1'b1;
end
//指派
always@(posedge clk)begin
a <= cnt;
b <= a;
c <= b;
end
RTL:
RTL行為級仿真(功能仿真):
在黃線時刻前,現态:a為1 b為0 c為0;上升沿後,次态:a<=cnt=0 b<=a(現态)=1 c<=b(現态)=0,以此類推。
【2】阻塞:
code:
//計數
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt <= 0;
else if(cnt == 4'd9)
cnt <= 0;
else
cnt <= cnt + 1'b1;
end
//指派
always@(posedge clk)begin
a = cnt;
b = a;
c = b;
end
RTL:
RTL行為級仿真(功能仿真):
tip:在時序中,非阻塞指派隻要出現寄存器就需要考慮時序的現态次态問題,而阻塞指派無需考慮。