任务
本例中我们实现了一个 led 灯的"呼吸",而板子上有 4 个 led 灯,我们可以修改代码让 4 个 led 灯的呼吸频率都不同步,大家可以尝试一下。
代码
module breath_led
#(
parameter CNT_1US_MAX = 6'd49,
parameter CNT_1MS_MAX = 10'd999,
parameter CNT_1S_MAX = 10'd999
)
(
input sys_clk,
input sys_rst_n,
output reg [3:0] led_out
);
// 计数器定义
reg [5:0] cnt_1us;
reg [9:0] cnt_1ms;
reg [9:0] cnt_1s [3:0];
reg cnt_1s_en [3:0];
// 1us计数器
always @(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
cnt_1us <= 6'd0;
else if(cnt_1us == CNT_1US_MAX)
cnt_1us <= 6'd0;
else
cnt_1us <= cnt_1us + 1'b1;
// 1ms计数器
always @(posedge sys_clk or negedge sys_rst_n)
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 + 1'b1;
// 为每个LED生成独立的秒计数器和控制逻辑
genvar i;
generate
for (i = 0; i < 4; i = i + 1) begin : led_inst
// 独立的秒计数器,初始相位错开
always @(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
cnt_1s[i] <= i * 10'd250;
else if(cnt_1s[i] == CNT_1S_MAX && cnt_1ms == CNT_1MS_MAX && cnt_1us == CNT_1US_MAX)
cnt_1s[i] <= 10'd0;
else if(cnt_1ms == CNT_1MS_MAX && cnt_1us == CNT_1US_MAX)
cnt_1s[i] <= cnt_1s[i] + 1'b1;
// 独立的方向标志
always @(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
cnt_1s_en[i] <= 1'b0;
else if(cnt_1s[i] == CNT_1S_MAX && cnt_1ms == CNT_1MS_MAX && cnt_1us == CNT_1US_MAX)
cnt_1s_en[i] <= ~cnt_1s_en[i];
// PWM输出控制
always @(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
led_out[i] <= 1'b0;
else if((cnt_1s_en[i] && cnt_1ms < cnt_1s[i]) || (!cnt_1s_en[i] && cnt_1ms > cnt_1s[i]))
led_out[i] <= 1'b0;
else
led_out[i] <= 1'b1;
end
endgenerate
endmodule
引脚限制
=============================================================================
时钟与复位信号约束
=============================================================================
系统时钟输入(50MHz晶振)
set_property PACKAGE_PIN W19 [get_ports sys_clk]
set_property IOSTANDARD LVCMOS33 [get_ports sys_clk]
全局复位按键(低电平有效)
set_property PACKAGE_PIN N15 [get_ports sys_rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports sys_rst_n]
=============================================================================
LED灯引脚约束
开发板LED为共阳极接法:led_out=0时灯亮,led_out=1时灯灭
=============================================================================
LED0 控制信号
set_property PACKAGE_PIN M21 [get_ports {led_out[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led_out[0]}]
LED1 控制信号
set_property PACKAGE_PIN L21 [get_ports {led_out[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led_out[1]}]
LED2 控制信号
set_property PACKAGE_PIN K21 [get_ports {led_out[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led_out[2]}]
LED3 控制信号
set_property PACKAGE_PIN K22 [get_ports {led_out[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led_out[3]}]