目录
- 一、模块框图
- 二、大致原理
- 三、波形图
- 1、时钟与复位信号
- 2、计数器
- 3、输出信号
- 4、使能信号
- 四、代码部分
- 1、Verilog代码
- 2、tb仿真代码
- 五、仿真波形
一、模块框图
包含两个输入信号:系统时钟(sys_clk)以及复位信号(sys_rst_n)。
一个输出信号:led_out
二、大致原理
通过PWN来控制呼吸灯的亮、灭程度
前一周期为:完全熄灭 ——> 完全点亮
后一周期为:完全点亮 ——> 完全熄灭
三、波形图
1、时钟与复位信号
2、计数器
完全熄灭 ——> 完全点亮 、 完全点亮 ——> 完全熄灭 时间均为1s
由板子频率可知,1us需要50个时钟周期,1ms需要1000us,1s则需要1000ms。
将1s分成1000份,每个T为1ms(份数分得越大,呼吸效果越明显)
将每个T分成1000份,每次越变的宽度就增加一小份,即为1us
3、输出信号
当cnt_1ms计数器的值 ≤ cnt_1s计数器的值 led_out为低电平,其余时间为高电平
上半部分为: 完全熄灭 ——> 完全点亮
下半部分为:完全点亮 ——> 完全熄灭 (即led_out取反)
4、使能信号
用于区分led_out是由 完全熄灭 ——> 完全点亮 还是 完全点亮 ——> 完全熄灭。
完全熄灭 ——> 完全点亮:先低后高
完全点亮 ——> 完全熄灭:先高后低
文章来源:https://uudwc.com/A/JGZpa
四、代码部分
1、Verilog代码
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 [9:0] cnt_1s;
reg [9: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 <= 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))
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))
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_1ms <= cnt_1s)
led_out <= cnt_en;
else
led_out <= ~cnt_en;
endmodule
2、tb仿真代码
`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
always #10 sys_clk = ~sys_clk;
breath_led
#(
.CNT_1US_MAX(6'd4),
.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
五、仿真波形
经分析,与开始手动绘制的波形图吻合,结果正确,此处不再上传上版验证结果。文章来源地址https://uudwc.com/A/JGZpa