Verilog 編譯指令簡介
以反引號 ` 開始的某些識別符號是 Verilog 系統編譯指令。編譯指令為 Verilog 程式碼的撰寫、編譯、除錯等提供了極大的便利。 |
下面介紹下完整的 8 種編譯指令,其中前 4 種使用頻率較高。
在編譯階段,`define 用於文字替換,類似於 C 語言中的 #define。
一旦 `define 指令被編譯,其在整個編譯過程中都會有效。例如,在一個檔案中定義:
`define DATA_DW 32
則在另一個檔案中也可以直接使用 DATA_DW。
`define S $stop; //用`S來代替系統函式$stop; (包括分號) `define WORD_DEF reg [31:0] //可以用`WORD_DEF來宣告32bit暫存器變數
`undef 用來取消之前的宏定義,例如:
`define DATA_DW 32 …… reg [DATA_DW-1:0] data_in ; …… `undef DATA_DW `ifdef, `ifndef, `elsif, `else, `endif
這些屬於條件編譯指令。例如下面的例子中,如果定義了 MCU51,則使用第一種引數說明;如果沒有定義 MCU、定義了 WINDOW,則使用第二種引數說明;如果 2 個都沒有定義,則使用第三種引數說明。
`ifdef MCU51 parameter DATA_DW = 8 ; `elsif WINDOW parameter DATA_DW = 64 ; `else parameter DATA_DW = 32 ; `endif
`elsif, `else 編譯指令對於 `ifdef 指令是可選的,即可以只有 `ifdef 和 `endif 組成一次條件編譯指令塊。
當然,也可用 `ifndef 來設定條件編譯,表示如果沒有相關的宏定義,則執行相關語句。
下面例子中,如果定義了 WINDOW,則使用第二種引數說明。如果沒有定義 WINDOW,則使用第一種引數說明。
例項
`ifndef WINDOW parameter DATA_DW = 32 ; `else parameter DATA_DW = 64 ; `endif
使用 `include 可以在編譯時將一個 Verilog 檔案內嵌到另一個 Verilog 檔案中,作用類似於 C 語言中的 #include 結構。該指令通常用於將全域性或公用的標頭檔案包含在設計檔案裡。
檔案路徑既可以使用相對路徑,也可以使用絕對路徑。
`include "../../param.v" `include "header.v"
在 Verilog 模型中,時延有具體的單位時間表述,並用 `timescale 編譯指令將時間單位與實際時間相關聯。
該指令用於定義時延、模擬的單位和精度,格式為:
`timescale time_unit / time_precision
time_unit 表示時間單位,time_precision 表示時間精度,它們均是由數字以及單位 s(秒),ms(毫秒),us(微妙),ns(納秒),ps(皮秒)和 fs(飛秒)組成。時間精度可以和時間單位一樣,但是時間精度大小不能超過時間單位大小,例如下面例子中,輸出端 Z 會延遲 5.21ns 輸出 A&B 的結果。
例項
`timescale 1ns/100ps //時間單位為1ns,精度為100ps,合法 //`timescale 100ps/1ns //不合法 module AndFunc(Z, A, B); output Z; input A, B ; assign #5.207 Z = A & B endmodule
在編譯過程中,`timescale 指令會影響後面所有模組中的時延值,直至遇到另一個 `timescale 指令或 `resetall 指令。
由於在 Verilog 中沒有預設的 `timescale,如果沒有指定 `timescale,Verilog 模組就有會繼承前面編譯模組的 `timescale 引數。有可能導致設計出錯。
如果一個設計中的多個模組都帶有 `timescale 時,模擬器總是定位在所有模組的最小時延精度上,並且所有時延都相應地換算為最小時延精度,時延單位並不受影響。例如:
例項
`timescale 10ns/1ns module test; reg A, B ; wire OUTZ ; initial begin A = 1; B = 0; # 1.28 B = 1; # 3.1 A = 0; end AndFunc u_and(OUTZ, A, B) ; endmodule
在模組 AndFunc 中,5.207 對應 5.21ns。
在模組 test 中,1.28 對應 13ns,3.1 對應 31ns。
但是,當模擬 test 時,由於 AndFunc 中的最小精度為 100ps,因此 test 中的時延精度將進行重新調整。13ns 將對應 130*100ps,31ns 將對應 310*100ps。模擬時,時延精度也會使用 100ps。模擬時間單位大小沒有影響。
如果有並行子模組,子模組間的 `timescale 並不會相互影響。
例如在模組 test 中再例化一個子模組 OrFunc。模擬 test 時,OrFunc 中的 #5.207 延時依然對應 52ns。
例項
//子模組: `timescale 10ns/1ns //時間單位為1ns,精度為100ps,合法 module OrFunc(Z, A, B); output Z; input A, B ; assign #5.207 Z = A | B endmodule //頂層模組: `timescale 10ns/1ns module test; reg A, B ; wire OUTZ ; wire OUTX ; initial begin A = 1; B = 0; # 1.28 B = 1; # 3.1 A = 0; end AndFunc u_and(OUTZ, A, B) ; OrFunc u_and(OUTX, A, B) ; endmodule
此例中,模擬 test 時,OrFunc 中的 #5.207 延時依然對應 52ns。
`timescale 的時間精度設定是會影響模擬時間的。時間精度越小,模擬時佔用記憶體越多,實際使用的模擬時間就越長。所以如果沒有必要,應儘量將時間精度設定的大一些。
該指令用於為隱式的線網變數指定為線網型別,即將沒有被宣告的連線定義為線網型別。
`default_nettype wand
該例項定義的預設的線網為線與型別。因此,如果在此指令後面的任何模組中的連線沒有說明,那麼該線網被假定為線與型別。
`default_nettype none
該例項定義後,將不再自動產生 wire 型變數。
例如下面第一種寫法編譯時不會報 Error,第二種寫法編譯將不會透過。
例項
//Z1 無定義就使用,系統預設Z1為wire型變數,有 Warning 無 Error module test_and( input A, input B, output Z); assign Z1 = A & B ; endmodule
例項
//Z1無定義就使用,由於編譯指令的存在,系統會報Error,從而檢查出書寫錯誤 `default_nettype none module test_and( input A, input B, output Z); assign Z1 = A & B ; endmodule
該編譯器指令將所有的編譯指令重新設定為預設值。
`resetall 可以使得預設連線型別為線網型別。
當 `resetall 加到模組最後時,可以將當前的 `timescale 取消防止進一步傳遞,只保證當前的 `timescale 在區域性有效,避免 `timescale 的錯誤繼承。
這兩個程式指令用於將模組標記為單元模組,他們包含模組的定義。例如一些與、或、非門,一些 PLL 單元,PAD 模型,以及一些 Analog IP 等。
例項
`celldefine module ( input clk, input rst, output clk_pll, output flag); …… endmodule `endcelldefine
在模組例項化中,出現在這兩個編譯指令間的任何未連線的輸入埠,為正偏電路狀態或者為反偏電路狀態。
`unconnected_drive pull1 . . . / *在這兩個程式指令間的所有未連線的輸入埠為正偏電路狀態(連線到高電平) * / `nounconnected_drive
`unconnected_drive pull0 . . . / *在這兩個程式指令間的所有未連線的輸入埠為反偏電路狀態(連線到低電平) * / `nounconnected_drive
原文地址:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31559985/viewspace-2731447/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Go編譯器簡介【譯】Go編譯
- 編譯過程簡介編譯
- Verilog 多路分支語句簡介
- Verilog HDL迴圈語句簡介
- HTML 指令碼簡介HTML指令碼
- Bash 指令碼簡介指令碼
- [譯] WorkManager 簡介
- [譯]Elasticsearch 簡介Elasticsearch
- C語言編譯和連結過程簡介C語言編譯
- MHA常用指令碼簡介指令碼
- Ansys Student 2020R2中Fluent編譯UDF簡介編譯
- 【譯】Web Components簡介Web
- [譯] RxJava JDBC 簡介RxJavaJDBC
- 【譯】CSS Shapes 簡介CSS
- [譯]自主權身份簡介
- NEO Python編譯器介紹Python編譯
- 手撕Vue-編譯指令資料Vue編譯
- [20200117]ashtop指令碼使用簡介.txt指令碼
- 持久記憶體指令(PMDK)簡介記憶體
- pm2 簡介與常用指令
- [20211118]mutexprof指令碼使用簡介.txtMutex指令碼
- Kubernetes – 容器編排簡介
- HTML 編輯器簡介HTML
- 如何編寫一個前端框架之四-資料繫結簡介(譯)前端框架
- JavaScript 引擎和 Just-in-Time 編譯概念,Hot Function 的簡單介紹JavaScript編譯Function
- 簡單分析AutoIt指令碼的反編譯和程式碼格式化問題指令碼編譯
- [譯] 使用 Vue 編寫一個長按指令Vue
- ffmpeg iOS平臺編譯 指令碼註釋iOS編譯指令碼
- Java的指令碼機制、編譯器APIJava指令碼編譯API
- Unity引擎與C#指令碼簡介UnityC#指令碼
- ARM-GUN彙編簡介
- Linux編輯器Vim簡介Linux
- java中的編碼簡介Java
- Verilog 過程結構簡述
- (譯) 函式式 JS #1:簡介函式JS
- RocketMQ--原始碼編譯和介紹MQ原始碼編譯
- 編譯程式(compiler)的簡單分析編譯Compile
- 【譯】Java NIO 簡明教程系列之 NIO 簡介Java