在Verilog中,parameter既不屬於變量范疇也不屬於線網范疇,經常用來定義一個標志符代表一個常量,所以參數的值在仿真運行的過程中不能進行修改。但是通過使用參數,可以提高程序的可讀性、可復用性和可維護性。目前常用的參數主要分為兩大類:module參數(parameter和localparam)和specify參數(specparam)。
雖然參數使用起來較為方便,但是在使用參數時還需要注意以下幾點:
- parameter、specparam、localparam必須在elaboration階段有確定的值;
- parameter、specparam、localparam只能聲明於module、靜態任務和函數中,不能在動態函數和任務或者begin-end和fork-join中聲明;
- 在module或者specify中參數的名字必須是唯一的,即不能重復聲明,也不能使用已聲明的變量或者線網的名字;
- parameter可以在elaboration過程中通過defparam進行修改或者通過命令行進行修改;
- specparam在elaboraion階段被SDF中相關時序反標修改;
- localpram不能直接被修改,需要通過其它常量進行間接的修改;
【注意】
1、parameter
按照1364的描述,參數可以指定類型和范圍,但是要遵守一定的規則:
- 參數聲明的時候沒有指定類型和范圍時,參數和類型與被賦予的值相同;
- 參數聲明的時候僅指定了范圍沒有指定類型時,參數將為無符號參數,且范圍與聲明時指定的一致,即不隨被賦予的值而改變,所以如果被賦予的值范圍大於參數聲明時指定的范圍,那么高位將會被截取;
- 參數聲明時指定了類型,但是沒有指定范圍,那么參數的范圍將由被賦予的值的范圍決定,但是類型由參數聲明時指定的類型決定;
- 參數聲明時指定為有符號變量類型和范圍,那么參數不受被賦予的值的符號類型和范圍影響;
- 參數聲明時沒有指定范圍但是制定了是否有符號,且被賦予的值有范圍限制,那么這個參數的范圍為[被賦予的值的范圍-1:0];
- 參數聲明時沒有指定范圍但是制定了是否有符號,且被賦予的值無范圍限制,那么這個參數的范圍為[31:0],其中msb至少為31;
【示例】
通過對上述代碼的仿真,可以得到以下幾個特點:
第三行聲明的參數SIZE並沒有指定數據類型和參數范圍,所以在仿真時,SIZE的寬度默認為31位;
盡管在模塊例化時,通過參數傳遞覆蓋了模塊中的參數SIZE,但是defparam通過層次路徑覆蓋設計中的參數具有更高的優先級(由此可以知道defparam的執行處於elaboration的最后階段);
【注意】defparam可能在將來Verilog新的版本中刪除,所以在設計中盡量不要使用。
2、 localparam
localparam與parameter基本功能相同,兩者的不同主要表現在以下幾方面:
- localparam指定的參數不能通過defparam進行修改;
- localparam指定的參數不能通過模塊例化進行修改;
- localparam指定的參數可通過parameter賦值進行間接的修改,此時可利用parameter的修改方式實現localparam的修改;
【示例】
上述代碼中MSB和LSB均可以通過defparam和模塊例化的方式進行修改,但是FIFO_MSB和FIFO_LSB僅能通過MSB、LSB、SIZE進行修改或者直接賦值為常量。也就是說,如果要對localparam進行重新修改,那么只能通過parameter間接的進行修改,其參數化是通過parameter體現的;
3、specparam
specparam聲明了一種較為特殊的參數,除了不能賦值給parameter外,其可以出現在一個模塊的任何位置,specparam指定的參數的聲明必須先於其使用。與其他參數不同的是,specparam指定的參數不能在模塊中通過例化或者參數傳遞進行修改,唯一可以修改參數肚餓方法是通過SDF反標修改;
【示例】
通過上例,這里需要注意以下幾點:
-
parameter不能被specparam指定的參數修改,否則編譯將不會通過;
-
當specparam指定的是一個參數范圍時,該參數將不能被修改!
4、 異同點
三種參數的主要異同點如下表:
specparam參數 |
parameter參數 |
localparam參數 |
聲明時關鍵詞為specparam |
聲明時關鍵詞為parameter |
聲明時關鍵詞為localparam |
可在模塊(module)內或specify塊內進行聲明 |
在specify塊外,module中聲明 |
在specify塊外,module中聲明 |
可在模塊(module)內或specify塊內使用 |
不能在specify塊中使用 |
不能在specify塊中使用 |
可以通過specparam或者parameter指定的參數賦值 |
不能被specparam指定的參數賦值 |
只能通過parameter參數賦值 |
常用於時序約束,在本模塊中聲明定義,用於specify塊 |
常用於模塊間參數傳遞,在本模塊中聲明定義 |
不可直接進行參數傳遞,在本模塊中聲明定義 |
可通過SDF反標修改指定的參數值 |
通過defparam或者模塊例化修改原參數值 |
通過parameter修改原參數值 |
Specparam指定參數時,可以指定參數的取值范圍,但是指定參數范圍后改參數將不能被修改 |
不能指定參數的取值范圍 |
不能指定參數的取值范圍 |
5、 參數值修改方法
通過defparam語句進行修改,但是通過該語句僅能修改parameter參數;
通過模塊例化修改設計中的參數(參數傳遞的方式與端口信號傳遞方式類型:參數順序隱實式傳遞和參數名顯示傳遞),但是修改的對象也僅限於parameter參數,localparam只能通過parameter間接的被修改;
specparam只能通過SDF反標的方式被修改,且parameter不能賦值給specparam;
這里需要注意的是,如果模塊中的參數在模塊中取決於另一個參數,但是在頂層通過defparam對該參數進行了修改,那么改參數的最終值取決於defparam執行后賦予的值,不受其他參數影響;
【示例】
上例中雖然參數TEST被賦予了參數SIZE,但是最終實際上傳遞TEST的值取決於defparam指定的值。
更多資訊,請關注個人公眾號:芯光燦爛