时序图
代码
breath_led.v文件
module breath_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 [5:0] cnt_1us; //系统时钟为20ns,最大值49,需要6位
reg [9:0] cnt_1ms; //最大值999,需要10位
reg [9:0] cnt_1s; //最大值999,需要10位
reg cnt_en; //使能信号,完成取反操作
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_1us <= 6'd0;
else if(cnt_1us == CNT_1US_MAX) //计时1us
cnt_1us <= 6'd0;
else
cnt_1us <= cnt_1us + 6'd1;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_1ms <= 10'd0;
else if(cnt_1ms == CNT_1MS_MAX && cnt_1us == CNT_1US_MAX) //计时1ms
cnt_1ms <= 10'd0;
else if(cnt_1us == CNT_1US_MAX)
cnt_1ms <= cnt_1ms + 10'd1;
else
cnt_1ms <= cnt_1ms;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_1s <= 10'd0;
else if(cnt_1s == CNT_1S_MAX && cnt_1ms == CNT_1MS_MAX && cnt_1us == CNT_1US_MAX) //计时1s
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;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
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;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
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;
endmodule
tb_breath_led.v文件
`timescale 1ns/1ns
module tb_breath_led();
//声明变量
reg sys_clk;
reg sys_rst_n;
wire led_out;
//初始化变量
initial
begin
sys_clk = 1'b0;
sys_rst_n <= 1'b0;
#20
sys_rst_n <= 1'b1;
end
//系统时钟初始化,周期为20ns
always #10 sys_clk = ~sys_clk;
//实例化
breath_led
#(
.CNT_1US_MAX(6'd6) ,
.CNT_1MS_MAX(10'd9) ,
.CNT_1S_MAX (10'd9)
)
breath_led_inst
(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.led_out (led_out)
);
endmodule
vivado时序
时序图中,led_out 是从 1开始的