明德扬吴老师 发表于 2020-3-1 23:42:01

至简设计法_fpga万年历设计-明德扬科教(mdy-edu.com)

1.功能概述   万年历是记录一定时间范围内的年历,其名称只是一种象征,表示时间跨度大。由于其功能非常常用,且极为方便人们查询使用,因此广泛应用于钟表、历书出版物、电子产品、电脑软件和手机应用等等行业中。
      与传统计时工具如钟表日历等相比,数字万年历具备精确度高、成本低廉、运行稳定、功能多样等众多优点,因此国内外许多设计人员先后进行了相关设计开发。其中,基于FPGA开发除设计简便、开发成本低、电路简洁等,更具备功能设计灵活方面的优势。只需要在软件上做简单修改即可添加不同功能,如闹钟、阴阳历对照等。
      在FPGA设计中,数字万年历属于小规模集成电路。从原理上来讲,是典型的数字电路,包括组合逻辑电路和时序电路。在本案例中具体功能要求如下:
      本项目要求设计一个电子万年历,具体功能要求如下:
1. 上板复位后从元年1月1号开始计数,为方便上板调试,将一天的时间压缩为1秒;2. 按键用于设置日历,按下按键0进入设置状态,再次按下按键0退出设置状态;3. 按键1用来选择想要设置的年月日的各个位;4. 按键2在设置状态时进行计数设置,每按一次数码管显示数字加1;5. 平年365天(52周+1天),闰年366天(52周+2天),其中平年2月28天,闰年2月29天。6. 闰年:每400年整一闰,或每4年且不为百年的一闰。即能被400整除,或不能被100整除但能被4整除的年份为闰年。
2.设计思路      首先根据所需要的功能,列出工程顶层的输入输出信号列表。
      信号列表如下:http://www.mdy-edu.com/upaa/666/0slgny4ud4416.jpg
我们可以把工程划分成三个模块,分别是万年历计数模块、按键模块和数码管显示模块。
http://www.mdy-edu.com/upaa/666/mqsijy1p52z17.jpg
   1. 计数模块——实现的是万年历计数功能,为方便观看,将一天时间设置为1秒;日计数器dat_cnt、月份计数器mon_cnt_h、mon_cnt_1、mon_2_h、mon_2_1分别为大月小月以及平年闰年的2月计数器、年份计数器yea_one、yea_ten、yea_hun、yea_tho分别为年份的个十百千位,由yea_cnt_tol <= yea_cnt1000 + yea_cnt100 + yea_cnt10 + yea_one得到年份。本模块还自动计算当年是否是平闰年。
      信号列表如下:http://www.mdy-edu.com/upaa/666/yvsobbta1n518.jpg
   2. 按键模块——4x4矩阵键盘,实现了矩阵键盘的扫描并使用按键消抖功能。
      信号列表如下:http://www.mdy-edu.com/upaa/666/k1fqos5vgsu19.jpg
      3. 数码管模块——实现将年月日的信息显示在数码管上。
      信号列表如下:
http://www.mdy-edu.com/upaa/666/txedzrjokn020.jpg

      3.程序设计
顶层模块 1 module calendar_top(
2   clk    ,
3   rst_n,
4   key_col,
5   key_row,
6   segment,
7   seg_sel
8   );
9
10   parameter   SEG_NUM =   8    ;
11   parameter   SEG_W   =   8    ;
12   parameter   TIME_1S =50_000_000;
13
14   input                  clk   ;
15   input                  rst_n   ;
16   input         key_col ;
17
18   output    segment ;
19   output    seg_sel ;
20   output          key_row ;
21
22   wire      segment ;
23   wire      seg_sel ;
24   
25   wire            key_num ;
26   wire                   key_vld ;
27   wire    data_out;
28   wire      din_vld ;
29
30   assign din_vld = 8'b11111111   ;
31
32   key_scan      u_key_scan(
33                              .clk    (clk    )         ,
34                              .rst_n(rst_n)         ,
35                              .key_col(key_col)         ,
36                              .key_row(key_row)         ,
37                              .key_out(key_num)         ,
38                              .key_vld(key_vld)   
39                           );
40
41   seg_display   u_seg_display(
42                              .clk   (clk   )         ,
43                              .rst_n   (rst_n   )         ,
44                              .din   (data_out)         ,
45                              .din_vld (din_vld )         ,      
46                              .segment (segment )         ,
47                              .seg_sel (seg_sel )
48                         );
49
50   counter #(.TIME_1S(TIME_1S))    u_counter(
51                           .clk          (clk          ),
52                           .rst_n      (rst_n      ),
53                           .key_vld      (key_vld      ),
54                           .key_num      (key_num      ),
55                           .dout         (data_out   )
56                        );
57 endmodule
58


