基于FPGA的按键控制4盏LED灯循环左移点亮

一:背景介绍:

本篇文章是对昨天程序的一个再使用,关于LED的循环移动,我有话说,其他的就没什么要说的了。

循环左移有两种方法:

一个是:左移运算符 <<;还有一种是:Verilog描述语言特有的拼接符号{ } ;

我个人推荐 拼接符号,简约,快捷,清晰明朗。


二:程序

//======================================//
//==Fosc		:	50MHz
//==Timescale   :	1ns/1ns
//==File name   :	huxideng.v
//==Date		:	2016-09-30
//==Author	    :	CY
//==Function	:	每按键一次,则 led灯左移一位变亮,每次仅有一个LED灯亮
//==Description:
//	当没有按键 按下时,flag_10ms=1'b0;
//	当有  按键 按下时,flag_10ms=1'b1;
//	
//======================================//
module	key_new(
	input		wire			sclk,
	input		wire			rst_n,
	input		wire			key_in,
	
	output		reg	[3:0]		LED_out
	);
	
	//==========================//
	parameter	T_10ms=19'd499_999;
	//==========================//
	reg	[18:0]	cnt_10ms;
	reg			flag_10ms;
	reg			key_value;
	//==========cnt_10ms==========//
	always@(posedge	sclk	or	negedge	rst_n)
		if(!rst_n)
			cnt_10ms	<=19'd0;
		else	if(key_in==1'b1) 	 //没有这一句,意味着是可以累积计数的,如此会出现,即使遇到1就停止计数,一旦监测到0就会累加计数;
			cnt_10ms	<=19'd0;	//我们实际需要的是:key_in=1时,清零,遇到0时就累积加,所以,必须要添加此句		
		else	if(cnt_10ms==T_10ms)	//为的是cnt_10ms>T_10ms,如此就不会执行	cnt_10ms	<=cnt_10ms+1'b1;
			cnt_10ms	<=19'd500_000;
//		else	if(key_in==1'b0)	//
		else	if(key_in==1'b0&&cnt_10ms<=T_10ms)	//目的 是:计数T_10ms+1'b1之后,就不加1
			cnt_10ms	<=cnt_10ms+1'b1;
			
	//==========flag_10ms========//		
	always@(posedge	sclk	or	negedge	rst_n)
		if(!rst_n)
			flag_10ms	<=1'b0;		//因为key_value要取反,所以光有flag_10ms=0是不行的,还需要key_in==1'b0;按下了才有效果
		else	if(cnt_10ms==T_10ms-1'b1)
			flag_10ms	<=1'b1;
		else
			flag_10ms	<=1'b0;

	//==================//
	always@(posedge	sclk	or	negedge	rst_n)
		if(!rst_n)
			key_value	<=1'b0;		//我看到是LED上电就亮,我还就奇怪了,不可能的啊!后来看看电路图,
//		else	if(flag_10ms==1'b1)	//原来LED是高电平亮,我的初始化key_value<=1'b1;
		else	if(flag_10ms==1'b1&&key_in==1'b0)//所以不管怎么修改电路,都是LED开机就亮,修正为0时,就可以 了
			key_value	<=1'b1;
		else
			key_value	<=1'b0;	
		
	always@(posedge	sclk	or negedge	rst_n)
		if(!rst_n)
			LED_out	<=4'b0001;
		else	if(key_value==1'b1)
			LED_out	<=	{LED_out[2:0],LED_out[3]};
			
			
endmodule
			

你可能感兴趣的:(FPGA基础篇,FPGA,左移,按键)