官方论坛
官方淘宝
官方博客
微信公众号
点击联系吴工 点击联系周老师

【案例】fpga闹钟设计

发布时间:2021-06-24   作者:admin 浏览量:

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

数码管段选信号

 

在轮流显示过程中,每位数码管的点亮时间为12ms,由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感

 

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   程序设计

工程模块

 1 module timer_top(
 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       


数码管显示模块

  1 module  seg_disp(
  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


矩阵键盘模块

  1 module key_scan(
  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     


时钟计数模块

  1 module timer_data(
  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       


闹钟设定模块

  1 module match_bell(
  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       

上一篇:没有了
   拓展阅读