基于FPGA的复杂的数字时钟设计(代码)

  复杂的数字时钟设计
一.设计要求:
1、正常显示功能
正常显示时,六位数码管显示日期、时间以及闹钟。对于日期来说,前两位显示年份的后两位(如2020年
显示20),中间两位显示月份,最后两位显示日。对于时间(时间、闹钟时间)来说,前两位显示小时,
中间两位显示分钟,最后两位显示秒;每个两位之间用小数点隔开,最后两位后的小数点不用亮。
2、切换功能
复位时,数码管显示时间;当外部按下“切换”键时,数码管显示日期;再次按下“切换”键时,数码管显示
闹钟时间;再次按下“切换”键时,数码管恢复显示时间。
3、调整功能
当显示时间时,按下“调整”键时,时间的分钟两位闪动,按下“向上”键或“向下”键可以加减分钟。按下“切换”
键时,小时、日、月、年依次闪动,调节方法与上同。
再次按下“调整”键时,即为确定调整。如果对上述调整有疑问,可以再次调整。如果在调整期间,按下“调整”键,所做调整也会生效。调整状态20秒无操作,自动退出调整状态,正常显示时间。
4、调整功能显示
功能进行调整时,所对应调整的部分应该亮0.5s,熄灭0.5s。
5、闹钟
闹钟的小时可以调整到24,用以关闭闹钟。其他时间打开闹钟。闹钟的时间与日期无关,即每日闹钟
都会有作用。当闹钟时间和时间相同时,以LED作为指示,LED指示时间最长为2分钟,或者直到有按
键按下,终止LED指示。
年月日不区分大小月、瑞年等,每月按30天设计。
 
二.顶层设计

input
rst	:	高电平有效复位输入
clk	:	50Mhz的晶振输入
key_reft	:	高电平有效的切换键输入
key_right	:	高电平有效的调整键输入
key_up	:	高电平有效的调整加按键输入
key_down :	高电平有效的调整减按键输入

output
seg	:	数码管段选信号
sel	:	数码管位选信号
led	:	闹钟信号输出




module	clock_top(
input		clk,
input		rst,
input		key_left,
input		key_right,
input		key_up,
input		key_down,
output	wire	[7:0]	seg,
output	wire	[5:0]	sel,
output	wire	[7:0]	led
);

//定义经过pll输出的50Mhz的时钟clk0
wire	clk0 ;
wire	locked ;

//定义消抖后的上下左右4个按键
wire	key_left_out ;			
wire	key_right_out ;
wire	key_up_out ;
wire	key_down_out ;

wire	key ;					//定义一个任意按键取消闹钟报警的信号

wire	[7:0]	Number1 ;
wire    [7:0]	Number2 ;
wire    [7:0]	Number3 ;
wire	[2:0]	dance ;

wire	[7:0]
		bcd1 ,					//当前数码管一,二位显示的数字的BCD码
		bcd2 ,					//当前数码管三,四位显示的数字的BCD码
		bcd3 ;					//当前数码管五,六位显示的数字的BCD码

wire	flag ;

control		inst_control(
.clk				(clk0),
.rst				(rst),
.key_left_out		(key_left_out),
.key_right_out		(key_right_out),
.key_up_out			(key_up_out	),
.key_down_out		(key_down_out),
.Number1			(Number1),
.Number2			(Number2),
.Number3            (Number3),
.dance				(dance),
.flag				(flag),
.key				(key)
);

