答:因為對應的電路結構往往與觸發沿沒有關系,隻與輸入電平的變化有關系。阻塞指派的操作可以認為是隻有一個步驟的操作,即計算指派号右邊的語句并更新指派号左邊的語句,此時不允許有來自任何其他 verilog語句的幹擾,直到現行的指派完成時刻,即把目前指派号右邊的值指派給左邊的時刻完成後,它才允許下一條的指派語句的執行。串行塊(begin-end)中的各條阻塞型過程指派語句将以它們在順序塊後的排列次序依次執行。阻塞型過程指派語句的執行過程是:首先計算指派号右邊的值,然後立即将計算結果指派給左邊,指派語句結束,變量值立即發生改變。阻塞的概念是指在同一個 always 塊中,其後面的指派語句從概念上是在前一句指派語句結束後再開始下面的指派。
答:這是因為對應的電路結構往往與觸發沿有關系,隻有在觸發沿的時刻才能進行非阻塞指派。非阻塞操作開始時計算非阻塞指派符的指派号右邊的語句,指派操作結束時刻才更新指派号左邊的語句,可以認為是兩個步驟(指派開始時刻和結束時刻)來完成非阻塞指派。在計算非阻塞語句指派号右邊的語句和更新指派号左邊的語句期間,其他的 verilog語句包括其他的 verilog 非阻塞指派語句都能同時計算指派号右邊的語句和更新指派号左邊的語句,允許其他的 verilog 語句同時進行操作。非阻塞指派的操作可以看作為兩個步驟的過程:在指派開始時刻,計算指派号右邊的語句。在指派結束時刻,更新指派号左邊的語句。注意:非阻塞操作隻能用于對寄存器類型變量進行指派,是以隻能用于“initial”和“always”塊中,不允許用于連續指派“assign”。
阻塞指派(=)”和“非阻塞指派(<=)”符号其實我們早就見過,大家可能存在疑問,有時候用阻塞指派而有時候用非阻塞指派,是以阻塞指派和非阻塞指派的概念一直是初學者較為頭疼的一件事情,因為大多數人往往因為文字概念的描述了解不透徹,說白了就是看那些文字的解釋反而讓我們更難了解,更容易被繞進去,産生懵的感覺。甚至有些很有經驗的 邏輯設計工程師也不能完全正确地了解何時使用非阻塞指派何時使用阻塞指派才能設計出符合要求的電路,不明白在電路結構的設計中,即可綜合風格的 verilog子產品的設計中,究竟為什麼還要用非阻塞指派,以及符合ieee标準的verilog 仿真器究竟如何來處理非阻塞指派的仿真。
本章的目的是盡可能地把阻塞和非阻塞指派的含義和用法詳細地解釋清楚,并通過執行個體給出正确的用法,使之能夠設計出符合我們意願的的代碼及功能。
一、阻塞指派
開始 rtl 代碼的編寫,rtl 代碼編寫出的子產品叫 rtl 子產品(後文中也稱功能子產品、可綜合子產品)。之是以叫 rtl 代碼是因為用 verilog hdl 在 resistances transistors logic(寄存器傳輸級邏輯)來描述硬體電路,rtl 代碼能夠綜合出真實的電路以實作我們設計的功能,差別于不可綜合的仿真代碼。
打開 modelsim 執行仿真,仿真出來的波形如圖所示,我們讓仿真運作了 500ns即可得到較好的觀察效果。
我們知道一個寄存器就是“延一拍”,是以該仿真波形和前面的 rtl視圖剛好對應,發現<code>輸入信号 in</code> 和<code>中間變量 in_reg</code>、<code>輸出信号out</code>的關系就是延遲一拍的關系,但是為什麼隻是延遲一拍呢?
首先中間變量<code>in_reg</code>一定要等待複位被釋放後且第一個時鐘上升沿來到時才會被指派為<code>輸入信号in</code> 的值,是以會比輸入信号<code>in</code>延遲一拍,而<code>中間變量 in_reg</code> 和<code>輸出信号 out</code> 卻沒有延遲一拍的關系了,而是在同一時刻同時變化的,因為我們使用的是阻塞指派,也就是說隻要指派号右邊的表達式的值有變化,指派号左邊的表達式的值也将立刻變化,是以我們最終看到的結果是中間變量in_reg 和輸出信号 out是同時變化的。
二、非阻塞指派
開始rtl代碼的編寫,rtl代碼編寫出的子產品叫rtl子產品(後文中也稱功能子產品、可綜合子產品)。之是以叫rtl代碼是因為用verilog hdl在resistances transistors logic(寄存器傳輸級邏輯)來描述硬體電路,rtl代碼能夠綜合出真實的電路以實作我們設計的功能,差別于不可綜合的仿真代碼。
打開modelsim執行仿真,仿真出來的波形如圖所示,我們讓仿真運作了 500ns即可得到較好的觀察效果。
同樣該仿真波形和其對應的 rtl視圖也是剛好對應的,我們發現<code>輸入信号 in</code>和<code>中間變量 in_reg</code> 是延遲一拍的關系,而<code>中間變量 in_reg</code> 和<code>輸出信号 out</code>也是延遲一拍的關系,也就是<code>輸入信号 in</code> 和<code>輸出信号 out</code> 一共是延遲兩拍的關系,為什麼會這樣呢?
首先<code>中間變量 in_reg</code>一定要等待複位被釋放後且第一個時鐘上升沿來到時才會被指派為<code>輸入信号 in</code>的值,是以會比輸入信号 in延遲一拍,這是和阻塞指派過程相同的,
但是接下來就不一樣了,因為我們使用的是非阻塞指派,也就是說隻要指派号右邊的表達式的值有變化,指派号左邊的表達式的值也不會立刻變化,需要等待下一次時鐘沿到來時一起變化,是以我們最終看到的結果是<code>輸出信号out</code>相對于<code>輸入信号</code>是打了兩拍的關系。