基础知识
呼吸灯的效果是灯逐渐由暗变亮再逐渐由亮变暗,FPGA的引脚电压只有“0”和“1”两个等级。因此通过改变引脚单位时间内高电平的输出时间来实现呼吸灯,也就是让FPGA引脚输出一系列PWM波信号并不断改变PWM波的占空比。
PWM(Pluse Width Modulation)脉冲宽度调制,是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。占空比(Duty Cycle or Duty Ratio),可以解释为,在一脉冲序列中(方波),正脉冲序列的持续时间与脉冲总周期的比值。也可理解为,电路释放能量的有效时间与总释放时间的比值。
波形图
代码
module breach_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 [9:0]cnt_1s;
reg [9:0]cnt_1ms;
reg [5:0]cnt_1us;
reg cnt_en;
always @(posedge sys_clk or negedge sys_rst_n)
begin
if(!sys_rst_n)
cnt_1us <= 6'd0;
else if (cnt_1us == CNT_1US_MAX)
cnt_1us <= 6'd0;
else
cnt_1us <= cnt_1us + 6'd1;
end
always @(posedge sys_clk or negedge sys_rst_n)
begin
if(!sys_rst_n)
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;
end
always @(posedge sys_clk or negedge sys_rst_n)
begin
if(!sys_rst_n)
cnt_1s <= 10'd0;
else if ((cnt_1s == CNT_1S_MAX) && (cnt_1ms == CNT_1MS_MAX) && (cnt_1us == CNT_1US_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;
end
always @(posedge sys_clk or negedge sys_rst_n)
begin
if(!sys_rst_n)
cnt_en <= 1'b0;
else if((cnt_1s == CNT_1S_MAX) && (cnt_1ms == CNT_1MS_MAX) && (cnt_1us == CNT_1US_MAX))
cnt_en <= ~cnt_en;
else
cnt_en <= cnt_en;
end
always @(posedge sys_clk or negedge sys_rst_n)
begin
if(!sys_rst_n)
led_out <= 1'b1;
else if(((cnt_en == 1'b0)&&(cnt_1ms <= cnt_1s))||((cnt_en == 1'b1)&&(cnt_1ms > cnt_1s)))
led_out <= 1'b0;
else
led_out <= 1'b1;
end
endmodule
`timescale 1ns/1ns
module tb_breach_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;
breach_led
#(
.CNT_1US_MAX (6'd4),
.CNT_1MS_MAX (10'd9),
.CNT_1S_MAX (10'd9)
)
breach_led_inst
(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.led_out (led_out)
);
endmodule