【FPGA】用Verilog语言实现呼吸灯实验

目录

  • 一、模块框图
  • 二、大致原理
  • 三、波形图
    • 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是由 完全熄灭 ——> 完全点亮 还是 完全点亮 ——> 完全熄灭。
完全熄灭 ——> 完全点亮:先低后高
在这里插入图片描述
完全点亮 ——> 完全熄灭:先高后低
在这里插入图片描述

四、代码部分

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

原文地址:https://blog.csdn.net/lzh1415926/article/details/124353904

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请联系站长进行投诉反馈,一经查实,立即删除!

h
上一篇 2023年06月19日 19:26
[教程]一文搞懂STM32使用DHT11采集温湿度
下一篇 2023年06月19日 19:26