学习笔记:FPGA之数字时钟设计与实现

       数字时钟我们分为四个子模块:一个是按键模块(主要用来按键输入和按键去抖动),一个计数器模块(主要用于时分秒的计数),一个LED数码管显示模块(主要用于时分秒数字显示),一个蜂鸣器模块(根据按键的不同,发出不同频率的声音)。

设计的RTL图如下:

学习笔记:FPGA之数字时钟设计与实现_第1张图片

各模块源码如下:

//--	描述		:	用外设实现数字电子时钟顶层文件

//---------------------------------------------------------------------------
module A4_Clock_Top
(
	//输入端口
	CLK_50M,RST_N,KEY,LED,
	//输出端口
	SEG_EN,SEG_DATA,BEEP
);

//---------------------------------------------------------------------------
//--	外部端口声明
//---------------------------------------------------------------------------
input 				CLK_50M;					//时钟端口
input 				RST_N;					//复位端口						
input	 	[ 7:0]	KEY;						//按键端口
output 				BEEP;						//蜂鸣器端口
output 	[ 7:0]	LED;						//LED端口
output 	[ 5:0]	SEG_EN;					//数码管使能端口
output 	[ 7:0]	SEG_DATA;				//数码管端口

//---------------------------------------------------------------------------
//--	内部端口声明
//---------------------------------------------------------------------------
wire		[ 3:0] 	hours2_data;			//时钟高4位数据
wire		[ 3:0] 	hours1_data;			//时钟低4位数据
wire		[ 3:0] 	minutes2_data;			//分钟高4位数据
wire		[ 3:0] 	minutes1_data;			//分钟低4位数据
wire		[ 3:0] 	seconds2_data;			//秒钟高4位数据
wire		[ 3:0] 	seconds1_data;			//秒钟低4位数据
wire 		[ 7:0] 	key_out;					//消抖完毕输出

//---------------------------------------------------------------------------
//--	逻辑功能实现	
//---------------------------------------------------------------------------
//例化时钟计时模块
Counter_Module		Counter_Init
(
	.CLK_50M			(CLK_50M			),		//时钟端口
	.RST_N			(RST_N			),		//复位端口
	.LED				(LED				),		//按键端口
	.key_out			(key_out			),		//消抖完毕输入
	.hours2_data	(hours2_data	),		//时钟高4位数据
	.hours1_data	(hours1_data	),		//时钟低4位数据
	.minutes2_data	(minutes2_data	),		//分钟高4位数据
	.minutes1_data	(minutes1_data	),		//分钟低4位数据
	.seconds2_data	(seconds2_data	),		//秒钟高4位数据
	.seconds1_data	(seconds1_data	)		//秒钟低4位数据
);

//---------------------------------------------------------------------------
//例化数码管模块
Segled_Module		Segled_Init
(
	.CLK_50M			(CLK_50M			),		//时钟端口
	.RST_N			(RST_N			),		//复位端口
	.hours2_data	(hours2_data	),		//时钟高4位数据
	.hours1_data	(hours1_data	),		//时钟低4位数据
	.minutes2_data	(minutes2_data	),		//分钟高4位数据
	.minutes1_data	(minutes1_data	),		//分钟低4位数据
	.seconds2_data	(seconds2_data	),		//秒钟高4位数据
	.seconds1_data	(seconds1_data	),		//秒钟低4位数据
	.SEG_EN			(SEG_EN			),		//数码管使能端口
	.SEG_DATA		(SEG_DATA		)		//数码管端口
);

//---------------------------------------------------------------------------
//例化蜂鸣器模块
Beep_Module			Beep_Init
(
	.CLK_50M			(CLK_50M			),		//时钟端口
	.RST_N			(RST_N			),		//复位端口
	.BEEP				(BEEP				),		//蜂鸣器端口
	.KEY				(KEY				)		//没有消抖输入
);

//---------------------------------------------------------------------------
//例化按键消抖模块
Key_Module			Key_Init
(
	.CLK_50M			(CLK_50M			),		//时钟端口
	.RST_N			(RST_N			),		//复位端口
	.KEY				(KEY				),		//没有消抖输入
	.key_out			(key_out			)		//消抖完毕输出
);
	