万年历计数模块1 module counter(
2               clk   ,
3               rst_n   ,
4               key_vld ,
5               key_num ,
6               dout   
7   );
8
9   
10   parameter      DATA_W    =         32;
11   parameter      TIME_1S   = 50_000_000;
12
13   input               clk            ;
14   input               rst_n            ;
15   input               key_vld          ;
16   input          key_num          ;
17
18   output            dout             ;
19
20   reg   dout             ;
21
22   wire                start_set      ;
23   wire                stop_set         ;
24   reg               flag_set         ;
25   reg         clk_cnt          ;
26   wire                clk_cnt_add      ;
27   wire                clk_cnt_end      ;
28   reg         dat_cnt          ;
29   wire          dat_cnt_tmp      ;
30   wire                dat_cnt_add      ;
31   wire                dat_cnt_end      ;
32   wire          dat_one          ;
33   wire          dat_ten          ;
34   wire                mon_cnt_h      ;
35   wire                mon_cnt_l      ;
36   wire                mon_2_l          ;
37   wire                mon_2_h          ;
38   reg         mon_cnt          ;
39   wire          mon_cnt_tmp      ;
40   wire                mon_cnt_add      ;
41   wire                mon_cnt_end      ;
42   wire          mon_one          ;
43   wire          mon_ten          ;
44   reg         yea_one          ;
45   wire                yea_one_add      ;
46   wire                yea_one_end      ;
47   reg         yea_ten          ;
48   wire                yea_ten_add      ;
49   wire                yea_ten_end      ;
50   reg         yea_hun          ;
51   wire                yea_hun_add      ;
52   wire                yea_hun_end      ;
53   reg         yea_tho          ;
54   wire                yea_tho_add      ;
55   wire                yea_tho_end      ;
56   reg         yea_cnt1000      ;
57   reg         yea_cnt100       ;
58   reg         yea_cnt10      ;
59   reg         yea_cnt_tol      ;
60   reg         yea_cnt_tol_100;
61   wire          yea_mult4      ;
62   wire          yea_mult100_tmp;
63   reg         yea_mult100      ;
64   wire          yea_cnt400       ;
65   reg         yea_mult400      ;
66   wire                yea_leap         ;
67   reg         set_cnt          ;
68   wire                set_cnt_add      ;
69   wire                set_cnt_end      ;
70   wire                set_dat          ;
71   wire                set_mon          ;
72   wire                set_yea_one      ;
73   wire                set_yea_ten      ;
74   wire                set_yea_hun      ;
75   wire                set_yea_tho      ;
76   reg         set_num          ;
77   wire                set_num_add      ;
78   wire                set_num_end      ;
79   reg         x                ;
80   
81   
82   always@(posedge clk or negedge rst_n)begin
83         if(rst_n==1'b0)begin
84             flag_set <= 0;
85         end
86         else if(start_set)begin
87             flag_set <= 1;
88         end
89         else if(stop_set)begin
90             flag_set <= 0;
91         end
92   end
93   assign start_set = flag_set==0 && key_vld==1 && key_num==0;
94   assign stop_set= flag_set==1 && key_vld==1 && key_num==0;
95
96   always @(posedge clk or negedge rst_n)begin
97         if (!rst_n)begin
98             clk_cnt <= 0;
99         end
100         else if(clk_cnt_add)begin
101             if(clk_cnt_end)
102               clk_cnt <= 0;
103             else
104               clk_cnt <= clk_cnt + 1;
105         end
106   end
107   assign clk_cnt_add = flag_set == 0;      
108   assign clk_cnt_end = clk_cnt_add && clk_cnt == TIME_1S - 1;
109
110   always @(posedge clk or negedge rst_n)begin
111         if(!rst_n)begin
112             dat_cnt <= 0;
113         end
114         else if(dat_cnt_add)begin
115             if(dat_cnt_end)
116               dat_cnt <= 0;
117             else
118               dat_cnt <= dat_cnt + 1;
119         end
120         else if(set_dat)begin
121             dat_cnt <= set_num;
122         end
123   end
124   assign dat_cnt_add = clk_cnt_end;   
125   assign dat_cnt_end = dat_cnt_add && dat_cnt == x - 1;
126   
127   assign dat_cnt_tmp = dat_cnt + 1;
128
129   assign dat_ten = dat_cnt_tmp/10;
130   assign dat_one = dat_cnt_tmp%10;
131   
132   always @(posedge clk or negedge rst_n)begin
133         if(!rst_n)begin
134             mon_cnt <= 0;
135         end
136         else if(mon_cnt_add)begin
137             if(mon_cnt_end)
138               mon_cnt <= 0;
139             else
140               mon_cnt <= mon_cnt + 1;
141         end
142         else if(set_mon)begin
143             mon_cnt <= set_num;
144         end
145   end
146   assign mon_cnt_add = dat_cnt_end;      
147   assign mon_cnt_end = mon_cnt_add && mon_cnt == 12 - 1;      
148
149   assign mon_cnt_tmp = mon_cnt + 1;
150
151   assign mon_ten = mon_cnt_tmp/10;
152   assign mon_one = mon_cnt_tmp%10;
153      
154   always@(*)begin
155         if(mon_cnt_h)
156             x = 31;
157         else if(mon_cnt_l)
158             x = 30;
159         else if(mon_2_h)
160             x = 29;
161         else
162             x = 28;
163   end
164   assign mon_cnt_h = mon_cnt_tmp==1||mon_cnt_tmp==3||mon_cnt_tmp==5||mon_cnt_tmp==7||mon_cnt_tmp==8||mon_cnt_tmp==10||mon_cnt_tmp==12;
165   assign mon_cnt_l = mon_cnt_tmp==4||mon_cnt_tmp==6||mon_cnt_tmp==9||mon_cnt_tmp==11;
166   assign mon_2_h   = yea_leap==1   &&mon_cnt_tmp==2;
167   assign mon_2_l   = yea_leap==0   &&mon_cnt_tmp==2;
168
169   always @(posedge clk or negedge rst_n)begin
170         if(!rst_n)begin
171             yea_one <= 0;
172         end
173         else if(yea_one_add)begin
174             if(yea_one_end)
175               yea_one <= 0;
176             else
177               yea_one <= yea_one + 1;
178         end
179         else if(set_yea_one)begin
180             yea_one <= set_num;
181         end
182   end
183   assign yea_one_add = mon_cnt_end;      
184   assign yea_one_end = yea_one_add && yea_one == 10 - 1;   
185
186   
187   always @(posedge clk or negedge rst_n)begin
188         if(!rst_n)begin
189             yea_ten <= 0;
190         end
191         else if(yea_ten_add)begin
192             if(yea_ten_end)
193               yea_ten <= 0;
194             else
195               yea_ten <= yea_ten + 1;
196         end
197         else if(set_yea_ten)begin
198             yea_ten <= set_num;
199         end
200   end
201   assign yea_ten_add = yea_one_end;      
202   assign yea_ten_end = yea_ten_add && yea_ten == 10 - 1;      
203
204   
205   always @(posedge clk or negedge rst_n)begin
206         if(!rst_n)begin
207             yea_hun <= 0;
208         end
209         else if(yea_hun_add)begin
210             if(yea_hun_end)
211               yea_hun <= 0;
212             else
213               yea_hun <= yea_hun + 1;
214         end
215         else if(set_yea_hun)begin
216             yea_hun <= set_num;
217         end
218   end
219   assign yea_hun_add = yea_ten_end;      
220   assign yea_hun_end = yea_hun_add && yea_hun == 10 - 1;      
221
222   always @(posedge clk or negedge rst_n)begin
223         if(!rst_n)begin
224             yea_tho <= 0;
225         end
226         else if(yea_tho_add)begin
227             if(yea_tho_end)
228               yea_tho <= 0;
229             else
230               yea_tho <= yea_tho + 1;
231         end
232         else if(set_yea_tho)begin
233             yea_tho <= set_num;
234         end
235   end
236   assign yea_tho_add = yea_hun_end;      
237   assign yea_tho_end = yea_tho_add && yea_tho == 10 - 1;      
238
239   always@(posedge clk or negedge rst_n)begin
240         if(rst_n==1'b0)begin
241             yea_cnt1000 <= 0;
242         end
243         else begin
244             yea_cnt1000 <= yea_tho*1000;
245         end
246   end
247
248   always@(posedge clk or negedge rst_n)begin
249         if(rst_n==1'b0)begin
250             yea_cnt100 <= 0;
251         end
252         else begin
253             yea_cnt100 <= yea_hun*100;
254         end
255   end
256
257   always@(posedge clk or negedge rst_n)begin
258         if(rst_n==1'b0)begin
259             yea_cnt10 <= 0;
260         end
261         else begin
262             yea_cnt10 <= yea_ten*10;
263         end
264   end
265   
266   always@(posedge clk or negedge rst_n)begin
267         if(rst_n==1'b0)begin
268             yea_cnt_tol <= 0;
269         end
270         else begin
271             yea_cnt_tol <= yea_cnt1000 + yea_cnt100 + yea_cnt10 + yea_one;
272         end
273   end
274
275   always@(posedge clk or negedge rst_n)begin
276         if(rst_n==1'b0)begin
277             yea_cnt_tol_100 <= 0;
278         end
279         else begin
280             yea_cnt_tol_100 <=yea_tho*10+ yea_hun;
281         end
282   end
283
284   assign yea_mult4       = {yea_cnt_tol>>2,2'b00};   
285   assign yea_mult100_tmp = yea_cnt1000 + yea_cnt100;
286   assign yea_cnt400      = {yea_cnt_tol_100>>2,2'b00};
287
288   always@(posedge clk or negedge rst_n)begin
289         if(rst_n==1'b0)begin
290             yea_mult100 <= 0;
291         end
292         else begin
293             yea_mult100 <= yea_mult100_tmp;
294         end
295   end
296
297   always@(posedge clk or negedge rst_n)begin
298         if(rst_n==1'b0)begin
299             yea_mult400 <= 0;
300         end
301         else begin
302             yea_mult400 <= yea_cnt400*100;
303         end
304   end
305      
306   assign yea_leap = (yea_cnt_tol==yea_mult400)||(yea_cnt_tol==yea_mult4&&yea_cnt_tol!=yea_mult100);
307   
308   always @(posedge clk or negedge rst_n)begin
309         if(!rst_n)begin
310             set_cnt <= 0;
311         end
312         else if(set_cnt_add)begin
313             if(set_cnt_end)
314               set_cnt <= 0;
315             else
316               set_cnt <= set_cnt + 1;
317         end
318         else if(stop_set)begin
319             set_cnt <= 0;
320         end
321   end
322   assign set_cnt_add = flag_set == 1 && key_vld == 1 && key_num == 1;      
323   assign set_cnt_end = set_cnt_add && set_cnt == 8 - 1            ;      
324
325   assign set_dat   = set_num_add && set_cnt == 1-1                ;
326   assign set_mon   = set_num_add && set_cnt == 3-1                ;
327   assign set_yea_one = set_num_add && set_cnt == 5-1                ;
328   assign set_yea_ten = set_num_add && set_cnt == 6-1                ;
329   assign set_yea_hun = set_num_add && set_cnt == 7-1                ;
330   assign set_yea_tho = set_num_add && set_cnt == 8-1                ;
331
332   reg     y_temp                                             ;
333   wire    y_temp2                                              ;
334
335   assign set_num_add = flag_set == 1 && key_vld == 1 && key_num == 2;   
336
337   always@(*)begin
338         if(set_dat)
339             y_temp = dat_cnt;
340         else if(set_mon)
341             y_temp = mon_cnt;
342         else if(set_yea_one)
343             y_temp = yea_one;
344         else if(set_yea_ten)
345             y_temp = yea_ten;
346         else if(set_yea_hun)
347             y_temp = yea_hun;
348         else
349             y_temp = yea_tho;
350
351   end
352
353   assign y_temp2 = y_temp + 1;
354
355   always@(*)begin
356         if(set_dat)begin
357             if(y_temp2>=x)
358               set_num = 0;
359             else
360               set_num = y_temp2;
361         end
362         else if(set_num)begin
363             if(y_temp2>=12)
364               set_num = 0;
365             else
366               set_num = y_temp2;
367         end
368         else begin
369             if(y_temp2>9)
370               set_num = 0;
371             else
372               set_num = y_temp2;
373         end
374   end
375
376   always@(posedge clk or negedge rst_n)begin
377         if(rst_n==1'b0)begin
378             dout <= 0;
379         end
380         else begin
381             dout <= {yea_tho,yea_hun,yea_ten,yea_one,mon_ten,mon_one,dat_ten,dat_one};
382         end
383   end
384
385 endmodule
386


矩阵键盘扫描模块1 modulekey_scan(
2                  clk    ,
3                  rst_n,
4                  key_col,
5                  key_row,
6                  key_out,
7                  key_vld   
8                );
9
10
11   parameter      KEY_W    =   4 ;
12   parameter      COL      =   0 ;
13   parameter      ROW      =   1 ;
14   parameter      DLY      =   2 ;
15   parameter      FIN      =   3 ;
16   parameter      COL_CNT=   16;
17   parameter      TIME_20MS=   1000000;
18
19   input               clk    ;
20   input               rst_n;
21   input      key_col;
22
23   output            key_vld;
24   output         key_out;
25   output   key_row;
26
27   reg            key_out;
28   reg      key_row;
29   reg               key_vld;
30
31   reg   [ 3:0]      key_col_ff0   ;
32   reg   [ 3:0]      key_col_ff1   ;
33   reg   [ 1:0]      key_col_get   ;
34   reg               shake_flag    ;
35   reg               shake_flag_ff0;
36   reg   [ 3:0]      state_c       ;
37   reg         shake_cnt   ;
38   reg   [ 3:0]      state_n       ;
39   reg   [ 1:0]      row_index   ;
40   reg         row_cnt       ;
41   reg   [ 2:0]      x             ;
42
43
44   always@(posedge clk or negedge rst_n)begin
45         if(rst_n==1'b0)begin
46             key_col_ff0 <= 4'b1111;
47             key_col_ff1 <= 4'b1111;
48         end
49         else begin
50             key_col_ff0 <= key_col    ;
51             key_col_ff1 <= key_col_ff0;
52         end
53   end
54   
55   always@(posedge clk or negedge rst_n)begin
56         if(rst_n==1'b0)begin
57             shake_cnt <= 0;
58         end
59         else if(add_shake_cnt)begin
60             if(end_shake_cnt)
61               shake_cnt <= 0;
62             else
63               shake_cnt <= shake_cnt + 1;
64         end
65         else begin
66             shake_cnt <= 0;
67         end
68   end
69   assignadd_shake_cnt = key_col_ff1!=4'hf && shake_flag==0;
70   assignend_shake_cnt = add_shake_cnt && shake_cnt==TIME_20MS-1;
71   
72   always@(posedge clk or negedge rst_n)begin
73         if(rst_n==1'b0)begin
74             shake_flag <= 0;
75         end
76         else if(end_shake_cnt) begin
77             shake_flag <= 1'b1;
78         end
79         else if(key_col_ff1==4'hf) begin
80             shake_flag <= 1'b0;
81         end
82   end
83   
84   always@(posedge clk or negedge rst_n)begin
85         if(rst_n==1'b0)begin
86             state_c <= COL;
87         end
88         else begin
89             state_c <= state_n;
90         end
91   end
92      
93   always@(*)begin
94         case(state_c)
95             COL:begin
96               if(col2row_start)begin
97                     state_n = ROW;
98               end
99               else begin
100                     state_n = state_c;
101               end
102             end
103             ROW:begin
104               if(row2dly_start)begin
105                     state_n = DLY;
106               end
107               else begin
108                     state_n = state_c;
109               end
110             end
111             DLY:begin
112               if(dly2fin_start)begin
113                     state_n = FIN;
114               end
115               else begin
116                     state_n = state_c;
117               end
118             end
119             FIN:begin
120               if(fin2col_start)begin
121                     state_n = COL;
122               end
123               else begin
124                     state_n = state_c;
125               end
126             end
127             default:begin
128               state_n = COL;
129             end
130         endcase
131   end
132   
133   assigncol2row_start = state_c==COL && end_shake_cnt;
134   assignrow2dly_start = state_c==ROW && end_row_index;
135   assigndly2fin_start = state_c==DLY && end_row_index;
136   assignfin2col_start = state_c==FIN && key_col_ff1==4'hf;
137   
138   always@(posedge clk or negedge rst_n)begin
139         if(rst_n==1'b0)begin
140             key_row <= 4'b0;
141         end
142         else if(state_c==ROW)begin
143             key_row <= ~(1'b1 << row_index);
144         end
145         else begin
146             key_row <= 4'b0;
147         end
148   end
149   
150   always@(posedge clk or negedge rst_n)begin
151         if(rst_n==1'b0)begin
152             row_cnt <= 0;
153         end
154         else if(add_row_cnt) begin
155             if(end_row_cnt)
156               row_cnt <= 0;
157             else
158               row_cnt <= row_cnt + 1;
159         end
160   end
161   assign add_row_cnt = state_c==ROW || state_c==DLY;
162   assign end_row_cnt = add_row_cnt && row_cnt==COL_CNT-1;
163   
164   always@(posedge clk or negedge rst_n)begin
165         if(rst_n==1'b0)begin
166             row_index <= 0;
167         end
168         else if(add_row_index) begin
169             if(end_row_index)
170               row_index <= 0;
171             else
172               row_index <= row_index + 1;
173         end
174   end
175   assign add_row_index = end_row_cnt;
176   assign end_row_index = add_row_index && row_index==x-1;
177
178   always@(*)begin
179         if(state_c==ROW)
180             x = 4;
181         else
182             x = 1;
183   end
184   
185   always@(posedge clk or negedge rst_n)begin
186         if(rst_n==1'b0)begin
187             key_col_get <= 0;
188         end
189         else if(col2row_start) begin
190             if(key_col_ff1==4'b1110)
191               key_col_get <= 0;
192             else if(key_col_ff1==4'b1101)
193               key_col_get <= 1;
194             else if(key_col_ff1==4'b1011)
195               key_col_get <= 2;
196             else
197               key_col_get <= 3;
198         end
199   end
200      
201   always@(posedge clk or negedge rst_n)begin
202         if(rst_n==1'b0)begin
203             key_out <= 0;
204         end
205         else if(state_c==ROW && end_row_cnt)begin
206             key_out <= {row_index,key_col_get};
207         end
208         else begin
209             key_out <= 0;
210         end
211   end
212   
213   always@(posedge clk or negedge rst_n)begin
214         if(rst_n==1'b0)begin
215             key_vld <= 1'b0;
216         end
217         else if(state_c==ROW && end_row_cnt && key_col_ff1==1'b0)begin
218             key_vld <= 1'b1;
219         end
220         else begin
221             key_vld <= 1'b0;
222         end
223   end
224   
225 endmodule
226


数码管显示模块1 module seg_display(
2   clk    ,
3   rst_n,
4   din    ,
5   din_vld,
6   segment,
7   seg_sel
8   );
9
10   `include "clogb2.v"
11   
12   parameter      SEG_W   =      8          ;
13   parameter      SEG_NUM   =      8          ;
14   parameter      DIS_NUM   =       10          ;
15   parameter      TIME_20US =   1000          ;
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      SEG_NUM_C= clogb2(SEG_NUM)-1;
27
28   
29   input               clk      ;
30   input               rst_n    ;
31   inputdin      ;
32   input    din_vld;
33   
34   output                segment;
35   output                seg_sel;
36      
37   reg      segment;
38   reg      seg_sel;
39
40   wire         seg_tmp;
41   reg    din_ff0;
42   reg            clk_cnt;
43   reg            sel_cnt;
44   integer               i      ;   
45   
46   wire                clk_cnt_add;
47   wire                clk_cnt_end;
48   wire                sel_cnt_add;
49   wire                sel_cnt_end;
50
51   always@(posedge clk or negedge rst_n)begin
52         if(rst_n==1'b0)begin
53             segment <= NUM_0;
54         end
55         else begin
56             case(seg_tmp)
57               4'd0 : segment <= NUM_0   ;
58               4'd1 : segment <= NUM_1   ;
59               4'd2 : segment <= NUM_2   ;
60               4'd3 : segment <= NUM_3   ;
61               4'd4 : segment <= NUM_4   ;
62               4'd5 : segment <= NUM_5   ;
63               4'd6 : segment <= NUM_6   ;
64               4'd7 : segment <= NUM_7   ;
65               4'd8 : segment <= NUM_8   ;
66               4'd9 : segment <= NUM_9   ;
67               default : segment <= NUM_0;
68             endcase
69         end
70   end
71
72   assign   seg_tmp = din_ff0[(sel_cnt+1)*4-1 -:4];
73
74   always@(posedge clk or negedge rst_n)begin
75         if(rst_n==1'b0)begin
76             din_ff0 <= 0;
77         end
78         else begin
79             for(i=0;i<SEG_NUM;i=i+1)begin
80               if(din_vld==1'b1)begin
81                     din_ff0[(i+1)*4-1 -:4] <= din[(i+1)*4-1 -:4];
82               end
83               else begin
84                     din_ff0[(i+1)*4-1 -:4] <= din_ff0[(i+1)*4-1 -:4];
85               end
86             end
87         end
88   end
89      
90   always @(posedge clk or negedge rst_n)begin
91         if (!rst_n)begin
92             clk_cnt <= 0;
93         end
94         else if(clk_cnt_add)begin
95             if(clk_cnt_end)
96               clk_cnt <= 0;
97             else
98               clk_cnt <= clk_cnt + 1;
99         end
100   end
101   assign clk_cnt_add = 1;      
102   assign clk_cnt_end = clk_cnt_add && clk_cnt == TIME_20US - 1;         
103
104   always @(posedge clk or negedge rst_n)begin
105         if (!rst_n)begin
106             sel_cnt <= 0;
107         end
108         else if(sel_cnt_add)begin
109             if(sel_cnt_end)
110               sel_cnt <= 0;
111             else
112               sel_cnt <= sel_cnt + 1;
113         end
114   end
115   assign sel_cnt_add = clk_cnt_end;   
116   assign sel_cnt_end = sel_cnt_add && sel_cnt == SEG_NUM - 1;
117
118   always@(posedge clk or negedge rst_n)begin
119         if(rst_n==1'b0)begin
120             seg_sel <= {SEG_NUM{1'b1}};
121         end
122         else begin
123             seg_sel <= ~(1'b1 << sel_cnt);
124         end
125   end
126
127 endmodule
128


技术交流群:54453837 明德扬官网:www.mdy-edu.com
页: [1]
查看完整版本: 至简设计法_fpga万年历设计-明德扬科教(mdy-edu.com)