Verilog 带参例化

defparam

用defparam通过模块层次调用的方法,改写低层次模块的参数值 如对1个单口地址线和数据线都是4bit宽度的ram模块的MASK参数进行改写:

defparam u_ram_4*4.MASK = 7;
ram_4*4 u_ram_4*4
	(
		.CLK (clk),
		.A (a[4-1:0]),
		.D (d),
		.EN (en),
		.WR (wr),
		.Q (q));
module ram4*4
	(
	input CLK,
	input [4-1:0] A,
	input [4-1:0] D,
	input EN,
	input WR,
	output reg [4-1:0] Q);
	
	parameter MASK =3;
	reg [4-1:0] mem[0:(1<<4)-1];
	always @(posedge CLK) begin
		if (EN&&WR) begin
			mem[A] <=D&MASK;
		end
		else if(EN&&!WR) begin
			Q <=mem[A]&MASK;
		end
	end
endmodule

带参数模块例化

例化模块时,将新的参数值写入模块例化语句,以此改写原module的参数值

ram #(.AW(4),.DW(4))
	u_ram
	(
		.CLK (clk),
		.A (a[AW-1:0]),
		.D (d),
		.EN (en),
		.WR (wr),
		.Q (q)
	);
module ram
	#( parameter AW=2,
	   parameter DW=3)
	(
		input CLK,
		input [AW-1:0] A,
		input [DW-1:0] D,
		input EN,
		input WR,
		output reg [DW-1:0] Q
	);
	
	reg [DW-1:0] mem[0:(1<<AW)-1];
	always @(posedge CLK) begin
		if (EN&&WR) begin
			mem[A] <= D;
		end
		else if(EN&&!WR) begin
			Q<=mem[A];
		end
	end
endmodule

区别与建议

  • 与模块实例一样,参数例化时,可以不指定原有参数名字,按顺序进行参数例化
  • 也可以带参例化
  • 也可以混用
  • 若1个模块中既有模块在声明时声明的参数,又有在模块实体中声明的参数,那这两种参数还能同时改写吗?
module ram
	#( parameter AW=2,
	   parameter DW=3 )
	   (
	   input CLK,
	   input [AW-1:0] A,
	   input [DW-1:0] D,
	   input EN,
	   input WR,
	   output reg [DW-1:0] Q);
	   
	   parameter MASK=3;
	   
	   reg [DW-1:0] mem[0:(1<<AW)-1];
	   always @(posedge CLK) begin
		   if (EN&&WR) begin
			   mem[A] <=D;
			end
			else if (EN&&!WR) begin
				Q<=mem[A]
			end
		end
endmodule

此时defparame改写MASK,编译报Error

defparam u_ram.AW =4;
defparam u_ram.DW =4;
defparam u_ram.MASK =7;
ram u_ram (......)

defparam u_ram.MASK=7;
ram #(.AW(4),.DW(4)) u_ram(......);

用带参数模例化的方法改写MASK的值,编译不会报错,MASK不会被改写 ->:一种可能的解释时:编译器看来,如果有模块在端口声明时的参数,那么实体中的参数将会被视作localparam,使用defparam不能改写模块实体中声明的参数

  • 不推荐defparam
  • 推荐有要改写的参数,都写入到模块端口声明之前的地方,用关键字#表示,可读性+1