天天看點

Verilog parameter 參數

文章目錄

        • 文法
        • 注意
        • 示例:支援遞增或遞減的計數器
        • localparam

Verilog支援使用參數來指定資料位寬或表示某些有特殊含義的常量,可以便于實作子產品的通用性和以後的維護,對于同一個子產品,可以通過指定不同的參數值來實作不同的功能,比如通過改變加法器子產品的資料位寬來實作4/8/16位資料操作,類似函數調用時傳入的不同參數。

文法

例如:

parameter msb = 7;                  // unsigned value 7
parameter e = 25, f = 9;            // defines two unsigned value
parameter r = 5.7;                  // real parameter
parameter byte_size = 8,		    //unsigned value
          byte_mask = byte_size - 1;// = 7
parameter average_delay = (r + f) / 2;
parameter signed [3:0] mux_selector = 0;//signed 
parameter real r1 = 3.5e17;	//si
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]
           

注意

  • 如果參數在聲明時沒有指定type和range,則預設為最後指派給參數的type和range;
  • 如果參數有指定range,但沒有type,則它的符号預設為unsigned,并且range和符号都不會被後面的聲明所覆寫;
  • 如果參數有指定range,并且指定為有符号type,則它的range和符号都不會被後面的聲明所覆寫;

定義為parameter類型的資料是常量,不能對它進行指派操作。

示例#:支援不同資料寬度的FIFO子產品

// 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

//Verilog 2001 style port declaration
module design_ip #(
    parameter BUS_WIDTH=32,
    parameter DATA_WIDTH=64
)(
    input [BUS_WIDTH-1:0] addr,
    // Other port declarations
);
           

參數的傳入可以通過以下兩種方式,第二種方式靈活性更高,一般用于Testbench檔案。

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
           

如果以上兩種方式同時存在,并且有多個defparam定義同一個參數,則以最後一個defparam為準。

示例:支援遞增或遞減的計數器

通過指定資料寬度和遞增或遞減,可以實作任意資料寬度的遞增或遞減計數器。

module counte #(
    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
           

寬度為2的計數器,由于沒有指定DOWN的值,則預設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
           

4位寬度的遞減計數器

module design_top (   
    input clk,
    input rstn,
    input en,
    output [3:0] out
);

counter #(
    .N(4)
    .DOWN(1)
)u0(
    .clk(clk),
    .rstn(rstn),
    .en(en)
);

endmodule
           

localparam

localparam和parameter非常類似,隻不過localparam不能直接進行傳遞,隻能通過parameter來進行間接傳遞參數。localparam一般用于狀态機狀态定義,或其他間接性參數。

例如:

parameter       X = 3;
localparam      Y = X*2;
           

FROM:verilog-parameters