通过顶层模块调用子模块(.v文件)来实现模块的复用,这里通过对led_controller模块的计数参数赋不同的值来控制LED的不同闪烁时间。
注意:led_controller.v要放在顶层模块的工程目录下
顶层模块:
module flash_led_top(
input sys_clk,
input sys_rst_n,
output led1,led2,led3,led4//注意,这里要传给子模块,所以不能定义为reg!!!!!!
);
// Instantiate the module
led_controller //这个不赋值,因为它有一个默认值19,即数20个数
u_led_1
(
.clk(sys_clk),
.rst_n(sys_rst_n),
.led(led1)
);
led_controller #(.CNT_MAX(9))//修改参数的值,数10个数
u_led_2
(
.clk(sys_clk),
.rst_n(sys_rst_n),
.led(led2)
);
led_controller #(.CNT_MAX(14))
u_led_3
(
.clk(sys_clk),
.rst_n(sys_rst_n),
.led(led3)
);
led_controller #(.CNT_MAX(4))
u_led_4
(
.clk(sys_clk),
.rst_n(sys_rst_n),
.led(led4)
);
endmodule
led_controller.v子模块:
module led_controller(
input clk,
input rst_n,
output reg led
);
reg [5:0] cnt; //根据计数值的大小可以调整位数
parameter CNT_MAX=19; //设置成参数型供用户设定,注意仿真时长限制
always @(posedge clk or negedge rst_n)
if(!rst_n) cnt<=0;
else if(cnt<CNT_MAX) cnt<=cnt+1'b1;
else cnt<=0;
always @(posedge clk or negedge rst_n)
if(!rst_n) led<=0;
else if(cnt==CNT_MAX) led<=~led;
endmodule
testbench文件:
module flash_tb;
// Inputs
reg sys_clk;
reg sys_rst_n;
// Outputs
wire led1;
wire led2;
wire led3;
wire led4;
// Instantiate the Unit Under Test (UUT)
flash_led_top uut (
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.led1(led1),
.led2(led2),
.led3(led3),
.led4(led4)
);
initial begin
// Initialize Inputs
sys_clk = 0;
sys_rst_n = 0;
// Wait 100 ns for global reset to finish
#20;
sys_rst_n = 1;
// Add stimulus here
end
always #10 sys_clk =~sys_clk;
endmodule
工程结构,在实例化子模块后会自动将其放在顶层模块下一级
仿真波形
一点总结:
调用子模块时,输出端口只能使用wire类型变量进行映射,这是语法规定。
举例说明:
//模块
module led(
input sys_clk,
input sys_rst_n,
output reg led
);
//..........模块内容.........
endmodule
//调用时
reg u_led;//错误,不能把reg变量传给reg参数
wire u_led;//正确
led u_led(
.clk(sys_clk),
.rst_n(sys_rst_n),
.led(u_led)
);