一、题目
8个Led灯分别以不同频率循环闪烁,led[0]0.1ms亮一次;led[1]0.2ms亮一次;led[2]0.3ms亮一次依次类推
二、思路
每个灯的亮的时间不同,但是都在原来的基础上加了0.1ms. 先在文件led_diff_1中设计一个灯,再Add sources创建一个新的设计文件led_diff_8,在这个新的设计文件中依次例化8个led模块
三、设计文件
设计文件共两个,先设计一个led灯的功能led_flash_1_run;在另外一个设计文件led_flash_8中例化8次led_flash_1_run模块
`timescale 1ns / 1ns
module led_flash_1_run(clk,reset_n,led
);
input clk;
input reset_n;
output reg led;
reg [31:0] counter;//注意led的闪烁频率设置的较慢,要防止数据溢出,导致程序出错;
//led灯最长时间0.8ms一次,计数器计数40000000次,d40000000=b1 0111 1101 0111 1000 0100 0000 0000;需要宽度29位;此处32位,可以正常使用
parameter MCNT = 8'd24999999;//parameter 参数,此处参数任意,例化可以修改该参数
always@(posedge clk or negedge reset_n)
if(!reset_n)
counter <=0;
else if(counter == MCNT)
counter <=0;
else
counter <=counter +1'b1;
always@(posedge clk or negedge reset_n)
if(!reset_n)
led <=0;
else if(counter == MCNT)
led <=!led; //在always里赋值,则必须为reg型
endmodule
`timescale 1ns / 1ns
module led_flash_8(clk,reset_n,led);
input clk;
input reset_n;
output [7:0]led;
led_flash_1_run led_flash_8_inst0(
.clk(clk),
.reset_n(reset_n),
.led(led[0])
);
defparam led_flash_8_inst0.MCNT = 5000000-1;//led灯亮0.1ms一次,0.1ms=100000000ns,100000000ns/20ns= 5000000
led_flash_1_run led_flash_8_inst1(
.clk(clk),
.reset_n(reset_n),
.led(led[1])
);
defparam led_flash_8_inst1.MCNT = 10000000-1;//led灯亮0.2ms一次,0.2ms=200000000ns,200000000ns/20ns= 10000000
led_flash_1_run led_flash_8_inst2(
.clk(clk),
.reset_n(reset_n),
.led(led[2])
);
defparam led_flash_8_inst2.MCNT = 15000000-1;//led灯亮0.3ms一次,0.3ms=300000000ns,300000000ns/20ns= 15000000
led_flash_1_run led_flash_8_inst3(
.clk(clk),
.reset_n(reset_n),
.led(led[3])
);
defparam led_flash_8_inst3.MCNT = 20000000-1;//led灯亮0.4ms一次,0.4ms=400000000ns,400000000ns/20ns= 20000000
led_flash_1_run led_flash_8_inst4(
.clk(clk),
.reset_n(reset_n),
.led(led[4])
);
defparam led_flash_8_inst4.MCNT = 25000000-1;//led灯亮0.5ms一次,0.5ms=500000000ns,500000000ns/20ns= 25000000
led_flash_1_run led_flash_8_inst5(
.clk(clk),
.reset_n(reset_n),
.led(led[5])
);
defparam led_flash_8_inst5.MCNT = 30000000-1;//led灯亮0.6ms一次,0.6ms=600000000ns,600000000ns/20ns= 30000000
led_flash_1_run led_flash_8_inst6(
.clk(clk),
.reset_n(reset_n),
.led(led[6])
);
defparam led_flash_8_inst6.MCNT = 35000000-1;//led灯亮0.7ms一次,0.7ms=700000000ns,700000000ns/20ns= 35000000
led_flash_1_run led_flash_8_inst7(
.clk(clk),
.reset_n(reset_n),
.led(led[7])
);
defparam led_flash_8_inst7.MCNT = 40000000-1;//led灯亮0.8ms一次,0.8ms=800000000ns,800000000ns/20ns= 40000000
endmodule
四、激励文件
`timescale 1ns / 1ns
module led_flash_8_tb(
);
reg clk;
reg reset_n;
wire [7:0]led;
led_flash_8 led_flash_8_inst(
.clk(clk),
.reset_n(reset_n),
.led(led)
);
initial clk=1;
always #10 clk=~clk;
initial begin
reset_n=0;
#201;
reset_n=1;
// #4000000000;
// $stop;
end
endmodule
五、仿真图
横坐标一个大刻度200ms,led[0]灯100ms亮一次;led[1]灯200ms亮一次;led[2]灯300ms亮一次;led[3]灯400ms亮一次;led[4]灯500ms亮一次;led[5]灯600ms亮一次;led[6]灯700ms亮一次;led[7]灯800ms亮一次

注意:是每隔100us led[0]都会亮 (并不是说在100us处亮了200us处该led[1]亮 led[0]就不亮了)
六、总结
1、在主模块led_flash_8中,通过调用子模块单个led闪烁功能,利用led_flash_8_inst1.MCNT 对8个led分别进行闪烁频率配置;并且要注意每一次调用子模块的函数名应当不同,要有唯一性

2、由于在主模块将led的闪烁频率设置的较慢,counter对于原来的25位数据溢出,导致程序出错,因此需要注意参数的数据位数。这里设置为32位防止溢出