FPGA——LED灯闪烁10次

LED灯闪烁10次

基本框架是基于用Verilog编写的定时器,每0.5s计数满,cnt_flag置位,LED翻转一次,那么如果要求只闪烁10次,就需要一个计数变量count,这里采用的方法是,每次cnt_flag置位的时候,都让count加一,因为需要闪烁10次,也就是有10个LED周期,那么就需要翻转20次,所以需要一个5位的计数count。

module flash_ten
#(
	parameter	CNT_MAX = 25'd24_999_999
)
(
	input	wire	sys_clk		,
	input	wire	sys_rst_n	,
	
	output	reg		led_out
);

reg	[24:0]	cnt		;//计数器
reg			cnt_flag;//计数满标志位
reg	 [4:0]	count	;//led闪烁次数10次,即cnt_flag需要20次到达计数次数,所以需要5位

//计数器
always	@(posedge sys_clk or negedge sys_rst_n) begin
	if(!sys_rst_n)
		cnt <= 25'b0;
	else if(cnt == CNT_MAX)
		cnt <= 25'b0;
	else	
		cnt <= cnt + 1'b1;
end

//计数满标志位
always	@(posedge sys_clk or negedge sys_rst_n) begin
	if(!sys_rst_n)
		cnt_flag <= 1'b0;
	else if(cnt == CNT_MAX - 1'b1)
		cnt_flag <= 1'b1;
	else
		cnt_flag <= 1'b0;	
end

以上部分是之前的常规代码,最终就是cnt_flag每0.5s置一。

//count控制
always	@(posedge sys_clk or negedge sys_rst_n) begin
	if(!sys_rst_n)
		count <= 5'b0;
	else if((cnt_flag == 1'b1) && (count <= 5'd19))
		count <= count + 1'b1;
	else
		count <= count;				//这样即可实现到达20次之后不再改变
end

而对于count,只要cnt_flag=1,并且没有超过19,就继续加1,否则就不变!!!!!!
这就是关键,else分支是需要保持不变,而不是等于0。

//led控制
always	@(posedge sys_clk or negedge sys_rst_n) begin
	if(!sys_rst_n)
		led_out <= 1'b0;
	else if(cnt_flag == 1'b1 && count <= 5'd19)
		led_out <= ~led_out;
	else if(count == 5'd20)			//这里必须要有这个条件,不然不亮,因为只有在那么一瞬间会点亮,所以led<=led_out这一句很重要
		led_out <= 1'b1;	
	else
		led_out <= led_out;
end

endmodule

注意,这里一定要加else if(count == 5'd20)这个分支,不能直接else里面就让led_out <= 1'b1;,这样人眼根本观察不到LED亮。

Testbench

`timescale  1ns/1ns

module  flash_ten_tb();

//wire  define
wire    led_out;

//reg   define
reg     sys_clk;
reg     sys_rst_n;

//初始化系统时钟、全局复位
initial begin
	sys_clk		 = 1'b1;
	sys_rst_n	<= 1'b0;
	#20
	sys_rst_n	<= 1'b1;
end

always #10 sys_clk <= ~sys_clk;

flash_ten	
#(
	.CNT_MAX (25'd24)		//20ns * 50 = 1000ns = 1us,10个周期就是10us,所以仿真至少10us
)
flash_ten_inst
(
	.sys_clk	(sys_clk	),
	.sys_rst_n	(sys_rst_n	),
	.led_out	(led_out	)
);

endmodule

在这里插入图片描述

注意在最后有一个小脉冲,
在这里插入图片描述
因为计数到19的时候,继续计数,当cntflag=1时,count在下一个计数周期加一。而此时,由于延一拍的效果,sysclk取到的count依旧是19,只有到了下一个周期的时候,sysclk取到的count才为20,才让ledout=1。

调试参数

  1. count改为计数到18,可以避免最后的小脉冲。仿真以及下载实验都正确。
    在这里插入图片描述
    在这里插入图片描述

一个modelsim的小问题

这个count变量我明明设置的是5位,为啥仿真的时候到15之后就成负数了 在这里插入图片描述
在这里插入图片描述
解决:
右键radix,不要选择decimal,而是选择unsigned,就可显示无符号数了。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值