前言:记录实现呼吸灯功能,学习FPGA的项目工程创建流程,仿真分析过程
一.模块框图
二.代码编写
呼吸灯由亮变暗再由暗变亮,首先拆分为2个大周期一循环即亮到暗,暗到亮循环执行,然后亮的强度由输出一个脉宽不断变化的方波控制;编程思路如下:2s一个大周期,然后1ms为方波的周期在1ms内调节脉宽从而控制灯亮度,即第一个ms内输出999us的脉宽,第二个ms内输出998us的脉宽......以此类推,从而控制LED的通路时间,从而控制LED的亮度
module breath_control#(
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 [3:0] control_out
);
reg [5:0] cnt_1us;
reg [9:0] cnt_1ms;
reg [9:0] cnt_1s;
reg cnt_en;
//当时钟计数到CNT_1US_MAX时,1us时间
always@(posedge sys_clk or negedge sys_rst_n)begin
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;
end
//us计数,满时产生1ms
always@(posedge sys_clk or negedge sys_rst_n)begin
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;
end
//ms计数,满时产生1s
always@(posedge sys_clk or negedge sys_rst_n)begin
if(sys_rst_n == 1'b0)
cnt_1s <= 10'd0;
else if((cnt_1us == CNT_1US_MAX)
&& (cnt_1ms == CNT_1MS_MAX)
&& (cnt_1s == CNT_1S_MAX))
cnt_1s <= 10'd0;
else if((cnt_1us == CNT_1US_MAX) && (cnt_1ms == CNT_1MS_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 == 1'b0)
cnt_en <= 1'b1;
else if((cnt_1us == CNT_1US_MAX)
&&(cnt_1ms == CNT_1MS_MAX)
&&(cnt_1s == CNT_1S_MAX))
cnt_en <= ~cnt_en;
else
cnt_en <= cnt_en;
end
//输出PWM波形
always@(posedge sys_clk or negedge sys_rst_n)begin
if(sys_rst_n == 1'b0)
control_out <= 4'b0000;
else if((cnt_en == 1'b1) && (cnt_1ms <= cnt_1s)
||(cnt_en == 1'b0) && (cnt_1ms > cnt_1s))
control_out <= 4'b1111;
else
control_out <= 4'b0000;
end
endmodule
三.工程顶层原理图
四.实验验证