FPGA实现万年历

verilog实现万年历

` 模块分为:时间产生模块,时钟模块,报警模块

项目要求

设计要求:

  1. 6个数码管显示年月日或者时分秒,通过外部一个按键A可以切换显示;
  2. 按键A长按可以进入时间设置;短按B按键可以切换要设置的内容;
  3. 外部第二个按键 B,长按 2s,显示闹钟设置界面:
  4. 闹钟显示时,数码管会闪烁(0.5s亮0.5s 灭),设置小时,小时闪烁:设置分钟,分钟闪烁:闹钟可设置小时和分钟,闹钟显示 形式可以是xx0000显示,也可以是0000xx显示,其中xx就是全黑;设置闹钟模式下,短按B键,切换设置小时或者分钟;
  5. 外部第三第四个按键C和D,设置小时时,C加D减,设置分钟时,同样是C加D减:设置完毕,长按B键2s退出设置闹钟模式,回到正常显示模式:
  6. 当前时间和闹钟时间(小时和分钟)一致时,蜂鸣器响3s,(程序已经改成led闪烁3s)

整体架构流程

在时间产生模块,产生 年月日, 时分秒;时钟模块实现 设置时钟的时间;报警模块实现,声光报警

例如:
在语言模型中,编码器和解码器都是由一个个的 Transformer 组件拼接在一起形成的。

程序实现

1.顶层文件
module top(

input	wire				clk,
input	wire				rst_n,
input	wire		[3:0]	key,
output	wire		[5:0]	sel,
output	wire		[7:0]	seg,
output	wire		[3:0]	led

);

wire				[5:0]	code;

wire						switch_flag;
wire						alarm_flag;
wire						add_flag;
wire						reduce_flag;
wire				[7:0]	hour_data;
wire				[7:0]	min_data;
wire				[7:0]	s_data;
wire						day_add;
wire				[7:0]	year_data;
wire				[7:0]	mon_data;
wire				[7:0]	day_data;
wire				[7:0]	seg_data_12;
wire				[7:0]	seg_data_34;
wire				[7:0]	seg_data_56;
wire				[5:0]	code_alarm;
wire				[7:0]	alarm_hour_data;
wire				[7:0]	alarm_min_data;
wire						alarm_set_flag;
wire						alarm_switch_flag;
wire						time_set_flag;
wire						time_switch_flag;
wire						adjust_time_en;
wire				[5:0]	time_code;
wire						display_day_time;
wire				[5:0]	day_code;
wire						adjust_day_en;

jitter_alarm jitter_alarm_inst(

	.clk					(clk),
	.rst_n					(rst_n),
	.key					(key[1]),
	
	.long_flag				(alarm_set_flag),
	.short_flag				(alarm_switch_flag)
);

jitter_alarm jitter_time_inst(

	.clk					(clk),
	.rst_n					(rst_n),
	.key					(key[0]),
	
	.long_flag				(time_set_flag),
	.short_flag				(time_switch_flag)
);

jitter jitter_inst_add(

  .clk						(clk),
  .rst_n					(rst_n),
  .key						(key[2]),
                     
  .flag						(add_flag)
);

jitter jitter_inst_reduce(

	.clk					(clk),
	.rst_n					(rst_n),
	.key					(key[3]),
					
	.flag					(reduce_flag)
);

time_data time_data_inst(

	.clk					(clk),
	.rst_n					(rst_n),
	.add_flag				(add_flag),
	.reduce_flag			(reduce_flag),
	.time_set_flag			(~time_set_flag),
	.time_switch_flag		(~time_switch_flag),
	.hour_data				(hour_data),
	.min_data				(min_data),
	.s_data					(s_data),
	.day_add_flag			(day_add),
	.adjust_time_en			(adjust_time_en),
	.time_code				(time_code),
	.display_day_time		(display_day_time)
);

year_data year_data_inst(

	.clk					(clk),
	.rst_n					(rst_n),
	.day_add_flag			(day_add),
	.add_flag				(add_flag),
	.reduce_flag			(reduce_flag),
	.day_set_flag			(~time_set_flag),
	.day_switch_flag		(~time_switch_flag),
	.display_day_time		(display_day_time),
	.year_data				(year_data),
	.mon_data				(mon_data),
	.day_data				(day_data),
	.adjust_day_en			(adjust_day_en),
	.day_code				(day_code)
);

alarm_set alarm_set_inst(

	.clk					(clk),
	.rst_n					(rst_n),
	.add_flag				(add_flag),
	.alarm_set_flag			(~alarm_set_flag),
	.alarm_switch_flag		(~alarm_switch_flag),
	.reduce_flag			(reduce_flag),
	.hour_data				(hour_data),
	.min_data				(min_data),
	.code_alarm				(code_alarm),
	.alarm_hour_data		(alarm_hour_data),
	.alarm_min_data			(alarm_min_data)
);

mux3_1 mux3_1_inst(

	.clk					(clk),
	.rst_n					(rst_n),
	.hour_data				(hour_data),
	.min_data				(min_data),
	.s_data					(s_data),
	.yeat_data				(year_data),
	.mon_data				(mon_data),
	.day_data				(day_data),
	.switch_flag			(~time_switch_flag),
	.alarm_hour_data		(alarm_hour_data),
	.alarm_min_data			(alarm_min_data),
	.code_alarm				(code_alarm),
	.alarm_set_flag			(~alarm_set_flag),
	.adjust_time_en			(adjust_time_en),
	.adjust_day_en			(adjust_day_en),
	.time_code				(time_code),
	.day_code				(day_code),
             
	.seg_data_12			(seg_data_12),
	.seg_data_34			(seg_data_34),
	.seg_data_56			(seg_data_56),
	.code					(code),
	.display_day_time		(display_day_time)
);

seven_tube_driver seven_tube_driver_inst(

  .clk						(clk),
  .rst_n					(rst_n),
  .data12					(seg_data_12),
  .data34					(seg_data_34),
  .data56					(seg_data_56),
  .code						(code),
                     
  .sel						(sel),
  .seg						(seg)
);

warn warn_inst(

	.clk					(clk),
	.rst_n					(rst_n),
	.hour_data				(hour_data),
	.min_data				(min_data),
	.s_data					(s_data),
	.alarm_h				(alarm_hour_data),
	.alarm_m				(alarm_min_data),
	.led					(led)
);

endmodule

  1. 按键模块(长按 短按)
`timescale 1ns / 1ps

