1. 程式人生 > >Verilog十大基本功6 (關於Verilog的可綜合性)

Verilog十大基本功6 (關於Verilog的可綜合性)

來自:https://blog.csdn.net/a8039974/article/details/43635425

 

可綜合模型的結構

    如果程式只用於模擬,那麼幾乎所有的語法和程式設計語句都可以使用。但如果程式是用於硬體實現,那麼我們就必須保證程式的可綜合性,即所編寫的程式能被綜合器 轉化為相應的電路結構。不可綜合的HDL語句在用綜合工具綜合時將被忽略或者報錯。作為設計者,應該對可綜合模型的結構有所瞭解。

    雖然不同的綜合工具對Verilog HDL語法結構的支援不盡相同,但Verilog HDL中某些典型的結構是很明確地被所有綜合工具支援或不支援的。

    (1)所有綜合工具都支援的結 構:always,assign,begin,end,case,wire,tri,aupply0,supply1,reg,integer,default,for,function,and,nand,or,nor,xor,xnor,buf,not,bufif0,bufif1,notif0,notif1,if,inout,input,instantitation,module,negedge,posedge,operators,output,parameter。

    (2)所有綜合工具都不支援的結構:time,defparam,$finish,fork,join,initial,delays,UDP,wait。

    (3)有些工具支援有些工具不支援的結構:casex,casez,wand,triand,wor,trior,real,disable,forever,arrays,memories,repeat,task,while。

    因此,要編寫出可綜合的模型,應儘量採用所有綜合工具都支援的結構來描述,這樣才能保證設計的正確性和縮短設計週期。

 

建立可綜合模型的原則

    要保證Verilog HDL賦值語句的可綜合性,在建模時應注意以下要點:

    (1)不使用初始化語句。

    (2)不使用帶有延時的描述。

    (3)不使用迴圈次數不確定的迴圈語句,如forever、while等。

    (4)不使用使用者自定義原語(UDP元件)。

    (5)儘量使用同步方式設計電路。

    (6)除非是關鍵路徑的設計,一般不採用呼叫門級元件來描述設計的方法,建議採用行為語句來完成設計。

    (7)用always過程塊描述組合邏輯,應在敏感訊號列表中列出所有的輸入訊號。

    (8)所有的內部暫存器都應該能夠被複位,在使用FPGA實現設計時,應儘量使用器件的全域性復位端作為系統總的復位。

    (9)對時序邏輯描述和建模,應儘量使用非阻塞賦值方式。對組合邏輯描述和建模,既可以用阻塞賦值,也可以用非阻塞賦值。但在同一個過程塊中,最好不要同時用阻塞賦值和非阻塞賦值。

    (10)不能在一個以上的always過程塊中對同一個變數賦值。而對同一個賦值物件不能既使用阻塞式賦值,又使用非阻塞式賦值。

    (11)如果不打算把變數推導成鎖存器,那麼必須在if語句或case語句的所有條件分支中都對變數明確地賦值。

    (12)避免混合使用上升沿和下降沿觸發的觸發器。

    (13)同一個變數的賦值不能受多個時鐘控制,也不能受兩種不同的時鐘條件(或者不同的時鐘沿)控制。

    (14)避免在case語句的分支項中使用x值或z值。

 

阻塞與非阻塞

    建議在時序邏輯建模時使用非阻塞式賦值。因為對於阻塞式賦值來說,賦值語句的順序對最後的綜合結果有著直接的影響,設計者稍不留意就會使綜合結果與設計本 意大相徑庭。而如果採用非阻塞式賦值,則可以不考慮賦值語句的排列順序,只需將其連線關係描述清楚即可。如下面的模型:

     always @ (posedge clkA)   //Label  AwA

         … = DataOut;              //讀DataOut的值



     always @ (posedge clkA)   //Label  AwB

         DataOut <= …;        //採用非阻塞式賦值

    如果將上述模型改為阻塞式賦值“DataOut = …”,按照程式中的書寫順序模擬這些always語句,在clkA上升沿處,always語句AwA讀取了DataOut的當前值,然後always語句 AwB再向DataOut賦新值。如果顛倒了這兩條always語句的順序(或模擬器選擇重新排定這兩條always語句的執行順序),那麼先執行 always語句AwB,導致零時間內將新值賦給DataOut,隨後always語句AwA讀取的便是更新後的DataOut值。這看起來是由於 always語句都可以執行時,向DataOut的賦值是在零時間內發生並完成的。因此根據先執行哪一條always語句,AwA中讀取的DataOut 值可能是其原值,也可能是其新值。

    使用非阻塞賦值就可以消除這種模擬行為的依賴性,這時,讀取DataOut發生在當前時刻,而在當前模擬週期結束時(即所有的變數讀取都已完成)才將新值 賦給DataOut。這樣上述模型的行為不再受always語句執行順序的影響。因此,在某條always語句內對變數賦值而在該always語句外讀取 變數,那麼賦值語句應是非阻塞式賦值。