新闻  |   论坛  |   博客  |   在线研讨会
fpga闹钟程序_fpga时钟模块应用_明德扬资料
billow兔 | 2017-08-03 09:17:18    阅读:524   发布文章

 

闹钟

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.数码管显示模块——实现将时钟数据或者闹钟数据显示到七段译码器上的功能。

七段译码器引脚图:

说明: W(YPUS~@YEI81`}N[U}HI3C

根据七段译码器的型号共阴极或者共阳极,给予信号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   程序设计

工程模块

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

module timer_top(

clk      ,

rst_n    ,

key_col  ,

key_row  ,

seg_ment ,

seg_sel   ,

bell

);

 

parameter SEG_NUM   =        6       ;

parameter TIME_1S    =    50000000    ;

parameter TIME_20MS =   1000000       ;

 

input                  clk           ;

input                  rst_n         ;

 

output        [3:0]       key_row       ;

output        [7:0]       seg_ment      ;

output        [5:0]       seg_sel        ;

input         [3:0]       key_col        ;

output                 bell             ;

 

wire          [3:0]       key_num      ;

wire                   key_vld       ;

wire          [23:0]      time_now      ;

wire          [23:0]      time_display    ;

wire                   time_now_vld   ;

wire                   setting         ;

wire          [23:0]      set_group      ;

 

 

timer_data    #(.TIME_1S(TIME_1S))timer_data_inst(

.clk(clk)  ,

.rst_n(rst_n) ,

.dout(time_now),

.dout_vld(time_now_vld),

.key_num(key_num)  ,

.key_vld(key_vld)

);

 

 

key_scan    #(.TIME_20MS(TIME_20MS))key_scan_inst(

.clk(clk),

.rst_n(rst_n),

.key_col(key_col) ,

.key_row(key_row),

.key_out(key_num) ,

.key_vld(key_vld)

);

 

 

match_bell    #(.TIME_1S(TIME_1S))match_bell_inst(

.clk(clk)      ,

.rst_n(rst_n),

.time_now(time_now)       ,

.time_now_vld(time_now_vld),

.key_num(key_num)  ,

.key_vld(key_vld)      ,

.setting(setting)   ,

.set_group(set_group) ,

.bell(bell)

);

 

 

seg_disp #(.SEG_NUM(SEG_NUM))seg_display_inst(

.clk (clk),

.rst_n (rst_n),

.din(time_display),

.segment(seg_ment),

.seg_sel(seg_sel)

 

);

assign time_display=setting?set_group:time_now ;

endmodule

 

数码管显示模块

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

module  seg_disp(

                 rst_n       ,

                 clk         ,

                 din         ,

                 seg_sel     ,

                 segment     

             );

 

        parameter  SEG_WID        =       8                               ;

        parameter  SEG_NUM       =         8                       ;

        parameter  CNT_WID          =        10                      ;

        parameter  TIME_20US      =         10'd1000         ;

 

        parameter  NUM_0          =       8'b1100_0000;

        parameter  NUM_1          =       8'b1111_1001;

        parameter  NUM_2          =       8'b1010_0100;

        parameter  NUM_3          =       8'b1011_0000;

        parameter  NUM_4          =       8'b1001_1001;

        parameter  NUM_5          =       8'b1001_0010;

        parameter  NUM_6            =       8'b1000_0010;

        parameter  NUM_7          =       8'b1111_1000;

        parameter  NUM_8          =       8'b1000_0000;

        parameter  NUM_9          =       8'b1001_0000;

        parameter  NUM_ERR       =         8'b1111_1111;

 

        input                             clk                ;

        input                             rst_n             ;

        input    [SEG_NUM*4-1:0]           din                      ;

        output [SEG_NUM - 1:0]            seg_sel          ;

        output [SEG_WID - 1:0]            segment          ;

 

        reg      [SEG_NUM - 1:0]              seg_sel         ;

        reg      [SEG_WID - 1:0]              segment               ;

 

        reg      [CNT_WID - 1:0]             cnt_20us         ;

        reg      [SEG_NUM - 1:0]              sel_cnt         ;

        reg      [        4-1:0]            seg_tmp          ;

 

        wire                             add_cnt_20us    ;

        wire                          end_cnt_20us      ;

        wire                          add_sel_cnt          ;

        wire                          end_sel_cnt          ;

 

       always  @(posedge clk or negedge   rst_n)begin

         if(rst_n==1'b0)begin

             cnt_20us <= 0;

         end

         else if(add_cnt_20us)begin

             if(end_cnt_20us)

                 cnt_20us <= 0;

             else

                 cnt_20us <= cnt_20us + 1;

         end

       end

       assign add_cnt_20us = 1;

       assign end_cnt_20us = add_cnt_20us && cnt_20us == TIME_20US-1;

      

      

       always  @(posedge clk or negedge   rst_n)begin

         if(rst_n==1'b0)begin

             sel_cnt <= 0;

         end

         else if(add_sel_cnt)begin

             if(end_sel_cnt)

                 sel_cnt <= 0;

             else

                 sel_cnt <= sel_cnt + 1;

         end

       end

       assign add_sel_cnt = end_cnt_20us;

       assign end_sel_cnt = add_sel_cnt && sel_cnt == SEG_NUM-1;

      

       always  @(posedge clk or negedge   rst_n)begin

         if(rst_n==1'b0)begin

             seg_sel <= {SEG_NUM{1'b1}};

         end

         else begin

             seg_sel <= ~(1'b1 <<   sel_cnt);

         end

       end

      

       always  @(*)begin

         seg_tmp = din[(sel_cnt+1)*4-1 -:4];

       end

      

       always@(posedge clk or negedge rst_n)begin

         if(rst_n==1'b0)begin

             segment<=NUM_0;

         end

         else    begin

             case (seg_tmp)

                 0 : segment <= NUM_0;

                 1 : segment <= NUM_1;

                 2 : segment <= NUM_2;

                 3 : segment <= NUM_3;

                 4 : segment <= NUM_4;

                 5 : segment <= NUM_5;

                 6 : segment <= NUM_6;

                 7 : segment <= NUM_7;

                 8 : segment <= NUM_8;

                 9 : segment <= NUM_9;

                 default : segment <=   NUM_ERR;

             endcase

         end

       end

endmodule

 

矩阵键盘模块

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

module key_scan(

                clk          ,

                rst_n        ,

                key_col      ,

                key_row      ,

                key_out      ,

                key_vld

         );

 

         parameter      TIME_20MS=1000_000    ;

 

         input                   clk           ;

         input                     rst_n          ;

         input       [3:0]        key_col          ;

 

         output      [3:0]        key_row         ;

         output      [3:0]        key_out        ;

         output                    key_vld        ;

 

         reg         [3:0]        key_out          ;

         reg                       key_vld        ;

 

         wire                      add_cnt_8clks   ;

         wire                      end_cnt_8clks   ;

         wire                      delay_over      ;

         wire                      add_row_index  ;

         wire                      end_row_index  ;

         wire                    vld            ;

         wire                      key_up        ;

         wire                      add_cnt_20ms  ;

         wire                      end_cnt_20ms  ;

         wire                      add_cnt_phase  ;

         wire                      end_cnt_phase  ;

         wire                      possible_vld    ;

 

 

         reg         [2:0]       cnt_8clks        ;

         reg         [3:0]       key_col_ff0      ;

         reg         [3:0]       key_col_ff1      ;

         reg         [1:0]       row_index       ;

         reg         [3:0]       key_row         ;

         reg         [1:0]       cnt_phase        ;

         reg         [1:0]       key_col_get      ;

         reg         [20:0]      cnt_20ms       ;

 

         always  @(posedge clk or negedge   rst_n)begin

           if(rst_n==1'b0)begin

                   key_col_ff0<=4'hf;

                   key_col_ff1<=4'hf;

           end    

           else begin

               key_col_ff0<=key_col;

               key_col_ff1<=key_col_ff0;

           end

         end

 

         always  @(posedge clk or negedge   rst_n)begin

           if(rst_n==1'b0)begin

               cnt_phase<=0;

           end

           else if(add_cnt_phase)begin

               if(end_cnt_phase)

                    cnt_phase<=0;

                else

                   cnt_phase<=cnt_phase+1;

           end

         end

         assign add_cnt_phase=end_cnt_20ms||end_row_index||delay_over||key_up;

         assign end_cnt_phase=add_cnt_phase&&cnt_phase==4-1;

         assign delay_over=end_cnt_8clks&&cnt_phase==3-1;

         assign key_up=cnt_phase==4-1&&key_col_ff1==4'hf;

 

         always  @(posedge clk or negedge   rst_n)begin

           if(rst_n==1'b0)begin

               cnt_20ms<=0;

           end

           else if(add_cnt_20ms)begin

               if(end_cnt_20ms)

                   cnt_20ms<=0;

               else

                   cnt_20ms<=cnt_20ms+1;

           end

           else

                   cnt_20ms<=0;

         end

         assign add_cnt_20ms=key_col_ff1!=4'hf&&cnt_phase==0;

         assign end_cnt_20ms=add_cnt_20ms&&cnt_20ms==TIME_20MS-1;

 

 

         always  @(posedge clk or negedge   rst_n)begin

           if(rst_n==1'b0)begin

               cnt_8clks<=0;

           end

           else if(add_cnt_8clks)begin

               if(end_cnt_8clks)

                    cnt_8clks<=0;

                else

                   cnt_8clks<=cnt_8clks+1;

           end

         end

 

         assign add_cnt_8clks=cnt_phase==2-1||cnt_phase==3-1;

         assign end_cnt_8clks=add_cnt_8clks&&cnt_8clks==8-1;

 

         always  @(posedge clk or negedge   rst_n)begin

           if(rst_n==1'b0)begin

               row_index<=0;

           end

           else if(add_row_index)begin

               if(end_row_index)

                   row_index<=0;

               else

                     row_index<=row_index+1;

           end

         end

         assign add_row_index=end_cnt_8clks&&cnt_phase==2-1;

         assign end_row_index=add_row_index&&row_index==4-1;

 

 

         always  @(posedge clk or negedge   rst_n)begin

           if(rst_n==1'b0)begin

               key_row<=4'b0000;

           end

           else if(cnt_phase==1)begin

                 key_row<=~(1<<row_index);

           end

           else

               key_row<=4'b0000;

         end

 

         always  @(posedge clk or negedge   rst_n)begin

           if(rst_n==1'b0)begin

               key_out <= 0;

           end

           else if(possible_vld)begin

               key_out <=   {row_index,key_col_get};

           end

           else begin

               key_out <= 0;

           end

         end

         assign possible_vld=cnt_phase==1 && end_cnt_8clks;

 

 

         always  @(posedge clk or negedge   rst_n)begin

           if(rst_n==1'b0)begin

               key_col_get <= 0;

           end

           else if(end_cnt_20ms) begin

               if(key_col_ff1==4'b1110)

                   key_col_get <= 0;

               else if(key_col_ff1==4'b1101)

                   key_col_get <= 1;

               else if(key_col_ff1==4'b1011)

                   key_col_get <= 2;

               else

                   key_col_get <= 3;

           end

         end

 

         always  @(posedge clk or negedge   rst_n)begin

           if(rst_n==1'b0)begin

               key_vld <= 1'b0;

           end

           else if(vld)begin

               key_vld <= 1'b1;

           end

           else begin

               key_vld <= 1'b0;

           end

         end

         assign vld=possible_vld && key_col_ff1[key_col_get]==1'b0;

 

endmodule

 

时钟计数模块

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

module timer_data(

                  clk        ,

                rst_n      ,   

key_num ,

                  key_vld   ,

                  dout        ,

dout_vld

         );

         parameter   DATA_W  =    4          ;

         parameter   TIME_1S  =    50_000_000  ;  

 

         input         clk                               ;

         input         rst_n                              ;

         input  [3:0]   key_num                           ;

         input         key_vld                           ;     

 

         output [23:0]  dout                              ;

         output       dout_vld                           ;

         reg          dout_vld                             ;

         reg          pause_flag                          ;

 

         reg    [3:0]   x                              ;

         reg    [3:0]   y                       ;

         reg    [3:0]   miao_g                         ;

         reg    [3:0]   miao_s                         ;

         reg    [3:0]   fen_g                          ;

         reg    [3:0]   fen_s                           ;

         reg    [3:0]   shi_g                           ;

         reg    [3:0]   shi_s                           ;

         reg      [2:0]   cnt_key2                        ;

reg    [25:0]   cnt                     ;

 

         wire   [23:0]  dout                                ;

         wire          add_cnt_key2                ;

         wire          end_cnt_key2                ;

         wire          add_cnt                           ;

         wire          end_cnt                           ;

         wire          add_miao_g                   ;

         wire          end_miao_g                   ;

         wire          press_key3                     ;

         wire          add_miao_s                    ;

         wire          end_miao_s                    ;

         wire          add_fen_g                         ;

         wire          end_fen_g                         ;

 

         wire          add_fen_s                   ;

         wire          end_fen_s                   ;

         wire          add_shi_g                      ;

         wire          end_shi_g                      ;

         wire          add_shi_s                      ;

         wire          end_shi_s                      ;

 

         wire          key_add_fen_g                     ;

         wire            key_add_miao_s                ;

         wire          key_add_shi_g                  ;

         wire          key_add_fen_s                  ;

         wire            key_add_miao_g                ;

         wire          key_add_shi_s                  ;

 

         always  @(posedge clk or negedge   rst_n)begin

           if(rst_n==1'b0)begin

               pause_flag<=0;

           end

           else   if(key_vld&&key_num==1)begin

               if(pause_flag)

                   pause_flag<=0;

               else

                   pause_flag<=1;

           end

         end

 

         always  @(posedge clk or negedge   rst_n)begin

           if(rst_n==1'b0)begin

               cnt_key2<=0;

           end

           else if(add_cnt_key2)begin

               if(end_cnt_key2)

                   cnt_key2<=0;

               else

                   cnt_key2<=cnt_key2+1;

           end

           else if(pause_flag==0)

             cnt_key2<=0;

         end

         assign add_cnt_key2=key_vld&&key_num==2&&pause_flag==1;

         assign end_cnt_key2=add_cnt_key2&&cnt_key2==6-1;

 

         always  @(posedge clk or negedge   rst_n)begin

           if(rst_n==1'b0)begin

               cnt<=0;

           end

           else if(add_cnt)begin

               if(end_cnt)

                   cnt<=0;

               else

                   cnt<=cnt+1;

           end

         end

         assign add_cnt=pause_flag==0;

         assign end_cnt=add_cnt&&cnt==TIME_1S-1;

 

         always  @(posedge clk or negedge   rst_n)begin

           if(rst_n==1'b0)begin

               miao_g<=0;

           end

           else if(add_miao_g)begin

               if(end_miao_g)

                   miao_g<=0;

               else

                   miao_g<=miao_g+1;

           end

         end

         assign add_miao_g=end_cnt||key_add_miao_g;

         assign end_miao_g=add_miao_g&&miao_g==10-1;

         assign key_add_miao_g=press_key3&&cnt_key2==0;

 

         assign press_key3=pause_flag==1&&key_vld&&key_num==3;

 

         always  @(posedge clk or negedge   rst_n)begin

           if(rst_n==1'b0)begin

               miao_s<=0;

           end

           else if(add_miao_s)begin

               if(end_miao_s)

                  miao_s<=0;

               else

                   miao_s<=miao_s+1;

           end

         end

         assign   add_miao_s=end_miao_g||key_add_miao_s;

         assign end_miao_s=add_miao_s&&miao_s==6-1;

 

         assign key_add_miao_s=cnt_key2==1&&press_key3;

 

         always  @(posedge clk or negedge   rst_n)begin

           if(rst_n==1'b0)begin

               fen_g<=0;

           end

           else if(add_fen_g)begin

               if(end_fen_g)

                  fen_g<=0;

               else

                   fen_g<=fen_g+1;

           end

         end

         assign add_fen_g=end_miao_s||key_add_fen_g;

         assign end_fen_g=add_fen_g&&fen_g==10-1;

 

         assign key_add_fen_g=cnt_key2==2&&press_key3;

 

         always  @(posedge clk or negedge   rst_n)begin

           if(rst_n==1'b0)begin

               fen_s<=0;

           end

           else if(add_fen_s)begin

               if(end_fen_s)

                  fen_s<=0;

               else

                   fen_s<=fen_s+1;

           end

         end

         assign add_fen_s=end_fen_g||(key_add_fen_s);

         assign end_fen_s=add_fen_s&&fen_s==6-1;

 

         assign key_add_fen_s=cnt_key2==3&&press_key3;

 

         always  @(posedge clk or negedge   rst_n)begin

           if(rst_n==1'b0)begin

               shi_g<=0;

           end

           else if(add_shi_g)begin

                 if(end_shi_g)

                  shi_g<=0;

               else

                   shi_g<=shi_g+1;

           end

         end

         assign add_shi_g=end_fen_s ||key_add_shi_g;

         assign end_shi_g=add_shi_g&& shi_g ==x -1;

 

         always@(*) begin

           if(shi_s==2)

                   x = 4;

              else

                   x = 10;

         end

 

         assign key_add_shi_g=cnt_key2==4&&press_key3;

 

         always  @(posedge clk or negedge   rst_n)begin

           if(rst_n==1'b0)begin

               shi_s<=0;

           end

           else if(add_shi_s)begin

               if(end_shi_s)

                  shi_s<=0;

               else

                   shi_s<=shi_s+1;

           end

         end

         assign add_shi_s=end_shi_g|| key_add_shi_s;

         assign end_shi_s=add_shi_s && shi_s==y-1;

 

         assign key_add_shi_s=cnt_key2==5&&press_key3;

 

         always  @(*)begin

           if(shi_g>=4)

               y = 2;

           else

               y = 3;

         end

 

         assign dout = {shi_s,shi_g,fen_s,fen_g,miao_s,miao_g};

 

         always  @(posedge clk or negedge   rst_n)begin

           if(rst_n==1'b0)begin

               dout_vld<=0;

           end

           else if(end_cnt)begin

               dout_vld<=1;

           end

           else

                 dout_vld<=0;

         end

endmodule

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

闹钟设定模块

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

module match_bell(

              clk                 ,

              rst_n                ,

              time_now           ,

              time_now_vld,

              key_num            ,

              key_vld             ,

              set_group    ,

              setting        ,

              bell

       );

 

       parameter     TIME_1S=50_000_000  ;

 

       input          clk            ;

       input          rst_n          ;

       input   [23:0]  time_now      ;

       input          time_now_vld   ;

       input   [3:0]   key_num       ;

       input          key_vld        ;

 

       output         bell           ;

       output         set_group      ;

       output         setting         ;

 

       reg            bell            ;

       reg     [3:0]   key_num_ff0    ;

       wire           equal_flag      ;

       reg     [23:0]  set_group       ;

       reg            setting         ;

       wire           start_set      ;

       wire           end_set        ;

 

       wire           add_cnt_1s      ;

       wire           end_cnt_1s      ;

       wire           add_cnt_5s      ;

       wire           end_cnt_5s     ;

       reg     [2:0]   cnt_5s          ;

       reg     [25:0]  cnt_1s          ;

       reg     [2:0]     cnt_key13      ;

       wire               add_cnt_key13  ;

       wire             end_cnt_key13 ;

       reg                set_alarm_vld   ;

       wire             value_0_9      ;

       wire             value_0_5      ;

       wire             value_0_2      ;

       wire             value_0_1      ;

       wire             value_0_3      ;

 

       always  @(posedge clk or negedge   rst_n)begin

         if(rst_n==1'b0)begin

             bell<=1;

         end

         else if(equal_flag)begin

             bell<=0;

         end

         else if(end_cnt_5s)

             bell<=1;

       end

 

       always  @(posedge clk or negedge   rst_n)begin

         if(rst_n==1'b0)begin

             cnt_1s<=23'b0;

         end

         else if(add_cnt_1s)begin

             if(end_cnt_1s)

                 cnt_1s<=23'b0;

             else

                 cnt_1s<=cnt_1s+1'b1;

         end

       end

       assign add_cnt_1s=bell==0;

       assign end_cnt_1s=add_cnt_1s&&cnt_1s==TIME_1S-1;

 

       always  @(posedge clk or negedge   rst_n)begin

         if(rst_n==1'b0)begin

             cnt_5s<=0;

         end

           else if(add_cnt_5s)begin

             if(end_cnt_5s)

                 cnt_5s<=0;

             else

                 cnt_5s<=cnt_5s+1;

         end

       end

       assign add_cnt_5s=end_cnt_1s;

       assign end_cnt_5s=add_cnt_5s&&cnt_5s==5-1;

 

       assign equal_flag=(set_group==time_now)&&time_now_vld;

 

       always  @(posedge clk or negedge   rst_n)begin

         if(rst_n==1'b0)begin

             cnt_key13<=0;

         end

         else if(add_cnt_key13)begin

             if(end_cnt_key13)

                 cnt_key13<=0;

             else

                 cnt_key13<=cnt_key13+1;

         end

        else if(end_set)

                 cnt_key13<=0;

       end

       assign add_cnt_key13=setting&&key_vld&&key_num==13;

       assign end_cnt_key13=add_cnt_key13&&cnt_key13==6-1;

 

       always  @(posedge clk or negedge   rst_n)begin

         if(rst_n==1'b0)begin

             set_group<=24'h000009;

         end

         else if(set_alarm_vld)begin

             if(cnt_key13==0)

                   set_group[3:0]<=key_num_ff0;

             else if(cnt_key13==1)

                   set_group[7:4]<=key_num_ff0;

             else if(cnt_key13==2)

                   set_group[11:8]<=key_num_ff0;

             else if(cnt_key13==3)

                   set_group[15:12]<=key_num_ff0;

             else if(cnt_key13==4)

                   set_group[19:16]<=key_num_ff0;

             else if(cnt_key13==5)

                   set_group[23:20]<=key_num_ff0;

         end

       end

 

       assign   value_0_9=key_vld&&(0<=key_num&&key_num<10);

       assign value_0_5=key_vld&&(0<=key_num&&key_num<6);

       assign   value_0_2=key_vld&&(0<=key_num&&key_num<3);

       assign   value_0_3=key_vld&&(0<=key_num&&key_num<4);

       assign   value_0_1=key_vld&&(0<=key_num&&key_num<2);

 

       always  @(posedge clk or negedge   rst_n)begin

           if(rst_n==1'b0)begin

             set_alarm_vld<=0;

         end

         else   if(key_vld&&setting)begin

              if(cnt_key13==0)begin

                     if(value_0_9)

                            set_alarm_vld<=1;

                     else

                            set_alarm_vld<=0;

              end

              else   if(cnt_key13==1)begin  

                     if(value_0_5)

                            set_alarm_vld<=1;

                     else

                            set_alarm_vld<=0;

              end

              else   if(cnt_key13==2)begin

                     if(value_0_9)

                            set_alarm_vld<=1;

                     else

                            set_alarm_vld<=0;

              end

              else   if(cnt_key13==3)begin

                     if(value_0_5)

                            set_alarm_vld<=1;

                     else

                            set_alarm_vld<=0;

              end

              else   if(cnt_key13==4)begin

                if(set_group[23:20]==2)begin

                      if(value_0_3)

                             set_alarm_vld<=1;

                      else

                             set_alarm_vld<=0;

                end

                else if(value_0_9)

                            set_alarm_vld<=1;

                else

                    set_alarm_vld<=0;

              end

              else   if(cnt_key13==5)begin

                     if(0<=set_group[19:16]&&set_group[19:16]<4)begin

                            if(value_0_2)

                                   set_alarm_vld<=1; 

                            else

                                   set_alarm_vld<=0;        

                     end

                     else          if(value_0_1)

                            set_alarm_vld<=1;        

                     else

                            set_alarm_vld<=0;

              end

       end

       else  

              set_alarm_vld<=0;

       end

 

       always  @(posedge clk or negedge   rst_n)begin

         if(rst_n==1'b0)begin

             key_num_ff0<=0;

         end

         else

              key_num_ff0<=key_num;  

       end

 

       always  @(posedge clk or negedge   rst_n)begin

         if(rst_n==1'b0)begin

             setting<=0;

         end

         else if(start_set)begin

             setting<=1;

         end

         else if(end_set)begin

             setting<=0;

         end

       end

       assign start_set=key_vld&&key_num==14;

       assign end_set    =key_vld&&key_num==15;

 

endmodule

 


*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客