endmodule
//--	描述		:	按键消抖模块

//---------------------------------------------------------------------------
module Key_Module
(
	//输入端口
	CLK_50M,RST_N,KEY,
	//输出端口
	key_out
);  
 
//---------------------------------------------------------------------------
//--	外部端口声明
//---------------------------------------------------------------------------
input					CLK_50M;				//时钟的端口,开发板用的50MHz晶振
input					RST_N;				//复位的端口,低电平复位
input		[ 7:0]	KEY;					//对应开发板上的KEY
output	[ 7:0]	key_out;				//对应开发板上的LED

//---------------------------------------------------------------------------
//--	内部端口声明
//---------------------------------------------------------------------------
reg		[19:0]	time_cnt;			//用来计数按键延迟的定时计数器
reg		[19:0]	time_cnt_n;			//time_cnt的下一个状态
reg		[ 7:0]	key_reg;				//用来接收按键信号的寄存器
reg		[ 7:0]	key_reg_n;			//key_reg的下一个状态
reg		[ 7:0]	led_reg;				//用来控制LED亮灭的显示寄存器			
reg		[ 7:0]	led_reg_n;			//led_reg的下一个状态
wire		[ 7:0]	key_out;				//消抖完成输出按键

//设置定时器的时间为20ms,计算方法为  (20*10^6)ns / (1/50)ns  50MHz为开发板晶振
parameter SET_TIME_20MS = 27'd1_000_000;	

//---------------------------------------------------------------------------
//--	逻辑功能实现	
//---------------------------------------------------------------------------
//时序电路,用来给time_cnt寄存器赋值
always @ (posedge CLK_50M, negedge RST_N)
begin
	if(!RST_N)								//判断复位
		time_cnt <= 20'h0;				//初始化time_cnt值
	else
		time_cnt <= time_cnt_n;			//用来给time_cnt赋值
end

//组合电路,实现20ms的定时计数器
always @ (*)
begin
	if(time_cnt == SET_TIME_20MS)		//判断20ms时间
		time_cnt_n = 20'h0;				//如果到达20ms,定时计数器将会被清零
	else
		time_cnt_n <= time_cnt + 1'b1;//如果未到20ms,定时计数器将会继续累加
end

//时序电路,用来key_reg寄存器赋值
always @ (posedge CLK_50M, negedge RST_N)
begin
	if(!RST_N)								//判断复位
		key_reg <= 8'h11;					//初始化key_reg值
	else
		key_reg <= key_reg_n;			//用来给time_cnt赋值
end

//组合电路,每20ms接收一次按键的值
always @ (*)
begin
	if(time_cnt == SET_TIME_20MS)		//判断20ms时间
		key_reg_n <= KEY;					//如果到达20ms,接收一次按键的值
	else
		key_reg_n <= key_reg;			//如果未到20ms,保持原状态不变
end

assign key_out = key_reg & (~key_reg_n);	//判断按键有没有按下

	 
endmodule
//--	描述		:	时钟计时模块

//---------------------------------------------------------------------------
module Counter_Module
( 
	//输入端口
	CLK_50M,RST_N,key_out,LED,
	//输出端口
	hours2_data,hours1_data,minutes2_data,minutes1_data,seconds2_data,
	seconds1_data
);

//---------------------------------------------------------------------------
//--	外部端口声明
//---------------------------------------------------------------------------
input 				CLK_50M;							//时钟的端口,开发板用的50MHz晶振
input 				RST_N;							//复位的端口,低电平复位
input		[ 7:0]	key_out;							//按键端口
output	[ 7:0]	LED;								//LED端口
output 				hours2_data;					//时钟高4位数据
output 				hours1_data;					//时钟低4位数据
output 				minutes2_data;					//分钟高4位数据
output 				minutes1_data;					//分钟低4位数据
output 				seconds2_data;					//秒钟高4位数据
output 				seconds1_data;					//秒钟低4位数据

