1、阻塞賦值對應(yīng)的電路往往與觸發(fā)沿沒有關(guān)系,只與輸入電平的變化有關(guān)系。阻塞賦值符號:=
2非阻塞賦值對應(yīng)的電路結(jié)構(gòu)往往與觸發(fā)沿有關(guān)系,只有在觸發(fā)沿時(shí)才有可能發(fā)生賦值的情況。非阻塞賦值符號:<=
1、阻塞賦值操作符用等號(即 = )表示?!白枞笔侵冈谶M(jìn)程語句(initial和always)中,當(dāng)前的賦值語句阻斷了其后的語句,也就是說后面的語句必須等到當(dāng)前的賦值語句執(zhí)行完畢才能執(zhí)行。而且阻塞賦值可以看成是一步完成的,即:計(jì)算等號右邊的值并同時(shí)賦給左邊變量。例如:
當(dāng)執(zhí)行“x=next_x;”時(shí),x會立即的到next_x的值。而下一句“y=x;”必須等到“x=next_x;”執(zhí)行完畢才能被執(zhí)行。由于這兩條語句都沒有延遲(相當(dāng)于導(dǎo)線),導(dǎo)致他們的等價(jià)語句為“y=next_x;”。
賦值是實(shí)時(shí)的,計(jì)算完右面的馬上賦值給左邊的,然后再執(zhí)行下一句,操作時(shí)串行的,且在一個(gè)alway內(nèi)完成。
2、非阻塞賦值操作符用小于等于號 (即 <= )表示?!胺亲枞笔侵冈谶M(jìn)程語句(initial和always)中,當(dāng)前的賦值語句不會阻斷其后的語句。非阻塞語句可以認(rèn)為是分為兩個(gè)步驟進(jìn)行的:
①計(jì)算等號右邊的表達(dá)式的值,(我的理解是:在進(jìn)入進(jìn)程后,所有的非阻塞語句的右端表達(dá)式同時(shí)計(jì)算,賦值動作只發(fā)生在順序執(zhí)行到當(dāng)前非阻塞語句那一刻)。
②在本條賦值語句結(jié)束時(shí),將等號右邊的值賦給等號左邊的變量。
例如:
當(dāng)執(zhí)行“x<=next_x;”時(shí),并不會阻斷語句“y<=x;”的執(zhí)行。因此,語句“y<=x;”中的x的值與語句“x<=next_x;”中的x的值不同:語句“y<=x;”中的x是第一個(gè)D觸發(fā)器的初值(Q0)。而語句“x<=next_x;”中的x的值是D觸發(fā)器經(jīng)過一個(gè)同步脈沖后的輸出值(Q1)?;诖诉@個(gè)進(jìn)程產(chǎn)生了與阻塞賦值進(jìn)程截然不同的結(jié)果,即:產(chǎn)生了移位寄存器的效果。
簡單理解就是,阻塞賦值是按需執(zhí)行,非阻塞賦值是并行執(zhí)行。
為了更好地理解上述要點(diǎn),我們需要對Verilog 語言中的阻塞賦值和非阻塞賦值的功能和執(zhí)行時(shí)間上的差別有深入的了解。為了解釋問題方便下面定義兩個(gè)縮寫字:
RHS – 方程式右手方向的表達(dá)式或變量可分別縮寫為:RHS表達(dá)式或RHS變量。LHS – 方程式左手方向的表達(dá)式或變量可分別縮寫為:LHS表達(dá)式或LHS變量。
IEEE Verilog標(biāo)準(zhǔn)定義了有些語句有確定的執(zhí)行時(shí)間,有些語句沒有確定的執(zhí)行時(shí)間。若有兩條或兩條以上語句準(zhǔn)備在同一時(shí)刻執(zhí)行,但由于語句的排列次序不同(而這種排列次序的不同是IEEE Verilog標(biāo)準(zhǔn)所允許的), 卻產(chǎn)生了不同的輸出結(jié)果。這就是造成Verilog模塊冒險(xiǎn)和競爭現(xiàn)象的原因。為了避免產(chǎn)生競爭,理解阻塞和非阻塞賦值在執(zhí)行時(shí)間上的差別是至關(guān)重要的。
阻塞賦值
阻塞賦值操作符用等號(即 = )表示。為什么稱這種賦值為阻塞賦值呢?這是因?yàn)樵谫x值時(shí)先計(jì)算等號右手方向(RHS)部分的值,這時(shí)賦值語句不允許任何別的Verilog語句的干擾,直到現(xiàn)行的賦值完成時(shí)刻,即把RHS賦值給 LHS的時(shí)刻,它才允許別的賦值語句的執(zhí)行。一般可綜合的阻塞賦值操作在RHS不能設(shè)定有延遲,(即使是零延遲也不允許)。從理論上講,它與后面的賦值語句只有概念上的先后,而無實(shí)質(zhì)上的延遲。若在RHS 加上延遲,則在延遲期間會阻止賦值語句的執(zhí)行, 延遲后才執(zhí)行賦值,這種賦值語句是不可綜合的,在需要綜合的模塊設(shè)計(jì)中不可使用這種風(fēng)格的代碼。
阻塞賦值的執(zhí)行可以認(rèn)為是只有一個(gè)步驟的操作:
計(jì)算RHS并更新LHS,此時(shí)不能允許有來自任何其他Verilog語句的干擾。所謂阻塞的概念是指在同一個(gè)always塊中,其后面的賦值語句從概念上(即使不設(shè)定延遲)是在前一句賦值語句結(jié)束后再開始賦值的。
如果在一個(gè)過程塊中阻塞賦值的RHS變量正好是另一個(gè)過程塊中阻塞賦值的LHS變量,這兩個(gè)過程塊又用同一個(gè)時(shí)鐘沿觸發(fā),這時(shí)阻塞賦值操作會出現(xiàn)問題,即如果阻塞賦值的次序安排不好,就會出現(xiàn)競爭。若這兩個(gè)阻塞賦值操作用同一個(gè)時(shí)鐘沿觸發(fā),則執(zhí)行的次序是無法確定的。下面的例子可以說明這個(gè)問題。
[例1]. 用阻塞賦值的反饋振蕩器
module fbosc1 (y1, y2, clk, rst);
output y1, y2;
input clk, rst;
reg y1, y2;
always @(posedge clk or posedge rst)
if (rst) y1 = 0; // reset
else y1 = y2;
always @(posedge clk or posedge rst)
if (rst) y2 = 1; // preset
else y2 = y1;
endmodule
按照IEEE Verilog 的標(biāo)準(zhǔn),上例中兩個(gè)always塊是并行執(zhí)行的,與前后次序無關(guān)。如果前一個(gè)always塊的復(fù)位信號先到0時(shí)刻,則y1 和y2都會取1,而如果后一個(gè)always塊的復(fù)位信號先到0時(shí)刻,則y1 和y2都會取0。這清楚地說明這個(gè)Verilog模塊是不穩(wěn)定的會產(chǎn)生冒險(xiǎn)和競爭的情況。
非阻塞賦值
非阻塞賦值操作符用小于等于號 (即 <= )表示。為什么稱這種賦值為非阻塞賦值?這是因?yàn)樵谫x值操作時(shí)刻開始時(shí)計(jì)算非阻塞賦值符的RHS表達(dá)式,賦值操作時(shí)刻結(jié)束時(shí)更新LHS。在計(jì)算非阻塞賦值的RHS表達(dá)式和更新LHS期間,其他的Verilog語句,包括其他的Verilog非阻塞賦值語句都能同時(shí)計(jì)算RHS表達(dá)式和更新LHS。非阻塞賦值允許其他的Verilog語句同時(shí)進(jìn)行操作。非阻塞賦值的操作可以看作為兩個(gè)步驟的過程:
1) 在賦值時(shí)刻開始時(shí),計(jì)算非阻塞賦值RHS表達(dá)式。
2) 在賦值時(shí)刻結(jié)束時(shí),更新非阻塞賦值LHS表達(dá)式。
非阻塞賦值操作只能用于對寄存器類型變量進(jìn)行賦值,因此只能用在"initial"塊和"always"塊等過程塊中。非阻塞賦值不允許用于連續(xù)賦值。下面的例子可以說明這個(gè)問題:
[例2]. 用非阻塞賦值的反饋振蕩器
module fbosc2 (y1, y2, clk, rst);
output y1, y2;
input clk, rst;
reg y1, y2;
always @(posedge clk or posedge rst)
if (rst) y1 <= 0; // reset
else y1 <= y2;
always @(posedge clk or posedge rst)
if (rst) y2 <= 1; // preset
else y2 <= y1;
endmodule
同樣,按照IEEE Verilog 的標(biāo)準(zhǔn),上例中兩個(gè)always塊是并行執(zhí)行的,與前后次序無關(guān)。無論哪一個(gè)always塊的復(fù)位信號先到, 兩個(gè)always塊中的非阻塞賦值都在賦值開始時(shí)刻計(jì)算RHS表達(dá)式,,而在結(jié)束時(shí)刻才更新LHS表達(dá)式。所以這兩個(gè)always塊在復(fù)位信號到來后,在always塊結(jié)束時(shí) y1為0而y2為1是確定的。從用戶的角度看這兩個(gè)非阻塞賦值正好是并行執(zhí)行的。
掌握可綜合風(fēng)格的Verilog模塊編程的八個(gè)原則會有很大的幫助。在編寫時(shí)牢記這八個(gè)要點(diǎn)可以為絕大多數(shù)的Verilog用戶解決在綜合后仿真中出現(xiàn)的90-100% 的冒險(xiǎn)競爭問題。
1) 時(shí)序電路建模時(shí),用非阻塞賦值。
2) 鎖存器電路建模時(shí),用非阻塞賦值。
3) 用always塊建立組合邏輯模型時(shí),用阻塞賦值。
4) 在同一個(gè)always塊中建立時(shí)序和組合邏輯電路時(shí),用非阻塞賦值。
5) 在同一個(gè)always塊中不要既用非阻塞賦值又用阻塞賦值。
6) 不要在一個(gè)以上的always塊中為同一個(gè)變量賦值。
7) 用$strobe系統(tǒng)任務(wù)來顯示用非阻塞賦值的變量值
8) 在賦值時(shí)不要使用 #0 延遲
編輯:黃飛
?
評論