基于FPGA的多功能电子表(时间显示、日期显示、调整时间、日期设置、世界时间、闹钟设置、倒计时、秒表)
基于FPGA的多功能电子表
- 题目要求
- 一、仿真代码verilog
- 1.顶层
- 2.seg_decoder
- 3.seg_scan
- 4.beep
- 6.tb
- 二、仿真结果
- 总结
题目要求
多功能电子表
设计FPGA模块模拟多功能电子表的工作过程,具有多种功能,功能如下
(1)时间显示界面,要求从00:00点计到23:59。
(2)日期显示界面,要求显示当前日期,包含年、月、日。
(3)调整时间界面,即可以设置或更改当前的时间(小时、分)。
(4)日期设置界面。可以设置当前的日期,比如2020年09月22日。要求支持闰年与大小月的识别。
(5) 闹钟设置界面,可以设置3个闹钟,闹钟时间到了后会用LED闪烁提醒,提醒时间持续5秒,如果提醒时按解除键,则该闹钟解除提醒,如果闹钟响时没有按键或按其他按键,则响完5秒之后暂停,然后10秒钟后重新提醒一次后解除。
(6) 倒计时功能。可以设定倒计时的起始时间,比如1分钟,然后开始倒计时,从01:00倒计时到00:00,然后LED灯闪烁5秒钟。倒计时中间可以暂停或重新开始。
(7) 电子表只有六个按键。请只使用六个按键来完成所有功能。
(8)秒表功能
(9)3种国家时间切换
一、仿真代码verilog
仿真不要按键消抖
1.顶层
`timescale 1ns / 1ps
module seg_show_t(clk,rst_n,key1,key2,key3,key4,key5,seg_sel,seg_data,LED_indicate,blink_countdown,blink_alarm1,blink_alarm2,blink_alarm3,beep);
input clk;
input rst_n;
input key1;
input key2;
input key3;
input key4;
input key5;
output[7:0]seg_sel;
output[6:0]seg_data;
output[6:0]LED_indicate;
output blink_countdown;
output blink_alarm1;
output blink_alarm2;
output blink_alarm3;
output beep;
reg blink_countdown;
reg blink_alarm1;
reg blink_alarm2;
reg blink_alarm3;//-----主状态机-----//
reg[6:0] state;//-----世界时间相关定义-----//
// 时差定义(基于北京时间UTC+8)
parameter USA_TIME_DIFF = 8'd13; // 美国东部时间(UTC-5) 时差13小时
parameter NZ_TIME_DIFF = 8'd4; // 新西兰时间(UTC+12) 时差-4小时(快4小时)
parameter TH_TIME_DIFF = 8'd1; // 泰国时间(UTC+7) 时差1小时// 时区选择(00:本地 01:美国 10:新西兰 11:泰国)
reg[1:0] time_zone;
localparam LOCAL_TIME = 2'b00;
localparam USA_TIME = 2'b01;
localparam NZ_TIME = 2'b10;
localparam TH_TIME = 2'b11;// 美国时间变量
reg[4:0] us_hour, us_date;
reg[5:0] us_minute, us_second;
reg[3:0] us_month;
reg[11:0] us_year;
reg us_flag1; // 闰年标志
reg[4:0] us_max_month_day; // 当月最大日期// 新西兰时间变量
reg[4:0] nz_hour, nz_date;
reg[5:0] nz_minute, nz_second;
reg[3:0] nz_month;
reg[11:0] nz_year;
reg nz_flag1;
reg[4:0] nz_max_month_day;// 泰国时间变量
reg[4:0] th_hour, th_date;
reg[5:0] th_minute, th_second;
reg[3:0] th_month;
reg[11:0] th_year;
reg th_flag1;
reg[4:0] th_max_month_day;//-----子状态机及其他原有变量-----//
reg[1:0] state1;
reg[4:0] state2;
reg[5:0] state3;
reg[5:0] state4;
reg[5:0] state5;
reg[5:0] state6;
reg[5:0] state7_1;
reg[1:0] state7_2;
reg state_seg_blink;
reg stop_timing;//-----日期和时间变量-----//
reg[4:0] date;
reg[3:0] month;
reg[11:0] year;
reg flag1; // 本地闰年标志
reg flag2; // 倒计时状态标记
reg flag3; // 倒计时结束标志
reg flag4; // 倒计时暂停标志
reg flag5; // 倒计时重置标志
reg flag6,flag7,flag8; // 闹钟响铃标志
reg flag9; // 倒计时结束亮灯标志
reg flag10; // 闹钟响铃综合标志
reg[4:0] max_month_day; // 本地当月最大日期//-----时分秒及闹钟变量-----//
reg[5:0] second, minute;
reg[4:0] hour;
reg[5:0] alarm1_second, alarm1_minute, alarm2_second, alarm2_minute, alarm3_second, alarm3_minute;
reg[4:0] alarm1_hour, alarm2_hour, alarm3_hour;//-----倒计时变量-----//
reg[5:0] countdown_second, countdown_minute, origin_countdown_second, origin_countdown_minute;
reg[4:0] countdown_hour, origin_countdown_hour;//-----数码管显示相关-----//
wire[3:0] count0, count1, count2, count3, count4, count5, count6, count7;
wire[6:0] seg_data_0;
reg[3:0] state3_count;
reg[3:0] num0, num1, num2, num3, num4, num5, num6, num7;//-----计时器变量-----//
reg[31:0] timer_cnt, timer_countdown, timer_countdown_blink;
reg[31:0] timer_alarm1_blink, timer_alarm2_blink, timer_alarm3_blink;
reg[31:0] timer_alarm1_5s, timer_alarm2_5s, timer_alarm3_5s;
reg[31:0] timer_seg_blink;
reg en_1hz, en_countdown;
reg[4:0] count_blink_countdown;
reg[5:0] count_blink_alarm1, count_blink_alarm2, count_blink_alarm3;//-----按键消抖相关-----//
wire button_negedge1, button_negedge2, button_negedge3, button_negedge4, button_negedge5;//-----秒表变量--------// 10:02:78
reg[23:0] stopwatch_count_10ms;
reg[5:0] stopwatch_second, stopwatch_minute;
reg[6:0] stopwatch_frame;
reg flag_watch;
reg flag_watch_clear;
//清空秒表标志
always@(posedge clk or negedge rst_n)
beginif(rst_n == 1'b0)beginflag_watch_clear <= 1'b0;endelse if(state==7'b010_0000 && key3==1)beginflag_watch_clear <= 1'b1;endelse if(state==7'b010_0000 && flag_watch_clear)beginflag_watch_clear <= 1'b0;endelse beginflag_watch_clear <= flag_watch_clear;end
end
//秒表开始或者暂停标志
always@(posedge clk or negedge rst_n)
beginif(rst_n == 1'b0)beginflag_watch <= 1'b0;endelse if(state==7'b010_0000 && key2==1)beginflag_watch <= ~flag_watch;endelse beginflag_watch <= flag_watch;end
end
//秒表计时器 10ms为单位
always@(posedge clk or negedge rst_n)
beginif(rst_n == 1'b0)beginstopwatch_count_10ms <= 24'd0;endelse if(flag_watch && ~flag_watch_clear)beginif(stopwatch_count_10ms >= 24'd100)beginstopwatch_count_10ms <= 24'd1;endelse beginstopwatch_count_10ms <= stopwatch_count_10ms + 24'd1;endendelse if(flag_watch==1'b0 && ~flag_watch_clear )beginstopwatch_count_10ms <= stopwatch_count_10ms;endelse if(flag_watch_clear ==1)beginstopwatch_count_10ms <= 24'd0;end
end
//reg[5:0] stopwatch_second, stopwatch_minute;
//reg[6:0] stopwatch_frame;always@(posedge clk or negedge rst_n)
beginif(rst_n == 1'b0)beginstopwatch_second<=6'd0;stopwatch_minute<=6'd0;stopwatch_frame<=7'd0;endelse if(flag_watch && ~flag_watch_clear)beginif(stopwatch_count_10ms==24'd100 && stopwatch_frame<99)beginstopwatch_frame <= stopwatch_frame + 1;endelse if(stopwatch_count_10ms==24'd100 && stopwatch_frame>=99 && stopwatch_second<59)beginstopwatch_frame <= 7'd0;stopwatch_second<= stopwatch_second + 1;endelse if(stopwatch_count_10ms==24'd100 && stopwatch_frame>=99 && stopwatch_second>=59 && stopwatch_minute<59)beginstopwatch_frame <= 7'd0;stopwatch_second<= 6'd0;stopwatch_minute<= stopwatch_minute + 1;endelse if(stopwatch_count_10ms==24'd100 && stopwatch_frame>=99 && stopwatch_second>=59 && stopwatch_minute>=59)beginstopwatch_frame <= 7'd0;stopwatch_second<= 6'd0;stopwatch_minute<= 6'd0;endendelse if(flag_watch_clear)beginstopwatch_second<=6'd0;stopwatch_minute<=6'd0;stopwatch_frame<=7'd0;end
end//-----1s计时器-----//
always@(posedge clk or negedge rst_n)
beginif(rst_n == 1'b0)beginen_1hz <= 1'b0;timer_cnt <= 32'd0;endelse if(timer_cnt >= 32'd100_0)beginen_1hz <= 1'b1;timer_cnt <= 32'd1;endelse if(stop_timing==0)beginen_1hz <= 1'b0;timer_cnt <= timer_cnt + 32'd1; endelse timer_cnt <= timer_cnt;
endalways@(posedge clk or negedge rst_n)
beginif(rst_n==0) stop_timing<=0;else if(state==7'b000_0010||state==7'b000_0100) stop_timing<=1;else stop_timing<=0;
end//-----主状态转移-----//
always@(posedge clk or negedge rst_n)
beginif(rst_n==1'b0) beginstate<=7'b000_0001;flag2<=0;endelse if(key1==1)state<={state[5:0],state[6]};else if(key5==1)beginif(state!=7'b1000_000) state<=7'b000_0001;else if(flag3==1) flag2<=0;else flag2<=1;endelse if(flag3==0) flag2<=1;else if(flag3==1) flag2<=0;
end//-----时区切换逻辑-----//
always@(posedge clk or negedge rst_n)
beginif(rst_n == 1'b0)time_zone <= LOCAL_TIME; // 默认显示本地时间// 在时间显示状态下,按key3切换时区else if(state==7'b000_0001 && key3==1)time_zone <= time_zone + 1'b1; // 循环切换:本地→美国→新西兰→泰国→本地
end//-----子状态转移-----//
always@(posedge clk or negedge rst_n)
beginif(rst_n==1'b0) state1<=2'b01;else if(state==7'b000_0001&&key2==1) state1<={state1[0],state1[1]}; // key2切换日期/时间显示
endalways@(posedge clk or negedge rst_n)
beginif(rst_n==1'b0) state2<=5'b00_001;else if(state==7'b000_0010&&key2==1) state2<={state2[3:0],state2[4]};
endalways@(posedge clk or negedge rst_n)
beginif(rst_n==1'b0) state3<=6'b000_001;else if(state==7'b000_0100&&key2==1) state3<={state3[4:0],state3[5]};
endalways@(posedge clk or negedge rst_n)
beginif(rst_n==1'b0) state4<=6'b000_001;else if(state==7'b000_1000&&key2==1) state4<={state4[4:0],state4[5]};
endalways@(posedge clk or negedge rst_n)
beginif(rst_n==1'b0) state5<=6'b000_001;else if(state==7'b001_0000&&key2==1) state5<={state5[4:0],state5[5]};
end//always@(posedge clk or negedge rst_n)
//begin
// if(rst_n==1'b0) state6<=6'b000_001;
// else if(state==7'b010_0000&&key2==1) state6<={state6[4:0],state6[5]};
//endalways@(posedge clk or negedge rst_n)
beginif(rst_n==1'b0) state7_1<=6'b000_001;else if(state==7'b100_0000&&flag3==1&&key2==1) state7_1<={state7_1[4:0],state7_1[5]};
endalways@(posedge clk or negedge rst_n)
beginif(rst_n==1'b0)beginstate7_2<=2'b01;origin_countdown_second<=0;origin_countdown_minute<=1;origin_countdown_hour<=0; endelse if(state==7'b100_0000&&flag3==0&&key2==1) state7_2<={state7_2[0],state7_2[1]};else if(state==7'b100_0000&&flag3==1&&key5==1) beginorigin_countdown_second<=countdown_second;origin_countdown_minute<=countdown_minute;origin_countdown_hour<=countdown_hour;endelse if(state==7'b100_0000&&key5==1) state7_2<=2'b10;else if(countdown_second==0&&countdown_minute==0&&countdown_hour==0) state7_2<=2'b01;
end//-----1s倒计时计时器-----//
always@(posedge clk or negedge rst_n)
beginif(rst_n == 1'b0)beginen_countdown <= 1'b0;timer_countdown <= 32'd0;endelse if(state7_2==2'b10)beginif(timer_countdown == 32'd100_0)beginen_countdown <= 1'b1;timer_countdown <= 32'd0;endelsebeginen_countdown <= 1'b0;timer_countdown <= timer_countdown + 32'd1; endendelse timer_countdown <= timer_countdown;
end//-----本地时间闰年判断-----//
always@(posedge clk)
beginif(year%400==0) flag1<=1;else if(year%4==0 && year%100!=0) flag1<=1;else flag1<=0;
end//-----本地当月最大日数-----//
always@(posedge clk)
begincase(month)1:max_month_day<=31;2:max_month_day<=(flag1==1) ? 29 : 28;3:max_month_day<=31;4:max_month_day<=30;5:max_month_day<=31;6:max_month_day<=30;7:max_month_day<=31;8:max_month_day<=31;9:max_month_day<=30;10:max_month_day<=31;11:max_month_day<=30;12:max_month_day<=31;endcase
end//-----美国时间闰年和最大日期-----//
always@(posedge clk)
beginif(us_year%400==0) us_flag1<=1;else if(us_year%4==0 && us_year%100!=0) us_flag1<=1;else us_flag1<=0;
endalways@(posedge clk)
begincase(us_month)1:us_max_month_day<=31;2:us_max_month_day<=(us_flag1==1) ? 29 : 28;3:us_max_month_day<=31;4:us_max_month_day<=30;5:us_max_month_day<=31;6:us_max_month_day<=30;7:us_max_month_day<=31;8:us_max_month_day<=31;9:us_max_month_day<=30;10:us_max_month_day<=31;11:us_max_month_day<=30;12:us_max_month_day<=31;endcase
end//-----新西兰时间闰年和最大日期-----//
always@(posedge clk)
beginif(nz_year%400==0) nz_flag1<=1;else if(nz_year%4==0 && nz_year%100!=0) nz_flag1<=1;else nz_flag1<=0;
endalways@(posedge clk)
begincase(nz_month)1:nz_max_month_day<=31;2:nz_max_month_day<=(nz_flag1==1) ? 29 : 28;3:nz_max_month_day<=31;4:nz_max_month_day<=30;5:nz_max_month_day<=31;6:nz_max_month_day<=30;7:nz_max_month_day<=31;8:nz_max_month_day<=31;9:nz_max_month_day<=30;10:nz_max_month_day<=31;11:nz_max_month_day<=30;12:nz_max_month_day<=31;endcase
end//-----泰国时间闰年和最大日期-----//
always@(posedge clk)
beginif(th_year%400==0) th_flag1<=1;else if(th_year%4==0 && th_year%100!=0) th_flag1<=1;else th_flag1<=0;
endalways@(posedge clk)
begincase(th_month)1:th_max_month_day<=31;2:th_max_month_day<=(th_flag1==1) ? 29 : 28;3:th_max_month_day<=31;4:th_max_month_day<=30;5:th_max_month_day<=31;6:th_max_month_day<=30;7:th_max_month_day<=31;8:th_max_month_day<=31;9:th_max_month_day<=30;10:th_max_month_day<=31;11:th_max_month_day<=30;12:th_max_month_day<=31;endcase
end//-----数码管闪烁控制-----//
always@(posedge clk or negedge rst_n)
beginif(rst_n==0) timer_seg_blink<=0;else if(timer_seg_blink==32'd25_0) timer_seg_blink<=0;else timer_seg_blink<=timer_seg_blink+1;
endalways@(posedge clk or negedge rst_n)
beginif(rst_n==0) state_seg_blink<=0;else if(timer_seg_blink==32'd25_0) state_seg_blink<=~state_seg_blink;
end//-----数码管显示的数字-----//
always@(posedge clk)
begincase(state)7'b000_0001:case(time_zone)// 本地时间显示LOCAL_TIME: beginif(state1==2'b01) beginnum0<=second%10;num1<=second/10;num2<=minute%10;num3<=minute/10;num4<=hour%10;num5<=hour/10;num6<=10; // 空白num7<=10; // 空白end else beginnum0<=date%10;num1<=date/10;num2<=month%10;num3<=month/10;num4<=year%10;num5<=(year-num4)%100/10;num6<=(year-num4-num5*10)%1000/100;num7<=year/1000;end end// 美国时间显示USA_TIME: beginif(state1==2'b01) beginnum0<=us_second%10;num1<=us_second/10;num2<=us_minute%10;num3<=us_minute/10;num4<=us_hour%10;num5<=us_hour/10;num6<=10;num7<=11; // "U"标记end else beginnum0<=us_date%10;num1<=us_date/10;num2<=us_month%10;num3<=us_month/10;num4<=us_year%10;num5<=(us_year-us_year%10)%100/10;num6<=(us_year-us_year%10-((us_year-us_year%10)%100))%1000/100;num7<=us_year/1000;end end// 新西兰时间显示NZ_TIME: beginif(state1==2'b01) beginnum0<=nz_second%10;num1<=nz_second/10;num2<=nz_minute%10;num3<=nz_minute/10;num4<=nz_hour%10;num5<=nz_hour/10;num6<=10;num7<=12; // "N"标记end else beginnum0<=nz_date%10;num1<=nz_date/10;num2<=nz_month%10;num3<=nz_month/10;num4<=nz_year%10;num5<=(nz_year-nz_year%10)%100/10;num6<=(nz_year-nz_year%10-((nz_year-nz_year%10)%100))%1000/100;num7<=nz_year/1000;end end// 泰国时间显示TH_TIME: beginif(state1==2'b01) beginnum0<=th_second%10;num1<=th_second/10;num2<=th_minute%10;num3<=th_minute/10;num4<=th_hour%10;num5<=th_hour/10;num6<=10;num7<=13; // "T"标记end else beginnum0<=th_date%10;num1<=th_date/10;num2<=th_month%10;num3<=th_month/10;num4<=th_year%10;num5<=(th_year-th_year%10)%100/10;num6<=(th_year-th_year%10-((th_year-th_year%10)%100))%1000/100;num7<=th_year/1000;end endendcase// 其他状态显示逻辑保持不变...7'b000_0010:beginnum0<=date%10+(10-date%10)*((state2==5'b00001)&&(state_seg_blink==1));num1<=date/10+(10-date/10)*((state2==5'b00001)&&(state_seg_blink==1));num2<=month%10+(10-month%10)*((state2==5'b00010)&&(state_seg_blink==1));num3<=month/10+(10-month/10)*((state2==5'b00010)&&(state_seg_blink==1));num4<=year%10+(10-year%10)*((state2==5'b00100)&&(state_seg_blink==1));num5<=(year-year%10)%100/10+(10-(year-year%10)%100/10)*((state2==5'b01000)&&(state_seg_blink==1));num6<=(year-year%10-((year-year%10)%100))%1000/100+(10-(year-year%10-((year-year%10)%100))%1000/100)*((state2==5'b10000)&&(state_seg_blink==1));num7<=year/1000;end 7'b000_0100:beginnum0<=second%10+(10-second%10)*((state3==6'b000001)&&(state_seg_blink==1));num1<=second/10+(10-second/10)*((state3==6'b000010)&&(state_seg_blink==1));num2<=minute%10+(10-minute%10)*((state3==6'b000100)&&(state_seg_blink==1));num3<=minute/10+(10-minute/10)*((state3==6'b001000)&&(state_seg_blink==1));num4<=hour%10+(10-hour%10)*((state3==6'b010000)&&(state_seg_blink==1));num5<=hour/10+(10-hour/10)*((state3==6'b100000)&&(state_seg_blink==1));num6<=10;num7<=10;end 7'b000_1000:beginnum0<=alarm1_second%10+(10-alarm1_second%10)*((state4==6'b000001)&&(state_seg_blink==1));num1<=alarm1_second/10+(10-alarm1_second/10)*((state4==6'b000010)&&(state_seg_blink==1));num2<=alarm1_minute%10+(10-alarm1_minute%10)*((state4==6'b000100)&&(state_seg_blink==1));num3<=alarm1_minute/10+(10-alarm1_minute/10)*((state4==6'b001000)&&(state_seg_blink==1));num4<=alarm1_hour%10+(10-alarm1_hour%10)*((state4==6'b010000)&&(state_seg_blink==1));num5<=alarm1_hour/10+(10-alarm1_hour/10)*((state4==6'b100000)&&(state_seg_blink==1));num6<=10;num7<=10;end 7'b001_0000:beginnum0<=alarm2_second%10+(10-alarm2_second%10)*((state5==6'b000001)&&(state_seg_blink==1));num1<=alarm2_second/10+(10-alarm2_second/10)*((state5==6'b000010)&&(state_seg_blink==1));num2<=alarm2_minute%10+(10-alarm2_minute%10)*((state5==6'b000100)&&(state_seg_blink==1));num3<=alarm2_minute/10+(10-alarm2_minute/10)*((state5==6'b001000)&&(state_seg_blink==1));num4<=alarm2_hour%10+(10-alarm2_hour%10)*((state5==6'b010000)&&(state_seg_blink==1));num5<=alarm2_hour/10+(10-alarm2_hour/10)*((state5==6'b100000)&&(state_seg_blink==1));num6<=10;num7<=10;end 7'b010_0000:beginnum0<=stopwatch_frame%10;num1<=stopwatch_frame/10;num2<=stopwatch_second%10;num3<=stopwatch_second/10;num4<=stopwatch_minute%10;num5<=stopwatch_minute/10;num6<=10;num7<=14;
// num0<=alarm3_second%10+(10-alarm3_second%10)*((state6==6'b000001)&&(state_seg_blink==1));
// num1<=alarm3_second/10+(10-alarm3_second/10)*((state6==6'b000010)&&(state_seg_blink==1));
// num2<=alarm3_minute%10+(10-alarm3_minute%10)*((state6==6'b000100)&&(state_seg_blink==1));
// num3<=alarm3_minute/10+(10-alarm3_minute/10)*((state6==6'b001000)&&(state_seg_blink==1));
// num4<=alarm3_hour%10+(10-alarm3_hour%10)*((state6==6'b010000)&&(state_seg_blink==1));
// num5<=alarm3_hour/10+(10-alarm3_hour/10)*((state6==6'b100000)&&(state_seg_blink==1));
// num6<=10;
// num7<=10;end 7'b100_0000:beginnum0<=countdown_second%10+(10-countdown_second%10)*((state7_1==6'b000001)&&(flag2==0)&&(state_seg_blink==1));num1<=countdown_second/10+(10-countdown_second/10)*((state7_1==6'b000010)&&(flag2==0)&&(state_seg_blink==1));num2<=countdown_minute%10+(10-countdown_minute%10)*((state7_1==6'b000100)&&(flag2==0)&&(state_seg_blink==1));num3<=countdown_minute/10+(10-countdown_minute/10)*((state7_1==6'b001000)&&(flag2==0)&&(state_seg_blink==1));num4<=countdown_hour%10+(10-countdown_hour%10)*((state7_1==6'b010000)&&(flag2==0)&&(state_seg_blink==1));num5<=countdown_hour/10+(10-countdown_hour/10)*((state7_1==6'b100000)&&(flag2==0)&&(state_seg_blink==1));num6<=10;num7<=10;end endcase
end//-----设置当前日期-----//
always@(posedge clk or negedge rst_n)
beginif(rst_n==1'b0)begindate<=1;month<=1;year<=2010;endelse if(date>max_month_day) date<=max_month_day;else if(state==7'b000_0010&&key3==1)begincase(state2)5'b00_001: beginif(date==max_month_day) date<=1;else date<=date+1;end5'b00_010: beginif(month==12) month<=1;else month<=month+1;end5'b00_100: beginif(year%10==9) year<=year-9;else year<=year+1;end5'b01_000: beginif(year/10%10==9)year<=year-90;else year<=year+10;end5'b10_000: beginif(year/100%10==9)year<=year-900;else year<=year+100;endendcaseendelse if(state==7'b000_0010&&key4==1)begincase(state2)5'b00_001: beginif(date==1) date<=max_month_day;else date<=date-1;end5'b00_010: beginif(month==1) month<=12;else month<=month-1;end5'b00_100: beginif(year%10==0) year<=year+9;else year<=year-1;end5'b01_000: beginif(year/10%10==0)year<=year+90;else year<=year-10;end5'b10_000: beginif(year/100%10==0)year<=year+900;else year<=year-100;endendcaseendelse if(hour==23&&minute==59&&second==59&&en_1hz==1)beginif(date==max_month_day)begindate<=1;if(month==12)beginmonth<=1; year<=year+1;endelse month<=month+1;endelse date<=date+1;end
end//-----设置当前时间-----//
always@(posedge clk or negedge rst_n)
beginif(rst_n==1'b0)beginsecond<=0;minute<=0;hour<=13;endelse if(state==7'b000_0100&&key3==1)begincase(state3)6'b000_001: beginif(second%10==9) second<=second-9;else second<=second+1;end6'b000_010: beginif(second>=50) second<=second-50;else second<=second+10;end6'b000_100: beginif(minute%10==9) minute<=minute-9;else minute<=minute+1;end6'b001_000: beginif(minute>=50) minute<=minute-50;else minute<=minute+10;end6'b010_000: beginif(hour/10==2) beginif(hour%10==3) hour<=hour-3;else hour<=hour+1; endelsebeginif(hour%10==9) hour<=hour-9;else hour<=hour+1; endend6'b100_000: beginif(hour>=20) hour<=hour-20;else if(hour>=14&&hour<=19) hour<=23;else hour<=hour+10;endendcaseendelse if(state==7'b000_0100&&key4==1)begincase(state3)6'b000_001: beginif(second%10==0) second<=second+9;else second<=second-1;end6'b000_010: beginif(second<10) second<=second+50; else second<=second-10;end6'b000_100: beginif(minute%10==0) minute<=minute+9; else minute<=minute-1;end6'b001_000: beginif(minute<10) minute<=minute+50;else minute<=minute-10;end6'b010_000: beginif(hour/10==2) beginif(hour%10==0) hour<=hour+3;else hour<=hour-1; endelse beginif(hour%10==0) hour<=hour+9;else hour<=hour-1; endend6'b100_000: beginif(hour<=3) hour<=hour+20; else if(hour>=4&&hour<=9) hour<=00;else hour<=hour-10;endendcaseendelse if(en_1hz==1)beginif(second==59)beginsecond<=0;if(minute>=59)beginminute<=0;if(hour>=23) hour<=0;else hour<=hour+1;endelse minute<=minute+1;endelse second<=second+1;end
end//-----美国时间计算-----//
always@(posedge clk or negedge rst_n)
beginif(rst_n == 1'b0)beginus_second <= 0;us_minute <= 0;us_hour <= 0;us_date <= 1;us_month <= 1;us_year <= 2010;endelsebeginus_second <= second;us_minute <= minute;// 计算小时(考虑时差和日期变更)if(hour >= USA_TIME_DIFF)beginus_hour <= hour - USA_TIME_DIFF;us_date <= date;us_month <= month;us_year <= year;endelsebeginus_hour <= hour + 24 - USA_TIME_DIFF;// 计算美国日期(前一天)if(date == 1)beginif(month == 1)beginus_date <= 31;us_month <= 12;us_year <= year - 1;endelsebeginus_month <= month - 1;us_year <= year;case(us_month)1: us_date <= 31;2: us_date <= (us_flag1) ? 29 : 28;3: us_date <= 31;4: us_date <= 30;5: us_date <= 31;6: us_date <= 30;7: us_date <= 31;8: us_date <= 31;9: us_date <= 30;10: us_date <= 31;11: us_date <= 30;12: us_date <= 31;default: us_date <= 30;endcaseendendelsebeginus_date <= date - 1;us_month <= month;us_year <= year;endendend
end//-----新西兰时间计算-----//
always@(posedge clk or negedge rst_n)
beginif(rst_n == 1'b0)beginnz_second <= 0;nz_minute <= 0;nz_hour <= 0;nz_date <= 1;nz_month <= 1;nz_year <= 2010;endelsebeginnz_second <= second;nz_minute <= minute;// 计算小时(新西兰比北京快4小时,时差为负)if(hour + NZ_TIME_DIFF < 24)beginnz_hour <= hour + NZ_TIME_DIFF;nz_date <= date;nz_month <= month;nz_year <= year;endelsebeginnz_hour <= hour + NZ_TIME_DIFF -24 ;// 计算新西兰日期(后一天)if(date == max_month_day)beginnz_date <= 1;if(month == 12)beginnz_month <= 1;nz_year <= year + 1;endelsebeginnz_month <= month + 1;nz_year <= year;endendelsebeginnz_date <= date + 1;nz_month <= month;nz_year <= year;endendend
end//-----泰国时间计算-----//
always@(posedge clk or negedge rst_n)
beginif(rst_n == 1'b0)beginth_second <= 0;th_minute <= 0;th_hour <= 0;th_date <= 1;th_month <= 1;th_year <= 2010;endelsebeginth_second <= second;th_minute <= minute;// 计算小时(泰国比北京慢1小时)if(hour >= TH_TIME_DIFF)beginth_hour <= hour - TH_TIME_DIFF;th_date <= date;th_month <= month;th_year <= year;endelsebeginth_hour <= hour + 24 - TH_TIME_DIFF;// 计算泰国日期(前一天)if(date == 1)beginif(month == 1)beginth_date <= 31;th_month <= 12;th_year <= year - 1;endelsebeginth_month <= month - 1;th_year <= year;case(th_month)1: th_date <= 31;2: th_date <= (th_flag1) ? 29 : 28;3: th_date <= 31;4: th_date <= 30;5: th_date <= 31;6: th_date <= 30;7: th_date <= 31;8: th_date <= 31;9: th_date <= 30;10: th_date <= 31;11: th_date <= 30;12: th_date <= 31;default: th_date <= 30;endcaseendendelsebeginth_date <= date - 1;th_month <= month;th_year <= year;endendend
end//-----闹钟设置(保持不变)-----//
always@(posedge clk or negedge rst_n)
beginif(rst_n==1'b0)beginalarm1_second<=10;alarm1_minute<=0;alarm1_hour<=0;endelse if(state==7'b000_1000&&key3==1)begincase(state4)6'b000_001: beginif(alarm1_second%10==9) alarm1_second<=alarm1_second-9;else alarm1_second<=alarm1_second+1;end6'b000_010: beginif(alarm1_second>=50) alarm1_second<=alarm1_second-50;else alarm1_second<=alarm1_second+10;end6'b000_100: beginif(alarm1_minute%10==9) alarm1_minute<=alarm1_minute-9;else alarm1_minute<=alarm1_minute+1;end6'b001_000: beginif(alarm1_minute>=50) alarm1_minute<=alarm1_minute-50;else alarm1_minute<=alarm1_minute+10;end6'b010_000: beginif(alarm1_hour/10==2) beginif(hour%10==3) alarm1_hour<=alarm1_hour-3;else alarm1_hour<=alarm1_hour+1; endelsebeginif(alarm1_hour%10==9) alarm1_hour<=alarm1_hour-9;else alarm1_hour<=alarm1_hour+1; endend6'b100_000: beginif(alarm1_hour>=20) alarm1_hour<=alarm1_hour-20;else if(alarm1_hour>=14&&alarm1_hour<=19) alarm1_hour<=23;else alarm1_hour<=alarm1_hour+10;endendcaseendelse if(state==7'b000_1000&&key4==1)begincase(state4)6'b000_001: beginif(alarm1_second%10==0) alarm1_second<=alarm1_second+9;else alarm1_second<=alarm1_second-1;end6'b000_010: beginif(alarm1_second<10) alarm1_second<=alarm1_second+50; else alarm1_second<=alarm1_second-10;end6'b000_100: beginif(alarm1_minute%10==0) alarm1_minute<=alarm1_minute+9; else alarm1_minute<=alarm1_minute-1;end6'b001_000: beginif(alarm1_minute<10) alarm1_minute<=alarm1_minute+50;else alarm1_minute<=alarm1_minute-10;end6'b010_000: beginif(alarm1_hour/10==2) beginif(alarm1_hour%10==0) alarm1_hour<=alarm1_hour+3;else alarm1_hour<=alarm1_hour-1; endelse beginif(alarm1_hour%10==0) alarm1_hour<=alarm1_hour+9;else alarm1_hour<=alarm1_hour-1; endend6'b100_000: beginif(alarm1_hour<=3) alarm1_hour<=alarm1_hour+20; else if(alarm1_hour>=4&&alarm1_hour<=9) alarm1_hour<=00;else alarm1_hour<=alarm1_hour-10;endendcaseend
end//-----闹钟2设置(保持不变)-----//
always@(posedge clk or negedge rst_n)
beginif(rst_n==1'b0)beginalarm2_second<=40;alarm2_minute<=0;alarm2_hour<=0;endelse if(state==7'b001_0000&&key3==1)begincase(state5)6'b000_001: beginif(alarm2_second%10==9) alarm2_second<=alarm2_second-9;else alarm2_second<=alarm2_second+1;end6'b000_010: beginif(alarm2_second>=50) alarm2_second<=alarm2_second-50;else alarm2_second<=alarm2_second+10;end6'b000_100: beginif(alarm2_minute%10==9) alarm2_minute<=alarm2_minute-9;else alarm2_minute<=alarm2_minute+1;end6'b001_000: beginif(alarm2_minute>=50) alarm2_minute<=alarm2_minute-50;else alarm2_minute<=alarm2_minute+10;end6'b010_000: beginif(alarm2_hour/10==2) beginif(hour%10==3) alarm2_hour<=alarm2_hour-3;else alarm2_hour<=alarm2_hour+1; endelsebeginif(alarm2_hour%10==9) alarm2_hour<=alarm2_hour-9;else alarm2_hour<=alarm2_hour+1; endend6'b100_000: beginif(alarm2_hour>=20) alarm2_hour<=alarm2_hour-20;else if(alarm2_hour>=14&&alarm2_hour<=19) alarm2_hour<=23;else alarm2_hour<=alarm2_hour+10;endendcaseendelse if(state==7'b001_0000&&key4==1)begincase(state5)6'b000_001: beginif(alarm2_second%10==0) alarm2_second<=alarm2_second+9;else alarm2_second<=alarm2_second-1;end6'b000_010: beginif(alarm2_second<10) alarm2_second<=alarm2_second+50; else alarm2_second<=alarm2_second-10;end6'b000_100: beginif(alarm2_minute%10==0) alarm2_minute<=alarm2_minute+9; else alarm2_minute<=alarm2_minute-1;end6'b001_000: beginif(alarm2_minute<10) alarm2_minute<=alarm2_minute+50;else alarm2_minute<=alarm2_minute-10;end6'b010_000: beginif(alarm2_hour/10==2) beginif(alarm2_hour%10==0) alarm2_hour<=alarm2_hour+3;else alarm2_hour<=alarm2_hour-1; endelse beginif(alarm2_hour%10==0) alarm2_hour<=alarm2_hour+9;else alarm2_hour<=alarm2_hour-1; endend6'b100_000: beginif(alarm2_hour<=3) alarm2_hour<=alarm2_hour+20; else if(alarm2_hour>=4&&alarm2_hour<=9) alarm2_hour<=00;else alarm2_hour<=alarm2_hour-10;endendcaseend
end//-----闹钟3设置(保持不变)-----//
//always@(posedge clk or negedge rst_n)
//begin
// if(rst_n==1'b0)
// begin
// alarm3_second<=10;
// alarm3_minute<=1;
// alarm3_hour<=0;
// end
// else if(state==7'b010_0000&&key3==1)
// begin
// case(state6)
// 6'b000_001: begin
// if(alarm3_second%10==9) alarm3_second<=alarm3_second-9;
// else alarm3_second<=alarm3_second+1;
// end
// 6'b000_010: begin
// if(alarm3_second>=50) alarm3_second<=alarm3_second-50;
// else alarm3_second<=alarm3_second+10;
// end
// 6'b000_100: begin
// if(alarm3_minute%10==9) alarm3_minute<=alarm3_minute-9;
// else alarm3_minute<=alarm3_minute+1;
// end
// 6'b001_000: begin
// if(alarm3_minute>=50) alarm3_minute<=alarm3_minute-50;
// else alarm3_minute<=alarm3_minute+10;
// end
// 6'b010_000: begin
// if(alarm3_hour/10==2)
// begin
// if(alarm3_hour%10==3) alarm3_hour<=alarm3_hour-3;
// else alarm3_hour<=alarm3_hour+1;
// end
// else
// begin
// if(alarm3_hour%10==9) alarm3_hour<=alarm3_hour-9;
// else alarm3_hour<=alarm3_hour+1;
// end
// end
// 6'b100_000: begin
// if(alarm3_hour>=20) alarm3_hour<=alarm3_hour-20;
// else if(alarm3_hour>=14&&alarm3_hour<=19) alarm3_hour<=23;
// else alarm3_hour<=alarm3_hour+10;
// end
// endcase
// end
// else if(state==7'b010_0000&&key4==1)
// begin
// case(state6)
// 6'b000_001: begin
// if(alarm3_second%10==0) alarm3_second<=alarm3_second+9;
// else alarm3_second<=alarm3_second-1;
// end
// 6'b000_010: begin
// if(alarm3_second<10) alarm3_second<=alarm3_second+50;
// else alarm3_second<=alarm3_second-10;
// end
// 6'b000_100: begin
// if(alarm3_minute%10==0) alarm3_minute<=alarm3_minute+9;
// else alarm3_minute<=alarm3_minute-1;
// end
// 6'b001_000: begin
// if(alarm3_minute<10) alarm3_minute<=alarm3_minute+50;
// else alarm3_minute<=alarm3_minute-10;
// end
// 6'b010_000: begin
// if(alarm3_hour/10==2)
// begin
// if(alarm3_hour%10==0) alarm3_hour<=alarm3_hour+3;
// else alarm3_hour<=alarm3_hour-1;
// end
// else
// begin
// if(alarm3_hour%10==0) alarm3_hour<=alarm3_hour+9;
// else alarm3_hour<=alarm3_hour-1;
// end
// end
// 6'b100_000: begin
// if(alarm3_hour<=3) alarm3_hour<=alarm3_hour+20;
// else if(alarm3_hour>=4&&alarm3_hour<=9) alarm3_hour<=00;
// else alarm3_hour<=alarm3_hour-10;
// end
// endcase
// end
//end//-----倒计时及闹钟响铃逻辑(保持不变)-----//
always@(posedge clk or negedge rst_n)
beginif(rst_n==0) flag9<=0;else if(countdown_hour==0&&countdown_minute==0&&countdown_second==1) flag9<=1;else if(flag9==1) flag9<=0;
endalways@(posedge clk or negedge rst_n)
beginif(rst_n==0) begintimer_countdown_blink<=0;blink_countdown<=0;count_blink_countdown<=0;endelse if(flag9==1)begintimer_countdown_blink<=0;blink_countdown<=0;count_blink_countdown<=20; endelse if(count_blink_countdown!=0)beginif(timer_countdown_blink==32'd25_0)begintimer_countdown_blink<=0;count_blink_countdown<=count_blink_countdown-1;blink_countdown<=~blink_countdown;endelse timer_countdown_blink<=timer_countdown_blink+1;end
endalways@(posedge clk or negedge rst_n)
beginif(rst_n==1'b0)begincountdown_second<=0;countdown_minute<=1;countdown_hour<=0;flag3<=1;flag5<=0;endelse if(flag3==1&&key5==1) beginflag3<=0;endelse if(flag3==0&&key5==1)begincountdown_second<=origin_countdown_second;countdown_minute<=origin_countdown_minute;countdown_hour<=origin_countdown_hour;flag3<=1;endelse if(flag5==1) flag5<=0;else if(flag2==1) beginif(en_countdown==1)beginif(countdown_second==0)beginif(countdown_minute==0)beginif(countdown_hour==0) beginflag3<=1;flag5<=1;endelsebeginflag5<=0;flag3<=0;countdown_hour<=countdown_hour-1;countdown_minute<=59;countdown_second<=59;endendelse begincountdown_minute<=countdown_minute-1;countdown_second<=59;endendelse countdown_second<=countdown_second-1;endendelse if(state==7'b100_0000&&key3==1)beginflag3<=1;case(state7_1)6'b000_001: beginif(countdown_second%10==9) countdown_second<=countdown_second-9;else countdown_second<=countdown_second+1;end6'b000_010: beginif(countdown_second>=50) countdown_second<=countdown_second-50;else countdown_second<=countdown_second+10;end6'b000_100: beginif(countdown_minute%10==9) countdown_minute<=countdown_minute-9;else countdown_minute<=countdown_minute+1;end6'b001_000: beginif(countdown_minute>=50) countdown_minute<=countdown_minute-50;else countdown_minute<=countdown_minute+10;end6'b010_000: beginif(countdown_hour/10==2) beginif(countdown_hour%10==3) countdown_hour<=countdown_hour-3;else countdown_hour<=countdown_hour+1; endelsebeginif(countdown_hour%10==9) countdown_hour<=countdown_hour-9;else countdown_hour<=countdown_hour+1; endend6'b100_000: beginif(countdown_hour>=20) countdown_hour<=countdown_hour-20;else if(countdown_hour>=14&&countdown_hour<=19) countdown_hour<=23;else countdown_hour<=countdown_hour+10;endendcaseendelse if(state==7'b100_0000&&key4==1)beginflag3<=1;case(state7_1)6'b000_001: beginif(countdown_second%10==0) countdown_second<=countdown_second+9;else countdown_second<=countdown_second-1;end6'b000_010: beginif(countdown_second<10) countdown_second<=countdown_second+50; else countdown_second<=countdown_second-10;end6'b000_100: beginif(countdown_minute%10==0) countdown_minute<=countdown_minute+9; else countdown_minute<=countdown_minute-1;end6'b001_000: beginif(countdown_minute<10) countdown_minute<=countdown_minute+50;else countdown_minute<=countdown_minute-10;end6'b010_000: beginif(countdown_hour/10==2) beginif(countdown_hour%10==0) countdown_hour<=countdown_hour+3;else countdown_hour<=countdown_hour-1; endelse beginif(countdown_hour%10==0) countdown_hour<=countdown_hour+9;else countdown_hour<=countdown_hour-1; endend6'b100_000: beginif(countdown_hour<=3) countdown_hour<=countdown_hour+20; else if(countdown_hour>=4&&countdown_hour<=9) countdown_hour<=00;else countdown_hour<=countdown_hour-10;endendcaseend
endalways@(posedge clk or negedge rst_n)
beginif(rst_n==0)beginflag6<=0;flag7<=0;flag8<=0;endelse if(hour==alarm1_hour&&minute==alarm1_minute&&second==alarm1_second) flag6<=1;else if(hour==alarm2_hour&&minute==alarm2_minute&&second==alarm2_second) flag7<=1;else if(hour==alarm3_hour&&minute==alarm3_minute&&second==alarm3_second) flag8<=1;else if(flag6==1) #100 flag6<=0;else if(flag7==1) #100 flag7<=0;else if(flag8==1) #100 flag8<=0;
endalways@(posedge clk or negedge rst_n)
beginif(rst_n==0) begintimer_alarm1_blink<=0;blink_alarm1<=0;count_blink_alarm1<=0;timer_alarm1_5s<=0;end else if(flag6==1) count_blink_alarm1<=40;else if(state!=7'b1000_000&&key5==1&&timer_alarm1_5s==0)beginblink_alarm1<=0;count_blink_alarm1<=0;end else if(count_blink_alarm1!=0)if(timer_alarm1_blink==32'd25_0)begintimer_alarm1_blink<=0;if(count_blink_alarm1==20)beginif(timer_alarm1_5s==32'd1000_0)begintimer_alarm1_5s<=0;count_blink_alarm1<=count_blink_alarm1-1;blink_alarm1<=~blink_alarm1;endelse begintimer_alarm1_blink<=32'd25_0;timer_alarm1_5s<=timer_alarm1_5s+1;endendelsebegincount_blink_alarm1<=count_blink_alarm1-1;blink_alarm1<=~blink_alarm1;endendelse timer_alarm1_blink<=timer_alarm1_blink+1;
endalways@(posedge clk or negedge rst_n)
beginif(rst_n==0) begintimer_alarm2_blink<=0;count_blink_alarm2<=0;blink_alarm2<=0;timer_alarm2_5s<=0;endelse if(flag7==1) count_blink_alarm2<=40;else if(state!=7'b1000_000&&key5==1&&timer_alarm2_5s==0)begincount_blink_alarm2<=0;blink_alarm2<=0;endelse if(count_blink_alarm2!=0)if(timer_alarm2_blink==32'd25_0)begintimer_alarm2_blink<=0;if(count_blink_alarm2==20)beginif(timer_alarm2_5s==32'd1000_0)begintimer_alarm2_5s<=0;count_blink_alarm2<=count_blink_alarm2-1;blink_alarm2<=~blink_alarm2;endelse begintimer_alarm2_blink<=32'd25_0;timer_alarm2_5s<=timer_alarm2_5s+1;endendelsebegincount_blink_alarm2<=count_blink_alarm2-1;blink_alarm2<=~blink_alarm2;endendelse timer_alarm2_blink<=timer_alarm2_blink+1;
end//always@(posedge clk or negedge rst_n)
//begin
// if(rst_n==0)
// begin
// timer_alarm3_blink<=0;
// count_blink_alarm3<=0;
// blink_alarm3<=0;
// timer_alarm3_5s<=0;
// end
// else if(flag8==1) count_blink_alarm3<=40;
// else if(state!=7'b1000_000&&key5==1&&timer_alarm3_5s==0)
// begin
// count_blink_alarm3<=0;
// blink_alarm3<=0;
// end
// else if(count_blink_alarm3!=0)
// if(timer_alarm3_blink==32'd25_0)
// begin
// timer_alarm3_blink<=0;
// if(count_blink_alarm3==20)
// begin
// if(timer_alarm3_5s==32'd1000_0)
// begin
// timer_alarm3_5s<=0;
// count_blink_alarm3<=count_blink_alarm3-1;
// blink_alarm3<=~blink_alarm3;
// end
// else
// begin
// timer_alarm3_blink<=32'd25_0;
// timer_alarm3_5s<=timer_alarm3_5s+1;
// end
// end
// else
// begin
// count_blink_alarm3<=count_blink_alarm3-1;
// blink_alarm3<=~blink_alarm3;
// end
// end
// else timer_alarm3_blink<=timer_alarm3_blink+1;
//endalways@(posedge clk )
beginflag10<=(count_blink_alarm1>0&&count_blink_alarm1!=20||count_blink_alarm2>0&&count_blink_alarm2!=20||count_blink_alarm3>0&&count_blink_alarm3!=20);
end//-----数码管驱动及其他模块实例化-----//
seg_decoder seg_decoder_m0(.bin_data (count0),.seg_data (seg_data_0)
);
wire[6:0] seg_data_1;
seg_decoder seg_decoder_m1(.bin_data (count1),.seg_data (seg_data_1)
);
wire[6:0] seg_data_2;
seg_decoder seg_decoder_m2(.bin_data (count2),.seg_data (seg_data_2)
);
wire[6:0] seg_data_3;
seg_decoder seg_decoder_m3(.bin_data (count3),.seg_data (seg_data_3)
);
wire[6:0] seg_data_4;
seg_decoder seg_decoder_m4(.bin_data (count4),.seg_data (seg_data_4)
);wire[6:0] seg_data_5;
seg_decoder seg_decoder_m5(.bin_data (count5),.seg_data (seg_data_5)
);wire[6:0] seg_data_6;
seg_decoder seg_decoder_m6(.bin_data (count6),.seg_data (seg_data_6)
);wire[6:0] seg_data_7;
seg_decoder seg_decoder_m7(.bin_data (count7),.seg_data (seg_data_7)
);seg_scan seg_scan_m0(.clk (clk),.rst_n (rst_n),.seg_sel (seg_sel),.seg_data (seg_data),.seg_data_7 (seg_data_0),.seg_data_6 (seg_data_1), .seg_data_5 (seg_data_2),.seg_data_4 (seg_data_3),.seg_data_3 (seg_data_4),.seg_data_2 (seg_data_5),.seg_data_1 (seg_data_6),.seg_data_0 (seg_data_7)
);
ax_debounce ax_debounce_m1
(.clk (clk),.rst (~rst_n),.button_in (key1),.button_posedge ( ),.button_negedge (button_negedge1),.button_out ()
);
ax_debounce ax_debounce_m2
(.clk (clk),.rst (~rst_n),.button_in (key2),.button_posedge ( ),.button_negedge (button_negedge2),.button_out ()
);
ax_debounce ax_debounce_m3
(.clk (clk),.rst (~rst_n),.button_in (key3),.button_posedge ( ),.button_negedge (button_negedge3),.button_out ()
);
ax_debounce ax_debounce_m4
(.clk (clk),.rst (~rst_n),.button_in (key4),.button_posedge ( ),.button_negedge (button_negedge4),.button_out ()
);
ax_debounce ax_debounce_m5
(.clk (clk),.rst (~rst_n),.button_in (key5),.button_posedge ( ),.button_negedge (button_negedge5),.button_out ()
);beep beep1
(.clk(clk),.rst_n(rst_n),.aloud(flag10),.beep(beep)
);
assign count0=num0;
assign count1=num1;
assign count2=num2;
assign count3=num3;
assign count4=num4;
assign count5=num5;
assign count6=num6;
assign count7=num7;
assign LED_indicate=state;
endmodule
2.seg_decoder
module seg_decoder
(input[3:0] bin_data, // bin data inputoutput reg[6:0] seg_data // seven segments LED output
);always@(*)
begincase(bin_data)4'd0:seg_data <= 7'b000_0001;//{a,b,c,d,e,f,g}4'd1:seg_data <= 7'b100_1111;4'd2:seg_data <= 7'b001_0010;4'd3:seg_data <= 7'b000_0110;4'd4:seg_data <= 7'b100_1100;4'd5:seg_data <= 7'b010_0100;4'd6:seg_data <= 7'b010_0000;4'd7:seg_data <= 7'b000_1111;4'd8:seg_data <= 7'b000_0000;4'd9:seg_data <= 7'b000_0100;default:seg_data <= 7'b111_1111;endcase
end
endmodule
3.seg_scan
`timescale 1ns / 1ps
module seg_scan(input clk,input rst_n,output reg[7:0] seg_sel, //digital led chip selectoutput reg[6:0] seg_data, //seven segment digital tube output,MSB is the decimal pointinput[6:0] seg_data_7,input[6:0] seg_data_6,input[6:0] seg_data_5,input[6:0] seg_data_4,input[6:0] seg_data_3,input[6:0] seg_data_2,input[6:0] seg_data_1,input[6:0] seg_data_0
);
parameter SCAN_FREQ = 200; //scan frequency
parameter CLK_FREQ = 50_000_000; //clock frequencyparameter SCAN_COUNT = CLK_FREQ /(SCAN_FREQ * 6) - 1;reg[31:0] scan_timer; //scan time counter
reg[3:0] scan_sel; //Scan select counter
always@(posedge clk or negedge rst_n)
beginif(rst_n == 1'b0)beginscan_timer <= 32'd0;scan_sel <= 4'd0;endelse if(scan_timer >= SCAN_COUNT)beginscan_timer <= 32'd0;if(scan_sel == 4'd7)scan_sel <= 4'd0;elsescan_sel <= scan_sel + 4'd1;endelsebeginscan_timer <= scan_timer + 32'd1;end
end
always@(posedge clk or negedge rst_n)
beginif(rst_n == 1'b0)beginseg_sel <= 8'b11111111;seg_data <= 8'hff;endelsebegincase(scan_sel)//first digital led4'd0:beginseg_sel <= 8'b1111_1110;seg_data <= seg_data_0;end//second digital led4'd1:beginseg_sel <= 8'b1111_1101;seg_data <= seg_data_1;end//...4'd2:beginseg_sel <= 8'b1111_1011;seg_data <= seg_data_2;end4'd3:beginseg_sel <= 8'b1111_0111;seg_data <= seg_data_3;end4'd4:beginseg_sel <= 8'b1110_1111;seg_data <= seg_data_4;end4'd5:beginseg_sel <= 8'b1101_1111;seg_data <= seg_data_5;end4'd6:beginseg_sel <= 8'b1011_1111;seg_data <= seg_data_6; end4'd7:beginseg_sel <= 8'b0111_1111;seg_data <= seg_data_7; enddefault:beginseg_sel <= 8'b1111_1111;seg_data <= 7'h7f;endendcaseend
endendmodule
4.beep
`timescale 1ns / 1ps
module beep(input clk,input rst_n,input aloud,output reg beep
);//-----低音-----//
parameter L1 = 19'd381680;
parameter L2 = 19'd340140;
parameter L3 = 19'd303030;
parameter L4 = 19'd286530;
parameter L5 = 18'd255100;
parameter L6 = 18'd227270;
parameter L7 = 18'd202430;//-----中音-----//
parameter M1 = 18'd191200;
parameter M2 = 18'd170360;
parameter M3 = 18'd151750;
parameter M4 = 18'd143270;
parameter M5 = 17'd127550;
parameter M6 = 17'd113640;
parameter M7 = 17'd101210;//----高音----//
parameter H1 = 17'd95602;
parameter H2 = 17'd85106;
parameter H3 = 17'd75873;
parameter H4 = 17'd71582;
parameter H5 = 17'd63776;
parameter H6 = 17'd56818;
parameter H7 = 17'd50607;reg [16:0] cnt0;//音符周期计数器
wire add_cnt0;
wire end_cnt0;reg [8:0] cnt1;//音符重复次数计数器
wire add_cnt1;
wire end_cnt1;reg [4:0] cnt2;//音符总次数
wire add_cnt2;
wire end_cnt2;reg [16:0] preset_note;//预设音符周期数
wire [16:0] preset_duty;//占空比
//音符周期计数
always@(posedge clk or negedge rst_n)
beginif(!rst_n) cnt0 <= 17'b0;else if(add_cnt0&&aloud==1)beginif(end_cnt0) cnt0 <= 17'b0;else cnt0 <= cnt0 +1'b1;endelse cnt0<=0;
end
assign add_cnt0 = 1'b1;
assign end_cnt0 = add_cnt0 && (cnt0 == preset_note - 1);//音符重复次数
always@(posedge clk or negedge rst_n)
beginif(!rst_n) cnt1 <= 9'b0;else if(add_cnt1)beginif(end_cnt1) cnt1 <= 9'b0;else cnt1 <= cnt1 +1'b1;end
end
assign add_cnt1 = end_cnt0;
assign end_cnt1 = add_cnt1 && (cnt1 == 299);//音符总次数
always@(posedge clk or negedge rst_n)
beginif(!rst_n) cnt2 <= 5'b0;else if(add_cnt2)beginif(end_cnt2) cnt2 <= 5'b0;else cnt2 <= cnt2 +1'b1;end
end
assign add_cnt2 = end_cnt1;
assign end_cnt2 = add_cnt2 && (cnt2 ==28);//给音符周期赋值 对照乐谱的音符位置赋值
always@(posedge clk or negedge rst_n)
beginif(!rst_n) preset_note <= 17'b0;else begincase(cnt2)6'd0 : preset_note <= H1;6'd1 : preset_note <= H2;6'd2 : preset_note <= H3;6'd3 : preset_note <= H1;6'd4 : preset_note <= H1;6'd5 : preset_note <= H2;6'd6 : preset_note <= H3;6'd7 : preset_note <= H1;6'd8 : preset_note <= H3;6'd9 : preset_note <= H4;6'd10 : preset_note <= H5;6'd11 : preset_note <= H3;6'd12 : preset_note <= H4;6'd13 : preset_note <= H5;6'd14 : preset_note <= H5;6'd15 : preset_note <= H6;6'd16 : preset_note <= H5;6'd17 : preset_note <= H4;6'd18 : preset_note <= H3;6'd19 : preset_note <= H1;6'd20 : preset_note <= H5;6'd21 : preset_note <= H6;6'd22 : preset_note <= H5;6'd23 : preset_note <= H4;6'd24 : preset_note <= H3;6'd25 : preset_note <= H1;6'd26 : preset_note <= H2;6'd27 : preset_note <= H5;6'd28 : preset_note <= H1;6'd29 : preset_note <= H2;6'd30 : preset_note <= H5;6'd31 : preset_note <= H1;default : preset_note <= H1; endcaseend
end//给蜂鸣器赋值,并设定占空比
always@(posedge clk or negedge rst_n)
beginif(!rst_n) beep <= 1'b1;else if(cnt0 <= preset_duty) beep <= 1'b0;//蜂鸣器低电平有效else beep <= 1'b1;
end
assign preset_duty = preset_note >> 1;//50%占空比
endmodule
6.tb
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2025/09/18 09:42:14
// Design Name:
// Module Name: tb_top
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////module tb_top();
// 输入信号定义reg clk;reg rst_n;reg key1;reg key2;reg key3;reg key4;reg key5;// 输出信号定义wire [7:0] seg_sel;wire [6:0] seg_data;wire [6:0] LED_indicate;wire blink_countdown;wire blink_alarm1;wire blink_alarm2;wire blink_alarm3;wire beep;// 实例化被测试模块seg_show_t uut (.clk(clk),.rst_n(rst_n),.key1(key1),.key2(key2),.key3(key3),.key4(key4),.key5(key5),.seg_sel(seg_sel),.seg_data(seg_data),.LED_indicate(LED_indicate),.blink_countdown(blink_countdown),.blink_alarm1(blink_alarm1),.blink_alarm2(blink_alarm2),.blink_alarm3(blink_alarm3),.beep(beep));
// 生成时钟信号100MHzinitial beginclk = 0;forever #5 clk = ~clk; // 10ns周期,100MHzendinitial beginrst_n = 0;key1 = 0; key2 = 0;key3 = 0;key4 = 0;key5 = 0;#1000rst_n = 1;//初始状态在显示日期 时间界面,key2切换日期或者时间#100000key2=1;#10key2=0;//切换显示不同国家时间#100000key3=1;#10key3=0;//切换日期或者时间#100000key2=1;#10key2=0;//切换日期或者时间#100000key2=1;#10key2=0;//切换显示不同国家时间#100000key3=1;#10key3=0;//切换日期或者时间#100000key2=1;#10key2=0;//切换日期或者时间#100000key2=1;#10key2=0;//切换显示不同国家时间#100000key3=1;#10key3=0;//切换日期或者时间#100000key2=1;#10key2=0;//切换日期或者时间#100000key2=1;#10key2=0;#100key1=1;#10key1=0;#100key1=1;#10key1=0;#100key1=1;#10key1=0;#100key1=1;#10key1=0;#100key1=1;#10key1=0;//开始秒表#1000key2=1;#10key2=0;//停止#10000000key2=1;#10key2=0;#10000key3=1;#10key3=0;endendmodule
二、仿真结果
总结
仿真只针对秒表和世界时间演示,可自行添加tb代码。