文章目錄
-
- 前言
- 正文
-
- 子產品參數
- 覆寫參數
- 例子說明
-
- 遞增計數器
- 遞減計數器
- Specify參數
- 子產品參數與Specify參數的差別
- 往期回顧
- 參考資料及推薦關注
Verilog中的參數是使得設計更具有通用性、易讀性的手段之一,使用十分頻繁。
參數是Verilog結構,它允許一個子產品以不同的規格重複使用。例如,一個4位加法器可以被參數化為接受一個位數的值,并且可以在子產品執行個體化期間傳遞新的參數值。是以,一個N位加法器可以變成4位、8位或16位加法器。它們就像函數的參數一樣,在函數調用過程中被傳遞進來。
parameter MSB = 7; // MSB is a parameter with a constant value 7
parameter REAL = 4.5; // REAL holds a real number
parameter FIFO_DEPTH = 256,
MAX_WIDTH = 32; // Declares two parameters
parameter [7:0] f_const = 2'b3; // 2 bit value is converted to 8 bits; 8'b3
參數基本上是常量,是以在運作時修改它們的值是非法的。重新聲明一個已經被net、變量或其他參數使用的名稱是非法的。(即不能使用已經被使用過的名稱)
參數主要有兩種,
module parameter
和
specify parameter
,都可以接受範圍規格。但是,一般情況下,隻要要存儲的值符合要求的寬就可以,是以不需要範圍規格。
子產品參數可以用來覆寫子產品内的參數定義,這使得子產品在編譯時有一組不同的參數。參數可以用
defparam
語句或在子產品執行個體語句中修改。通常的做法是在參數的名稱中使用
大寫字母
,使其一目了然。
下圖所示的子產品使用參數來指定設計内的總線寬度、資料寬度和FIFO的深度,在子產品執行個體化時可以用新的值覆寫,也可以使用
defparam
語句。
// Verilog 1995 style port declaration
module design_ip ( addr,
wdata,
write,
sel,
rdata);
parameter BUS_WIDTH = 32,
DATA_WIDTH = 64,
FIFO_DEPTH = 512;
input addr;
input wdata;
input write;
input sel;
output rdata;
wire [BUS_WIDTH-1:0] addr;
wire [DATA_WIDTH-1:0] wdata;
reg [DATA_WIDTH-1:0] rdata;
reg [7:0] fifo [FIFO_DEPTH];
// Design code goes here ...
endmodule
在新的 ANSI 風格的 Verilog port 聲明中,您可以聲明如下所示的參數。
module design_ip
#(parameter BUS_WIDTH=32,
parameter DATA_WIDTH=64) (
input [BUS_WIDTH-1:0] addr,
// Other port declarations
);
在子產品執行個體化的過程中,可以用新的值來覆寫參數。第一部分執行個體化名為design_ip的子產品,名稱為d0,其中新的參數是在
#( )
内傳遞進來的。第二部分使用名為
defparam
的Verilog構造來設定新的參數值。
- 第一種方法是RTL設計中最常用的傳遞新參數的方法。
- 第二種方法常用于測試台仿真中,以快速更新設計參數,而無需對子產品進行重新設定。
module tb;
// Module instantiation override
design_ip #(BUS_WIDTH = 64, DATA_WIDTH = 128) d0 ( [port list]);
// Use of defparam to override
defparam d0.FIFO_DEPTH = 128;
endmodule
子產品計數器有兩個參數N和DOWN,聲明其預設值分别為2和0。N控制輸出的位數,有效控制計數器的寬度。預設情況下,它是一個2位的計數器。參數DOWN控制計數器是遞增還是遞減。預設情況下,計數器将遞減,因為該參數被設定為0。
module counter
#( parameter N = 2,
parameter DOWN = 0)
( input clk,
input rstn,
input en,
output reg [N-1:0] out);
always @ (posedge clk) begin
if (!rstn) begin
out <= 0;
end
else begin
if (en)
if (DOWN)
out <= out - 1;
else
out <= out + 1;
else
out <= out;
end
end
endmodule
子產品計數器被執行個體化時,N為2,盡管它不是必需的,因為預設值是2。在子產品執行個體化過程中,DOWN沒有被傳遞進來,是以預設值為0,使其成為一個向上的計數器。
module design_top ( input clk,
input rstn,
input en,
output [1:0] out);
counter #(.N(2)) u0 ( .clk(clk),
.rstn(rstn),
.en(en));
endmodule
請看,預設參數是用來實作計數器的,其中N等于2使其成為2位計數器,DOWN等于0使其成為遞增計數器。計數器的輸出在頂層不連接配接。
展開計數器:
上述計數器參數傳遞修改下就可以實作遞減計數器,如下:
module design_top ( input clk,
input rstn,
input en,
output [3:0] out);
counter #(.N(4), .DOWN(1))
u1 ( .clk(clk),
.rstn(rstn),
.en(en));
endmodule
這些主要用于提供定時和延遲值,使用
specparam
關鍵字來聲明。它既可以在specify塊内使用,也可以在主子產品體中使用。
// Use of specify block
specify
specparam t_rise = 200, t_fall = 150;
specparam clk_to_q = 70, d_to_q = 100;
endspecify
// Within main module
module my_block ( ... );
specparam dhold = 2.0;
specparam ddly = 1.5;
parameter WIDTH = 32;
endmodule
由關鍵詞 聲明 | 通過parameter聲明 |
可以在specify塊内或者主子產品内部聲明 | 僅僅可以在主子產品内部聲明 |
SDF可用于覆寫值 | 執行個體聲明參數值或defparam可用于覆寫 |
Verilog初級教程(18)Verilog中的函數與任務
Verilog初級教程(17)Verilog中的case語句
Verilog初級教程(16)Verilog中的控制塊
Verilog初級教程(15)Verilog中的阻塞與非阻塞語句
Verilog初級教程(14)Verilog中的指派語句
Verilog初級教程(13)Verilog中的塊語句
Verilog初級教程(12)Verilog中的generate塊
Verilog初級教程(11)Verilog中的initial塊
Verilog初級教程(10)Verilog的always塊
Verilog初級教程(9)Verilog的運算符
Verilog初級教程(8)Verilog中的assign語句
Verilog初級教程(7)Verilog子產品例化以及懸空端口的處理
Verilog初級教程(6)Verilog子產品與端口
Verilog初級教程(5)Verilog中的多元數組和存儲器
Verilog初級教程(4)Verilog中的标量與向量
Verilog初級教程(3)Verilog 資料類型
Verilog初級教程(2)Verilog HDL的初級文法
Verilog初級教程(1)認識 Verilog HDL
晶片設計抽象層及其設計風格
Verilog以及VHDL所倡導的的代碼準則
FPGA/ASIC初學者應該學習Verilog還是VHDL?