在Verilog设计中,模块化有利于提升代码的可重用性,从而提升设计的效率以及可阅读性。
有时候同一个模块在不同的地方被引用时,可能需要配置不同的参数值。
为了实现这一目的,我们可以在子模块中采用“parameter” 来定义。
下面举个例子,来说明参数传递的两种方法:计数器做为子模块,负责计时。LED模块来调用计数器模块。
首先我们创建一个counter.v,带参数的变量 parameter CNT_MAX = 25’d24_999_999;
module counter(Clk,Rst_n,led);
input Clk; //系统时钟
input Rst_n; //全局复位,低电平复位
output reg led; //led输出
reg [24:0]cnt; //定义计数器寄存器
parameter CNT_MAX = 25'd24_999_999;
//计数器计数进程
always@(posedge Clk or negedge Rst_n)
if(Rst_n == 1'b0)
cnt <= 25'd0;
else if(cnt == CNT_MAX)
cnt <= 25'd0;
else
cnt <= cnt + 1'b1;
//led输出控制进程
always@(posedge Clk or negedge Rst_n)
if(Rst_n == 1'b0)
led <= 1'b1;
else if(cnt == CNT_MAX)
led <= ~led;
else
led <= led;
endmodule
然后创建一个顶层模块LED_flicker.v ,
例化 counter 时,通过不同的参数赋值,实现同一模块,不同参数的目的。
方法一:
defparam counter0.CNT_MAX = 24_999_99;
defparam counter1.CNT_MAX = 24_999_9;
module LED_flicker(
Clk,
Rst_n,
LED
);
input Clk;
input Rst_n;
output [1:0]LED;
counter counter0(
.Clk(Clk),
.Rst_n(Rst_n),
.led(LED[0])
);
counter counter1(
.Clk(Clk),
.Rst_n(Rst_n),
.led(LED[1])
);
defparam counter0.CNT_MAX = 24_999_99;
defparam counter1.CNT_MAX = 24_999_9;
endmodule
方法二:
#( 24_999_99)
module LED_flicker(
Clk,
Rst_n,
LED
);
input Clk;
input Rst_n;
output [1:0]LED;
counter #(24_999_99) counter0(
.Clk(Clk),
.Rst_n(Rst_n),
.led(LED[0])
);
counter #(24_999_9) counter1(
.Clk(Clk),
.Rst_n(Rst_n),
.led(LED[1])
);
endmodule
如果模块中有多个参数的情况,可以顺序赋值:
#(para1,para2,para3)