Hi,我是小杜。小杜工作中經常看到驗證環境中的宏定義,之前僅有一點了解,最近小杜需要用到宏,于是整理了一下宏的使用場景和注意事項。小杜經驗尚淺,如有錯誤,還請批評指正。
宏定義`define的用法
SV中使用預處理指令`define來定義宏,宏可以用來創建文本替換。根據場景不同,`define主要用來定義常量、簡化復雜的表達式或代碼段以及提高代碼的可移植性。其基本語法為:
`defineMACRO_NAMEreplaced_text
下面是小杜對一些使用場景的簡單舉例:
定義常量
`defineDATA_WIDTH 32
條件編譯
`ifdef USE_SNPS_VIP ... `endif
簡化復雜表達式
`defineIS_EVEN(x)((x)%2==0) initial begin num = 10; if(`IS_EVEN(num)) ... end
定義宏函數
如果需要定義帶參數的宏函數,使用``來實現變量的整體替換。
`definePRINT_MAX(a, b) if((a)> (b)) $display("Maxvalue:%0b",a); else $display("Max value: %0d", b); initial begin x = 10; y= 20; `PRINT_MAX(x,y); end
`defineTEST_PARAM(X)'"test_``x``param`" $display(`TEST_PARAM(a)); //打印:test_a_param
定義信號路徑
相較于上面,這是一種常用但并非spec推薦的用法,因為`define只是文本替換工具,使用宏來指代信號路徑會導致信號可讀性降低,在調試和維護中容易出錯。但工作中真的很有用。
`define INNER_DATA u_submodule2.u_submodule1.inner_data module submodule1; reg [31:0] inner_data; initial begin inner_data = 32'hDEADBEEF; end endmodule module submodule2; submodule1 u_submodule1(); endmodule module top; submodule2 u_submodule2(); initial begin // 使用 `define 定義的信號路徑 $display("Inner Data: %h", `INNER_DATA); end endmodule
`define的作用域
`define定義的宏在SV中是全局有效的,作用域從宏被定義的地方開始,一直到文件結束,或者宏被`undef顯示的取消定義為止。比如經常使用宏定義信號位寬就是全局作用。
如果在被包含的文件中定義了一個宏,該宏對包含該文件的主文件以及該文件之后的所有內容有效。
//test.sv `defineTEST_NUM 100 //main.sv `include "test.sv" module to; initial begin $display("TEST_NUM:%0d", `TEST_NUM); //將打印 TEST_NUM: 100 end endmodule
使用`undef顯示取消宏定義來控制宏的作用范圍。
`defineMY_MACRO 32 ... `undefMY_MACRO //在`undef之后再調用MY_MACRO就會報錯
`define的使用注意事項
小杜這里列舉幾個會經常遇到的注意事項:
盡量使用大寫字母命名,以便和變量名/函數名區分開,并且一定要避免和其他宏出現命名沖突。盡量保持宏定義簡單明了,保持代碼的可讀性和可維護性,必要時在宏定義旁添加注釋。
如果使用宏定義簡化表達式,最好使用括號來確保表達式求值順序的正確,這是因為宏展開后會直接替換文本,可能會導致變量執行順序出錯。
最重要的是避免過度使用宏!!雖然宏使用起來非常方便,但對于較大的驗證環境,這會導致代碼可讀性變差和維護難度提升。平時隨手寫個宏,方便了自己,但很可能會讓負責環境維護的同事付出更多的時間進行維護。
以上就是小杜對SV中`define宏定義的一些總結,工作中根據需求使用`define即可。感謝你看到這里。
-
代碼
+關注
關注
30文章
4821瀏覽量
68890 -
宏定義
+關注
關注
0文章
51瀏覽量
9043 -
define
+關注
關注
0文章
16瀏覽量
3759
原文標題:【SV】宏定義`define的使用場景和注意事項小結
文章出處:【微信號:小杜的芯片驗證日記,微信公眾號:小杜的芯片驗證日記】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論