detector_clk	inst_detector_clk(
.clk 		(clk0),
.rst 		(rst),
.number1	(bcd1),
.number2	(bcd2),
.number3	(bcd3),
.dp 		(6'b101011),
.dance 		(dance),
.seg 		(seg),
.sel        (sel)
) ;	

BinToBCD_clock	inst_BinToBCD_clock1(
.bin 	(Number1),
.bcd 	(bcd1)
) ;

BinToBCD_clock	inst_BinToBCD_clock2(
.bin 	(Number2),
.bcd 	(bcd2)
) ;

BinToBCD_clock	inst_BinToBCD_clock3(
.bin 	(Number3),
.bcd 	(bcd3)
) ;

mypll	mypll_inst(
.areset ( rst ),
.inclk0 ( clk ),
.c0 	( clk0 ),
.locked ( locked )
) ;

dither_button_clock	inst_dither_button_clock(
.clk 		(clk0 	),
.rst 		(rst 	),
.key_in 	(key_left ),
.key_out	(key_left_out)
) ;

dither_button_clock	inst_dither_button_clock2(
.clk 		(clk0 	),
.rst 		(rst 	),
.key_in 	(key_right ),
.key_out	(key_right_out)
) ;

dither_button_clock	inst_dither_button_clock3(
.clk 		(clk0 	),
.rst 		(rst 	),
.key_in 	(key_up ),
.key_out	(key_up_out)
) ;

dither_button_clock	inst_dither_button_clock4(
.clk 		(clk0 	),
.rst 		(rst 	),
.key_in 	(key_down ),
.key_out	(key_down_out)
) ;

alarm	inst_alarm(
.clk	(clk),
.rst	(rst),
.key	(key),
.flag	(flag),
.led	(led)
);


endmodule
二.模块设计

1.按键消抖模块

module	dither_button_clock	(
input			clk ,
input			rst ,
input			key_in ,
output	reg		key_out
) ;

reg		key_in_1 ;
reg		key_in_2 ;
reg		flag ;
reg		flag_filter ;
reg		[25:0]	cnt ;
parameter	[25:0]	T = 50_000_0 ;


always	@(posedge	clk or posedge	rst)
	if	(rst)	begin
		key_in_1 <= 0 ;
        key_in_2 <= 0 ;
	end
	else	begin
		key_in_1 <= key_in ;
        key_in_2 <= key_in_1 ;	
	end

	
always	@(posedge	clk or posedge	rst)
	if	(rst)	
		flag <= 0 ;
	else	if	(key_in_1  == 1 && key_in_2 == 0)
		flag <= 1 ;
	else
		flag <= 0 ;
		

always	@(posedge	clk or posedge	rst)
	if	(rst)
		flag_filter <= 0 ;
	else	if	(flag)
		flag_filter <= 1 ;
	else	if	(cnt == T-1)
		flag_filter <= 0 ;
	else
		flag_filter <= flag_filter ;


always	@(posedge	clk or posedge	rst)	
	if	(rst)	begin
		cnt <= 0 ;
		key_out <= 0 ;
	end
	else	if	(cnt == T-1)	begin
		cnt <= 0 ;
		key_out <= 1 ;
	end
	else	if	(key_in == 0)
		cnt <= 0 ;
	else	if	(flag_filter	&&	key_in == 1)
		cnt	<= cnt + 1 ;
	else
		key_out <= 0 ;



endmodule
2.控制模块

·计数部分:

·显示部分:

module	control(
input	clk,
input	rst,
input		key_left_out,
input		key_right_out,
input		key_up_out,
input		key_down_out,
output		reg		[7:0]	Number1,	//当前数码管一,二位显示的数字的二进制数
output		reg		[7:0]	Number2,    //当前数码管三,四位显示的数字的二进制数
output		reg		[7:0]	Number3,    //当前数码管五,六位显示的数字的二进制数
output		reg		[2:0]	dance,		//定义一个闪动信号,3'b001为数码管右两位闪,3'b010为数码管中间两位闪,3'b100为数码管左两位闪
output		reg		flag,				//定义一个闹钟信号
output		wire	key					//定义一个任意按键取消闹钟报警的信号
);

assign	key = key_left_out | key_right_out | key_up_out | key_down_out ;


reg		[3:0]	cstate = 0 ;			//定义一个数码管当前所显示的数字的状态
reg		clock_cstate = 0 ;				//定义一个当前时钟的状态
reg		[2:0]	adjust_cstate = 0 ;		//定义一个调整时间的状态
reg		[6:0]	
		number1 =0 ,			//秒
		number2 =0 ,			//分
		number3 =0 ,			//时
		numbera =1 ,			//日
		numberb =1 ,			//月
		numberc =0 ,			//年
		number_1 = 0 ,			//闹钟的秒
		number_2 = 0 ,			//闹钟的分
		number_3 = 0 ;			//闹钟的时
	
		

reg		[25:0]	cnt = 0 ;				//记秒的计数器
parameter	[31:0]	T = 50_000_000 ;	//1秒钟
reg		[25:0]	adjust_cnt = 0 ;		//自动退出调整状态的秒计数器
reg		[4:0]	adjust_t = 0 ;			//自动退出调整状态的计时器
reg		adjust_flag = 1 ;				//自动退出调整状态的信号
reg		alarm_adjust_flag = 0 ;			//闹钟调整信号
reg		alarm_adjust_cstate = 0 ;		//定义一个闹钟调整状态
parameter	[31:0]	T2 = 500_000_000 ;  //10秒钟		
reg		[31:0]	nz_cnt = 0 ;			//定义一个闹钟报警时间的计数器


		
always	@(posedge	clk or posedge	rst)	begin
	if	(rst)	begin
		cnt <= 0 ;
		clock_cstate <= 0 ;
		adjust_cstate <= 0 ;
		cstate <= 0 ;		
	end
	else	begin
			case	(clock_cstate)
			0	:	begin
						if	(key_right_out && !alarm_adjust_flag)			//如果按右键时钟进入时间调整状态
							clock_cstate <= 1 ;
						else	if	(cnt == T-1)				//如果没按右键,计数器开始计数,时钟处于正常显示状态
							cnt <= 0 ;
						else	cnt <= cnt + 1 ;
						if	(numberb == 8'd12 && numbera == 8'd30 && number3 == 8'd23 && number2 == 8'd59 && number1 == 8'd59 && cnt == T-1)	begin
							number1 <= 0 ;
							number2 <= 0 ;
							number3 <= 0 ;
							numbera <= 1 ;
							numberb <= 1 ;
							numberc <= numberc + 1 ;
						end
						else	if	(numbera == 8'd30 && number3 == 8'd23 && number2 == 8'd59 && number1 == 8'd59 && cnt == T-1)	begin
							number1 <= 0 ;
							number2 <= 0 ;
							number3 <= 0 ;
							numbera <= 1 ;
							numberb <= numberb + 1 ;
						end
						else	if	(number3 == 8'd23 && number2 == 8'd59 && number1 == 8'd59 && cnt == T-1)	begin
							number1 <= 0 ;
							number2 <= 0 ;
							number3 <= 0 ;
							numbera <= numbera + 1 ;
						end
						else	if	(number2 == 8'd59 && number1 == 8'd59 && cnt == T-1)	begin
							number1 <= 0 ;
							number2 <= 0 ;
							number3 <= number3 + 1 ;
						end
						else	if	(number1 == 8'd59 && cnt == T-1)	begin		
							number1 <= 0 ;
							number2 <= number2 + 1 ;
						end
						else	if	(cnt == T-1)
							number1 <= number1 + 1 ;
						else	begin
							number1 <= number1 ;
							number2 <= number2 ;
							number3 <= number3 ;
							numbera <= numbera ;
							numberb <= numberb ;
							numberc <= numberc ;	
						end					
					end
					
					
			1	:	begin
							case	(adjust_cstate)
							0	:	begin									//调整分
										dance <= 3'b010 ;
										if	(key_up_out)	begin
											adjust_flag <= 0 ;
											if	(number2 == 8'd59)
												number2 <= number2 ;
											else
												number2 <= number2 + 1 ;
										end
										else	if	(key_down_out)	begin
											adjust_flag <= 0 ;
											if	(number2 == 8'd0)
												number2 <= number2 ;
											else
												number2 <= number2 - 1 ;
										end
										else	if	(key_left_out)	begin			//如果按左键,切换到调整小时状态
											adjust_flag <= 0 ;
											adjust_cstate <= 1 ;
										end
										else	if	(key_right_out)	
											adjust_cstate <= 0 ;
										else	number2 <= number2 ;
									end
									
							1	:	begin									//调整时
										dance <= 3'b100 ;
										if	(key_up_out)	begin
											if	(number3 ==8'd23)
												number3 <= number3 ;
											else
												number3 <= number3 + 1 ;
										end
										else	if	(key_down_out)	begin
											if	(number3 ==8'd0)
												number3 <= number3 ;
											else
												number3 <= number3 - 1 ;
										end
										else	if	(key_left_out)					//如果按左键,切换到调整日状态
											adjust_cstate <= 2 ;
										else	if	(key_right_out)	
											adjust_cstate <= 0 ;
										else	number3 <= number3 ;
									end
									
							2	:	begin									//调整日
										dance <= 3'b001 ;
										if	(key_up_out)	begin
											if	(numbera == 8'd30)
												numbera <= numbera ;
											else
												numbera <= numbera + 1 ;
										end
										else	if	(key_down_out)	begin
											if	(numbera == 8'd1)
												numbera <= numbera ;
											else
												numbera <= numbera - 1 ;
										end
										else	if	(key_left_out)					//如果按左键,切换到调整月状态
											adjust_cstate <= 3 ;
										else	if	(key_right_out)	
											adjust_cstate <= 0 ;
										else	numbera <= numbera ;
									end
									
							3	:	begin									//调整月
										dance <= 3'b010 ;
										if	(key_up_out)	begin
											if	(numberb == 8'd12)
												numberb <= numberb ;
											else
												numberb <= numberb + 1 ;
										end
										else	if	(key_down_out)	begin
											if	(numberb == 8'd1)
												numberb <= numberb ;
											else
												numberb <= numberb - 1 ;
										end
										else	if	(key_left_out)					//如果按左键,切换到调整年状态
											adjust_cstate <= 4 ;
										else	if	(key_right_out)	
											adjust_cstate <= 0 ;
										else	numberb <= numberb ;
									end
									
							4	:	begin									//调整年
										dance <= 3'b100 ;
										if	(key_up_out)	begin
											if	(numberc == 8'd99)
												numberc <= numberc ;
											else
												numberc <= numberc + 1 ;
										end
										else	if	(key_down_out)	begin	
											if	(numberc == 8'd0)
												numberc <= numberc ;
											else
												numberc <= numberc - 1 ;
										end
										else	if	(key_left_out)					//如果按左键,切换到调整分状态
											adjust_cstate <= 0 ;
										else	if	(key_right_out)	
											adjust_cstate <= 0 ;
										else	numberc <= numberc ;
									end
							default	:	begin
										number2 <= number2 ;
										number3 <= number3 ;
										numbera <= numbera ;
										numberb <= numberb ;
										numberc <= numberc ;
									end
							endcase
						if	(key_right_out)		begin				//如果按右键,表明时间调整确认,回到正常显示状态
							adjust_flag <= 1 ;
							adjust_t <= 0 ;
							adjust_cnt <= 0 ;
							clock_cstate <= 0 ;
							dance <= 3'b000 ;
						end
						else	if	(adjust_flag == 1 && adjust_t == 5'd20)	begin		//当进入调整状态20秒内无操作,自动退出调整状态,显示正常时间
							adjust_t <= 0 ;
							adjust_cnt <= 0 ;
							clock_cstate <= 0 ;
							dance <= 3'b000 ;
							if	(number1 > 8'd39)	begin
								if	(numberb == 8'd12 && numbera == 8'd30 && number3 == 8'd23 && number2 == 8'd59)	begin
									numberc <= numberc + 1 ;
									numberb <= 1 ;
									numbera <= 1 ;
									number3 <= 0 ;
									number2 <= 0 ;
									number1 <= 8'd19 - (8'd59 - number1) ;
								end
								else	if	(numbera == 8'd30 && number3 == 8'd23 && number2 == 8'd59)	begin
									numberb <= numberb + 1 ;
									numbera <= 0 ;
									number3 <= 0 ;
									number2 <= 0 ;
									number1 <= 8'd19 - (8'd59 - number1) ;
								end
								else	if	(number3 == 8'd23 && number2 == 8'd59)	begin
									numbera <= numbera + 1 ;
									number3 <= 0 ;
									number2 <= 0 ;
									number1 <= 8'd19 - (8'd59 - number1) ;
								end
								else	if	(number2 == 8'd59)	begin
									number3 <= number3 + 1 ;
									number2 <= 0 ;
									number1 <= 8'd19 - (8'd59 - number1) ;
								end
								else	begin
										number2 <= number2 + 1 ;
										number1 <= 8'd19 - (8'd59 - number1) ;
								end
							end
							else
								number1 <= number1 + 8'd20 ;
						end						
						else	if	(adjust_flag == 1 && adjust_cnt == T-1)	begin
							adjust_t <= adjust_t + 1 ;
							adjust_cnt <= 0 ;
						end
						else	if	(adjust_flag == 1)
							adjust_cnt <= adjust_cnt + 1 ;
						else
							adjust_cnt <= adjust_cnt ;
					end
		default	:	begin
						cnt <= 0 ;
						clock_cstate <= 0 ;
						adjust_cstate<=0 ;
						cstate <= 0 ;
					end
		endcase
		
		
		case	(cstate)
				0	:	begin						//数码管停留在显示时分秒状态
							Number1 <= number1 ;
							Number2 <= number2 ;
							Number3 <= number3 ;
							if	(key_right_out)	//如果按右键,进入调整分状态
								cstate <= 2 ;
							else	if	(key_left_out)	//如果按左键,切换到显示年月日状态
								cstate <= 1 ;
							else	cstate <= 0 ;
						end
						
				1	:	begin						//数码管停留在显示年月日状态
							Number1 <= numbera ;
							Number2 <= numberb ;
							Number3 <= numberc ;
							if	(key_right_out)	//如果按右键,进入调整分状态				
								cstate <= 2 ;
							else	if	(key_left_out)	//如果按左键,切换到显示设定闹钟时间状态
								begin
									cstate <= 7 ;
									alarm_adjust_flag <= 1 ;
								end
							else	cstate <= 1 ;
						end
						
				2	:	begin						//数码管停留在调整分钟状态
							Number1 <= number1 ;
							Number2 <= number2 ;
							Number3 <= number3 ;
							if	(key_right_out)				//如果按右键,表明时间调整确认,回到显示时分秒状态
								cstate <= 0 ;
							else	if	(key_left_out)		//如果按左键,切换到调整小时状态
								cstate <= 3 ;
							else	cstate <= 2 ;
						end
						
				3	:	begin						//数码管停留在调整小时状态
							Number1 <= number1 ;
							Number2 <= number2 ;
							Number3 <= number3 ;
							if	(key_right_out)				//如果按右键,表明时间调整确认,回到显示时分秒状态
								cstate <= 0 ;
							else	if	(key_left_out)		//如果按左键,切换到调整日状态
								cstate <= 4 ;
							else	cstate <= 3 ;
						end
						
				4	:	begin						//数码管停留在调整日状态
							Number1 <= numbera ;
							Number2 <= numberb ;
							Number3 <= numberc ;
							if	(key_right_out)				//如果按右键,表明时间调整确认,回到显示时分秒状态
								cstate <= 0 ;
							else	if	(key_left_out)		//如果按左键,切换到调整月状态
								cstate <= 5 ;
							else	cstate <= 4 ;
						end
						
				5	:	begin						//数码管停留在调整月状态
							Number1 <= numbera ;
							Number2 <= numberb ;
							Number3 <= numberc ;
							if	(key_right_out)				//如果按右键,表明时间调整确认,回到显示时分秒状态
								cstate <= 0 ;
							else	if	(key_left_out)		//如果按左键,切换到调整年状态
								cstate <= 6 ;
							else	cstate <= 5 ;
						end
						
				6	:	begin						//数码管停留在调整年状态
							Number1 <= numbera ;
							Number2 <= numberb ;
							Number3 <= numberc ;
							if	(key_right_out)				//如果按右键,表明时间调整确认,回到显示时分秒状态
								cstate <= 0 ;
							else	if	(key_left_out)		//如果按左键,切换到调整分状态
								cstate <= 2 ;
							else	cstate <= 6 ;
						end
						
				7	:	begin						//数码管停留在显示闹钟时间状态
							Number1 <= number_1 ;
							Number2 <= number_2 ;
							Number3 <= number_3 ;
							if	(key_right_out)				//如果按右键,进入闹钟时间调整状态
								cstate <= 8 ;
							else	if	(key_left_out)		//如果按左键,切换到显示时分秒状态
								begin
									cstate <= 0 ;
									alarm_adjust_flag <= 0 ;
								end
							else	
								cstate <= 7 ;
						end
						
				8	:	begin
							Number1 <= number_1 ;
							Number2 <= number_2 ;
							Number3 <= number_3 ;
							case	(alarm_adjust_cstate)
								0	:	begin
											dance <= 3'b010 ;
											if	(key_right_out)		begin	//如果按右键,闹钟时间调整结束
												cstate <= 7 ;
												dance <= 3'b000 ;
											end
											else	if	(key_left_out)		//如果按左键,调整闹钟的小时
												alarm_adjust_cstate <= 1 ;
											else	if	(key_up_out)	begin
												if	(number_2 == 8'd59)
													number_2 <= number_2 ;
												else
													number_2 <= number_2 + 1 ;																			
											end
											else	if	(key_down_out)	begin
												if	(number_2 == 8'd0)
													number_2 <= number_2 ;
												else
													number_2 <= number_2 - 1 ;
											end
											else	alarm_adjust_cstate <= 0 ;
										end
								1	:	begin
											dance <= 3'b100 ;
											if	(key_right_out)	begin	//如果按右键,闹钟时间调整结束
												cstate <= 7 ;
												alarm_adjust_cstate <= 0 ;
												dance <= 3'b000 ;
											end
											else	if	(key_left_out)	//如果按左键,调整闹钟的分
												alarm_adjust_cstate <= 0 ;
											else	if	(key_up_out)	begin
												if	(number_3 == 8'd24)	begin
													number_3 <= number_3 ;
													number_2 <= 0 ;
													end
												else
													number_3 <= number_3 + 1 ;																			
											end
											else	if	(key_down_out)	begin
												if	(number_3 == 8'd0)
													number_3 <= number_3 ;
												else
													number_3 <= number_3 - 1 ;
											end
											else	alarm_adjust_cstate <= 1 ;
										end
							default	:	alarm_adjust_cstate <= 0 ;
							endcase
						end
							
				default	:	begin
								Number1 <= 0 ;
								Number2 <= 0 ;
								Number3 <= 0 ;
								cstate <= 0 ;
							end
				endcase
		end
end


//当显示时间到达闹钟时间,输出一个高电平信号flag
always	@(posedge	clk or posedge	rst)
	if	(rst)
		flag <= 0 ;
	else	if	(nz_cnt == T2-1 || key)	begin		//当闹钟报警时间结束后,flag回归低电平状态
		flag <= 0 ;
		nz_cnt <= 0 ;
	end
	else	if	(number1 == number_1 && number2 == number_2 && number3 == number_3)
		flag <= 1 ;
	else	if	(flag)
		nz_cnt <= nz_cnt + 1 ;
	else	begin
		flag <= flag ;	
	end
		

endmodule
3.二进制转BCD模块

module	BinToBCD_clock	(
input	[6:0]	bin ,
output	[7:0]	bcd  
) ;

reg		[14:0]	number ;
reg		[2:0]	i ;

always	@(*)	begin
		number = {8'b0,bin} ;
		for	(i=0 ; i<=6 ; i = i+1)	begin
			number = number << 1 ;
			if	(i>=2 && i < 6)	begin
				if	(number[10:7] > 4)
					number[10:7] = number[10:7] + 3 ;
				else
					number[10:7] = number[10:7] ;
				if	(number[14:11] > 4)
					number[14:11] = number[14:11] + 3 ;
				else
					number[14:11] = number[14:11] ;
			end
		end
end

assign	bcd = number[14:7] ;

endmodule
4.闹钟模块

module	alarm(
input	clk,
input	rst,
input	flag,
input	key,
output	reg	[7:0]	led
);

		
always	@(posedge	clk or posedge	rst)	begin	
	if	(rst)	
		led <= 8'b0000_0000 ;
	else	if		(key)
		led <= 8'b0000_0000 ;
	else	if		(flag)	
		led <= 8'b1111_1111 ;			//当闹钟报警期间,led灯全亮
	else	led <= 8'b0000_0000 ;
end
		

endmodule
5.数码管显示模块

module	detector_clk(
input			clk ,
input			rst ,
input			[7:0]	number1,
input			[7:0]	number2,
input			[7:0]	number3,
input			[5:0]	dp ,
input			[2:0]	dance ,
output	reg		[7:0]	seg ,
output	reg		[5:0]	sel
) ;

reg		dpi ;
reg		[3:0]	a ;
reg		[2:0]	cstate ;
reg		[2:0]	nstate ;
reg		[25:0]	cnt	;
parameter	[25:0]	T = 50_000	;			//1毫秒
reg		dance_flag = 0 ;
reg		[25:0]	dance_cnt = 0 ;
parameter	[25:0]	T_dance = 25_000_000	;		//0.5秒


always	@(posedge	clk	or	posedge	rst)
	if	(rst)
		dance_flag <= 0 ;
	else	if	(dance_cnt == T_dance-1)
		dance_flag <= !dance_flag ;
	else
		dance_flag <= dance_flag ;


always	@(posedge	clk	or	posedge	rst)
	if	(rst)
		dance_cnt <= 0 ;
	else	if	(dance_cnt == T_dance-1)
		dance_cnt <= 0 ;
	else
		dance_cnt <= dance_cnt + 1 ;		
		

always	@(posedge	clk	or	posedge	rst)
	if	(rst)
		cnt <= 0 ;
	else	if	(cnt == T-1)
		cnt	<= 0 ;
	else
		cnt <= cnt + 1 ;


always	@(posedge	clk	or	posedge	rst)	
	if	(rst)
		cstate <= 0 ;
	else
		cstate <= nstate ;

			
always	@(*)	begin
	if	(rst)
		nstate = 0 ;
	else	case	(cstate)
				0	:	begin
							if	(cnt == T-1)
								nstate = 1 ;
							else
								nstate = 0 ;
						end
				1	:	begin
							if	(cnt == T-1)
								nstate = 2 ;
							else
								nstate = 1 ;
						end
				2	:	begin
							if	(cnt == T-1)
								nstate = 3 ;
							else
								nstate = 2 ;
						end
				3	:	begin
							if	(cnt == T-1)
								nstate = 4 ;
							else
								nstate = 3 ;
						end
				4	:	begin
							if	(cnt == T-1)
								nstate = 5 ;
							else
								nstate = 4 ;
						end
				5	:	begin
							if	(cnt == T-1)
								nstate = 0 ;
							else
								nstate = 5 ;
						end
			default	:	nstate = 0 ;
			endcase
end		


always	@(posedge	clk	or	posedge	rst)	begin	
	if	(rst)	begin
		a <= 0 ;
		sel <= 6'b111_111 ;	
		dpi <= 0 ;
	end		
	else	case	(cstate)
				0	:	begin
							a <= number1[3:0] ;
							dpi <= dp[0];
							if	(dance == 3'b001 && !dance_flag)
								sel <= 6'b111_110 ;
							else	if	(dance == 3'b001 && dance_flag)
								sel <= 6'b111_111 ;
							else	sel <= 6'b111_110 ;
						end
				1	:	begin
							a <= number1[7:4] ;
							dpi <= dp[1] ;
							if	(dance == 3'b001 && !dance_flag)
								sel <= 6'b111_101 ;
							else	if	(dance == 3'b001 && dance_flag)
								sel <= 6'b111_111 ;
							else	sel <= 6'b111_101 ;
						end
				2	:	begin
							a <= number2[3:0] ;
							dpi <= dp[2] ;
							if	(dance == 3'b010 && !dance_flag)
								sel <= 6'b111_011 ;
							else	if	(dance == 3'b010 && dance_flag)
								sel <= 6'b111_111 ;
							else	sel <= 6'b111_011 ;
						end
				3	:	begin
							a <= number2[7:4] ;
							dpi <= dp[3] ;
							if	(dance == 3'b010 && !dance_flag)
								sel <= 6'b110_111 ;
							else	if	(dance == 3'b010 && dance_flag)
								sel <= 6'b111_111 ;
							else	sel <= 6'b110_111 ;
						end
				4	:	begin
							a <= number3[3:0] ;
							dpi <= dp[4] ;
							if	(dance == 3'b100 && !dance_flag)
								sel <= 6'b101_111 ;
							else	if	(dance == 3'b100 && dance_flag)
								sel <= 6'b111_111 ;
							else	sel <= 6'b101_111 ;
						end
				5	:	begin
							a <= number3[7:4] ;
							dpi <= dp[5] ;
							if	(dance == 3'b100 && !dance_flag)
								sel <= 6'b011_111 ;
							else	if	(dance == 3'b100 && dance_flag)
								sel <= 6'b111_111 ;
							else	sel <= 6'b011_111 ;
						end
			
			default	:	begin
							a <= 0 ;
							sel <= 6'b111_111 ;
							dpi <= 0 ;
						end		
			endcase
end


always	@(*)	begin
	if	(rst)
		seg = {1'b1,7'b111_1111} ;
	else	case	(a)
				0	:	seg = {dpi,7'b100_0000} ;
				1	:	seg = {dpi,7'b111_1001} ;
				2	:	seg = {dpi,7'b010_0100} ;
				3   :   seg = {dpi,7'b011_0000} ;
				4   :   seg = {dpi,7'b001_1001} ;
				5   :   seg = {dpi,7'b001_0010} ;
				6   :   seg = {dpi,7'b000_0010} ;
				7   :   seg = {dpi,7'b111_1000} ;
				8   :   seg = {dpi,7'b000_0000} ;
				9   :   seg = {dpi,7'b001_0000} ;
				10  :   seg = {dpi,7'b000_1000} ;
				11  :   seg = {dpi,7'b000_0011} ;
				12  :   seg = {dpi,7'b100_0110} ;
				13  :   seg = {dpi,7'b010_0001} ;
				14  :   seg = {dpi,7'b000_0110} ;
				15  :   seg = {dpi,7'b000_1110} ;
			default	:	seg = {1'b1,7'b111_1111} ;
			endcase
end



endmodule

 

评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值