module breath_led
#(
parameter CNT_1US_MAX = 6'd49 ,
parameter CNT_1MS_MAX = 10'd999 ,
parameter CNT_1S_MAX = 10'd999
)
(
input wire sys_clk,
input wire sys_rst_n,
output reg led_out
);
reg [5:0] cnt_1us ;
reg [9:0] cnt_1ms ;
reg [9:0] cnt_1s ;
reg cnt_1s_en ;
//cnt_1us记到49后为一微秒,并产生溢出重置
always @(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_1us <= 6'b0;
else if(cnt_1us == CNT_1US_MAX)
cnt_1us <= 6'b0;
else
cnt_1us <= cnt_1us + 1'b1;
//cnt_1ms记到1000为一毫秒,并产生溢出重置
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_1ms <= 10'b0;
else if(cnt_1ms == CNT_1MS_MAX && cnt_1us == CNT_1US_MAX)
cnt_1ms <= 10'b0;
else if(cnt_1us == CNT_1US_MAX)
cnt_1ms <= cnt_1ms + 1'b1;
//cnt_1s记到1000为一秒,并产生溢出重置
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_1s <= 10'b0;
else if(cnt_1s == CNT_1S_MAX && cnt_1ms == CNT_1MS_MAX && cnt_1us == CNT_1US_MAX )
cnt_1s <= 10'b0;
else if(cnt_1ms == CNT_1MS_MAX && cnt_1us == CNT_1US_MAX)
cnt_1s <= cnt_1s + 1'b1;
//标志位,每隔一秒取一次反
always @(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_1s_en <= 1'b0;
else if(cnt_1s == CNT_1S_MAX && cnt_1ms == CNT_1MS_MAX && cnt_1us == CNT_1US_MAX )
cnt_1s_en <= ~cnt_1s_en;
//呼吸灯,整个程序的精华,先慢慢变亮,后来慢慢变暗,频率越高表现得越平滑
//这个程序表达的意思就是每隔一毫秒变化一次占空比 和毫秒单位比较先小后大
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n ==1'b0)
led_out <= 1'b0;
else if((cnt_1s_en == 1'b1 && cnt_1ms < cnt_1s)||(cnt_1s_en == 1'b0 && cnt_1ms > cnt_1s))
led_out <= 1'b0;
else
led_out <= 1'b1;
endmodule
`timescale 1ns/1ns
module tb_breath_led();
wire led_out;
reg sys_clk;
reg sys_rst_n;
initial begin
sys_clk = 1'b1;
sys_rst_n <= 1'b0;
#20
sys_rst_n <=1'b1;
end
always #10 sys_clk = ~sys_clk;
breath_led
#(
.CNT_1US_MAX (6'd4) ,
.CNT_1MS_MAX (10'd9),
.CNT_1S_MAX (10'd9)
)
breath_led_inst
(
.sys_clk (sys_clk ),
.sys_rst_n (sys_rst_n),
.led_out (led_out)
);
endmodule
关于思考题需要调整频率,有两种
第一种如果要调节呼吸的快慢就直接改变或添加使信号的周期就可以,并且前面的向量也需要改,改的呼吸灯亮的时间是频率的一半就可以了