愛伊米

【例說】Verilog HDL 編譯器指令,你見過幾個?

Verilog HDL 編譯器指令

複雜一點的系統在進行設計或者驗證時,都會用到一些編譯器指令,那麼什麼是編譯器指令?

Verilog HDL編譯器指令由重音符(‘)開始。在Verilog 語言編譯時,特定的編譯器指令在整個編譯過程中有效(編譯過程可跨越多個檔案),直到遇到其它的不同編譯程式指令。不完整的標準編譯器指令如下:

【例說】Verilog HDL 編譯器指令,你見過幾個?

下面分解一下,每個指令單獨說明一下:

’define和’undef

1。’define指令

’define指令用於文字替換,它很像C語言中#define指令。它生成一個文字宏。該指令既可以在模組內部定義,也可以在模組之外定義。一旦編譯了’define指令,它在整個編譯過程中都有效。

如果已經定義了一個文字宏,那麼在它的宏名之前加上重音符號(’)就可以在源程式中’引用該文字宏。

在編譯器編譯時,將會自動用相應的文字塊代替字串‘macro_name。將Verilog HDL中的所有編譯指令都看作預定義的宏名,將一個編譯指令重新定義為一個宏名是非法的。

一個文字宏定義可以帶有一個引數。這樣,就允許為每一個單獨的應用定製文字宏。

文字宏定義的語法格式如下:

其中:(1)為文字的宏名字,其語法格式為

text_macro_identifier[]

①text_macro_identifier為宏識別符號,要求簡單識別符號。

②為形參列表。一旦定義一個宏名,就可以在源程式的任何地方使用它,而沒有範圍限制。

(2)為宏文字,可以是與宏名同行的任意指定文字。

①如果指定的文字超過一行,那麼新的一行需要用反斜槓()作為起始。這樣,反斜槓後面的文字也將作為宏文字的一部分,參與宏替換。反斜槓本身並不參與宏替換,編譯時將忽略它。

