赞
踩
将系统时钟与复位按键作为输入,led灯状态作为输出,直观显示最终结果。
首先根据实现目标明确led灯在熄灭->点亮->熄灭过程中的波形图,其中低电平代表点亮,高电平代表熄灭;在熄灭->点亮过程,想要实现“呼吸”效果,就需要在每个周期T内逐渐增加led灯的点亮时间,最终将各个周期合并,实现“呼吸”效果。
那么,有了点亮时的呼吸效果,熄灭的呼吸效果就是将熄灭、点亮时间反过来就可以实现了。
接下来,我们利用上文提到的时钟与复位按键,同时引入中间变量绘制完整的波形图:
sys_clk是频率为50Mhz的系统时钟;
sys_rst_n:复位按键,低电平有效,这里我们设除开始一小段时间外,按键始终处于高电平即无效状态;
cnt_1s:1s计数器 ; cnt_1ms : 1ms计数器:以此类推…
特定时间计数器的模值在其他文章里已经说明过,这里不再赘述。
cnt_en : 使能信号,这里的作用是判断led灯何时转换状态,例如上图,当led由亮逐渐熄灭时,当led完全熄灭,cnt_en则由高电平进入低电平,从而使led开始逐渐点亮。
led_out: led输出波形。
module breath_led #( parameter CNT_1us_MAX = 6'd49 , //The maximum modulus of the counter parameter CNT_1ms_MAX = 11'd999 , parameter CNT_1s_MAX = 11'd999 ) ( input wire sys_clk , input wire sys_rst_n , output reg led_out ); reg [10:0] cnt_1s; reg [10:0] cnt_1ms; reg [5:0] cnt_1us; 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) cnt_1us <= 6'd0; else cnt_1us <= 6'd1 + cnt_1us ; always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) cnt_1ms <= 11'd0; else if(cnt_1us == CNT_1us_MAX && cnt_1ms == CNT_1ms_MAX) cnt_1ms <= 11'd0; else if(cnt_1us == CNT_1us_MAX) cnt_1ms <= 11'd1 + cnt_1ms ; else cnt_1ms <= cnt_1ms ; always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) cnt_1s <= 11'd0; else if(cnt_1ms == CNT_1ms_MAX && cnt_1s == CNT_1s_MAX && cnt_1us == CNT_1us_MAX ) cnt_1s <= 11'd0; else if(cnt_1ms == CNT_1ms_MAX && cnt_1us == CNT_1us_MAX) cnt_1s <= 11'd1 + cnt_1s ; else cnt_1s <= cnt_1s ; always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) cnt_en <= 1'd0; 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 ; 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'b1 ; else led_out <= 1'b0; endmodule
`timescale 1ns/1ns module tb_breath_led(); reg sys_clk; reg sys_rst_n; wire led_out; initial begin sys_clk = 1'b1; sys_rst_n <= 1'b0; #20 sys_rst_n <= 1'b1; end /*initial begin $timeformat(-9,0,"ns",6); $monitor("@time %t :in_1=%b,in_2=%b,cin=%b,sum=%b,count=%b" ,$time,in_1,in_2,cin,sum,count); end*/ always #10 sys_clk = ~sys_clk; //clk frequency breath_led #( .CNT_1us_MAX (7'd100), .CNT_1ms_MAX (10'd500), .CNT_1s_MAX (10'd500) ) breath_led_inst ( .sys_clk (sys_clk) , .sys_rst_n(sys_rst_n) , .led_out (led_out) ); endmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。