用一個例子來學習阻塞賦值和非阻塞賦值


阻塞賦值與非阻塞賦值

阻塞賦值的一般表達式為:目標變量名=驅動表達式  阻塞賦值是一種理想化的數據傳輸,賦值立即發生,不存在延時行為

非阻塞賦值一般表達式為:目標變量名<=驅動表達式   非阻塞賦值比較接近真實的電路工作狀態,應為他從綜合的角度考慮到了延時和並行性。

 

在過程啟動中,非阻塞賦值使三條語句同時運行,而阻塞賦值是按順序方式完成更新的數據的。

 

 

 

 

新建工程,編寫示例代碼

 

module block_nonblock(clk,rst_n,a,b,c,out );
input clk,rst_n,a,b,c;


output reg [1:0]out;//out=a+b+c>2,所以out應該為2位

reg [1:0] d;//定義一個中間變量
//d=a+b;
//out=d+c
always@(posedge clk or negedge rst_n)
if(!rst_n)

out=2'b0;

else begin
d=a+b;
out=d+c;
end

endmodule

 

 

 

 從RTL 視圖可以看出整個運行過程是順序執行的。

改變

d=a+b;
out=d+c;的賦值順序,再觀察RTL視圖,會發現兩者之間是有區別的,這說明順序決定着輸出的結果。

 

 

 

將賦值語句改為非阻塞賦值。

 

觀察RTL視圖,會發現兩者是有明顯不同。

 

同樣的改變

d<=a+b;
out<=d+c;的賦值順序,再觀察RTL視圖,會發現兩者之間是沒有區別的,這說明順序並沒有決定輸出的結果。

 

由RTL圖理論上可以看出兩種賦值語句的不同,下面編寫testbench進行仿真。

`timescale 1ns/1ns
module block_nonblock_tb;
`define clock_period 20

reg clock,rst_n,a,b,c;
wire [1:0] out ;
block_nonblock block_nonblock0(clock,
rst_n,
a,
b,
c,
out    );//這里采用一一對應的調用方式

initial clock=1'b0;
always#(`clock_period/2) clock=~clock;//產生時鍾信號
initial begin
rst_n=1'b0;
a=0;b=0;c=0; //賦值激勵信號
#(`clock_period*200+1)

rst_n=1'b1;
a=0;b=0;c=1; 
#(`clock_period*200)
a=0;b=1;c=0; 
#(`clock_period*200)
a=0;b=1;c=1; 
#(`clock_period*200)
a=1;b=0;c=0; 
#(`clock_period*200)
a=1;b=0;c=1; 
#(`clock_period*200)
a=1;b=1;c=0; 
#(`clock_period*200)
a=1;b=1;c=1; 
#(`clock_period*200)
#(`clock_period*200)
$stop;
end

endmodule

 

 設定文件路徑后按前面的四個程序進行前仿。

 

 

d=a+b;
out=d+c;

 

out=d+c;
d=a+b;

 


d<=a+b;
out<=d+c;

 

out<=d+c;
d<=a+b;

 


通過仿真可以看出四種情況的異同,至此阻塞賦值和非阻塞賦值就可以通過實際例子來理解了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM