(一)需求分析:
设计一个周期为4s的呼吸灯,实现LED灯慢慢变亮,然后变亮以后又慢慢变灭,从全暗到全亮需要2s,从全亮到全暗需要2s。
(二)源码展示
module led_breath(
clk,
rst_n,
led
);
input clk; //系统输入时钟,50MHz
input rst_n; //复位
output reg led;//呼吸灯
parameter CNT_2S_END = 10'd999; //设置2s的计数值
parameter CNT_2MS_END = 10'd999; //设置2ms的计数值
parameter CNT_2US_END = 7'd99; //设置2us的计数值
reg [9:0] cnt_2s; //999转换为二进制11_1110_0111,共需要10位位宽,所示设置为[9:0]
reg [9:0] cnt_2ms; //999转换为二进制11_1110_0111,共需要10位位宽,所示设置为[9:0]
reg [6:0] cnt_2us; //99转换为二进制0110_0011,共需要7位位宽,所示设置为[6:0]
reg flag; //标志信号,0为由灭到亮的呼吸过程,1为由亮到灭的呼吸过程
//cnt_2us
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt_2us <= 7'd0;
else if(cnt_2us == CNT_2US_END) /*系统输入时钟为50MHz,故每个时钟节拍为20ns,
所以时钟上升沿采集100次为2us */
cnt_2us <= 7'd0;
else
cnt_2us <= cnt_2us + 1'b1;
end
//cnt_2ms
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt_2ms <= 10'd0;
else if(cnt_2us == CNT_2US_END)begin
if(cnt_2ms == CNT_2MS_END)
cnt_2ms <= 10'd0;
else
cnt_2ms <= cnt_2ms + 1'b1;
end
else
cnt_2ms <= cnt_2ms;
end
//cnt_2s
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
cnt_2s <= 10'd0;
else if((cnt_2us == CNT_2US_END)&&(cnt_2ms == CNT_2MS_END))begin
if(cnt_2s == CNT_2S_END)
cnt_2s <= 10'd0;
else
cnt_2s <= cnt_2s + 1'b1;
end
else
cnt_2s <= cnt_2s;
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
flag <= 1'b0;
else if((cnt_2us == CNT_2US_END)&&(cnt_2ms == CNT_2MS_END)&&(cnt_2s == CNT_2S_END))
flag <= ~flag;
else
flag <= flag;
end
//led
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
led <= 0;
else if(!flag)begin
if(cnt_2s > cnt_2ms)
led <= 1;
else
led <= 0;
end
else begin
if(cnt_2s > cnt_2ms)
led <= 0;
else
led <= 1;
end
end
endmodule
//testbench
`timescale 1ns/1ns
`define CLK_PERIOD 20
module led_breath_tb();
reg clk;
reg rst_n;
wire led;
led_breath led_breath0(
.clk(clk),
.rst_n(rst_n),
.led(led)
);
defparam led_breath0.CNT_2S_END = 9;
defparam led_breath0.CNT_2MS_END = 9;
defparam led_breath0.CNT_2US_END = 9;
initial clk = 0;
always #(`CLK_PERIOD/2) clk = ~clk;
initial begin
rst_n = 0;
#(`CLK_PERIOD*5+1); rst_n = 1;
#(`CLK_PERIOD*5000);$stop;
end
endmodule