//---------------------------------------------------------------------------
//--	内部端口声明
//---------------------------------------------------------------------------
reg		[26:0] 	time_seconds;					//秒钟低位计数器
reg		[26:0] 	time_seconds_n;				//time_seconds的下一个状态
reg		[ 3:0] 	seconds1_data;					//秒钟低位数据寄存器1
reg		[ 3:0] 	seconds1_data_n;				//seconds1_data的下一个状态
reg		[ 3:0] 	seconds2_data;					//秒钟高位数据寄存器2
reg		[ 3:0] 	seconds2_data_n;				//seconds2_data的下一个状态
reg		[ 3:0] 	minutes1_data;					//分钟低位数据寄存器
reg		[ 3:0] 	minutes1_data_n;				//minutes1_data的下一个状态
reg		[ 3:0] 	minutes2_data;					//分钟高位数据寄存器
reg		[ 3:0] 	minutes2_data_n;				//minutes1_data的下一个状态
reg		[ 3:0] 	hours1_data;					//时钟低位数据寄存器
reg		[ 3:0] 	hours1_data_n;					//hours1_data一个状态
reg		[ 3:0] 	hours2_data;					//时钟高位数据寄存器
reg		[ 3:0] 	hours2_data_n;					//hours2_data一个状态
reg					stop_reg;						//控制时钟的开始和暂停
reg					stop_reg_n;						//stop_reg的下一个状态

//设置定时器的时间为1s,计算方法为  (1*10^9) / (1/50)  50MHZ为开发板晶振
parameter SEC_TIME_1S  = 27'd50_000_000;		

//---------------------------------------------------------------------------
//--	逻辑功能实现	
//---------------------------------------------------------------------------
//时序电路,用来给stop_reg寄存器赋值
always @ (posedge CLK_50M or negedge RST_N)
begin
	if(!RST_N)											//判断复位
		stop_reg <= 1'b0;								//初始化stop_reg值
	else
		stop_reg <= stop_reg_n;						//用来给stop_reg赋值
end

//组合电路,用于控制数字时钟的暂停与开始
always @ (*)
begin
	if(key_out[7])										//判断KEY8有没有按下
		stop_reg_n = ~stop_reg;						//当按键按下时,改变stop_reg寄存器的状态
	else
		stop_reg_n = stop_reg;						//当按键没有按下时,stop_reg保持原状态不变
end
//---------------------------------------------------------------------------
//时序电路,用来给time_seconds寄存器赋值
always @ (posedge CLK_50M or negedge RST_N)
begin
	if(!RST_N)											//判断复位
		time_seconds <= 1'b0;						//初始化time_seconds值
	else
		time_seconds <= time_seconds_n;			//用来给time_seconds赋值
end

//组合电路,实现1s的定时计数器
always @ (*)
begin
	if(time_seconds == SEC_TIME_1S)				//判断1s时间
		time_seconds_n = 1'b0;						//如果到达1s,定时计数器将会被清零
	else if(stop_reg)									//判断有没有按下暂停
		time_seconds_n = time_seconds + 1'b1;	//如果没有暂停,定时计数器将会继续累加
	else
		time_seconds_n = time_seconds;			//否则,定时计数器将会保持不变
end	
//---------------------------------------------------------------------------
//时序电路,用来给seconds1_data寄存器赋值
always @ (posedge CLK_50M or negedge RST_N)
begin
	if(!RST_N)											//判断复位
		seconds1_data <= 1'b0;						//初始化seconds1_data值
	else
		seconds1_data <= seconds1_data_n;		//用来给seconds1_data赋值
end

