- FPGA從入門到精通(實戰篇)
- 至芯科技教研組
- 1425字
- 2021-02-26 11:46:03
第2章 諄諄教誨莫相忘,字字珠璣記心頭
2.1 賦值語句實戰演練
在編寫代碼的過程中,用得最多的語句恐怕就是賦值語句了。常用的賦值方式有兩種:阻塞型過程賦值和非阻塞型過程賦值。小芯剛開始編寫代碼時就被這兩種賦值方式搞暈了—什么是阻塞型過程賦值?什么是非阻塞型過程賦值?什么時候用阻塞型過程賦值?什么時候用非阻塞型過程賦值?這兩種賦值方式到底有哪些不同?什么時候兩種賦值方式可以結合起來使用?
由于當時好的教材比較少,因此小芯被這些簡單的問題困擾了很久。下面小芯將通過一些實例來解答這些問題。
2.1.1 非阻塞型過程賦值語句
以賦值操作符 “<=” 來標識的賦值操作被稱為非阻塞型過程賦值(Nonblocking Assignment)。非阻塞型過程賦值語句的特點如下。
● 在begin-end 串行語句塊中,一條非阻塞型過程賦值語句的執行不會阻塞下一條語句的執行,也就是說,在本條非阻塞型過程賦值語句對應的賦值操作執行完之前,下一條語句也可以執行。
● 仿真進程在遇到非阻塞型過程賦值語句后,首先計算其右端賦值表達式的值,然后等到仿真進程結束后再將該計算結果賦給變量,也就是說,此時的賦值操作是在同一仿真時刻上的其他普通操作結束后才得以執行的。
例如,有如下代碼:


在上述語句中,包含兩條非阻塞型過程賦值語句S1 和S2。在仿真進程遇到begin-end串行語句塊后(0 時刻),語句S1 開始執行,即B 的值得到計算(對A 的賦值操作要等到當前時間步結束才能執行)。由于語句S1 是一條非阻塞型過程賦值語句,所以語句S1 的執行不會阻塞語句S2 的執行,語句S2 隨即開始執行,即A 的值得到計算。由于此時在語句S1 中對A 的賦值操作還沒有執行,所以計算得到的賦值表達式取值是A 的初值。由于語句S2 也是一條非阻塞型過程賦值語句,對B 的賦值操作也要等到當前時間步結束時才能執行,所以在當前時間步結束時,S1、S2 兩條語句對應的賦值操作同時執行,即分別將計算得到的A和B 的初值賦給變量B 和A,從而交換了A 與B 的取值。
下面小芯將和大家一起設計一個實例,實例代碼如下。

編寫如下測試代碼。


運行代碼,得到的仿真波形如圖2.1 所示。

圖2.1
從仿真波形可以看出,使用非阻塞型過程賦值語句可以把a 的初值賦給b,把b 的初值賦給a。非阻塞型過程賦值語句一般用在時序邏輯中。
2.1.2 阻塞型過程賦值語句
以賦值操作符 “=” 來標識的賦值操作被稱為阻塞型過程賦值(Blocking Assignment)。阻塞型過程賦值語句的特點如下:
● 串行語句塊(begin-end)中的各條阻塞型過程賦值語句將以它們的排列次序依次執行。
● 阻塞型過程賦值語句的執行過程:首先,計算右端賦值表達式的值;然后,立即將計算結果賦給 “=” 左端的被賦值變量。
阻塞型過程賦值語句的這兩個特點表明:仿真進程在遇到阻塞型過程賦值語句時,將計算表達式的值,并立即將其結果賦給等式左邊的被賦值變量;在串行語句塊中,下一條語句的執行會被本條阻塞型過程賦值語句所阻塞,只有在當前這條阻塞型過程賦值語句所對應的賦值操作執行完后,下一條語句才能開始執行。
例如,有如下代碼:

在這段語句中包含兩條阻塞型過程賦值語句S1 和S2,它們都是在仿真0 時刻得到執行的。由于語句S1 和S2 都是阻塞型過程賦值語句,所以在執行語句S1 時語句S2 因被阻塞而不能得到執行。只有在語句S1 執行完,a 被賦值為0 之后,語句S2 才能開始執行。而S2的執行將使a 被重新賦值為1,所以上述代碼執行后,變量a 的值最終為1。
下面小芯將和大家一起設計一個實例,實例代碼如下。

運行代碼,得到的仿真波形如圖2.2 所示。

圖2.2
通過對比圖2.1 和圖2.2 可以看出,哪怕僅是把賦值方式換成阻塞型,其產生的結果也和非阻塞型的不同。阻塞型過程賦值語句一般用在組合邏輯中。