②如果宏文字包含了一個單行註釋語句(以“//”開始的註釋語句),則該語句不屬於替換文字,編譯時不參與替換。

③宏文字可以空白。

[例] ’define指令Verilog HDL化述的例子1。

[例] ’define指令Verilog HDL非法描述的例子2

[例] ’define 指令 Verilog HDL 非法描述的例子 3。

將要擴充套件為

2。‘undef指令

’undef指令用於取消前面定義的宏。如果先前並沒有使用指令’define進行宏定義,那麼使用’undef指令將會導致一個警告。

’undef指令的語法格式如下:

一個取消的宏沒有值, 就如同沒有被定義一樣。

’celldefine和’endcelldefine

這兩個指令用於將模組標記為單元模組,它們表示包含模組定義。某些PLI使用單元模組用於這些應用,如計算延遲。

該命令可以出現在原始碼描述中的任何地方。但是,推薦將其放在模組定義的外部。

[例] ’celldefine指令Verilog HDL描述的例子。

’default_nettype

該指令用於為隱含網路指定網路型別,也就是為那些沒有被說明的連線定義網路型別。它只可以出現在模組宣告的外部,允許多個’default_netype指令。

如果沒有出現’default_netype指令,或者如果指定了’resetall指令,則隱含的網路型別是wire。當default_netype設定為none時,需要明確地宣告所有網路;如果沒有明確地宣告網路,則產生錯誤。

’default_netype指令格式為:

其中default_nettype_value的值可以是wire、tri、tri0、tri1、wand、triand、wor、trior、trireg、uwire和none。

‘ifdef、 ’else、 ’elsif、 ’endif 和’ifndef

‘ifdef編譯器命令

條件編譯:

顯而易見,即只有在條件滿足的時候才對這部分程式碼進行編譯,也就是對一部分內容指定了編譯的條件:

當滿足條件時對一組語句進行編譯,

當條件不滿足時則對另外一組語句進行編譯。

用途:

1、選擇一個模板的不同代表部分。

2、選擇不同的時序或結構資訊。

3、對不同的EDA工具,選擇不同的激勵。(如:Verilog程式碼中的一部分可能因編譯環境不同而不同,為避免在不同環境需要替換不同版本的Verilog 設計,條件編譯就是一個很好的解決方案)

用法

當宏名被定義過了,就編譯程式段1;反之,當宏名未被定義過,就編譯程式段2;

其中,else部分可以省略。即:當宏名被定義過了,就編譯程式段1;反之,不編譯程式段1;

[例] ’ifdef 指令 Verilog HDL 描述的例子。

‘ifndef編譯器命令

額外的,還有‘ifndef語句,與’ifdef功能相反:

即當宏名沒被定義過,就編譯程式段1;反之,當宏名未被定義過了,就編譯程式段2;

[例] ’ifndef 指令 Verilog HDL 描述的例子。

這裡還有一個‘elsif指令,簡單說明一下。

①當遇到’ifndef時,測試’ifdef文字宏識別符號,檢視在Verilog HDL原始檔描述中是否使用’define作為一個文字宏名字;②如果’ifndef沒有定義文字宏識別符號,則對’ifndef所包含的行作為描述的一部分進行編譯,如果還有’else或者’dsif編譯器指令,則忽略這些編譯器指令和相關的行組;③如果定義’ifiidef文字宏識別符號,則忽略’ifndef所包含的行;④如果有’elsif編譯器指令,測試‘elsif文字宏識別符號,檢視在Verilog HDL原始檔描述中,是否使用’define作為一個文字宏名字;⑤如果’elsdef定義文字宏識別符號,則對’elsdef所包含的行作為描述的一部分進行編譯,如果還有’else或者’elsif編譯器指令,則忽略這些編譯器指令和相關的行組;⑥如果沒有定義第一個‘elsif文字宏識別符號,則忽略第一個’elsif所包含的行;⑦如果有多個’elsif編譯器命令,將按照它們在Verilog HDL原始檔中的描述順序和評估第一個’elsif編譯器指令的方法,對這些指令進行評估;⑧如果有一個’else編譯器命令,則將’else所包含的行作為描述的一部分進行編譯。

’include

在編譯期間,’include編譯器指令用於嵌入另一個檔案的內容。既可以用相對路徑名定義檔案,也可以用全路徑名定義檔案。其語法格式為:

使用’inchide編譯器指令的優勢主要體現在以下幾方面:

(1)提供了一個配置管理不可分割的一部分;

(2)改善了VerilogHDL原始檔描述的組織結構;

(3)便於維護Verilog HDL原始檔描述。

[例 ]’include指令Verilog HDL描述的例子。

’resetall

該編譯器遇到’resetall指令時,會將所有的編譯指令重新設定為預設值。推薦在原始檔的開始放置’resetall。將‘resetall命令放置在模組內或者UDP宣告中是非法的。其語法格式為

’line

對於Verilog工具來說,跟蹤Verilog HDL原始檔的名字和檔案的行的行號是非常重要的,這些資訊可以用於除錯錯誤訊息或者原始碼,Verilog PL1訪問可以它。

然而,在很多情況下,Verilog原始檔由其他工具進行了預處理。由於預處理工具可能在Verilog HDL原始檔中添加了額外的行,或者將多個原始碼行合併為一個行,或者並置多個原始檔,等等,可能會丟失原始的原始檔和行資訊。

’line編譯器命令可以用於指定的原始原始碼的行號和檔名。如果其他過程修改了原始檔,這允許定位原始的檔案。當指定了新行的行號和檔名時,編譯器就可以正確地定位原始的原始檔位置。然而,這要求相應的工具不產生’line命令。

其語法格式為

其中,number是一個正整數,用於指定跟隨文字行的新行行號,filename是一個字串常數,將其看作檔案的新名字,檔名可以是全路徑名字或者相對路徑名字;level為該引數的值,可以是0、1或者2:①當為1的時候,輸入一個include行後的下面一行是第一行;②當為2的時候,退出一個inlcude行後的下面一行是第一行;③當為0的時候,指示任何其他行。

[例] ‘line 指令 Verilog HDL 描述的例子。

//該行是 orig。v 存在 include 檔案後的第 3 行。

’timescale

在Verilog HDL模型中,所有的時延都用單位時間表述。可使用’timescale編譯器指令將時間單位與實際時間相關聯,該指令用於定義時延的單位和時延精度。

作用:

timescale  1ns/100ps那麼時間單位就是1ns,精度就是100ps。

時間單位,表示了模擬時測量的單位,比如延時1,1ns;精度則表示模擬器只識別的範圍,比如精度是100ps,那麼如果你1。3ns,編譯器是識別,但是如果寫1。32,那麼由於精度達不到那麼細,所以0。02被四捨五入掉。

`timescale影響著全部模組,直到遇到另外的timescale。

’timescale編譯器指令格式為:

其中,time_unit指定用於時間和延遲測量的單位,可選的值為1、10或100;time_precision用於模擬前,確定四捨五入延遲值。時間解析度子,可選的單位為s \ms\us\ns\ps或fs。

[例] ‘timescale 指令 Verilog HDL 描述的例子。

根據時間精度, 引數 d 的值從 1。55 四捨五入到 1。6。模組的時間單位是 10ns 精度是1 ns。因此, 引數 d 的延遲從 1。6 標定到 16。

’unconnected_drive和’nounconnected_drive

當一個模組所有未連線的端口出現在‘unconnected_drive和’nounconnecteddrive指令之間時,將這些未連線的埠上拉或者下拉,而不是按通常的預設值處理。

指令’unconnected_drive使用pull1/pull0引數中的一個:當指定pull時,所有未連線的埠自動上拉;當指定pill0時,所有未連線的埠自動下拉。

建議成對使用’unconnected_drive和’nounconnected_drive指令,但不是強制要求。這些指令在模組外部成對指定。

‘resetall指令包括’nounconnected_drive指令的效果。

[例]nounconnected_drive/ ‘unconnected drive 指令 Verilog HDL 描述的例子。

’pragma

’pragma指令是一個結構化的說明,它用於改變對Verilog HDL原始檔的理解。由這個指令所引入的說明稱為編譯指示。編譯指示不同於Verilog HDL標準所指定的結果,它為指定實現的結果。其語法格式為

其中 ,pragma_name 為編譯指示的名字, 可以是 $ 開頭的系統識別符號或者一般識別符號; pragma_expression 為編譯指示表示式。

注:reset和resetall編譯指示將恢復預設值和pragma_keywords所影響的狀態。

‘begin_keywords和’end_keyword

’begin_keywords和‘end_keyword指令用於指定在一個原始碼塊中,基於不同版本的IEEE_Stdl364標準,確定用於關鍵字的保留字。該對指令只指定那些作為保留關鍵字的識別符號。只能在設計元素(模組、原語和配置)外指定該關鍵字,並且需要成對使用。其語法格式為:

其中,version_specifier為可選的引數,包括1364-1995、1364-2001、1364-2001-noconfig和1364-2005。

[例] ’begin_keywords 和 ’end_keyword 指令 Verilog HDL 描述的例子。

(補充一)Verilog編譯器指示語句

設計者在寫設計程式碼時,有時可能針對模擬寫一些語句,這些語句可能是不為DC所接受,也不希望DC接受;設計者如果不對這些語句進行特殊說明,DC讀入設計程式碼時就會產生語法錯誤。另一種情況是,設計者在寫設計程式碼,有些設計程式碼是為專有的物件寫的(如公司內部),這些專有的設計程式碼可能不希望被綜合。Synopsys提供了引導語句,設計者可以使用這些引導語句控制DC綜合的物件

可以利用HDL描述中的一些特定的註釋語句來控制綜合工具的工作,從而彌補模擬環境和綜合環境之間的差異,這些註釋語句稱為編譯器指示語句。

translate_off/ translate_on

這組語句用來指示DC停止翻譯 “//synopsys。。。translate_off”之後的Verilog描述,直至出現 “//synopsys translate_on”。當Verilog程式碼鍾含有供模擬用的不可綜合語句時,這項功能能使程式碼方便地在模擬工具與綜合工具之間移植。

例1(translate_off/ translate_on指示語句的使用):

parallel_case/ full_case

DC可能使用帶優先順序的結構來綜合Verilog的case語句,為避免這種情況,可以使用“//synopsys。。。parallel_case”指示DC將case語句綜合為並行的多路選擇器結構。

(parallel_case指示語句的使用):

另外,Verilog允許case語句不覆蓋所有可能情況,當這樣的程式碼由DC綜合時將產生鎖存器。為避免這種情況,可以使用“//synopsys full_case”指示DC所有可能已完全覆蓋。

例2 (full_case指示語句的使用):

(補充二)Verilog PL1是什麼?

上面有提到過PLI介面,這裡簡單介紹下,因為用的比較少,所以就一筆帶過。

程式語言介面(Program Language Interface,PLI)提供了透過C語言函式對Verilog資料結構進行儲存和讀取操作的方法。

PLI介面主要提供以下三種功能。

(1)PLI介面允許使用者編寫自定義的系統任務和系統函式。使用者寫出相應的PLI程式並連線到模擬器後,就可以在自己寫的VerilogHDL程式中使用這些系統任務和系統函式。一旦在模擬過程中呼叫這些任務或者函式,模擬器就會找到對應的使用者所編寫的PLI程式並執行,從而實現模擬器的定製。

(2)這個介面還允許使用者在自己的PLI程式中與模擬器中例化的VerilogHDL硬體進行互動,如讀一個線網路的值、向一排暫存器寫值以及設定一個單元的延遲,等等。

對於PLI程式而言,模擬器中的Verilog例項完全透明,使用者可以對這些硬體做任何操作(當然,不能修改硬體結構)。有了這個功能,使用者就可以在自定義的任務/函式中對硬體執行某些用VerilogHDL語言難以完成的操作。

(3)某些特定的操作需要對模擬過程中一些訊號的變化做出響應,雖然可以用always過程語句來監控少量訊號的變化,但如果需要監測大量訊號,這種機制並不現實。

PLI介面提供了一種函式回撥機制解決這個問題。使用者可以將某個線網路/暫存器等訊號掛上一個PLI程式中的C函式。每當該訊號變化時,呼叫這個C函式,從而很方便地監測訊號。

除了上面所說的這些機制外,PLI還能讓使用者控制模擬的過程,例如暫停、退出以及向日志文件裡寫資訊等,還可以獲取模擬過程的資料,如當前模擬時間等。在實際的PLI程式中,同樣不可缺少這些功能。

參考資料

1、http://www。elecfans。com/d/651393。html

2、EDA原理及Verilog實現

3、https://www。cnblogs。com/IClearner/p/7258983。html

NOW

學習Xilinx FPGA最好的資料其實就是官方手冊,下表總結了部分手冊的主要介紹內容,關注我,持續更新中……