//组合电路,用来控制秒数个位的进位和清零
always @ (*)
begin
	if(time_seconds == SEC_TIME_1S | key_out[6] == 1'b1)	//判断按键KEY7和判断1s时间
		seconds1_data_n = seconds1_data + 1'b1;//如果按键按下或者到达1s,seconds1_data将会加1
	else if(seconds1_data == 4'd10)				//判断seconds1_data有没有达到10s
		seconds1_data_n = 1'b0;						//如果seconds1_data到达10s,seconds1_data将会被清零
	else			
	seconds1_data_n = seconds1_data;				//否则seconds1_data将会保持不变
end
//---------------------------------------------------------------------------
//时序电路,用来给seconds2_data寄存器赋值
always @ (posedge CLK_50M or negedge RST_N)
begin	
	if(!RST_N)											//判断复位
		seconds2_data <= 4'd0;						//初始化seconds2_data值
	else
		seconds2_data <= seconds2_data_n;		//用来给seconds2_data赋值
end

//组合电路,用来控制秒数十位的进位和清零
always @ (*)
begin
	if(seconds1_data == 4'd10)						//判断seconds1_data有没有达到10s
		seconds2_data_n = seconds2_data + 1'b1;//如果seconds1_data到达10s,seconds2_data将会加1
	else if(seconds2_data == 4'd6)				//判断seconds2_data有没有达到60s
		seconds2_data_n = 1'b0;						//如果seconds2_data到达60s,seconds2_data将会被清零
	else
		seconds2_data_n = seconds2_data;			//否则seconds2_data将会保持不变
end
//---------------------------------------------------------------------------
//时序电路,用来给minutes1_data寄存器赋值
always @ (posedge CLK_50M or negedge RST_N)
begin
	if(!RST_N)											//判断复位
		minutes1_data <= 4'd0;						//初始化minutes1_data值
	else
		minutes1_data <= minutes1_data_n;		//用来给minutes1_data赋值
end

//组合电路,用来控制分数个位的进位和清零
always @ (*)
begin
	if(seconds2_data == 4'd6 | key_out[5] == 1'b1)	//判断按键KEY6和判断1m时间
		minutes1_data_n = minutes1_data + 1'b1;//如果按键按下或者到达1m,minutes1_data将会加1
	else if(minutes1_data == 4'd10)				//判断minutes1_data有没有达到10m
		minutes1_data_n = 1'b0;						//如果minutes1_data达到10m,minutes1_data将会被清零
	else
		minutes1_data_n = minutes1_data;			//否则minutes1_data将会保持不变
end
//---------------------------------------------------------------------------
//时序电路,用来给minutes2_data寄存器赋值
always @ (posedge CLK_50M or negedge RST_N)
begin
	if(!RST_N)											//判断复位
		minutes2_data <= 4'd0;						//初始化minutes2_data值
	else
		minutes2_data <= minutes2_data_n;		//用来给minutes2_data赋值
end

//组合电路,用来控制分数十位的进位和清零
always @ (*)
begin
	if(minutes1_data == 4'd10)						//判断minutes1_data有没有达到10m
		minutes2_data_n = minutes2_data + 1'b1;//如果minutes1_data达到10m,minutes2_data将会加1
	else if(minutes2_data == 4'd6)				//判断minutes2_data有没有达到60m
		minutes2_data_n = 1'b0;						//如果minutes2_data达到10m,minutes2_data将会被清零
	else
		minutes2_data_n = minutes2_data;			//否则minutes2_data将会保持不变
end
//---------------------------------------------------------------------------
//时序电路,用来给hours1_data寄存器赋值
always @ (posedge CLK_50M or negedge RST_N)
begin	
	if(!RST_N)											//判断复位
		hours1_data <= 4'd2;							//初始化hours1_data值
	else
		hours1_data <= hours1_data_n;				//用来给hours1_data赋值
end

//组合电路,用来控制时数个位的进位和清零
always @ (*)
begin
	if(minutes2_data == 4'd6 | key_out[4] == 1'b1)	//判断按键KEY5和判断1h时间
		hours1_data_n = hours1_data + 1'b1;		//如果按键按下或者到达1h,hours1_data将会加1	
	else if((hours2_data == 4'd0 || hours2_data == 4'd1) && hours1_data == 4'd10 || (hours2_data == 4'd2 && hours1_data == 4'd4))
		hours1_data_n = 1'b0;						//如果hours2_data等于0,且hours1_data等于10,hours1_data将会被清零
															//如果hours2_data等于1,且hours1_data等于10,hours1_data将会被清零
															//如果hours2_data等于2,且hours1_data等于 4,hours1_data将会被清零
	else
		hours1_data_n = hours1_data;				//否则hours1_data将会保持不变
end
//---------------------------------------------------------------------------
//时序电路,用来给hours2_data寄存器赋值
always @ (posedge CLK_50M or negedge RST_N)
begin
	if(!RST_N)											//判断复位
		hours2_data <= 1'b1;							//初始化hours2_data值
	else
		hours2_data <= hours2_data_n;				//用来给hours2_data赋值
end

//组合电路,用来控制时数十位的进位和清零
always @ (*)
begin
	if((hours2_data == 4'd0 || hours2_data == 4'd1) && hours1_data == 4'd10 || (hours2_data == 4'd2 && hours1_data == 4'd4))
		hours2_data_n = hours2_data + 1'b1;		//如果hours2_data等于0,且hours1_data等于10,hours1_data将会被清零
															//如果hours2_data等于1,且hours1_data等于10,hours1_data将会被清零
															//如果hours2_data等于2,且hours1_data等于 4,hours1_data将会被清零
	else if(hours2_data == 4'd3)							
		hours2_data_n = 1'b0;						//如果hours2_data等于3,hours2_data将会被清零
	else
		hours2_data_n = hours2_data;				//否则hours2_data将会保持不变
end
//---------------------------------------------------------------------------
assign LED = {seconds2_data,seconds1_data};	//将秒钟低4位数据和秒钟高4位数据赋值给LED端口

endmodule
//--	描述		:	蜂鸣器发声模块

//---------------------------------------------------------------------------
module Beep_Module
(
	//输入端口
	CLK_50M,RST_N,KEY,
	//输出端口
	BEEP
);

//---------------------------------------------------------------------------
//--	外部端口声明
//---------------------------------------------------------------------------
input					CLK_50M;					//时钟的端口,开发板用的50MHz晶振
input					RST_N;					//复位的端口,低电平复位
input 	[ 7:0]	KEY;						//按键端口
output				BEEP;						//蜂鸣器端口

//---------------------------------------------------------------------------
//--	内部端口声明
//---------------------------------------------------------------------------
reg		[19:0]	time_cnt;				//用来控制蜂鸣器发声频率的定时计数器
reg		[19:0]	time_cnt_n;				//time_cnt的下一个状态
reg		[15:0]	freq;						//各种音调的分频值
reg					beep_reg;				//用来控制蜂鸣器发声的寄存器
reg					beep_reg_n;				//beep_reg的下一个状态

//---------------------------------------------------------------------------
//--	逻辑功能实现	
//---------------------------------------------------------------------------
//时序电路,用来给time_cnt寄存器赋值
always @ (posedge CLK_50M or negedge RST_N)
begin
	if(!RST_N)									//判断复位
		time_cnt <= 1'b0;						//初始化time_cnt值
	else
		time_cnt <= time_cnt_n;				//用来给time_cnt赋值
end

//组合电路,判断频率,让定时器累加 
always @ (*)
begin
	if(time_cnt < freq)						//判断分频值
		time_cnt_n = time_cnt + 1'b1;		//定时器累加操作
	else
		time_cnt_n = 1'b0;					//定时器清零操作
end

//时序电路,用来给beep_reg寄存器赋值
always @ (posedge CLK_50M or negedge RST_N)
begin
	if(!RST_N)									//判断复位
		beep_reg <= 1'b0;						//初始化beep_reg值
	else
		beep_reg <= beep_reg_n;				//用来给beep_reg赋值
end

//组合电路,判断频率,使蜂鸣器发声
always @ (*)
begin
	if(time_cnt < freq)						//判断分频值
		beep_reg_n = beep_reg;				//蜂鸣器的状态保持不变
	else
		beep_reg_n = ~beep_reg;				//改变蜂鸣器的状态
end

//组合电路,按键选择分频值来实现蜂鸣器发出不同声音
//中音do的频率为523.3hz,freq = 50 * 10^6 / (523 * 2) = 47774
always@(KEY)
begin
	case(KEY)
		8'b00000001: freq<=16'd47774; 	//中音1的频率值523.3Hz
		8'b00000010: freq<=16'd42568; 	//中音2的频率值587.3Hz
		8'b00000100: freq<=16'd37919; 	//中音3的频率值659.3Hz
		8'b00001000: freq<=16'd35791; 	//中音4的频率值698.5Hz
		8'b00010000: freq<=16'd31888; 	//中音5的频率值784Hz
		8'b00100000: freq<=16'd28409; 	//中音6的频率值880Hz
		8'b01000000: freq<=16'd25309; 	//中音7的频率值987.8Hz
		8'b10000000: freq<=16'd23889; 	//高音1的频率值1046.5Hz
		default	  : freq<=16'd0;
	endcase
end

assign BEEP = beep_reg;		//最后,将寄存器的值赋值给端口BEEP

endmodule



//--	描述		:	数码管显示模块

//---------------------------------------------------------------------------
module Segled_Module
(	
	//输入端口 
	CLK_50M,RST_N,seconds2_data,seconds1_data,minutes1_data,minutes2_data,
	hours1_data,hours2_data,
	//输出端口
	SEG_DATA,SEG_EN
);
	
//---------------------------------------------------------------------------
//--	外部端口声明
//---------------------------------------------------------------------------
input 						CLK_50M;					//时钟端口
input							RST_N;					//复位端口
input	 		[ 3:0]		hours2_data;			//时钟高4位数据
input	 		[ 3:0]		hours1_data;			//时钟低4位数据
input	 		[ 3:0]		minutes2_data;			//分钟高4位数据
input	 		[ 3:0]		minutes1_data;			//分钟低4位数据
input	 		[ 3:0]		seconds2_data;			//秒钟高4位数据
input	 		[ 3:0]		seconds1_data;			//秒钟低4位数据
output reg 	[ 5:0] 		SEG_EN;					//数码管使能端口
output reg 	[ 7:0] 		SEG_DATA;				//数码管端口

//---------------------------------------------------------------------------
//--	内部端口声明
//---------------------------------------------------------------------------
reg			[26:0]		time_cnt;				//用来控制数码管闪烁频率的定时计数器
reg			[26:0]		time_cnt_n;				//time_cnt的下一个状态
reg			[ 2:0]		led_cnt;					//用来控制数码管亮灭及显示数据的显示计数器
reg			[ 2:0]		led_cnt_n;				//led_cnt的下一个状态
reg 			[ 3:0]		led_data;				//数据转换寄存器

//设置定时器的时间为10ms,计算方法为  (1*10^6) / (1/50)  50MHz为开发板晶振
parameter SEC_TIME = 16'd50_000;	

//---------------------------------------------------------------------------
//--	逻辑功能实现	
//---------------------------------------------------------------------------
//时序电路,用来给time_cnt寄存器赋值
always @ (posedge CLK_50M or negedge RST_N)  
begin
	if(!RST_N)											//判断复位
		time_cnt <= 27'h0;							//初始化time_cnt值
	else
		time_cnt <= time_cnt_n;						//用来给time_cnt赋值
end

//组合电路,实现10ms的定时计数器
always @ (*)  
begin
	if(time_cnt == SEC_TIME )						//判断10ms时间
		time_cnt_n = 27'h0;							//如果到达10ms,定时计数器将会被清零
	else
		time_cnt_n = time_cnt + 27'h1;			//如果未到10ms,定时计数器将会继续累加
end

//时序电路,用来给led_cnt寄存器赋值
always @ (posedge CLK_50M or negedge RST_N)  
begin
	if(!RST_N)											//判断复位
		led_cnt <= 3'b000;							//初始化led_cnt值
	else
		led_cnt <= led_cnt_n;						//用来给led_cnt赋值
end

//组合电路,判断时间,实现控制显示计数器累加
always @ (*)  
begin
	if(time_cnt == SEC_TIME )						//判断10ms时间		
		led_cnt_n = led_cnt + 1'b1;				//如果到达10ms,计数器进行累加
	else
		led_cnt_n = led_cnt;							//如果未到10ms,计数器保持不变
end

//组合电路,实现数码管的数字显示,将时钟中的数据转换成显示数据
always @ (*)
begin
	case(led_cnt)
		0 : led_data = hours2_data;				//时钟高4位显示
		1 : led_data = hours1_data;				//时钟低4位显示
		2 : led_data = minutes2_data;				//分钟高4位显示
		3 : led_data = minutes1_data;				//分钟低4位显示
		4 : led_data = seconds2_data;				//秒钟高4位显示
		5 : led_data = seconds1_data;				//秒钟低4位显示
		default: led_data = 4'hF;					//给数码管赋值为F
	endcase
end

//组合电路,控制数码管的亮灭
always @ (*)
begin
	case (led_cnt)  
		0 : SEG_EN = 6'b111110; 					//当计数器为0时,数码管SEG1显示
		1 : SEG_EN = 6'b111101;  					//当计数器为1时,数码管SEG2显示
		2 : SEG_EN = 6'b111011; 					//当计数器为2时,数码管SEG3显示
		3 : SEG_EN = 6'b110111; 					//当计数器为3时,数码管SEG4显示
		4 : SEG_EN = 6'b101111;						//当计数器为4时,数码管SEG5显示
		5 : SEG_EN = 6'b011111;						//当计数器为5时,数码管SEG6显示
		default : SEG_EN = 6'b111111;				//熄灭所有数码管	
	endcase 	
end

//组合电路,控制数码管小数点的亮灭
always @ (*)
begin
	case (led_cnt)  
		0 : SEG_DATA[7] = 1'b0;  					//熄灭数码管SEG1的小数点
		1 : SEG_DATA[7] = 1'b1;	  					//点亮数码管SEG2的小数点
		2 : SEG_DATA[7] = 1'b0; 					//熄灭数码管SEG3的小数点
		3 : SEG_DATA[7] = 1'b1;  					//点亮数码管SEG4的小数点
		4 : SEG_DATA[7] = 1'b0; 					//熄灭数码管SEG5的小数点
		5 : SEG_DATA[7] = 1'b0; 					//熄灭数码管SEG6的小数点
		default : SEG_DATA[7] = 1'b0;				//熄灭所有数码管的小数点
	endcase 	
end

//组合电路,实现数码管的显示
always @ (*)
begin
  case(led_data)
		0  : SEG_DATA[6:0] = 7'b0111111;   		//显示数字 "0"
		1  : SEG_DATA[6:0] = 7'b0000110;  		//显示数字 "1"
		2  : SEG_DATA[6:0] = 7'b1011011;   		//显示数字 "2"
		3  : SEG_DATA[6:0] = 7'b1001111;   		//显示数字 "3"
		4  : SEG_DATA[6:0] = 7'b1100110;  		//显示数字 "4"
		5  : SEG_DATA[6:0] = 7'b1101101;   		//显示数字 "5"
		6  : SEG_DATA[6:0] = 7'b1111101;   		//显示数字 "6"
		7  : SEG_DATA[6:0] = 7'b0000111;   		//显示数字 "7"
		8  : SEG_DATA[6:0] = 7'b1111111;   		//显示数字 "8"
		9  : SEG_DATA[6:0] = 7'b1101111;  		//显示数字 "9"
		10 : SEG_DATA[6:0] = 7'b1110111;   		//显示数字 "A"
		11 : SEG_DATA[6:0] = 7'b1111100;   		//显示数字 "B"
		12 : SEG_DATA[6:0] = 7'b1011000;   		//显示数字 "C"
		13 : SEG_DATA[6:0] = 7'b1011110;   		//显示数字 "D"
		14 : SEG_DATA[6:0] = 7'b1111001;   		//显示数字 "E"
		15 : SEG_DATA[6:0] = 7'b1110001;   		//显示数字 "F"
		default :SEG_DATA[6:0] = 7'b0111111;	//显示数字 "0"
  endcase
end

endmodule

在按键去抖动模块里面用到了脉冲边沿检测法,原理不是很清楚,后面再写一下。

你可能感兴趣的:(FPGA)