明德扬论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信扫一扫,快捷登录!

查看: 4403|回复: 0

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

[复制链接]
发表于 2020-3-1 23:42:01 | 显示全部楼层 |阅读模式

马上注册,看完整文章,学更多FPGA知识。

您需要 登录 才可以下载或查看,没有帐号?立即注册

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

顶层模块
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  [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


万年历计数模块
  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[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


矩阵键盘扫描模块
  1 module  key_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  [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


数码管显示模块
  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     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==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

FPGA视频课程  培训班 FPGA学习资料
吴老师 18022857217(微信同号) Q1241003385
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|MDYBBS ( 粤ICP备16061416号 )

GMT+8, 2024-4-20 09:30 , Processed in 0.061396 second(s), 22 queries .

Powered by Discuz! X3.4

本论坛由广州健飞通信有限公司所有

© 2001-2019 Comsenz Inc.

快速回复 返回顶部 返回列表