這幾天都在看這個經典問題,阻塞和非阻塞賦值,有點收穫,也有很多疑問!
一、特點:
阻塞賦值:1、rhs的表示式計算和lhs的賦值更新,這兩個動作之間不能插入其他動作,即所謂計算完畢,立即更新。
2、所謂阻塞就是指在乙個「begin...end」塊中的多個阻塞賦值語句內,只有上一句完全執行完畢後,才會
執行下一語句,否則阻塞程式的執行。
非阻塞賦值:rhs的表示式計算和lhs的賦值更新分兩個節拍執行,首先,應該是rhs的表示式計算,得到新值後並不
立即賦值,而是放在事件佇列中等待,直到當前**時刻的後期才執行(原因下文會提到)。
二、verilog的分層事件佇列:
在verilog中,事件佇列可以劃分為5個不同的區域,不同的事件根據規定放在不同的區域內,按照優先順序的高低決定執
行的先後順序,下表就列出了部分verilog分層事件佇列。其中,活躍事件的優先順序最高(最先執行),而監控事件的優先順序
最低,而且在活躍事件中的各事件的執行順序是隨機的(注:為方便起見,在一般的**器中,對同一區域的不同事件是按
照排程的先後關係執行的)。
三、結論:
由上表就可以知道,阻塞賦值屬於活躍事件,會立刻執行,這就是阻塞賦值「計算完畢,立刻更新」的原因。此外,由於
在分層事件佇列中,只有將活躍事件中排在前面的事件調出,並執行完畢後,才能夠執行下面的事件,這就可以解釋阻塞賦值
的第二個特點。
同樣是由上表知,非阻塞賦值的rhs計算屬於活躍事件,而非阻塞賦值更新事件排在非活躍事件之後,因此只有**佇列
中所有的活躍事件和非活躍事件都執行完畢後,才輪到非阻塞賦值更新事件,這就是非阻塞賦值必須分兩拍完成的原因。
但是我有很多疑問,何為當前**時間,我認為是在當前clk觸發週期內,但是我使用了很多小程式來驗證非阻塞賦值的
時序列,結果卻與理論不同,對於這個問題,仍然在疑惑中~~~
在veriloghdl中,有兩種過程性賦值方式,即阻塞式(blocking)和非阻塞式(non-blocking)。這兩種賦值方式看似差不多,其實在某些情況下卻有著根本的區別,如果使用不當,綜合出來的結果和你所想得到的結果會相去甚遠。
tip:所謂過程性賦值就是指在initial或always語句內的賦值,它只能對暫存器資料型別的變數賦值。
阻塞式(blocking)的操作符為「=」
非阻塞式(non-blocking)的操作符為「<=」
首先,我們通過兩個例子來看看這兩種賦值方式的區別,這裡使用的綜合工具為dc。
例1:非阻塞式賦值
modulenonblock(clock,in1,in2,in3,in4,out);
inputclock,in1,in2,in3,in4;
outputout;
regout;
regf;
always@(posedgeclock)
begin
f<=in2|in3;//語句1
if(in1)
out<=f&in4;//語句2
else
out<=in4;
endendmodule
例1綜合後的結果為(**注**):
modulenonblock(clock,in1,in2,in3,in4,out);
inputclock,in1,in2,in3,in4;
outputout;
wiref,n_6;
mfntnqout_reg(.q(out),.da(n_6),.db(in4),.sa(in1),.cp(clock));
mfntnqf_reg(.q(f),.da(1'b1),.db(in2),.sa(in3),.cp(clock));
an02d1u10(.z(n_6),.a1(f),.a2(in4));
endmodule
為了更直觀,給出相應的schematic:
例2:阻塞式賦值
moduleblock(clock,in1,in2,in3,in4,out);
inputclock,in1,in2,in3,in4;
outputout;
regout;
regf;
always@(posedgeclock)
begin
f=in2|in3;//語句1
if(in1)
out=f&in4;//語句2
else
out=in4;
endendmodule
例2綜合後的結果為:
moduleblock(clock,in1,in2,in3,in4,out);
inputclock,in1,in2,in3,in4;
outputout;
wiren_6;
mfntnqout_reg(.q(out),.da(n_6),.db(in4),.sa(in1),.cp(clock));
oa14d0u10(.z(n_6),.a1(in3),.a2(in2),.b(in4));
endmodule
相應的schematic:
分析:大家可以看到,例1和例2的code寫法完全一樣,只是在always語句塊中使用了不同的賦值方式,就導致綜合出來的結果不同。
在例1中,是非阻塞式賦值方式,非阻塞式賦值的賦值物件總是在當前**時刻結束時被賦值,所以,當在對語句2中的out賦值這一時刻,f值還沒有得到語句1中的新值,而是原來的值(即上乙個時刻的值)。
而在例2中,使用了阻塞式賦值方式,就是在always語句塊中是一句一句執行的。在執行語句2之前,語句1就已經執行完成,f被賦好了新值,所以語句2中的f值取的是新值。
建議:1.阻塞式賦值用於組合邏輯建模;
2.非阻塞式賦值用於時序邏輯建模。
**注**
mfntnqq=rising(cp)?(sa&da|!sa&db):'p'
an02d1z=a1&a2
oa14d0z=(a1|a2)&b
[補充]
以上內容只是非常非常簡單地介紹了這兩種賦值方式的語法區別,近日看到一篇獲獎**,題目為:
nonblockingassignmentsinverilogsynthesis,codingstylesthatkill!(
其中非常詳細的論述了這兩種方法的區別、用法及**結果。由於是pdf文件沒法上傳,如感興趣的朋友可發email問我要。
電力市場的輸電阻塞管理 w
摘要本問題是乙個優化問題,本文首先找出了輸電阻塞管理中的各約束的優先順序關係,然後通過線形回歸分析得到各線路上的有功潮流關於各發電機組出力的近似表示式 接著給出了阻塞費用的計算規則,該規則一方面保留了題目中清算費用採取最大段價原則,另一方面引入了風險機制 最後對於輸電阻塞管理建立了三種不同原則下的優...
電力市場的阻塞管理 龔宗耀
摘要在電力市場交易中,為了確保電力系統安全經濟執行,需要對輸電系統進行有效的管理,阻塞管理是其核心問題。本文利用matlab軟體中的曲線擬合 動態規劃等數學工具對輸電阻塞管理中所涉及的一系列的問題,進行了較合理的模型建立與求解過程。根據對題中資料表1和資料表2中資料的分析,可認為各個線路有功潮流的變...
慢性阻塞性肺疾病的家庭護理
慢性阻塞性肺疾病,簡稱 copd 是一種常見 多發 高致殘率和高病死率的慢性呼吸系統疾病。吸菸是引起copd最重要的危險因素,接觸職業性粉塵和化學物質 室內空氣汙染 戶外大氣汙染 被動吸菸 幼兒期呼吸道反覆感染等因素都是誘發copd發生的重要危險因素。據統計在全球和我國城鎮均為第四位導致死亡的 而在...