Verilog实现呼吸灯效果
呼吸灯的效果采用PWM调波的形式,即快速的改变每个周期的占空比(一个周期内高电平时间占一个周期时间的比值)来实现点亮到熄灭的效果。示意如下图
而关于整个波形图,用50MHz的晶振,从0开始计数到49则为1us。
而1ms是1us的1000倍,以1us为基准,从0开始计数到999则为1ms。
同理,以1ms为基准,从0开始计数到999则为1s。
cnt_en为使能信号,当其为0的时候,实现【完全熄灭】——【完全点亮】过程
当cen_en为1的时候,实现【完全点亮】——【完全熄灭】过程
下图实现的是以2s为周期,前1s实现【完全熄灭】——【完全点亮】,后1s实现【完全点亮】——【完全熄灭】。
Verilog代码为
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_en;
always@(posedge sys_clk or negedge sys_rst_n)//1us计数器的波形变化过程
if(sys_rst_n==1'b0)
cnt_1us<=6'd0;
else if(cnt_1us==CNT_1US_MAX)
cnt_1us<=6'd0;
else
cnt_1us<=cnt_1us+6'd1;
always@(posedge sys_clk or negedge sys_rst_n)//1ms计数器的波形变化过程
if(sys_rst_n==1'b0)
cnt_1ms<=10'd0;
else if((cnt_1ms==CNT_1MS_MAX)&&(cnt_1us==CNT_1US_MAX))
cnt_1ms<=10'd0;
else if((cnt_1us==CNT_1US_MAX))
cnt_1ms<=cnt_1ms+10'd1;
else
cnt_1ms<=cnt_1ms;
always@(posedge sys_clk or negedge sys_rst_n)//1s计数器的波形变化过程
if(sys_rst_n==1'b0)
cnt_1s<=10'd0;
else if((cnt_1ms==CNT_1MS_MAX)&&(cnt_1us==CNT_1US_MAX)&&(cnt_1s==CNT_1S_MAX))
cnt_1s<=10'd0;
else if((cnt_1ms==CNT_1MS_MAX)&&(cnt_1us==CNT_1US_MAX))
cnt_1s<=cnt_1s+10'd1;
else
cnt_1s<=cnt_1s;
always@(posedge sys_clk or negedge sys_rst_n)//呼吸灯的两个状态
if(sys_rst_n==1'b0)
cnt_en<=1'b0;
else if((cnt_1ms==CNT_1MS_MAX)&&(cnt_1us==CNT_1US_MAX)&&(cnt_1s==CNT_1S_MAX))
cnt_en<=~cnt_en;
else
cnt_en<=cnt_en;
always@(posedge sys_clk or negedge sys_rst_n)//LED灯的效果
if(sys_rst_n==1'b0)
led_out<=1'b1;
else if((cnt_en==0)&&(cnt_1ms<=cnt_1s)||(cnt_en==1)&&(cnt_1ms>cnt_1s))
led_out<=1'b0;
else
led_out<=1'b1;
endmodule
仿真测试代码如下
`timescale 1ns / 1ns
module tb_breath_led();
reg sys_clk;
reg sys_rst_n;
wire led_out;
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
vivado仿真波形图
三个计数器的计数波形
使能端和呼吸效果
注:LED灯为低电平点亮,高电平熄灭。