Verilog支持使用参数来指定数据位宽或表示某些有特殊含义的常量,可以便于实现模块的通用性和以后的维护,对于同一个模块,可以通过指定不同的参数值来实现不同的功能,比如通过改变加法器模块的数据位宽来实现4/8/16位数据操作,类似函数调用时传入的不同参数。
parameter [type] [range] [name] = [constant value];
例如:
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]
定义为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和parameter非常类似,只不过localparam不能直接进行传递,只能通过parameter来进行间接传递参数。localparam一般用于状态机状态定义,或其他间接性参数。
例如:
parameter X = 3;
localparam Y = X*2;
FROM:verilog-parameters