module jitter_alarm (
  
  input   wire            clk,
  input   wire            rst_n,
  input   wire            key,
  
  output  reg             long_flag,
  output  reg			  short_flag
);
  
  parameter t = 500_000;      //10_000_000/20
  parameter	T_2s = 2_000_000_000 / 20;
  parameter	T = 500_000;
//  reg       temp1, temp2;
//  wire      pos_edge, neg_edge;
  reg          		  state;
  reg       [18:0]    cnt;
  reg		[26:0]    cnt_push;
  reg				  flag;
  reg		[29:0]	  cnt_long;
  reg				  flag_r;
  wire				  flag_neg;
  /*
  always @ (posedge clk, negedge rst_n)
  begin
    if(rst_n == 1'b0)
      begin
        temp1 <= 1'b1;
        temp2 <= 1'b1;
      end
    else
      begin
        temp1 <= key;
        temp2 <= temp1;
      end
  end
  
  assign pos_edge = temp1 & (~temp2);
  assign neg_edge = (~temp1) & temp2;
  */
  
  always @ (posedge clk, negedge rst_n)
  begin
    if(rst_n == 1'b0)
      begin
        cnt <= 19'd0;
        state <= 1'b0;
        flag <= 1'b1;
		cnt_push <= 27'd0;
      end
    else
      case(state)
        1'd0  : begin
                  if(key == 1'b0)
                    begin
                      if(cnt_push == T - 1)
                        begin
                          cnt_push <= 27'd0;
                          state <= 1'b1;
                          flag <= 1'b0;
                        end
                      else
                        begin
                          cnt_push <= cnt_push + 1'b1;
                          state <= 1'b0;
                          flag <= 1'b1;
                        end
                    end
                  else
                    begin
                      cnt_push <= 27'd0;
                      state <= 1'b0;
                      flag <= 1'b1;
                    end
                end
        1'b1  : begin
                  if(key == 1'b1)
                    begin
                      if(cnt == t - 1)
                        begin
                          cnt <= 19'd0;
                          state <= 1'b0;
                          flag <= 1'b1;
                        end
                      else
                        begin
                          cnt <= cnt + 1'b1;
                          state <= 1'b1;
                          flag <= 1'b0;
                        end
                    end
                  else
                    begin
                      cnt <= 19'd0;
                      state <= 1'b1;
                      flag <= 1'b0;
                    end
                end
      endcase
  end
  
  always @ (posedge clk) flag_r <= flag;
  assign	flag_neg = flag & ~flag_r;
  
  always @ (posedge clk, negedge rst_n) begin
	if (rst_n == 1'b0)
		cnt_long <= 30'd0;
	else
		if (flag == 1'b0)
			cnt_long <= cnt_long + 1'b1;
		else
			cnt_long <= 30'd0;
  end
 
  always @ (posedge clk,negedge rst_n) begin
	if (rst_n == 1'b0)
		begin
			long_flag <= 1'b0;
			short_flag <= 1'b0;
		end
	else
		if (flag_neg == 1'b1)
			if (cnt_long > T_2s)
				long_flag <= 1'b1;
			else
				short_flag <= 1'b1;
		else
			begin
				long_flag <= 1'b0;
				short_flag <= 1'b0;
			end
	
  end
  
  
endmodule


3. top文件里面例化的按键消抖模块(低有效)

module jitter(
  
  input   wire            clk,
  input   wire            rst_n,
  input   wire            key,
  
  output  reg             flag
);
  
  parameter t = 500_000;      //10_000_000/20
  
//  reg       temp1, temp2;
//  wire      pos_edge, neg_edge;
  reg            state;
  reg       [18:0]    cnt;
  /*
  always @ (posedge clk, negedge rst_n)
  begin
    if(rst_n == 1'b0)
      begin
        temp1 <= 1'b1;
        temp2 <= 1'b1;
      end
    else
      begin
        temp1 <= key;
        temp2 <= temp1;
      end
  end
  
  assign pos_edge = temp1 & (~temp2);
  assign neg_edge = (~temp1) & temp2;
  */
  
  always @ (posedge clk, negedge rst_n)
  begin
    if(rst_n == 1'b0)
      begin
        cnt <= 19'd0;
        state <= 1'b0;
        flag <= 1'b1;
      end
    else
      case(state)
        1'd0  : begin
                  if(key == 1'b0)
                    begin
                      if(cnt == t - 1)
                        begin
                          cnt <= 19'd0;
                          state <= 1'b1;
                          flag <= 1'b0;
                        end
                      else
                        begin
                          cnt <= cnt + 1'b1;
                          state <= 1'b0;
                          flag <= 1'b1;
                        end
                    end
                  else
                    begin
                      cnt <= 19'd0;
                      state <= 1'b0;
                      flag <= 1'b1;
                    end
                end
        1'b1  : begin
                  if(key == 1'b1)
                    begin
                      if(cnt == t - 1)
                        begin
                          cnt <= 19'd0;
                          state <= 1'b0;
                          flag <= 1'b1;
                        end
                      else
                        begin
                          cnt <= cnt + 1'b1;
                          state <= 1'b1;
                          flag <= 1'b1;
                        end
                    end
                  else
                    begin
                      cnt <= 19'd0;
                      state <= 1'b1;
                      flag <= 1'b1;
                    end
                end
      endcase
  end
  
  
endmodule


4. 时间计时模块

module time_data (

	input	wire				clk,
	input	wire				rst_n,
	input	wire				add_flag,
	input	wire				reduce_flag,
	input	wire				time_set_flag,
	input	wire				time_switch_flag,
	input	wire				display_day_time,
	output	wire		[7:0]	hour_data,
	output	wire		[7:0]	min_data,
	output	wire		[7:0]	s_data,
	output	wire				day_add_flag,
	output	reg					adjust_time_en,
	output	reg			[5:0]	time_code
);

	parameter	T_1s = 1_000_000_000 / 20;

	reg					[25:0]	cnt;
	reg					[5:0]	cnt_s;
	reg					[5:0]	cnt_min;
	reg					[5:0]	cnt_hour;
	wire						s_flag;
	wire						min_flag;
	wire						hour_falg;
	wire						day_flag;
	reg					[1:0]	state_set_time;
	reg					[2:0]	state_switch_time;
	reg					[25:0]	cnt_set_time;

	always @ (posedge clk, negedge rst_n) begin
		if (rst_n == 1'b0)
			cnt <= 26'd0;
		else
			if (adjust_time_en == 1'b0)
				if (cnt < T_1s)
					cnt <= cnt + 1'b1;
				else
					cnt <= 26'd0;
			else
				cnt <= cnt;
	end

	assign	s_flag = (cnt == T_1s) ? 1'b1 : 1'b0;

	always @ (posedge clk, negedge rst_n) begin
		if (rst_n == 1'b0)
			cnt_s <= 6'd0;
		else
			if (adjust_time_en == 1'b0)
				if (s_flag == 1'b1)
					if (cnt_s < 6'd59)
						cnt_s <= cnt_s + 1'b1;
					else
						cnt_s <= 6'd0;
				else
					cnt_s <= cnt_s;
			else if (adjust_time_en == 1'b1 && display_day_time == 1'b0)
				if (state_switch_time == 3'd1)
					if (add_flag == 1'b0)
						if (cnt_s < 6'd59)
							cnt_s <= cnt_s + 1'b1;
						else
							cnt_s <= 6'd0;
					else if (reduce_flag == 1'b0)
						if (cnt_s > 6'd0)
							cnt_s <= cnt_s - 1'b1;
						else
							cnt_s <= 6'd59;
					else
						cnt_s <= cnt_s;
				else
					cnt_s <= cnt_s;
			else
				cnt_s <= cnt_s;
	end

	assign	min_flag = (cnt_s == 6'd59 && cnt == T_1s)? 1'b1 : 1'b0;

	always @ (posedge clk, negedge rst_n) begin
		if (rst_n == 1'b0)
			cnt_min <= 6'd59;
		else
			if (adjust_time_en == 1'b0)
				if (min_flag == 1'b1)
					if (cnt_min < 6'd59)
						cnt_min <= cnt_min + 1'b1;
					else
						cnt_min <= 6'd0;
				else
					cnt_min <= cnt_min;
			else if (adjust_time_en == 1'b1 && display_day_time == 1'b0)
				if (state_switch_time == 3'd2)
					if (add_flag == 1'b0)
						if (cnt_min < 6'd59)
							cnt_min <= cnt_min + 1'b1;
						else
							cnt_min <= 6'd0;
					else if (reduce_flag == 1'b0)
						if (cnt_min == 6'd0)
							cnt_min <= 6'd59;
						else
							cnt_min <= cnt_min - 1'b1;
					else
						cnt_min <= cnt_min;
				else
					cnt_min <= cnt_min;
			else
				cnt_min <= cnt_min;
	end

	assign	hour_falg = (cnt_min == 6'd59 && cnt_s == 6'd59 && cnt == T_1s)? 1'b1 : 1'b0;

	always @ (posedge clk, negedge rst_n) begin
		if (rst_n == 1'b0)
			cnt_hour <= 6'd10;
		else
			if (adjust_time_en == 1'b0)
				if (hour_falg == 1'b1)
					if (cnt_hour < 6'd23)
						cnt_hour <= cnt_hour + 1'b1;
					else
						cnt_hour <= 6'd0;
				else
					cnt_hour <= cnt_hour;
			else if (adjust_time_en == 1'b1 && display_day_time == 1'b0)
				if (state_switch_time == 3'd3)
					if (add_flag == 1'b0)
						if (cnt_hour < 6'd23)
							cnt_hour = cnt_hour + 1'b1;
						else
							cnt_hour <= 6'd0;
					else if (reduce_flag == 1'b0)
						if (cnt_hour == 6'd0)
							cnt_hour <= 6'd23;
						else
							cnt_hour <= cnt_hour - 1'b1;
					else
						cnt_hour <= cnt_hour;
				else
					cnt_hour <= cnt_hour;
			else
				cnt_hour <= cnt_hour;
						
	end

	assign	day_add_flag = (cnt_hour == 6'd23 && cnt_min == 6'd59 && cnt_s == 6'd59 && cnt == T_1s) ? 1'b1 : 1'b0;

	assign	hour_data = cnt_hour;
	assign	min_data = cnt_min;
	assign	s_data = cnt_s;

	always @ (posedge clk, negedge rst_n) begin
		if (rst_n == 1'b0)
			cnt_set_time <= 26'd0;
		else
			if (adjust_time_en == 1'b1 && display_day_time == 1'b0)
				if (cnt_set_time < T_1s)
					cnt_set_time <= cnt_set_time + 1'b1;
				else
					cnt_set_time <= 26'd0;
			else
				cnt_set_time <= 26'd0;
	end

	always @ (posedge clk, negedge rst_n) begin
		if (rst_n == 1'b0)
			begin
				adjust_time_en <= 1'b0;
				state_set_time <= 2'd0;
			end
		else
			if (display_day_time == 1'b0)
				case (state_set_time)
					2'd0	:	if (time_set_flag == 1'b0)
									state_set_time <= 2'd1;
								else
									begin
										state_set_time <= 2'd0;
										adjust_time_en <= 1'b0;
									end
					2'd1	:	if (time_set_flag == 1'b0)
									state_set_time <= 2'd0;
								else
									begin
										state_set_time <= 2'd1;
										adjust_time_en <= 1'b1;
									end
				endcase
			else
				begin
					adjust_time_en <= 1'b0;
					state_set_time <= 2'd0;
				end
	end

	always @ (posedge clk, negedge rst_n) begin
		if (rst_n == 1'b0)
			begin
				state_switch_time <= 3'd0;
				time_code <= 6'b11_11_11;
			end
		else
			case (state_switch_time)
				3'd0	:	if (state_set_time == 2'd1 && display_day_time == 1'b0)
								state_switch_time <= 3'd1;
							else
								state_switch_time <= 3'd0;
				3'd1	:	if (time_switch_flag == 1'b0)
								state_switch_time <= 3'd2;
							else
								if (cnt_set_time < T_1s / 2)
									time_code <= 6'b11_11_11;
								else
									time_code <= 6'b11_11_00;
				3'd2	:	if (time_switch_flag == 1'b0)
								state_switch_time <= 3'd3;
							else
								if (cnt_set_time < T_1s / 2)
									time_code <= 6'b11_11_11;
								else
									time_code <= 6'b11_00_11;
				3'd3	:	if (time_switch_flag == 1'b0)
								state_switch_time <= 3'd1;
							else
								if (cnt_set_time < T_1s / 2)
									time_code <= 6'b11_11_11;
								else
									time_code <= 6'b00_11_11;
								
			endcase
	end
	

endmodule


5. 年月日计时模块
module year_data (

	input	wire				clk,
	input	wire				rst_n,
	input	wire				day_add_flag,
	input	wire				add_flag,
	input	wire				reduce_flag,
	input	wire				day_set_flag,
	input	wire				day_switch_flag,
	input	wire				display_day_time,
	output	wire		[7:0]	year_data,
	output	wire		[7:0]	mon_data,
	output	wire		[7:0]	day_data,
	output	reg					adjust_day_en,
	output	reg			[5:0]	day_code
);

	parameter	T_1s = 1_000_000_000 / 20;

	reg					[5:0]	cnt_day;
	reg					[3:0]	cnt_mon;
	reg					[7:0]	cnt_year;
	wire						mon_flag;
	wire						year_flag;
	reg					[5:0]	num_day;
	reg					[1:0]	state_set_day;
	reg					[2:0]	state_switch_day;
	reg					[25:0]	cnt_set_day;

	always @ (posedge clk, negedge rst_n) begin
		if (rst_n == 1'b0)
			num_day <= 6'd0;
		else
			if (cnt_mon == 4'd1 && cnt_mon == 4'd3 && cnt_mon == 4'd5 && cnt_mon == 4'd7 && cnt_mon == 4'd8 && cnt_mon == 4'd10 && cnt_mon == 4'd12)
				num_day <= 6'd31;
			else if (cnt_mon == 4'd2)
				if (year_data % 4 == 1'b0)
					num_day <= 6'd29;
				else
					num_day <= 6'd28;
			else
				num_day <= 6'd30;
	end

	always @ (posedge clk, negedge rst_n) begin
		if (rst_n == 1'b0)
			cnt_day <= 6'd31;
		else
			if (adjust_day_en == 1'b0)
				if (day_add_flag == 1'b1)
					if (cnt_day < num_day)
						cnt_day <= cnt_day + 1'b1;
					else
						cnt_day <= 6'd0;
				else
					cnt_day <= cnt_day;
			else if (adjust_day_en == 1'b1 && display_day_time == 1'b1)
				if (state_switch_day == 3'd1)
					if (add_flag == 1'b0)
						if (cnt_day < num_day)
							cnt_day <= cnt_day + 1'b1;
						else
							cnt_day <= 6'd0;
					else if (reduce_flag == 1'b0)
						if (cnt_day == 6'd0)
							cnt_day <= num_day;
						else
							cnt_day <= cnt_day - 1'b1;
					else
						cnt_day <= cnt_day;
				else
					cnt_day <= cnt_day;
			else
				cnt_day <= cnt_day;
	end

	assign	 mon_flag = (cnt_day == num_day && day_add_flag) ? 1'b1 : 1'b0;

	always @ (posedge clk, negedge rst_n) begin
		if (rst_n == 1'b0)
			cnt_mon <= 5'd12;
		else
			if (adjust_day_en == 1'b0)
				if (mon_flag == 1'b1)
					if (cnt_mon < 5'd12)
						cnt_mon <= cnt_mon + 1'b1;
					else
						cnt_mon <= 5'd1;
				else
					cnt_mon <= cnt_mon;
			else if (adjust_day_en == 1'b1 && display_day_time == 1'b1)
				if (state_switch_day == 3'd2)
					if (add_flag == 1'b0)
						if (cnt_mon < 5'd12)
							cnt_mon <= cnt_mon + 1'b1;
						else
							cnt_mon <= 5'd1;
					else if (reduce_flag == 1'b0)
						if (cnt_mon == 5'd1)
							cnt_mon <= 5'd12;
						else
							cnt_mon <= cnt_mon - 1'b1;
					else
						cnt_mon <= cnt_mon;
			else
				cnt_mon <= cnt_mon;
	end

	assign year_flag = (cnt_mon == 5'd12 && cnt_day == num_day && day_add_flag == 1'b1) ? 1'b1 : 1'b0;

	always @ (posedge clk, negedge rst_n) begin
		if (rst_n == 1'b0)
			cnt_year <= 8'd24;
		else
			if (adjust_day_en == 1'b0)
				if (year_flag == 1'b1)
					if (cnt_year < 8'd99)
						cnt_year <= cnt_year + 1'b1;
					else
						cnt_year <= 8'd0;
				else
					cnt_year <= cnt_year;
			else if (adjust_day_en == 1'b1 && display_day_time == 1'b1)
				if (state_switch_day == 3'd3)
					if (add_flag == 1'b0)
						if (cnt_year < 8'd99)
							cnt_year <= cnt_year + 1'b1;
						else
							cnt_year <= 8'd0;
					else if (reduce_flag == 1'b0)
						if (cnt_year == 8'd0)
							cnt_year <= 8'd99;
						else
							cnt_year <= cnt_year - 1'b1;
					else
						cnt_year <= cnt_year;
			else
				cnt_year <= cnt_year;
	end
	
	assign	year_data = cnt_year;
	assign	mon_data = cnt_mon;
	assign	day_data = cnt_day;

	always @ (posedge clk, negedge rst_n) begin
		if (rst_n == 1'b0)
			cnt_set_day <= 26'd0;
		else
			if (adjust_day_en == 1'b1 && display_day_time == 1'b1)
				if (cnt_set_day < T_1s)
					cnt_set_day <= cnt_set_day + 1'b1;
				else
					cnt_set_day <= 26'd0;
			else
				cnt_set_day <= 26'd0;
	end

	always @ (posedge clk, negedge rst_n) begin
		if (rst_n == 1'b0)
			begin
				adjust_day_en <= 1'b0;
				state_set_day <= 2'd0;
			end
		else
			if (display_day_time == 1'b1)
				case (state_set_day)
					2'd0	:	if (day_set_flag == 1'b0)
									state_set_day <= 2'd1;
								else
									begin
										state_set_day <= 2'd0;
										adjust_day_en <= 1'b0;
									end
					2'd1	:	if (day_set_flag == 1'b0)
									state_set_day <= 2'd0;
								else
									begin
										state_set_day <= 2'd1;
										adjust_day_en <= 1'b1;
									end
				endcase
			else
				begin
					adjust_day_en <= 1'b0;
					state_set_day <= 2'd0;
				end
	end

	always @ (posedge clk, negedge rst_n) begin
		if (rst_n == 1'b0)
			begin
				state_switch_day <= 3'd0;
				day_code <= 6'b11_11_11;
			end
		else
			case (state_switch_day)
				3'd0	:	if (state_set_day == 2'd1 && display_day_time == 1'b1)
								state_switch_day <= 3'd1;
							else
								state_switch_day <= 3'd0;
				3'd1	:	if (day_switch_flag == 1'b0)
								state_switch_day <= 3'd2;
							else
								if (cnt_set_day < T_1s / 2)
									day_code <= 6'b11_11_11;
								else
									day_code <= 6'b11_11_00;
				3'd2	:	if (day_switch_flag == 1'b0)
								state_switch_day <= 3'd3;
							else
								if (cnt_set_day < T_1s / 2)
									day_code <= 6'b11_11_11;
								else
									day_code <= 6'b11_00_11;
				3'd3	:	if (day_switch_flag == 1'b0)
								state_switch_day <= 3'd1;
							else
								if (cnt_set_day < T_1s / 2)
									day_code <= 6'b11_11_11;
								else
									day_code <= 6'b00_11_11;
			endcase
	end

endmodule

7.  设置闹钟模块
module alarm_set (

	input	wire				clk,
	input	wire				rst_n,
	input	wire				add_flag,
	input	wire				alarm_set_flag,
	input	wire				alarm_switch_flag,
	input	wire				reduce_flag,
	input	wire		[7:0]	hour_data,
	input	wire		[7:0]	min_data,
	output	reg			[5:0]	code_alarm,
	output	reg			[7:0]	alarm_hour_data,
	output	reg			[7:0]	alarm_min_data
);

	parameter	T	=	1_000_000_000 / 20;

	reg					[26:0]	cnt;
	reg					[1:0]	state_s;
	reg					[1:0]	state_code;
	reg							half_flag;
	reg					[2:0]	state_data;

	always @ (posedge clk, negedge rst_n) begin		//produce 0.5 time
		if (rst_n == 1'b0)
			begin
				cnt <= 27'd0;
				state_s <= 2'd0;
				half_flag <= 1'b0;
			end
		else
			case (state_s)
				2'd0	:	if (alarm_set_flag == 1'b0)
								state_s <= 2'd1;
							else
								begin
									state_s <= 2'd0;
									cnt <= 27'd0;
								end
				2'd1	:	if (alarm_set_flag == 1'b0)
								state_s <= 2'd0;
							else
								if (cnt == T - 1'b1)
									begin
										half_flag <= 1'b1;
										cnt <= 27'd0;
									end
								else
									begin
										cnt <= cnt + 1'b1;
										half_flag <= 1'b0;
									end
								
			endcase
	end

	always @ (posedge clk, negedge rst_n) begin		//0.5 light or close
		if (rst_n == 1'b0)
			begin
				code_alarm <= 6'b00_1111;
				state_code <= 2'd0;
			end
		else
			case (state_code)
				2'd0	:	if (alarm_set_flag == 1'b0)
								state_code <= 2'd1;
							else
								state_code <= 2'd0;
				2'd1	:	if (alarm_switch_flag == 1'b0)
								state_code <= 2'd2;
							else
								if (cnt < T / 2 - 1'b1)
									code_alarm <= 6'b00_11_11;
								else
									code_alarm <= 6'b00_11_00;
				2'd2	:	if (alarm_switch_flag == 1'b0)
								state_code <= 2'd1;
							else
								if (cnt < T / 2 - 1'b1)
									code_alarm <= 6'b00_11_11;
								else
									code_alarm <= 6'b00_00_11;
				default	:	code_alarm <= code_alarm;
			endcase
	end

	always @ (posedge clk, negedge rst_n) begin		//key control add or reduce
		if (rst_n == 1'b0)
			begin
				state_data <= 3'd0;
				alarm_hour_data <= 8'd0;
				alarm_min_data <= 8'd0;
			end
		else
			case (state_data)
				3'd0	:	if (alarm_set_flag == 1'b0)
								begin
									alarm_hour_data <= hour_data;
									alarm_min_data <= min_data;
									state_data <= 3'd1;
								end
							else
								begin
									alarm_hour_data <= alarm_hour_data;
									alarm_min_data <= alarm_min_data;
								end
				3'd1	:	if (state_code == 2'd1)
								if (add_flag == 1'b0)
									if (alarm_min_data < 8'd59)
										alarm_min_data <= alarm_min_data + 1'b1;
									else
										alarm_min_data <= 8'd0;
								else if (reduce_flag == 1'b0)
									if (alarm_min_data > 8'd0)
										alarm_min_data <= alarm_min_data - 1'b1;
									else
										alarm_min_data <= 8'd59;
								else
									alarm_min_data <= alarm_min_data;
							else if (state_code == 2'd2)
								if (add_flag == 1'b0)
									if (alarm_hour_data < 8'd23)
										alarm_hour_data <= alarm_hour_data + 1'b1;
									else
										alarm_hour_data <= 8'd0;
								else if (reduce_flag == 1'b0)
									if (alarm_hour_data > 8'd0)
										alarm_hour_data <= alarm_hour_data - 1'b1;
									else
										alarm_hour_data <= 8'd23;
								else
									alarm_hour_data <= alarm_hour_data;
							else
								begin
									alarm_hour_data <= alarm_hour_data;
									alarm_min_data <= alarm_min_data;
								end
								
			endcase
	end

endmodule

8. 具体给数码管显示的内容模块(年月日 / 时分秒/ 闹钟调时   三选一要显示的数据)
module mux3_1 (

	input	wire				clk,
	input	wire				rst_n,
	input	wire		[7:0]	hour_data,
	input	wire		[7:0]	min_data,
	input	wire		[7:0]	s_data,
	input	wire		[7:0]	yeat_data,
	input	wire		[7:0]	mon_data,
	input	wire		[7:0]	day_data,
	input	wire				switch_flag,
	input	wire		[7:0]	alarm_hour_data,
	input	wire		[7:0]	alarm_min_data,
	input	wire		[5:0]	code_alarm,
	input	wire				alarm_set_flag,
	input	wire				adjust_time_en,
	input	wire				adjust_day_en,
	input	wire		[5:0]	time_code,
	input	wire		[5:0]	day_code,
	
	output	reg			[7:0]	seg_data_12,
	output	reg			[7:0]	seg_data_34,
	output	reg			[7:0]	seg_data_56,
	output	reg			[5:0]	code,
	output	reg					display_day_time
);

	reg					[3:0]	state;

	always @ (posedge clk, negedge rst_n) begin
		if (rst_n == 1'b0)
			begin
				state <= 4'd0;
				seg_data_12 <= 8'd0;
				seg_data_34 <= 8'd0;
				seg_data_56 <= 8'd0;
				code <= 6'b11_11_11;
				display_day_time <= 1'b0;
			end
		else
			case (state)
				4'd0	:	if (switch_flag == 1'b0 && adjust_time_en == 1'b0)
								state <= 4'd1;
							else if (alarm_set_flag == 1'b0)
								state <= 4'd2;
							else
								begin
									if (adjust_time_en == 1'b0)
										begin
											code <= 6'b11_11_11;
											seg_data_12 <= hour_data;
											seg_data_34 <= min_data;
											seg_data_56 <= s_data;
											display_day_time <= 1'b0;
										end
									else
										begin
											code <= time_code;
											seg_data_12 <= hour_data;
											seg_data_34 <= min_data;
											seg_data_56 <= s_data;
											display_day_time <= 1'b0;
										end
								end
				4'd1	:	if (switch_flag == 1'b0 && adjust_day_en == 1'b0)
								state <= 4'd0;
							else
								if (adjust_day_en == 1'b0)
									begin
										state <= 4'd1;
										seg_data_12 <= yeat_data;
										seg_data_34 <= mon_data;
										seg_data_56 <= day_data;
										code <= 6'b11_11_11;
										display_day_time <= 1'b1;
									end
								else
									begin
										seg_data_12 <= yeat_data;
										seg_data_34 <= mon_data;
										seg_data_56 <= day_data;
										display_day_time <= 1'b1;
										code <= day_code;
									end
				4'd2	:	if (alarm_set_flag == 1'b0)
								state <= 4'd0;
							else
								begin
									state <= 4'd2;
									seg_data_34 <= alarm_hour_data;
									seg_data_56 <= alarm_min_data;
									code <= code_alarm;
								end
				default	:	begin
								seg_data_12 <= seg_data_12;
								seg_data_34 <= seg_data_34;
								seg_data_56 <= seg_data_56;
							end
			endcase
	end

endmodule 

 9. 数码管显示(七段数码管)
module seven_tube_driver(
  
  input   wire          clk,
  input   wire          rst_n,
  input   wire  [7:0]   data12,
  input   wire	[7:0]	data34,
  input   wire	[7:0]	data56,
  input   wire	[5:0]	code,
  
  output  reg   [5:0]   sel,
  output  wire  [7:0]   seg
);

  parameter t = 50_000;
  //parameter code = 6'b111_111;
//  parameter data = 24'h641691;       

  reg     [15:0]    cnt;
  reg     [3:0]     show_data;
  wire	  			seg_point;
  reg	  [7:0]		seg_temp;
  
  always @ (posedge clk, negedge rst_n)
  begin
    if(rst_n == 1'b0)
      cnt <= 16'd0;
    else if(cnt == t - 1)
      cnt <= 16'd0;
    else
      cnt <= cnt + 1'b1;
  end
  
  always @ (posedge clk, negedge rst_n)
  begin
    if(rst_n == 1'b0)
      sel <= 6'b111_110;
    else if(cnt == t - 1)
      sel <= {sel[4:0],sel[5]};
    else
      sel <= sel;
  end
  
  always @ (*)
  begin
    case(sel)
      6'b011_111 : begin
                      if(code[5])
                        show_data = data12/10;
                      else
                        show_data = 4'hf;
                    end
      6'b101_111 : begin
                      if(code[4])
                        show_data = data12%10;
                      else
                        show_data = 4'hf;
                    end
      6'b110_111 : begin
                      if(code[3])
                        show_data = data34/10;
                      else
                        show_data = 4'hf;
                    end
      6'b111_011 : begin
                      if(code[2])
                        show_data = data34%10;
                      else
                        show_data = 4'hf;
                    end
      6'b111_101 : begin
                      if(code[1])
                        show_data = data56/10;
                      else
                        show_data = 4'hf;
                    end
      6'b111_110 : begin
                      if(code[0])
                        show_data = data56%10;
                      else
                        show_data = 4'hf;
                    end
      default : show_data = 4'hf;
	endcase
  end
  
  always @ (*)
  begin
    case(show_data)
      4'd0  : seg_temp = 8'b1100_0000;
      4'd1  : seg_temp = 8'b1111_1001;
      4'd2  : seg_temp = 8'b1010_0100;
      4'd3  : seg_temp = 8'b1011_0000;
      4'd4  : seg_temp = 8'b1001_1001;
      4'd5  : seg_temp = 8'b1001_0010;
      4'd6  : seg_temp = 8'b1000_0010;
      4'd7  : seg_temp = 8'b1111_1000;
      4'd8  : seg_temp = 8'b1000_0000;
      4'd9  : seg_temp = 8'b1001_0000;
      default : seg_temp = 8'hff;
    endcase
  end
 
  assign	seg_point = (sel == 6'b101_111 || sel == 6'b111_011)? 1'b0 : 1'b1;
  
  assign	seg = {seg_temp[7] & seg_point, seg_temp[6:0]};
  
endmodule

10. 闹钟报警 (板子没有蜂鸣器,用了led灯闪光代替)
功能: 间隔0.5s闪烁,闪烁三秒
module warn (

	input	wire				clk,
	input	wire				rst_n,
	input	wire		[7:0]	hour_data,
	input	wire		[7:0]	min_data,
	input	wire		[7:0]	alarm_h,
	input	wire		[7:0]	alarm_m,
	input	wire		[7:0]	s_data,
	output	reg			[3:0]	led
);

	parameter	T_warn = 1_000_000_000 / 20 / 4;
	
	reg					[25:0]	cnt_warm;
	wire						warn_flag;

	
	assign warn_flag = (hour_data == alarm_h && min_data == alarm_m && s_data < 8'd4)? 1'b1 : 1'b0;
	
	
	always @ (posedge clk, negedge rst_n) begin
		if (rst_n == 1'b0)
			cnt_warm <= 26'd0;
		else 
			if (warn_flag == 1'b1)
				if (cnt_warm < T_warn)
					cnt_warm <= cnt_warm + 1'b1;
				else
					cnt_warm <= 26'd0;
			else
				cnt_warm <= 26'd0;
	end
	
	always @ (posedge clk, negedge rst_n) begin
		if (rst_n == 1'b0)
			led <= 4'b1111;
		else
			if (warn_flag == 1'b1)
				if (cnt_warm == T_warn)
					led <= ~led;
				else
					led <= led;
			else
				led <= 4'b1111;
	end
	
endmodule
## 小结
本项目是基于黑金xc7a35t 开发,数码管可以正常显示时间,按键可以正常使用(按键包含长按和短按),可以正常设置闹钟。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值