1功能(néng)概述
鬧鐘(zhōng)是(shì)一(yī)種(zhǒng)既能(néng)顯示时(shí)間(jiān),又能(néng)根(gēn)據(jù)人(rén)们(men)設定(dìng)的(de)时(shí)間(jiān),發(fà)出(chū)鈴聲、乐(lè)曲(qū)等提(tí)醒信(xìn)号(hào)的(de)計(jì)时(shí)工具。現(xiàn)在(zài),鬧鐘(zhōng)幾(jǐ)乎已經(jīng)是(shì)上(shàng)学、上(shàng)班族必不(bù)可(kě)少(shǎo)的(de)一(yī)个(gè)工具,主(zhǔ)要(yào)應(yìng)用(yòng)在(zài)電(diàn)腦、手(shǒu)機(jī)、電(diàn)子表(biǎo)等方(fāng)面(miàn)。在(zài)20小节(jié)數字(zì)时(shí)鐘(zhōng)里(lǐ)我(wǒ)们(men)介紹过(guò),與(yǔ)傳統機(jī)械式計(jì)时(shí)工具相比,數字(zì)計(jì)时(shí)系(xì)統具備體(tǐ)積小、重(zhòng)量(liàng)輕(qīng)、抗干(gàn)擾能(néng)力強(qiáng)、对(duì)环(huán)境要(yào)求高(gāo)、高(gāo)精确性(xìng)、容易開(kāi)發(fà)等特(tè)征。數字(zì)計(jì)时(shí)間(jiān)高(gāo)精度(dù)的(de)特(tè)征,在(zài)鬧鐘(zhōng)功能(néng)上(shàng)的(de)應(yìng)用(yòng)优勢更(gèng)为(wèi)突出(chū)。
科学地(dì)劃(huà)分(fēn)模块(kuài),充分(fēn)理順模块(kuài)間(jiān)的(de)相互關(guān)系(xì)对(duì)于(yú)FPGA設計(jì)来(lái)说(shuō)非(fēi)常重(zhòng)要(yào)。以(yǐ)鬧鐘(zhōng)設計(jì)为(wèi)例,我(wǒ)们(men)通(tòng)过(guò)建立四(sì)个(gè)清(qīng)晰直(zhí)观的(de)模块(kuài)(數碼管(guǎn)顯示模块(kuài),矩阵(zhèn)鍵盤掃描模块(kuài),时(shí)鐘(zhōng)計(jì)數模块(kuài),鬧鐘(zhōng)設定(dìng)模块(kuài)),以(yǐ)及(jí)建立完善的(de)信(xìn)号(hào)列表(biǎo)和(hé)運用(yòng)verilog語(yǔ)言編写簡潔流暢的(de)代(dài)碼,实現(xiàn)電(diàn)子鬧鐘(zhōng)时(shí)、分(fēn)、秒(miǎo)計(jì)时(shí)以(yǐ)及(jí)設置、修改、重(zhòng)置等功能(néng)。
具體(tǐ)功能(néng)要(yào)求如(rú)下(xià):
本(běn)工程包(bāo)括矩阵(zhèn)鍵盤和(hé)數碼管(guǎn)顯示模块(kuài),共(gòng)同(tóng)实現(xiàn)一(yī)个(gè)带(dài)有(yǒu)鬧鐘(zhōng)功能(néng)、可(kě)設置时(shí)間(jiān)的(de)數字(zì)时(shí)鐘(zhōng)。具體(tǐ)功能(néng)如(rú)下(xià):
1. 數碼管(guǎn)可(kě)以(yǐ)顯示时(shí)十(shí)位、时(shí)个(gè)位、分(fēn)十(shí)位、分(fēn)个(gè)位、秒(miǎo)十(shí)位、秒(miǎo)个(gè)位。
2. 上(shàng)電(diàn)後(hòu),數碼管(guǎn)顯示000000,并開(kāi)始每秒(miǎo)計(jì)时(shí)。
3. 按下(xià)按鍵1進(jìn)入(rù)时(shí)間(jiān)設置狀态。再按下(xià)按鍵1退(tuì)出(chū)时(shí)間(jiān)設置狀态,繼續計(jì)时(shí)。
4. 在(zài)时(shí)間(jiān)設置狀态,通(tòng)过(guò)按鍵2来(lái)選擇設置的(de)时(shí)間(jiān)位,在(zài)0~5之間(jiān)循环(huán)選擇。
5. 在(zài)时(shí)間(jiān)設置狀态,通(tòng)过(guò)按鍵3来(lái)对(duì)當前(qián)選擇的(de)时(shí)間(jiān)位進(jìn)行加1。
6. 在(zài)計(jì)时(shí)狀态下(xià),按下(xià)按鍵14,進(jìn)入(rù)鬧鐘(zhōng)时(shí)間(jiān)點(diǎn)設置狀态;再按下(xià)按健15,退(tuì)出(chū)鬧鐘(zhōng)設置狀态。
7. 在(zài)鬧鐘(zhōng)設置狀态,按下(xià)按鍵13選擇設置的(de)时(shí)間(jiān)位,此(cǐ)时(shí)可(kě)以(yǐ)按下(xià)所(suǒ)需要(yào)的(de)按鍵序号(hào)設置对(duì)應(yìng)鬧鐘(zhōng)时(shí)間(jiān)。
8. 當前(qián)时(shí)間(jiān)與(yǔ)所(suǒ)設置的(de)时(shí)間(jiān)點(diǎn)匹(pǐ)配上(shàng)了(le),蜂鳴器響應(yìng)5 s。
2 設計(jì)思(sī)路(lù)
我(wǒ)们(men)把工程分(fēn)成(chéng)四(sì)个(gè)模块(kuài),分(fēn)别是(shì)數碼管(guǎn)顯示模块(kuài),矩阵(zhèn)鍵盤掃描模块(kuài),时(shí)鐘(zhōng)計(jì)數模块(kuài),鬧鐘(zhōng)設定(dìng)模块(kuài)。
工程頂层模块(kuài)的(de)信(xìn)号(hào)列表(biǎo)
|
信(xìn)号(hào)名 |
I/O |
位宽(kuān) |
说(shuō)明(míng) |
|
clk |
I |
1 |
系(xì)統工作时(shí)鐘(zhōng)50MHz。 |
|
rst_n |
I |
1 |
系(xì)統複位信(xìn)号(hào),低電(diàn)平有(yǒu)效。 |
|
key_col |
I |
4 |
矩阵(zhèn)鍵盤按鍵列信(xìn)号(hào) |
|
key_row |
O |
4 |
矩阵(zhèn)鍵盤按鍵行信(xìn)号(hào) |
|
bell |
O |
1 |
蜂鳴器控制信(xìn)号(hào) |
1.數碼管(guǎn)顯示模块(kuài)——实現(xiàn)将时(shí)鐘(zhōng)數據(jù)或(huò)者(zhě)鬧鐘(zhōng)數據(jù)顯示到(dào)七(qī)段(duàn)譯碼器上(shàng)的(de)功能(néng)。
七(qī)段(duàn)譯碼器引脚图(tú):
根(gēn)據(jù)七(qī)段(duàn)譯碼器的(de)型号(hào)共(gòng)陰极(jí)或(huò)者(zhě)共(gòng)陽极(jí),給(gěi)予信(xìn)号(hào)0點(diǎn)亮(liàng)对(duì)應(yìng)的(de)led燈(dēng);一(yī)个(gè)八(bā)段(duàn)數碼管(guǎn)稱为(wèi)一(yī)位,多(duō)个(gè)數碼管(guǎn)并列在(zài)一(yī)起可(kě)構成(chéng)多(duō)位數碼管(guǎn),它(tā)们(men)的(de)段(duàn)選(a,b,c,d,e,f,g,dp)連(lián)在(zài)一(yī)起,而(ér)各(gè)自(zì)的(de)公共(gòng)端稱为(wèi)位選線(xiàn)。顯示时(shí),都從段(duàn)選線(xiàn)送入(rù)字(zì)符編碼,而(ér)選中(zhōng)哪个(gè)位選線(xiàn),那(nà)个(gè)數碼管(guǎn)便会(huì)被(bèi)點(diǎn)亮(liàng)。例如(rú),如(rú)果(guǒ)數碼管(guǎn)顯示數字(zì)0,那(nà)麼(me)共(gòng)陰數碼管(guǎn)的(de)字(zì)符編碼为(wèi)00111111,即共(gòng)陽數碼管(guǎn)的(de)字(zì)符編碼为(wèi)11000000。
信(xìn)号(hào)列表(biǎo)如(rú)下(xià):
|
信(xìn)号(hào)名 |
I/O |
位宽(kuān) |
说(shuō)明(míng) |
|
clk |
I |
1 |
系(xì)統工作时(shí)鐘(zhōng)50MHz。 |
|
rst_n |
I |
1 |
系(xì)統複位信(xìn)号(hào),低電(diàn)平有(yǒu)效。 |
|
din |
I |
32 |
每个(gè)數碼管(guǎn)的(de)时(shí)間(jiān)數據(jù) |
|
seg_sel |
O |
8 |
數碼管(guǎn)位選信(xìn)号(hào) |
|
seg_ment |
O |
8 |
數碼管(guǎn)段(duàn)選信(xìn)号(hào) |
在(zài)轮流顯示过(guò)程中(zhōng),每位數碼管(guǎn)的(de)點(diǎn)亮(liàng)时(shí)間(jiān)为(wèi)1~2ms,由(yóu)于(yú)人(rén)的(de)視覺暫留現(xiàn)象(xiàng)及(jí)發(fà)光(guāng)二(èr)极(jí)管(guǎn)的(de)餘輝效應(yìng),盡管(guǎn)实際上(shàng)各(gè)位數碼管(guǎn)并非(fēi)同(tóng)时(shí)點(diǎn)亮(liàng),但只(zhī)要(yào)掃描的(de)速度(dù)足够快(kuài),給(gěi)人(rén)的(de)印(yìn)象(xiàng)就(jiù)是(shì)一(yī)組稳定(dìng)的(de)顯示數據(jù),不(bù)会(huì)有(yǒu)閃爍感(gǎn)。
2.矩阵(zhèn)鍵盤掃描模块(kuài)——4x4矩阵(zhèn)鍵盤,实現(xiàn)了(le)矩阵(zhèn)鍵盤的(de)掃描并使用(yòng)以(yǐ)及(jí)按鍵消抖功能(néng)。通(tòng)过(guò)行掃描法得到(dào)按下(xià)的(de)鍵的(de)位置信(xìn)息。
信(xìn)号(hào)列表(biǎo)如(rú)下(xià):
|
信(xìn)号(hào)名 |
I/O |
位宽(kuān) |
说(shuō)明(míng) |
|
clk |
I |
1 |
系(xì)統工作时(shí)鐘(zhōng)50MHz。 |
|
rst_n |
I |
1 |
系(xì)統複位信(xìn)号(hào),低電(diàn)平有(yǒu)效。 |
|
key_col |
I |
4 |
矩阵(zhèn)鍵盤列信(xìn)号(hào) |
|
key_row |
O |
4 |
矩阵(zhèn)鍵盤行信(xìn)号(hào) |
|
key_out |
O |
4 |
按鍵位置信(xìn)号(hào) |
|
key_vld |
O |
1 |
按鍵有(yǒu)效信(xìn)号(hào) |
3.时(shí)鐘(zhōng)計(jì)數模块(kuài)——按下(xià)按鍵1則進(jìn)入(rù)时(shí)鐘(zhōng)數字(zì)調节(jié)界面(miàn),此(cǐ)时(shí)利用(yòng)按鍵2来(lái)位選,按鍵3来(lái)調节(jié)數字(zì),按一(yī)次(cì)按鍵3則加1,再次(cì)按下(xià)按鍵1則恢複計(jì)數。
信(xìn)号(hào)列表(biǎo)如(rú)下(xià):
|
信(xìn)号(hào)名 |
I/O |
位宽(kuān) |
说(shuō)明(míng) |
|
clk |
I |
1 |
系(xì)統工作时(shí)鐘(zhōng)50MHz。 |
|
rst_n |
I |
1 |
系(xì)統複位信(xìn)号(hào),低電(diàn)平有(yǒu)效。 |
|
key_num |
I |
4 |
輸入(rù)按鍵值 |
|
key_vld |
I |
1 |
按鍵輸入(rù)有(yǒu)效指示 |
|
dout |
O |
24 |
时(shí)鐘(zhōng)數據(jù)輸出(chū) |
|
dout_vld |
O |
24 |
时(shí)鐘(zhōng)數據(jù)輸出(chū)有(yǒu)效 |
4.鬧鐘(zhōng)設定(dìng)模块(kuài)——实現(xiàn)設定(dìng)鬧鐘(zhōng)时(shí)間(jiān)功能(néng),按下(xià)按鍵14則進(jìn)入(rù)鬧鐘(zhōng)时(shí)間(jiān)設定(dìng)界面(miàn),并利用(yòng)按鍵13来(lái)進(jìn)行位選;然後(hòu)按下(xià)对(duì)應(yìng)的(de)按鍵則設定(dìng)对(duì)應(yìng)的(de)數字(zì);按下(xià)按鍵15則退(tuì)出(chū)鬧鐘(zhōng)設定(dìng)界面(miàn)。當时(shí)鐘(zhōng)數據(jù)和(hé)鬧鐘(zhōng)數據(jù)相同(tóng)时(shí),也(yě)就(jiù)是(shì)到(dào)达(dá)設定(dìng)时(shí)間(jiān)时(shí),蜂鳴器響5s。
信(xìn)号(hào)列表(biǎo)如(rú)下(xià):
|
信(xìn)号(hào)名 |
I/O |
位宽(kuān) |
说(shuō)明(míng) |
|
clk |
I |
1 |
系(xì)統工作时(shí)鐘(zhōng)50MHz。 |
|
rst_n |
I |
1 |
系(xì)統複位信(xìn)号(hào),低電(diàn)平有(yǒu)效。 |
|
time_now |
I |
24 |
當前(qián)輸入(rù)时(shí)間(jiān) |
|
time_now_vld |
I |
1 |
當前(qián)輸入(rù)时(shí)間(jiān)有(yǒu)效 |
|
key_num |
I |
4 |
輸入(rù)按鍵值 |
|
key_vld |
I |
1 |
按鍵輸入(rù)有(yǒu)效指示 |
|
set_group |
O |
24 |
設置鬧鐘(zhōng)时(shí)間(jiān)點(diǎn) |
|
setting |
O |
1 |
設置狀态标(biāo)志 |
|
bell |
O |
1 |
蜂鳴器控制信(xìn)号(hào) |
3 程序設計(jì)
工程模块(kuài)
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
數碼管(guǎn)顯示模块(kuài)
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
矩阵(zhèn)鍵盤模块(kuài)
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
时(shí)鐘(zhōng)計(jì)數模块(kuài)
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
鬧鐘(zhōng)設定(dìng)模块(kuài)
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

















