作者:bleauchat
在設(shè)計(jì)仿真激勵(lì)文件時(shí),為了滿足和外部芯片接口的時(shí)序要求,經(jīng)常會(huì)用到延時(shí)賦值語句,由于不同的延時(shí)賦值語句在仿真過程中行為不同,會(huì)產(chǎn)生不同的激勵(lì)輸出,如果不認(rèn)真區(qū)分不同表達(dá)式引起的差異,就可能產(chǎn)生錯(cuò)誤的激勵(lì),無法保證仿真結(jié)果的正確,本文就是區(qū)分各種延時(shí)賦值語句的差異,并給出比較結(jié)果。
1:阻塞式左延時(shí)賦值語句
舉例說明如下:
module adder_t1 (co, sum, a, b, ci); output co; output [3:0] sum; input [3:0] a, b; input ci; reg co; reg [3:0] sum; always @(a or b or ci) #12 {co, sum} = a + b + ci; // 在15ns時(shí)a發(fā)生變化,啟動(dòng)該塊,但是等到27ns時(shí)才執(zhí)行后面的語句,所以是最新的結(jié)果 endmodule
分析:上面例子是希望在輸入信號(hào)變化后12ns再更新輸出結(jié)果,假設(shè)在15ns時(shí)a發(fā)生變化,在27ns時(shí),結(jié)果將被更新,但是如果在15ns到24ns這一段時(shí)間,a,b,ci又發(fā)生了變化,在27ns時(shí),結(jié)果將按照最新的a,b,ci進(jìn)行計(jì)算并被更新;
如果將程序修改成如下格式,仿真的結(jié)果不變:
module adder_t7a (co, sum, a, b, ci); output co; output [3:0] sum; input [3:0] a, b; input ci; reg co; reg [3:0] sum; reg [4:0] tmp; always @(a or b or ci) begin #12 tmp = a + b + ci; // 在15ns a發(fā)生變化時(shí),啟動(dòng)該always塊,但是12ns后即第27ns時(shí)才執(zhí)行 //tmp = a + b + ci tmp才被賦值,因此賦值的是最近的a,b,ci變化的值 {co, sum} = tmp; end endmodule
如果將程序做如下修改:
module adder_t7b (co, sum, a, b, ci); output co; output [3:0] sum; input [3:0] a, b; input ci; reg co; reg [3:0] sum; reg [4:0] tmp; always @(a or b or ci) begin tmp = a + b + ci; // 在15ns a發(fā)生變化時(shí),啟動(dòng)該always塊,執(zhí)行該語句,獲得當(dāng)前tem ,然后就開始執(zhí)行下一句 #12 #12 {co, sum} = tmp; // 所以tmp的值是15ns的值,再過12ns即27ns時(shí)賦值給輸出。因此,中間的變換被忽視 end //15~27之間執(zhí)行該語句塊,只有執(zhí)行完該語句塊之后才是開始執(zhí)行下一個(gè)語句塊 endmodule
仿真的結(jié)果如下圖所示:從15ns到27ns之間的變化被忽視;
結(jié)論:阻塞式賦值語句是一句一句執(zhí)行的,一句沒有執(zhí)行完,下一句絕不會(huì)執(zhí)行。正因?yàn)槿绱耍诖死性谘訒r(shí)12個(gè)ns的時(shí)間里,不作任何處理,tmp值保持不變(2’b10),而且對(duì)敏感變量的變化不作反應(yīng)。不要將延時(shí)放在阻塞式賦值語句的左側(cè),這是一種不好的代碼設(shè)計(jì)方式;
2:阻塞式右延時(shí)賦值語句
看下面的例子:
module adder_t6 (co, sum, a, b, ci); output co; output [3:0] sum; input [3:0] a, b; input ci; reg co; reg [3:0] sum; always @(a or b or ci) {co, sum} = #12 a + b + ci; // 先計(jì)算a + b + ci的值,過12ns后賦值為輸出;賦值語句是從右往左執(zhí)行 endmodule
它的仿真結(jié)果同adder_t7b,賦值語句是從右往左執(zhí)行,信號(hào)從15ns到27ns之間的變化被忽視;即 同:
tmp=a+b+ci; #12{co,sum}=tmp;
下面兩個(gè)例子的仿真結(jié)果和adder_t6相同:
module adder_t11a (co, sum, a, b, ci); output co; output [3:0] sum; input [3:0] a, b; input ci; reg co; reg [3:0] sum; reg [4:0] tmp; always @(a or b or ci) begin tmp = #12 a + b + ci; {co, sum} = tmp; end endmodule module adder_t11b (co, sum, a, b, ci); output co; output [3:0] sum; input [3:0] a, b; input ci; reg co; reg [3:0] sum; reg [4:0] tmp; always @(a or b or ci) begin tmp = a + b + ci; {co, sum} = #12 tmp; end endmodule
結(jié)論:不要將延時(shí)放在阻塞式賦值語句的右側(cè),這是一種不好的代碼設(shè)計(jì)方式;
3:非阻塞式左延時(shí)賦值語句
看例子:
module adder_t2 (co, sum, a, b, ci); output co; output [3:0] sum; input [3:0] a, b; input ci; reg co; reg [3:0] sum; always @(a or b or ci) #12 {co, sum} <= a + b + ci; endmodule
它的仿真結(jié)果同adder_t1,在27ns時(shí),結(jié)果將按照最新的a,b,ci進(jìn)行計(jì)算并被更新;由于首先要執(zhí)行#12,然后才能執(zhí)行非阻塞賦值,所以能對(duì)信號(hào)進(jìn)行實(shí)時(shí)跟蹤!
結(jié)論:不要將延時(shí)放在非阻塞式賦值語句的左側(cè),這是一種不好的代碼設(shè)計(jì)方式;
4:非阻塞式右延時(shí)賦值語句
看例子:
module adder_t3 (co, sum, a, b, ci); output co; output [3:0] sum; input [3:0] a, b; input ci; reg co; reg [3:0] sum; always @(a or b or ci) {co, sum} <= #12 a + b + ci; endmodule
非阻塞賦值,不會(huì)阻止下一條語句的執(zhí)行,輸出結(jié)果能隨時(shí)跟蹤輸入信號(hào)的變化;
結(jié)論:使用非阻塞式右延時(shí)賦值語句可以,輸出結(jié)果能夠跟隨輸入的變化,建議使用;
5:非阻塞式右延時(shí)多重賦值語句
看例子:
module adder_t9c (co, sum, a, b, ci); output co; output [3:0] sum; input [3:0] a, b; input ci; reg co; reg [3:0] sum; reg [4:0] tmp; always @(a or b or ci or tmp) begin tmp <= #12 a + b + ci; {co, sum} <= tmp; end endmodule
非阻塞賦值,不會(huì)阻止下一條語句的執(zhí)行,輸出結(jié)果能隨時(shí)跟蹤輸入信號(hào)的變化;這與下面的例子結(jié)果是相同的:
module adder_t9d (co, sum, a, b, ci); output co; output [3:0] sum; input [3:0] a, b; input ci; reg co; reg [3:0] sum; reg [4:0] tmp; always @(a or b or ci or tmp) begin tmp <= a + b + ci; {co, sum} <= #12 tmp; end endmodule
6:連續(xù)賦值語句
看例子:
module adder_t4 (co, sum, a, b, ci); output co; output [3:0] sum; input [3:0] a, b; input ci; assign #12 {co, sum} = a + b + ci; endmodule module adder_t5 (co, sum, a, b, ci); output co; output [3:0] sum; input [3:0] a, b; input ci; assign {co, sum} = #12 a + b + ci; endmodule
輸出結(jié)果能隨時(shí)跟蹤輸入信號(hào)的變化;
結(jié)論:非阻塞語句和連續(xù)賦值語句無論怎么添加延時(shí)語句,其輸出都會(huì)隨著輸入的變化而跟蹤變化!這里要特別注意阻塞語句的延時(shí)添加,一般不在阻塞賦值語句中添加延時(shí)!
編輯:hfy
-
Verilog
+關(guān)注
關(guān)注
28文章
1363瀏覽量
111378
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
基于MATLAB/Simulink的系統(tǒng)仿真技術(shù)與應(yīng)用
Cadence PSpice仿真技術(shù)的優(yōu)勢(shì)有哪些
ADAS研發(fā)與測(cè)試的模擬仿真技術(shù)
仿真技術(shù)在汽車電子設(shè)計(jì)中的應(yīng)用有哪些?
基于MATLAB Simulink的系統(tǒng)仿真技術(shù)與應(yīng)用 教材

Cadence PCB設(shè)計(jì)仿真技術(shù)

電路設(shè)計(jì)與仿真技術(shù)
模擬仿真技術(shù)是什么
JTAG/MPSD仿真技術(shù)參考

評(píng)論