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

一、模块框图

在这里插入图片描述
包含两个输入信号:系统时钟(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

五、仿真波形

在这里插入图片描述
经分析,与开始手动绘制的波形图吻合,结果正确,此处不再上传上版验证结果。

  • 6
    点赞
  • 91
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值