案例编号:001600000070
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.设计思路
首先根据所需要的功能,列出工程顶层的输入输出信号列表。
信号列表如下:
我们可以把工程划分成三个模块,分别是万年历计数模块、按键模块和数码管显示模块。
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得到年份。本模块还自动计算当年是否是平闰年。
信号列表如下:
2. 按键模块——4x4矩阵键盘,实现了矩阵键盘的扫描并使用按键消抖功能。
信号列表如下:
3. 数码管模块——实现将年月日的信息显示在数码管上。
信号列表如下:
3.程序设计
顶层模块
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 [3:0] key_col ;
17
18 output [SEG_W-1:0] segment ;
19 output [SEG_NUM-1:0] seg_sel ;
20 output [3:0] key_row ;
21
22 wire [SEG_W-1:0] segment ;
23 wire [SEG_NUM-1:0] seg_sel ;
24
25 wire [3:0] key_num ;
26 wire key_vld ;
27 wire [4*SEG_NUM-1:0] data_out;
28 wire [SEG_NUM-1:0] 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
万年历计数模块
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[3:0] key_num ;
17
18 output dout ;
19
20 reg [DATA_W-1:0] dout ;
21
22 wire start_set ;
23 wire stop_set ;
24 reg flag_set ;
25 reg [25:0] clk_cnt ;
26 wire clk_cnt_add ;
27 wire clk_cnt_end ;
28 reg [4 :0] dat_cnt ;
29 wire [4 :0] dat_cnt_tmp ;
30 wire dat_cnt_add ;
31 wire dat_cnt_end ;
32 wire [3 :0] dat_one ;
33 wire [3 :0] dat_ten ;
34 wire mon_cnt_h ;
35 wire mon_cnt_l ;
36 wire mon_2_l ;
37 wire mon_2_h ;
38 reg [3 :0] mon_cnt ;
39 wire [3 :0] mon_cnt_tmp ;
40 wire mon_cnt_add ;
41 wire mon_cnt_end ;
42 wire [3 :0] mon_one ;
43 wire [3 :0] mon_ten ;
44 reg [3 :0] yea_one ;
45 wire yea_one_add ;
46 wire yea_one_end ;
47 reg [3 :0] yea_ten ;
48 wire yea_ten_add ;
49 wire yea_ten_end ;
50 reg [3 :0] yea_hun ;
51 wire yea_hun_add ;
52 wire yea_hun_end ;
53 reg [3 :0] yea_tho ;
54 wire yea_tho_add ;
55 wire yea_tho_end ;
56 reg [13:0] yea_cnt1000 ;
57 reg [10:0] yea_cnt100 ;
58 reg [7 :0] yea_cnt10 ;
59 reg [13:0] yea_cnt_tol ;
60 reg [6 :0] yea_cnt_tol_100 ;
61 wire [13:0] yea_mult4 ;
62 wire [13:0] yea_mult100_tmp ;
63 reg [13:0] yea_mult100 ;
64 wire [13:0] yea_cnt400 ;
65 reg [13:0] yea_mult400 ;
66 wire yea_leap ;
67 reg [2 :0] 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 [4 :0] set_num ;
77 wire set_num_add ;
78 wire set_num_end ;
79 reg [4 :0] 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 [4:0] y_temp ;
333 wire[4:0] 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
矩阵键盘扫描模块
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 [3:0] key_col;
22
23 output key_vld;
24 output[3:0] key_out;
25 output[KEY_W-1:0] key_row;
26
27 reg [3:0] key_out;
28 reg [KEY_W-1:0] 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 [19:0] shake_cnt ;
38 reg [ 3:0] state_n ;
39 reg [ 1:0] row_index ;
40 reg [15:0] 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 assign add_shake_cnt = key_col_ff1!=4'hf && shake_flag==0;
70 assign end_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 assign col2row_start = state_c==COL && end_shake_cnt;
134 assign row2dly_start = state_c==ROW && end_row_index;
135 assign dly2fin_start = state_c==DLY && end_row_index;
136 assign fin2col_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[key_col_get]==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
数码管显示模块
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 input[4*SEG_NUM-1:0] din ;
32 input[SEG_NUM-1:0] din_vld ;
33
34 output segment ;
35 output seg_sel ;
36
37 reg [SEG_W-1:0] segment ;
38 reg [SEG_NUM-1:0] seg_sel ;
39
40 wire [3:0] seg_tmp ;
41 reg [4*SEG_NUM-1:0] din_ff0 ;
42 reg [9:0] clk_cnt ;
43 reg [2:0] 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[i]==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
明德扬官网:old.mdy-edu.com