1. 概述算法
在Verilog中咱們經常會遇到要將一個常量(算法中的某個參數)賦給不少個變量的狀況,如:spa
x = 10;
y = 10;
z = 10;
若是此時10要改成9,就須要在代碼中修改3個地方,很是的不方便,而且這個10是沒有任何意義的,咱們不知道它表明什麼,因此爲了代碼的易重用、易讀性,咱們應使常量參數化,如:.net
parameter MAX = 10;
x = MAX;
y = MAX;
z = MAX;blog
這樣就只須要修改MAX就能夠了,而且MAX是有意義的,增長代碼的易讀性。ip
parameter是常量,不是變量,因此不容許在運行時修改它的值,即不能在組合邏輯或者時序邏輯中對其進行賦值。內存
有兩種類型的parameters:
1)module parameters
2)specify parameters,只能提供定時和延時的值,不可綜合。
2. module parametersci
module parameters有parameter和localparam兩種,它們所表明的值均可在編譯時進行修改(參數傳遞),parameter可直接修改,localparam只能間接修改。it
2.1 parameterio
parameter在模塊中聲明後,後續編譯時還能夠被從新聲明的值所覆蓋。編譯
parameter msb = 7; // defines msb as a constant value 7
parameter e = 25, f = 9; // defines two constant numbers
parameter r = 5.7; // declares r as a real parameter
parameter byte_size = 8,
byte_mask = byte_size - 1;
parameter average_delay = (r + f) / 2;
parameter signed [3:0] mux_selector = 0;
parameter real r1 = 3.5e17;
parameter p1 = 13'h7e;
parameter [31:0] dec_const = 1'b1; // value converted to 32 bits
parameter newconst = 3'h4; // implied range of [2:0]
parameter newconst = 4; // implied range of at least [31:0]
注:
1)若是參數在聲明時沒有指定type和range,則默認爲最後賦值給參數的type和range;
2)若是參數有指定range,但沒有type,則它的符號默認爲unsigned,而且range和符號都不會被後面的聲明所覆蓋;
3)若是參數有指定range,而且指定爲有符號type,則它的range和符號都不會被後面的聲明所覆蓋;
2.2 localparam
localparam除了不能直接對其進行修改外,其餘屬性與parameter同樣。可經過在聲明時將parameter賦給localparam進行間接修改。狀態機通常都使用localparam。
parameter X = 3;
localparam Y = X*2;
這樣修改X就間接修改了localparam Y的值。
2.3 編譯時parameter的參數傳遞
對parameter的修改有兩種方式:
1)defparam聲明
2)模塊實例聲明
注:若是defparam聲明和模塊實例聲明衝突了,則使用defparam聲明的值。
2.3.1 defparam聲明
defparam使用層次化名稱對模塊中的參數從新賦值,以下面的代碼所示,mod_a是一個實例化的模塊,para_a和para_b是mod_a中的參數。
defparam mod_a.para_a = 2;
defparam mod_a.para_b = 3;
mod_mod mod_a();
注:若是有多個defparam聲明一個parameter,則該parameter取文本(代碼)中最後一個defparam聲明的值。
2.3.2 模塊實例聲明
模塊實例聲明有兩種實現方式:
1)有序列表
列表的順序必須嚴格按照模塊中參數聲明的順序,且不可跳過任何一個參數。以下面代碼,mod_mod中有三個參數,a = 4,b = 5,c = 6.
mod_mod #(1, 2, 3) mod_a(); //三個參數都修改
mod_mod #(4, 2, 3) mod_a(); //只修改b和c,可是也要將a的值聲明
mod_mod #(1, 5, 3) mod_a(); //只修改a和c,可是也要將b的值聲明
2)參數名
聲明時的參數名稱須要和模塊實例中的參數名稱一致,不須要從新聲明的參數能夠缺省。
mod_mod #(.a(2), .b(3)) mod_a(); //兩個參數都從新聲明
mod_mod #(.b(3)) mod_b(); //只聲明參數b
注:針對一個實例的參數聲明只能經過一種方式,不可混合,不一樣實例能夠混合。如
// 不合法
mod_mod #(3, .b(4)) mod_a(); //同時使用兩種方式,不合法
// 合法
mod_mod #(3, 4) mod_a(); //只使用有序列表的方式
mod_mod #(.a(3), .b(4)) mod_b(); //只使用參數名方式
3. `define與parameter的區別
`define做用於整個工程,而parameter只做用於本模塊,一旦`define指令被編譯,則在整個編譯過程當中都有效,因此仿真時使用`define相對於parameter重聲明佔用更少的內存。
參考資料:
1) IEEE Std 1364TM-2005: IEEE Standard for Verilog Hardware Description Language.
2) Verilog Coding Styles for Improved Simulation Efficiency.
3) https://blog.csdn.net/Times_poem/article/details/51371940
---------------------
做者:qq_16923717
來源:CSDN
原文:https://blog.csdn.net/qq_16923717/article/details/81067096