1功能概述
闹钟是一种既能显示时间,又能根据人们设定的时间,发出铃声、乐曲等提醒信号的计时工具。现在,闹钟几乎已经是上学、上班族必不可少的一个工具,主要应用在电脑、手机、电子表等方面。在20小节数字时钟里我们介绍过,与传统机械式计时工具相比,数字计时系统具备体积小、重量轻、抗干扰能力强、对环境要求高、高精确性、容易开发等特征。数字计时间高精度的特征,在闹钟功能上的应用优势更为突出。
科学地划分模块,充分理顺模块间的相互关系对于FPGA设计来说非常重要。以闹钟设计为例,我们通过建立四个清晰直观的模块(数码管显示模块,矩阵键盘扫描模块,时钟计数模块,闹钟设定模块),以及建立完善的信号列表和运用verilog语言编写简洁流畅的代码,实现电子闹钟时、分、秒计时以及设置、修改、重置等功能。
具体功能要求如下:
本工程包括矩阵键盘和数码管显示模块,共同实现一个带有闹钟功能、可设置时间的数字时钟。具体功能如下:
1. 数码管可以显示时十位、时个位、分十位、分个位、秒十位、秒个位。
2. 上电后,数码管显示000000,并开始每秒计时。
3. 按下按键1进入时间设置状态。再按下按键1退出时间设置状态,继续计时。
4. 在时间设置状态,通过按键2来选择设置的时间位,在0~5之间循环选择。
5. 在时间设置状态,通过按键3来对当前选择的时间位进行加1。
6. 在计时状态下,按下按键14,进入闹钟时间点设置状态;再按下按健15,退出闹钟设置状态。
7. 在闹钟设置状态,按下按键13选择设置的时间位,此时可以按下所需要的按键序号设置对应闹钟时间。
8. 当前时间与所设置的时间点匹配上了,蜂鸣器响应5 s。
2 设计思路
我们把工程分成四个模块,分别是数码管显示模块,矩阵键盘扫描模块,时钟计数模块,闹钟设定模块。
工程顶层模块的信号列表
信号名 |
I/O |
位宽 |
说明 |
clk |
I |
1 |
系统工作时钟50MHz。 |
rst_n |
I |
1 |
系统复位信号,低电平有效。 |
key_col |
I |
4 |
矩阵键盘按键列信号 |
key_row |
O |
4 |
矩阵键盘按键行信号 |
bell |
O |
1 |
蜂鸣器控制信号 |
1.数码管显示模块——实现将时钟数据或者闹钟数据显示到七段译码器上的功能。
七段译码器引脚图:
根据七段译码器的型号共阴极或者共阳极,给予信号0点亮对应的led灯;一个八段数码管称为一位,多个数码管并列在一起可构成多位数码管,它们的段选(a,b,c,d,e,f,g,dp)连在一起,而各自的公共端称为位选线。显示时,都从段选线送入字符编码,而选中哪个位选线,那个数码管便会被点亮。例如,如果数码管显示数字0,那么共阴数码管的字符编码为00111111,即共阳数码管的字符编码为11000000。
信号列表如下:
信号名 |
I/O |
位宽 |
说明 |
clk |
I |
1 |
系统工作时钟50MHz。 |
rst_n |
I |
1 |
系统复位信号,低电平有效。 |
din |
I |
32 |
每个数码管的时间数据 |
seg_sel |
O |
8 |
数码管位选信号 |
seg_ment |
O |
8 |
数码管段选信号 |
在轮流显示过程中,每位数码管的点亮时间为1~2ms,由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感。
2.矩阵键盘扫描模块——4x4矩阵键盘,实现了矩阵键盘的扫描并使用以及按键消抖功能。通过行扫描法得到按下的键的位置信息。
信号列表如下:
信号名 |
I/O |
位宽 |
说明 |
clk |
I |
1 |
系统工作时钟50MHz。 |
rst_n |
I |
1 |
系统复位信号,低电平有效。 |
key_col |
I |
4 |
矩阵键盘列信号 |
key_row |
O |
4 |
矩阵键盘行信号 |
key_out |
O |
4 |
按键位置信号 |
key_vld |
O |
1 |
按键有效信号 |
3.时钟计数模块——按下按键1则进入时钟数字调节界面,此时利用按键2来位选,按键3来调节数字,按一次按键3则加1,再次按下按键1则恢复计数。
信号列表如下:
信号名 |
I/O |
位宽 |
说明 |
clk |
I |
1 |
系统工作时钟50MHz。 |
rst_n |
I |
1 |
系统复位信号,低电平有效。 |
key_num |
I |
4 |
输入按键值 |
key_vld |
I |
1 |
按键输入有效指示 |
dout |
O |
24 |
时钟数据输出 |
dout_vld |
O |
24 |
时钟数据输出有效 |
4.闹钟设定模块——实现设定闹钟时间功能,按下按键14则进入闹钟时间设定界面,并利用按键13来进行位选;然后按下对应的按键则设定对应的数字;按下按键15则退出闹钟设定界面。当时钟数据和闹钟数据相同时,也就是到达设定时间时,蜂鸣器响5s。
信号列表如下:
信号名 |
I/O |
位宽 |
说明 |
clk |
I |
1 |
系统工作时钟50MHz。 |
rst_n |
I |
1 |
系统复位信号,低电平有效。 |
time_now |
I |
24 |
当前输入时间 |
time_now_vld |
I |
1 |
当前输入时间有效 |
key_num |
I |
4 |
输入按键值 |
key_vld |
I |
1 |
按键输入有效指示 |
set_group |
O |
24 |
设置闹钟时间点 |
setting |
O |
1 |
设置状态标志 |
bell |
O |
1 |
蜂鸣器控制信号 |
3 程序设计
工程模块
2 clk ,
3 rst_n ,
4 key_col ,
5 key_row ,
6 seg_ment,
7 seg_sel ,
8 bell
9 );
10
11
12 parameter SEG_NUM = 6 ;
13 parameter TIME_1S = 50000000 ;
14 parameter TIME_20MS = 1000000 ;
15
16 input clk ;
17 input rst_n ;
18
19 output [3:0] key_row ;
20 output [7:0] seg_ment ;
21 output [5:0] seg_sel ;
22 input [3:0] key_col ;
23 output bell ;
24
25 wire [3:0] key_num ;
26 wire key_vld ;
27 wire [23:0] time_now ;
28 wire [23:0] time_display ;
29 wire time_now_vld ;
30 wire setting ;
31 wire [23:0] set_group ;
32
33 timer_data #(.TIME_1S(TIME_1S))timer_data_inst(
34 .clk(clk) ,
35 .rst_n(rst_n) ,
36 .dout(time_now) ,
37 .dout_vld(time_now_vld) ,
38
39 .key_num(key_num) ,
40 .key_vld(key_vld)
41 );
42
43 key_scan #(.TIME_20MS(TIME_20MS))key_scan_inst(
44 .clk(clk) ,
45 .rst_n(rst_n) ,
46 .key_col(key_col) ,
47 .key_row(key_row) ,
48 .key_out(key_num) ,
49 .key_vld(key_vld)
50 );
51
52 match_bell #(.TIME_1S(TIME_1S))match_bell_inst(
53 .clk(clk) ,
54 .rst_n(rst_n) ,
55 .time_now(time_now) ,
56 .time_now_vld(time_now_vld),
57 .key_num(key_num) ,
58 .key_vld(key_vld) ,
59 .setting(setting) ,
60 .set_group(set_group) ,
61 .bell(bell)
62 );
63
64 seg_disp #(.SEG_NUM(SEG_NUM))seg_display_inst(
65 .clk (clk) ,
66 .rst_n (rst_n) ,
67 .din(time_display),
68 .segment(seg_ment),
69 .seg_sel(seg_sel)
70 );
71
72 assign time_display=setting?set_group:time_now ;
73
74 endmodule
75
数码管显示模块
2 rst_n ,
3 clk ,
4 din ,
5 seg_sel ,
6 segment
7 );
8
9
10 parameter SEG_WID = 8 ;
11 parameter SEG_NUM = 8 ;
12 parameter CNT_WID = 10 ;
13 parameter TIME_20US = 10'd1000 ;
14
15 //dp,g,f,e,d,c,b,a,
16 parameter NUM_0 = 8'b1100_0000;
17 parameter NUM_1 = 8'b1111_1001;
18 parameter NUM_2 = 8'b1010_0100;
19 parameter NUM_3 = 8'b1011_0000;
20 parameter NUM_4 = 8'b1001_1001;
21 parameter NUM_5 = 8'b1001_0010;
22 parameter NUM_6 = 8'b1000_0010;
23 parameter NUM_7 = 8'b1111_1000;
24 parameter NUM_8 = 8'b1000_0000;
25 parameter NUM_9 = 8'b1001_0000;
26 parameter NUM_ERR = 8'b1111_1111;
27
28
29 input clk ;
30 input rst_n ;
31 input [SEG_NUM*4-1:0] din ;
32 output [SEG_NUM - 1:0] seg_sel ;
33 output [SEG_WID - 1:0] segment ;
34
35 reg [SEG_NUM - 1:0] seg_sel ;
36 reg [SEG_WID - 1:0] segment ;
37
38 reg [CNT_WID - 1:0] cnt_20us ;
39 reg [SEG_NUM - 1:0] sel_cnt ;
40
41 reg [ 4-1:0] seg_tmp ;
42
43 wire add_cnt_20us ;
44 wire end_cnt_20us ;
45 wire add_sel_cnt ;
46 wire end_sel_cnt ;
47
48
49
50 always @(posedge clk or negedge rst_n)begin
51 if(rst_n==1'b0)begin
52 cnt_20us <= 0;
53 end
54 else if(add_cnt_20us)begin
55 if(end_cnt_20us)
56 cnt_20us <= 0;
57 else
58 cnt_20us <= cnt_20us + 1;
59 end
60 end
61 assign add_cnt_20us = 1;
62 assign end_cnt_20us = add_cnt_20us && cnt_20us == TIME_20US-1;
63
64
65 always @(posedge clk or negedge rst_n)begin
66 if(rst_n==1'b0)begin
67 sel_cnt <= 0;
68 end
69 else if(add_sel_cnt)begin
70 if(end_sel_cnt)
71 sel_cnt <= 0;
72 else
73 sel_cnt <= sel_cnt + 1;
74 end
75 end
76 assign add_sel_cnt = end_cnt_20us;
77 assign end_sel_cnt = add_sel_cnt && sel_cnt == SEG_NUM-1;
78
79 always @(posedge clk or negedge rst_n)begin
80 if(rst_n==1'b0)begin
81 seg_sel <= {SEG_NUM{1'b1}};
82 end
83 else begin
84 seg_sel <= ~(1'b1 << sel_cnt);
85 end
86 end
87
88 always @(*)begin
89 seg_tmp = din[(sel_cnt+1)*4-1 -:4];
90 end
91
92 always@(posedge clk or negedge rst_n)begin
93 if(rst_n==1'b0)begin
94 segment<=NUM_0;
95 end
96 else begin
97 case (seg_tmp)
98 0 : segment <= NUM_0;
99 1 : segment <= NUM_1;
100 2 : segment <= NUM_2;
101 3 : segment <= NUM_3;
102 4 : segment <= NUM_4;
103 5 : segment <= NUM_5;
104 6 : segment <= NUM_6;
105 7 : segment <= NUM_7;
106 8 : segment <= NUM_8;
107 9 : segment <= NUM_9;
108 default : segment <= NUM_ERR;
109 endcase
110 end
111 end
112
113 endmodule
矩阵键盘模块
2 clk ,
3 rst_n ,
4 key_col,
5 key_row,
6 key_out,
7 key_vld
8 );
9
10 parameter TIME_20MS=1000000;
11
12 input clk ;
13 input rst_n ;
14 input [3:0] key_col ;
15
16 output [3:0] key_row ;
17
18 output [3:0] key_out ;
19 output key_vld ;
20
21 reg [3:0] key_out ;
22 reg key_vld ;
23
24 wire add_cnt_8clks ;
25 wire end_cnt_8clks ;
26 wire delay_over ;
27 wire add_row_index ;
28 wire end_row_index ;
29 wire vld ;
30 wire key_up ;
31 wire add_cnt_20ms ;
32 wire end_cnt_20ms ;
33 wire add_cnt_phase ;
34 wire end_cnt_phase ;
35 wire possible_vld ;
36
37 reg [2:0] cnt_8clks ;
38 reg [3:0] key_col_ff0 ;
39 reg [3:0] key_col_ff1 ;
40 reg [1:0] row_index ;
41 reg [3:0] key_row ;
42 reg [1:0] cnt_phase ;
43 reg [1:0] key_col_get ;
44 reg [20:0] cnt_20ms ;
45
46 always @(posedge clk or negedge rst_n)begin
47 if(rst_n==1'b0)begin
48 key_col_ff0<=4'hf;
49 key_col_ff1<=4'hf;
50 end
51 else begin
52 key_col_ff0<=key_col;
53 key_col_ff1<=key_col_ff0;
54 end
55 end
56
57 always @(posedge clk or negedge rst_n)begin
58 if(rst_n==1'b0)begin
59 cnt_phase<=0;
60 end
61 else if(add_cnt_phase)begin
62 if(end_cnt_phase)
63 cnt_phase<=0;
64 else
65 cnt_phase<=cnt_phase+1;
66 end
67 end
68 assign add_cnt_phase=end_cnt_20ms||end_row_index||delay_over||key_up;
69 assign end_cnt_phase=add_cnt_phase&&cnt_phase==4-1;
70 assign delay_over=end_cnt_8clks&&cnt_phase==3-1;
71 assign key_up=cnt_phase==4-1&&key_col_ff1==4'hf;
72
73
74 always @(posedge clk or negedge rst_n)begin
75 if(rst_n==1'b0)begin
76 cnt_20ms<=0;
77 end
78 else if(add_cnt_20ms)begin
79 if(end_cnt_20ms)
80 cnt_20ms<=0;
81 else
82 cnt_20ms<=cnt_20ms+1;
83 end
84 else
85 cnt_20ms<=0;
86 end
87 assign add_cnt_20ms=key_col_ff1!=4'hf&&cnt_phase==0;
88 assign end_cnt_20ms=add_cnt_20ms&&cnt_20ms==TIME_20MS-1;
89
90
91 always @(posedge clk or negedge rst_n)begin
92 if(rst_n==1'b0)begin
93 cnt_8clks<=0;
94 end
95 else if(add_cnt_8clks)begin
96 if(end_cnt_8clks)
97 cnt_8clks<=0;
98 else
99 cnt_8clks<=cnt_8clks+1;
100 end
101 end
102
103 assign add_cnt_8clks=cnt_phase==2-1||cnt_phase==3-1;
104 assign end_cnt_8clks=add_cnt_8clks&&cnt_8clks==8-1;
105
106 always @(posedge clk or negedge rst_n)begin
107 if(rst_n==1'b0)begin
108 row_index<=0;
109 end
110 else if(add_row_index)begin
111 if(end_row_index)
112 row_index<=0;
113 else
114 row_index<=row_index+1;
115 end
116 end
117 assign add_row_index=end_cnt_8clks&&cnt_phase==2-1;
118 assign end_row_index=add_row_index&&row_index==4-1;
119
120
121 always @(posedge clk or negedge rst_n)begin
122 if(rst_n==1'b0)begin
123 key_row<=4'b0000;
124 end
125 else if(cnt_phase==1)begin
126 key_row<=~(1<<row_index);
127 end
128 else
129 key_row<=4'b0000;
130 end
131
132 always @(posedge clk or negedge rst_n)begin
133 if(rst_n==1'b0)begin
134 key_out <= 0;
135 end
136 else if(possible_vld)begin
137 key_out <= {row_index,key_col_get};
138 end
139 else begin
140 key_out <= 0;
141 end
142 end
143
144 assign possible_vld=cnt_phase==1 && end_cnt_8clks;
145
146
147 always @(posedge clk or negedge rst_n)begin
148 if(rst_n==1'b0)begin
149 key_col_get <= 0;
150 end
151 else if(end_cnt_20ms) begin
152 if(key_col_ff1==4'b1110)
153 key_col_get <= 0;
154 else if(key_col_ff1==4'b1101)
155 key_col_get <= 1;
156 else if(key_col_ff1==4'b1011)
157 key_col_get <= 2;
158 else
159 key_col_get <= 3;
160 end
161 end
162
163 always @(posedge clk or negedge rst_n)begin
164 if(rst_n==1'b0)begin
165 key_vld <= 1'b0;
166 end
167 else if(vld)begin
168 key_vld <= 1'b1;
169 end
170 else begin
171 key_vld <= 1'b0;
172 end
173 end
174
175
176 assign vld=possible_vld && key_col_ff1[key_col_get]==1'b0;
177
178 endmodule
179
180
181
182
时钟计数模块
2 clk ,
3 rst_n ,
4
5 key_num ,
6 key_vld ,
7
8 dout ,
9 dout_vld
10 );
11
12 parameter DATA_W = 4 ;
13 parameter TIME_1S = 50_000_000 ;
14
15 input clk ;
16 input rst_n ;
17 input [3:0] key_num ;
18 input key_vld ;
19
20 output [23:0] dout ;
21 output dout_vld ;
22 reg dout_vld ;
23 reg pause_flag ;
24
25 reg [3:0] x ;
26 reg [3:0] y ;
27 reg [3:0] miao_g ;
28 reg [3:0] miao_s ;
29 reg [3:0] fen_g ;
30 reg [3:0] fen_s ;
31 reg [3:0] shi_g ;
32 reg [3:0] shi_s ;
33 reg [2:0] cnt_key2 ;
34
35 wire [23:0] dout ;
36 wire add_cnt_key2 ;
37 wire end_cnt_key2 ;
38 wire add_cnt ;
39 wire end_cnt ;
40 wire add_miao_g ;
41 wire end_miao_g ;
42 wire press_key3 ;
43 wire add_miao_s ;
44 wire end_miao_s ;
45 wire add_fen_g ;
46 wire end_fen_g ;
47
48 wire add_fen_s ;
49 wire end_fen_s ;
50 wire add_shi_g ;
51 wire end_shi_g ;
52 wire add_shi_s ;
53 wire end_shi_s ;
54
55 wire key_add_fen_g ;
56 wire key_add_miao_s ;
57 wire key_add_shi_g ;
58 wire key_add_fen_s ;
59 wire key_add_miao_g ;
60 wire key_add_shi_s ;
61
62
63
64 always @(posedge clk or negedge rst_n)begin
65 if(rst_n==1'b0)begin
66 pause_flag<=0;
67 end
68 else if(key_vld&&key_num==1)begin
69 if(pause_flag)
70 pause_flag<=0;
71 else
72 pause_flag<=1;
73 end
74 end
75
76
77 always @(posedge clk or negedge rst_n)begin
78 if(rst_n==1'b0)begin
79 cnt_key2<=0;
80 end
81 else if(add_cnt_key2)begin
82 if(end_cnt_key2)
83 cnt_key2<=0;
84 else
85 cnt_key2<=cnt_key2+1;
86 end
87 else if(pause_flag==0)
88 cnt_key2<=0;
89 end
90
91 assign add_cnt_key2=key_vld&&key_num==2&&pause_flag==1;
92 assign end_cnt_key2=add_cnt_key2&&cnt_key2==6-1;
93
94
95 reg [25:0] cnt;
96
97 always @(posedge clk or negedge rst_n)begin
98 if(rst_n==1'b0)begin
99 cnt<=0;
100 end
101 else if(add_cnt)begin
102 if(end_cnt)
103 cnt<=0;
104 else
105 cnt<=cnt+1;
106 end
107 end
108
109 assign add_cnt=pause_flag==0;
110 assign end_cnt=add_cnt&&cnt==TIME_1S-1;
111
112
113 always @(posedge clk or negedge rst_n)begin
114 if(rst_n==1'b0)begin
115 miao_g<=0;
116 end
117 else if(add_miao_g)begin
118 if(end_miao_g)
119 miao_g<=0;
120 else
121 miao_g<=miao_g+1;
122 end
123
124 end
125
126 assign add_miao_g=end_cnt||key_add_miao_g;
127 assign end_miao_g=add_miao_g&&miao_g==10-1;
128 assign key_add_miao_g=press_key3&&cnt_key2==0;
129
130
131 assign press_key3=pause_flag==1&&key_vld&&key_num==3;
132
133
134 always @(posedge clk or negedge rst_n)begin
135 if(rst_n==1'b0)begin
136 miao_s<=0;
137 end
138 else if(add_miao_s)begin
139 if(end_miao_s)
140 miao_s<=0;
141 else
142 miao_s<=miao_s+1;
143 end
144
145 end
146
147 assign add_miao_s=end_miao_g||key_add_miao_s;
148 assign end_miao_s=add_miao_s&&miao_s==6-1;
149
150 assign key_add_miao_s=cnt_key2==1&&press_key3;
151
152
153 always @(posedge clk or negedge rst_n)begin
154 if(rst_n==1'b0)begin
155 fen_g<=0;
156 end
157 else if(add_fen_g)begin
158 if(end_fen_g)
159 fen_g<=0;
160 else
161 fen_g<=fen_g+1;
162 end
163
164 end
165
166 assign add_fen_g=end_miao_s||key_add_fen_g;
167 assign end_fen_g=add_fen_g&&fen_g==10-1;
168
169 assign key_add_fen_g=cnt_key2==2&&press_key3;
170
171 always @(posedge clk or negedge rst_n)begin
172 if(rst_n==1'b0)begin
173 fen_s<=0;
174 end
175 else if(add_fen_s)begin
176 if(end_fen_s)
177 fen_s<=0;
178 else
179 fen_s<=fen_s+1;
180 end
181 end
182
183 assign add_fen_s=end_fen_g||(key_add_fen_s);
184 assign end_fen_s=add_fen_s&&fen_s==6-1;
185
186
187 assign key_add_fen_s=cnt_key2==3&&press_key3;
188
189
190 always @(posedge clk or negedge rst_n)begin
191 if(rst_n==1'b0)begin
192 shi_g<=0;
193 end
194 else if(add_shi_g)begin
195 if(end_shi_g)
196 shi_g<=0;
197 else
198 shi_g<=shi_g+1;
199 end
200
201 end
202
203 assign add_shi_g=end_fen_s ||key_add_shi_g;
204 assign end_shi_g=add_shi_g&& shi_g ==x -1;
205
206
207 always@(*)
208 if(shi_s==2)
209 x = 4;
210 else
211 x = 10;
212
213 assign key_add_shi_g=cnt_key2==4&&press_key3;
214
215
216 always @(posedge clk or negedge rst_n)begin
217 if(rst_n==1'b0)begin
218 shi_s<=0;
219 end
220 else if(add_shi_s)begin
221 if(end_shi_s)
222 shi_s<=0;
223 else
224 shi_s<=shi_s+1;
225 end
226 end
227
228 assign add_shi_s=end_shi_g|| key_add_shi_s;
229 assign end_shi_s=add_shi_s && shi_s==y-1;
230
231 assign key_add_shi_s=cnt_key2==5&&press_key3;
232
233 always @(*)begin
234 if(shi_g>=4)
235 y = 2;
236 else
237 y = 3;
238 end
239
240
241 assign dout = {shi_s,shi_g,fen_s,fen_g,miao_s,miao_g};
242
243 always @(posedge clk or negedge rst_n)begin
244 if(rst_n==1'b0)begin
245 dout_vld<=0;
246 end
247 else if(end_cnt)begin
248 dout_vld<=1;
249 end
250 else
251 dout_vld<=0;
252 end
253
254
255 endmodule
256
闹钟设定模块
2 clk ,
3 rst_n ,
4 time_now ,
5 time_now_vld,
6 key_num ,
7 key_vld ,
8 set_group ,
9 setting ,
10 bell
11 );
12
13 parameter TIME_1S=50000000 ;
14
15 input clk ;
16 input rst_n ;
17 input [23:0] time_now ;
18 input time_now_vld ;
19 input [3:0] key_num ;
20 input key_vld ;
21
22
23 output bell ;
24 output set_group ;
25 output setting ;
26
27
28 reg bell ;
29 reg [3:0] key_num_ff0 ;
30 wire equal_flag ;
31 reg [23:0] set_group ;
32 reg setting ;
33 wire start_set ;
34 wire end_set ;
35
36
37 wire add_cnt_1s ;
38 wire end_cnt_1s ;
39 wire add_cnt_5s ;
40 wire end_cnt_5s ;
41 reg [2:0] cnt_5s ;
42 reg [25:0] cnt_1s ;
43 reg [2:0] cnt_key13 ;
44 wire add_cnt_key13 ;
45 wire end_cnt_key13 ;
46 reg set_alarm_vld ;
47 wire value_0_9 ;
48 wire value_0_5 ;
49 wire value_0_2 ;
50 wire value_0_1 ;
51 wire value_0_3 ;
52
53 always @(posedge clk or negedge rst_n)begin
54 if(rst_n==1'b0)begin
55 bell<=1;
56 end
57 else if(equal_flag)begin
58 bell<=0;
59 end
60 else if(end_cnt_5s)
61 bell<=1;
62 end
63
64
65 always @(posedge clk or negedge rst_n)begin
66 if(rst_n==1'b0)begin
67 cnt_1s<=23'b0;
68 end
69 else if(add_cnt_1s)begin
70 if(end_cnt_1s)
71 cnt_1s<=23'b0;
72 else
73 cnt_1s<=cnt_1s+1'b1;
74 end
75 end
76 assign add_cnt_1s=bell==0;
77 assign end_cnt_1s=add_cnt_1s&&cnt_1s==TIME_1S-1;
78
79 always @(posedge clk or negedge rst_n)begin
80 if(rst_n==1'b0)begin
81 cnt_5s<=0;
82 end
83 else if(add_cnt_5s)begin
84 if(end_cnt_5s)
85 cnt_5s<=0;
86 else
87 cnt_5s<=cnt_5s+1;
88 end
89 end
90
91 assign add_cnt_5s=end_cnt_1s;
92 assign end_cnt_5s=add_cnt_5s&&cnt_5s==5-1;
93
94
95 assign equal_flag=(set_group==time_now)&&time_now_vld;
96
97
98 always @(posedge clk or negedge rst_n)begin
99 if(rst_n==1'b0)begin
100 cnt_key13<=0;
101 end
102 else if(add_cnt_key13)begin
103 if(end_cnt_key13)
104 cnt_key13<=0;
105 else
106 cnt_key13<=cnt_key13+1;
107 end
108 else if(end_set)
109 cnt_key13<=0;
110 end
111
112 assign add_cnt_key13=setting&&key_vld&&key_num==13;
113 assign end_cnt_key13=add_cnt_key13&&cnt_key13==6-1;
114
115 always @(posedge clk or negedge rst_n)begin
116 if(rst_n==1'b0)begin
117 set_group<=24'h000009;
118 end
119 else if(set_alarm_vld)begin
120 if(cnt_key13==0)
121 set_group[3:0]<=key_num_ff0;
122 else if(cnt_key13==1)
123 set_group[7:4]<=key_num_ff0;
124 else if(cnt_key13==2)
125 set_group[11:8]<=key_num_ff0;
126 else if(cnt_key13==3)
127 set_group[15:12]<=key_num_ff0;
128 else if(cnt_key13==4)
129 set_group[19:16]<=key_num_ff0;
130 else if(cnt_key13==5)
131 set_group[23:20]<=key_num_ff0;
132 end
133 end
134
135
136 assign value_0_9=key_vld&&(0<=key_num&&key_num<10);
137 assign value_0_5=key_vld&&(0<=key_num&&key_num<6);
138 assign value_0_2=key_vld&&(0<=key_num&&key_num<3);
139 assign value_0_3=key_vld&&(0<=key_num&&key_num<4);
140 assign value_0_1=key_vld&&(0<=key_num&&key_num<2);
141
142 always @(posedge clk or negedge rst_n)begin
143 if(rst_n==1'b0)begin
144 set_alarm_vld<=0;
145 end
146 else if(key_vld&&setting)begin
147 if(cnt_key13==0)begin
148 if(value_0_9)
149 set_alarm_vld<=1;
150 else
151 set_alarm_vld<=0;
152 end
153 else if(cnt_key13==1)begin
154 if(value_0_5)
155 set_alarm_vld<=1;
156 else
157 set_alarm_vld<=0;
158 end
159 else if(cnt_key13==2)begin
160 if(value_0_9)
161 set_alarm_vld<=1;
162 else
163 set_alarm_vld<=0;
164 end
165 else if(cnt_key13==3)begin
166 if(value_0_5)
167 set_alarm_vld<=1;
168 else
169 set_alarm_vld<=0;
170 end
171 else if(cnt_key13==4)begin
172 if(set_group[23:20]==2)begin
173 if(value_0_3)
174 set_alarm_vld<=1;
175 else
176 set_alarm_vld<=0;
177 end
178 else if(value_0_9)
179 set_alarm_vld<=1;
180 else
181 set_alarm_vld<=0;
182 end
183 else if(cnt_key13==5)begin
184 if(0<=set_group[19:16]&&set_group[19:16]<4)begin
185 if(value_0_2)
186 set_alarm_vld<=1;
187 else
188 set_alarm_vld<=0;
189 end
190 else if(value_0_1)
191 set_alarm_vld<=1;
192 else
193 set_alarm_vld<=0;
194 end
195 end
196 else
197 set_alarm_vld<=0;
198 end
199
200 always @(posedge clk or negedge rst_n)begin
201 if(rst_n==1'b0)begin
202 key_num_ff0<=0;
203 end
204 else
205 key_num_ff0<=key_num;
206 end
207
208 always @(posedge clk or negedge rst_n)begin
209 if(rst_n==1'b0)begin
210 setting<=0;
211 end
212 else if(start_set)begin
213 setting<=1;
214 end
215 else if(end_set)begin
216 setting<=0;
217 end
218 end
219
220 assign start_set=key_vld&&key_num==14;
221 assign end_set =key_vld&&key_num==15;
222
223 endmodule
224