实现呼吸灯
时序图
## 代码
module breath_led
#(
parameter CNT_US_MAX = 16'd49;
parameter CNT_MS_MAX = 16'd999;
parameter CNT_S_MAX = 16'd999;
) (
input wire clk,
input wire rst_n,
output reg led_out
);
reg [15:0]cnt_s;
reg [15:0]cnt_ms;
reg [15:0]cnt_us;
reg cnt_en;
//us计数器
always @(posedge clk or negedge rst_n) begin
if (~rst_n) begin
cnt_us <= 16'd0;
end
else if (cnt_us == CNT_US_MAX) begin
cnt_us <= 16'd0;
end
else begin
cnt_us <= cnt_us + 16'd1;
end
end
//ms计数器
always @(posedge clk or negedge rst_n) begin
if (~rst_n) begin
cnt_ms <= 16'd0;
end
else if (cnt_ms == CNT_MS_MAX && cnt_us == CNT_US_MAX) begin
cnt_ms <= 16'd0;
end
else if(cnt_us == CNT_US_MAX)begin
cnt_ms <= cnt_ms + 16'd1;
end
else begin
cnt_ms <= cnt_ms;
end
end
//s计数器
always @(posedge clk or negedge rst_n) begin
if (~rst_n) begin
cnt_s <= 16'd0;
end
else if (cnt_s == CNT_S_MAX && cnt_ms == CNT_MS_MAX && cnt_us == CNT_US_MAX) begin
cnt_s <= 16'd0;
end
else if(cnt_ms == CNT_MS_MAX && cnt_us == CNT_US_MAX)begin
cnt_s <= cnt_s + 16'd1;
end
else begin
cnt_s <= cnt_s;
end
end
//en计数器(呼和吸是反过程,这是每秒反转的使能信号)
always @(posedge clk or negedge rst_n) begin
if (~rst_n) begin
cnt_en <= 1'b0;
end
else if(cnt_s == CNT_S_MAX && cnt_ms == CNT_MS_MAX && cnt_us == CNT_US_MAX)begin
cnt_en <= ~cnt_en;
end
else begin
cnt_en <= cnt_en;
end
end
always @(posedge clk or negedge rst_n) begin
if (~rst_n) begin
led_out <= 1'b1;
end
else if ((cnt_ms <= cnt_s && cnt_en == 1'b0) || (cnt_ms >= cnt_s && cnt_en == 1'b1)) begin
led_out <= 1'b0;
end
else if(cnt_s == 0) begin
led_out <= 1'b1;
end
else begin
led_out <= 1'b1;
end
end
endmodule
tb文件
`timescale 1ns/1ps
module breath_led_tb ();
reg clk;
reg rst_n;
wire led_out;
initial begin
clk = 1'b0;
rst_n = 1'b0;
#2
rst_n = 1'b1;
end
always #10 clk = ~clk;
breath_led breath_led_1(
.clk(clk),
.rst_n(rst_n),
.led_out(led_out)
);
endmodule