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

【案例】FPGA篮球倒计时设计

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

案例编号:001600000068

1.功能概述

篮球是一种以将篮球投入对方篮框里的对抗性体育运动,与足球、排球一起被称为“三大球”,是当今世界上最为广泛和受到关注的体育运动之一。24秒进攻规则是篮球比赛中非常重要的一项规则,保证了篮球运动的激烈性和观赏性。其主要内容时当某队在比赛中获得新的球权时,或在掷球入界中当球在场上被队员合法触及时,拥有球权的队必须在获得球后的24秒钟内投篮。完成投篮的条件是:(1)在24秒钟结束之前,球必须离开队员的手;(2)球离开队员的手后,球必须与篮圈接触。如果在24秒钟哨响前球出手后未接触篮圈,为24秒钟违例。发球权判给对方。可想而知,倒数计时系统非常适用于这项比赛规则。

篮球24秒倒计时是倒计时系统的一个典型运用。实际上,倒计时系统是一个非常常见的电路系统,生活中我们见到的如香港回归倒计时、某大型活动倒计时、评估倒计时等都属于此类。与单片机等实现模式相比,FPGA倒计时系统大大简化,整体性能和可靠性得到提高。在篮球24秒倒计时的模块架构设计方面,只需要一级架构下的BCD译码模块、倒计时模块和数码管显示模块,即可实现24秒倒计时功能。

具体功能要求:

本项目包含两个按键和4位数码管显示,要求共同实现一个篮球24秒的倒计时,并具有暂停和重新计数复位的功能。具体功能如下:

1. 数码管显示秒十位、秒个位、0.1秒和0.01秒。

2. 上电后,数码管显示2399,表示时间是23.99秒。

3. 按下按键S0,进入倒计时状态,进行倒计时,一直计到0000后停止。

4. 在倒计时状态时,再次按下按键S0,则暂停计时;再按下按键S0,则继续倒计时。

5. 在任何时刻,按下按键S1,则复位显示为2399


2.设计思路

我们可以把本项目设计划分成四个模块:顶层模块、倒计时模块、BCD译码模块和数码管显示模块。

fpga培训


1、顶层模块

本模块的信号列表如下:

fpga培训

2倒计时模块——实现的是24 s倒计时功能,其输出两组计数信号cnt_scnt_ms。例如当时间为23.99时,cnt_s的值为23cnt_ms的值为99当时间为08.12时,cnt_s的值为8cnt_ms的值为12。模块还实现了暂停和重开始功能。

本模块的信号列表如下:

至简设计法

3 BCD译码模块——将显示的十进制数值转化为数码管的二进制表示值得过程称为BCD译码,其功能会在BCD译码一章介绍。由于秒和毫秒都要译码,所以要例化两个BCD译码模块。

本模块的信号列表如下:

至简设计法

4数码管显示模块——将二进制数码,转成BCD数码管显示,其功能相对比较简单,这里不详细介绍

本模块的信号列表如下:

至简设计法


3.程序设计

顶层模块代码

 1 module top(
 2                   clk                  ,
 3                   rst_n                ,
 4                   key_vld              ,
 5                   seg_sel              ,
 6                   segment  
 7       );
 8       
 9       parameter  SEG_NUM   =    8      ;
10       
11       input                   clk      ;
12       input                   rst_n    ;
13       input   [1:0]           key_vld  ;
14       output  [7:0]           seg_sel  ;
15       output  [7:0]           segment  ;
16       
17       wire                    din_vld  ;
18       wire    [SEG_NUM*4-1:0] din      ;
19       wire    [7:0]           cnt_ms   ;
20       wire    [7:0]           cnt_s    ;
21       wire    [7:0]           bcd_ms   ;
22       wire    [7:0]           bcd_s    ;
23       
24       
25       cnt_down  U1(
26               .clk    (clk    ),
27               .rst_n  (rst_n  ),
28               .key_vld(key_vld),
29               .cnt_ms (cnt_ms ),
30               .cnt_s  (cnt_s  ),
31               .din_vld(din_vld)
32       );
33       
34       seg_disp #(.SEG_NUM(4))  U2(
35               .clk    (clk    ),
36               .rst_n  (rst_n  ),
37               .seg_sel(seg_sel),
38               .segment(segment),
39               .din    ({bcd_s,bcd_ms})
40       );
41       
42       bcd_water U3(
43               .clk   (clk    ) ,
44               .rst_n  (rst_n  ) ,
45               .din    (cnt_ms ) ,
46               .din_vld(din_vld) ,
47               .dout   (bcd_ms ) ,
48               .dout_vld(dout_vld )
49       );
50       
51       bcd_water U4(
52               .clk     (clk    ) ,
53               .rst_n   (rst_n  ) ,
54               .din     (cnt_s  ) ,
55               .din_vld (din_vld) ,
56               .dout    (bcd_s  ) ,
57               .dout_vld(dout_vld)
58       );
59       
60 endmodule 

倒计时模块代码

  1 module cnt_down(
  2                 clk                     ,
  3                 rst_n                   ,
  4                 cnt_s                   ,
  5                 cnt_ms                  ,
  6                 key_vld                 ,
  7                 din_vld  
  8     );
  9     parameter   TIME_10MS = 20'd500_000 ;
 10     parameter   TIME_20MS =   500000    ;
 11     
 12     input          clk                  ;
 13     input          rst_n                ;
 14     input  [ 1: 0] key_vld              ;
 15
 16     output [ 7: 0] cnt_s                ;
 17     output [ 7: 0] cnt_ms               ;
 18     output         din_vld              ;
 19
 20     reg    [ 7: 0] cnt_s                ;
 21     reg    [ 7: 0] cnt_ms               ;
 22     reg            din_vld              ;
 23     reg    [19: 0] cnt_10ms             ;
 24     reg    [25: 0] cnt                  ;
 25     reg            flag                 ;
 26     reg            flag1                ;
 27     reg    [19:0]  shake_cnt            ;
 28     reg    [1 :0]  key                  ;
 29
 30     wire           add_shake_cnt        ;
 31     wire           end_shake_cnt        ; 
 32     wire           add_cnt_s            ;
 33     wire           end_cnt_s            ;
 34     wire           add_cnt_ms           ;
 35     wire           end_cnt_ms           ;
 36     wire           add_cnt_10ms         ;
 37     wire           end_cnt_10ms         ;
 38         
 39     always @(posedge clk or negedge rst_n)begin
 40         if(rst_n==1'b0)begin
 41             cnt_10ms <= 20'b0;
 42         end
 43         else if(add_cnt_10ms)begin
 44             if(end_cnt_10ms)
 45                 cnt_10ms <= 20'b0;
 46             else 
 47                 cnt_10ms <= cnt_10ms + 1'b1;
 48         end
 49     end
 50     assign add_cnt_10ms= flag;
 51     assign end_cnt_10ms= (add_cnt_10ms && cnt_10ms == TIME_10MS - 1)||key[1];
 52
 53     always  @(posedge clk or negedge rst_n)begin
 54         if(rst_n==1'b0)begin
 55             shake_cnt <= 0;
 56         end
 57         else if(add_shake_cnt)begin
 58             if(end_shake_cnt)
 59                 shake_cnt <= 0;
 60             else
 61                 shake_cnt <= shake_cnt + 1;
 62         end
 63         else begin
 64             shake_cnt <= 0;
 65         end
 66     end
 67     assign  add_shake_cnt = key_vld!=0 && flag1==0;
 68     assign  end_shake_cnt = add_shake_cnt && shake_cnt==TIME_20MS-1;
 69
 70     always  @(posedge clk or negedge rst_n)begin
 71         if(rst_n==1'b0)begin
 72             flag1 <= 0;
 73         end
 74         else if(end_shake_cnt)begin
 75             flag1 <= 1;
 76         end
 77         else if(key_vld==0)begin
 78             flag1 <= 0;
 79         end
 80     end
 81
 82     always  @(posedge clk or negedge rst_n)begin
 83         if(rst_n==1'b0)begin
 84             key <= 0;
 85         end
 86         else if(end_shake_cnt)begin
 87             key <= key_vld;
 88         end
 89         else begin
 90             key <= 0;
 91         end
 92     end
 93
 94     always @(posedge clk or negedge rst_n)begin
 95         if(rst_n==1'b0)begin
 96             flag <= 1'b0;
 97         end
 98        else if(key[1]||end_cnt_s)begin  
 99             flag <= 1'b0;
100         end
101         else if(key[0])begin
102             flag <= ~flag;
103         end
104     end 
105     
106     always @(posedge clk or negedge rst_n)begin
107         if(rst_n==1'b0)begin
108             cnt_ms <= 8'd99;
109         end
110         else if(add_cnt_ms)begin
111             if(end_cnt_ms)
112                 cnt_ms <= 8'd99;
113             else 
114                 cnt_ms <= cnt_ms - 1'b1;
115         end
116     end
117     assign add_cnt_ms = end_cnt_10ms;
118     assign end_cnt_ms = (add_cnt_ms && cnt_ms == 0)||key[1];
119
120     always @(posedge clk or negedge rst_n)begin
121         if(rst_n==1'b0)begin
122             cnt_s <= 8'd23;
123         end
124         else if(add_cnt_s)begin
125             if(end_cnt_s)
126                 cnt_s <= 8'd23;
127             else 
128                cnt_s <= cnt_s - 1'b1;
129         end
130     end
131     assign add_cnt_s = end_cnt_ms;
132     assign end_cnt_s = (add_cnt_s && cnt_s== 8'd0)||key[1];
133     
134     always @(posedge clk or negedge rst_n)begin
135         if(rst_n==1'b0)begin
136             din_vld <= 1'd1;
137         end
138         else if(end_cnt_10ms)begin  
139             din_vld <= 1'd1;
140         end
141         else begin
142             din_vld <= 1'd0;
143         end
144     end
145 endmodule 

BCD译码模块代码

  1 module bcd_water(
  2                    clk                 ,
  3                    rst_n               ,
  4                    din                 ,
  5                    din_vld             ,
  6                    dout                ,
  7                    dout_vld
  8     );
  9
 10     input          clk                 ;
 11     input          rst_n               ;
 12     input  [ 7:0]  din                 ;
 13     input          din_vld             ;
 14     output [11:0]  dout                ;
 15     wire   [11:0]  dout                ;
 16     output         dout_vld            ;
 17     wire           dout_vld            ;
 18     reg    [19:0]  din_temp            ;
 19     reg    [19:0]  din_temp_ff0        ;
 20     reg    [19:0]  din_temp_ff1        ;
 21     reg    [19:0]  din_temp_ff2        ;
 22     reg    [19:0]  din_temp_ff3        ;
 23     reg    [19:0]  din_temp_ff4        ;
 24     wire   [20:0]  din_shift_temp      ;
 25     wire   [20:0]  din_shift_temp_ff0  ;
 26     wire   [20:0]  din_shift_temp_ff1  ;
 27     wire   [20:0]  din_shift_temp_ff2  ;
 28     wire   [20:0]  din_shift_temp_ff3  ;
 29     wire   [ 7:0]  din_a_temp          ;
 30     wire   [ 3:0]  din_b_temp          ;
 31     wire   [ 3:0]  din_c_temp          ;
 32     wire   [ 3:0]  din_d_temp          ;
 33     wire   [ 7:0]  din_add_a_temp      ;
 34     wire   [ 3:0]  din_add_b_temp      ;
 35     wire   [ 3:0]  din_add_c_temp      ;
 36     wire   [ 3:0]  din_add_d_temp      ;
 37     
 38     wire   [ 7:0]  din_a_temp_ff0      ;
 39     wire   [ 3:0]  din_b_temp_ff0      ;
 40     wire   [ 3:0]  din_c_temp_ff0      ;
 41     wire   [ 3:0]  din_d_temp_ff0      ;
 42     wire   [ 7:0]  din_a_temp_ff1      ;
 43     wire   [ 3:0]  din_b_temp_ff1      ;
 44     wire   [ 3:0]  din_c_temp_ff1      ;
 45     wire   [ 3:0]  din_d_temp_ff1      ;
 46     wire   [ 7:0]  din_a_temp_ff2      ;
 47     wire   [ 3:0]  din_b_temp_ff2      ;
 48     wire   [ 3:0]  din_c_temp_ff2      ;
 49     wire   [ 3:0]  din_d_temp_ff2      ;
 50     wire   [ 7:0]  din_a_temp_ff3      ;
 51     wire   [ 3:0]  din_b_temp_ff3      ;
 52     wire   [ 3:0]  din_c_temp_ff3      ;
 53     wire   [ 3:0]  din_d_temp_ff3      ;
 54     wire   [ 7:0]  din_add_a_temp_ff0  ;
 55     wire   [ 3:0]  din_add_b_temp_ff0  ;
 56     wire   [ 3:0]  din_add_c_temp_ff0  ;
 57     wire   [ 3:0]  din_add_d_temp_ff0  ;
 58     wire   [ 7:0]  din_add_a_temp_ff1  ;
 59     wire   [ 3:0]  din_add_b_temp_ff1  ;
 60     wire   [ 3:0]  din_add_c_temp_ff1  ;
 61     wire   [ 3:0]  din_add_d_temp_ff1  ;
 62     wire   [ 7:0]  din_add_a_temp_ff2  ;
 63     wire   [ 3:0]  din_add_b_temp_ff2  ;
 64     wire   [ 3:0]  din_add_c_temp_ff2  ;
 65     wire   [ 3:0]  din_add_d_temp_ff2  ;
 66     wire   [ 7:0]  din_add_a_temp_ff3  ;
 67     wire   [ 3:0]  din_add_b_temp_ff3  ;
 68     wire   [ 3:0]  din_add_c_temp_ff3  ;
 69     wire   [ 3:0]  din_add_d_temp_ff3  ;
 70     reg            dout_vld_temp       ;
 71     reg            dout_vld_temp_ff0   ;
 72     reg            dout_vld_temp_ff1   ;
 73     reg            dout_vld_temp_ff2   ;
 74     reg            dout_vld_temp_ff3   ;
 75     reg            dout_vld_temp_ff4   ;
 76         
 77     always  @(posedge clk or negedge rst_n)begin
 78         if(rst_n==1'b0)begin
 79             din_temp <= 20'b0;
 80         end
 81         else if(din_vld)begin
 82             din_temp <= {9'b0,din,3'b0};
 83         end
 84     end
 85
 86     always  @(posedge clk or negedge rst_n)begin
 87         if(rst_n==1'b0)begin
 88             dout_vld_temp <= 1'b0;
 89         end
 90         else if(din_vld)begin
 91             dout_vld_temp <= 1'b1;
 92         end
 93         else begin
 94             dout_vld_temp <= 1'b0;
 95         end
 96     end
 97     assign  din_a_temp     = din_temp[ 7: 0]                                                     ;
 98     assign  din_b_temp     = din_temp[11: 8]                                                     ;
 99     assign  din_c_temp     = din_temp[15:12]                                                     ;
100     assign  din_d_temp     = din_temp[19:16]                                                     ;
101     assign  din_add_a_temp = din_a_temp                                                          ;
102     assign  din_add_b_temp = din_b_temp + ((din_b_temp>=5)?4'd3:4'd0)                            ;
103     assign  din_add_c_temp = din_c_temp + ((din_c_temp>=5)?4'd3:4'd0)                            ;
104     assign  din_add_d_temp = din_d_temp + ((din_d_temp>=5)?4'd3:4'd0)                            ;
105     assign  din_shift_temp = {din_add_d_temp,din_add_c_temp,din_add_b_temp,din_add_a_temp,1'b0}  ;
106     
107     always  @(posedge clk or negedge rst_n)begin
108         if(rst_n==1'b0)begin
109             din_temp_ff0 <= 20'b0;
110         end
111         else begin
112             din_temp_ff0 <= din_shift_temp[19:0];
113     
114         end
115     end
116     always  @(posedge clk or negedge rst_n)begin
117         if(rst_n==1'b0)begin
118             dout_vld_temp_ff0 <= 1'b0 ;
119         end
120         else begin
121             dout_vld_temp_ff0 <= dout_vld_temp;
122         end
123     end
124     assign  din_a_temp_ff0     = din_temp_ff0[ 7: 0]                                             ;
125     assign  din_b_temp_ff0     = din_temp_ff0[11: 8]                                             ;
126     assign  din_c_temp_ff0     = din_temp_ff0[15:12]                                             ;
127     assign  din_d_temp_ff0     = din_temp_ff0[19:16]                                             ;
128     assign  din_add_a_temp_ff0 = din_a_temp_ff0                                                  ;
129     assign  din_add_b_temp_ff0 = din_b_temp_ff0 + ((din_b_temp_ff0>=5)?4'd3:4'd0)                ;
130     assign  din_add_c_temp_ff0 = din_c_temp_ff0 + ((din_c_temp_ff0>=5)?4'd3:4'd0)                ;
131     assign  din_add_d_temp_ff0 = din_d_temp_ff0 + ((din_d_temp_ff0>=5)?4'd3:4'd0)                ;
132     assign  din_shift_temp_ff0 = {din_add_d_temp_ff0,din_add_c_temp_ff0,din_add_b_temp_ff0,din_add_a_temp_ff0,1'b0};
133
134     always  @(posedge clk or negedge rst_n)begin
135         if(rst_n==1'b0)begin
136             din_temp_ff1 <= 20'b0;
137         end
138         else begin
139             din_temp_ff1 <= din_shift_temp_ff0[19:0];
140         end
141     end
142     always  @(posedge clk or negedge rst_n)begin
143         if(rst_n==1'b0)begin
144             dout_vld_temp_ff1 <= 1'b0;
145         end
146         else begin
147             dout_vld_temp_ff1 <= dout_vld_temp_ff0;
148         end
149     end
150     assign  din_a_temp_ff1     = din_temp_ff1[ 7: 0]                                             ;
151     assign  din_b_temp_ff1     = din_temp_ff1[11: 8]                                             ;
152     assign  din_c_temp_ff1     = din_temp_ff1[15:12]                                             ;
153     assign  din_d_temp_ff1     = din_temp_ff1[19:16]                                             ;
154     assign  din_add_a_temp_ff1 = din_a_temp_ff1                                                  ;
155     assign  din_add_b_temp_ff1 = din_b_temp_ff1 + ((din_b_temp_ff1>=5)?4'd3:4'd0)                ;
156     assign  din_add_c_temp_ff1 = din_c_temp_ff1 + ((din_c_temp_ff1>=5)?4'd3:4'd0)                ;
157     assign  din_add_d_temp_ff1 = din_d_temp_ff1 + ((din_d_temp_ff1>=5)?4'd3:4'd0)                ;
158     assign  din_shift_temp_ff1 = {din_add_d_temp_ff1,din_add_c_temp_ff1,din_add_b_temp_ff1,din_add_a_temp_ff1,1'b0};
159
160     always  @(posedge clk or negedge rst_n)begin 
161         if(rst_n==1'b0)begin
162             din_temp_ff2 <= 20'b0;
163         end
164         else begin
165             din_temp_ff2 <= din_shift_temp_ff1[19:0];
166         end
167     end
168
169     always  @(posedge clk or negedge rst_n)begin 
170         if(rst_n==1'b0)begin
171             dout_vld_temp_ff2 <= 1'b0;
172         end
173         else begin
174             dout_vld_temp_ff2 <= dout_vld_temp_ff1;
175         end
176     end
177     assign  din_a_temp_ff2     = din_temp_ff2[ 7: 0]                                             ;
178     assign  din_b_temp_ff2     = din_temp_ff2[11: 8]                                             ;
179     assign  din_c_temp_ff2     = din_temp_ff2[15:12]                                             ;
180     assign  din_d_temp_ff2     = din_temp_ff2[19:16]                                             ;
181     assign  din_add_a_temp_ff2 = din_a_temp_ff2                                                  ;
182     assign  din_add_b_temp_ff2 = din_b_temp_ff2 + ((din_b_temp_ff2>=5)?4'd3:4'd0)                ;
183     assign  din_add_c_temp_ff2 = din_c_temp_ff2 + ((din_c_temp_ff2>=5)?4'd3:4'd0)                ;
184     assign  din_add_d_temp_ff2 = din_d_temp_ff2 + ((din_d_temp_ff2>=5)?4'd3:4'd0)                ;
185     assign  din_shift_temp_ff2 = {din_add_d_temp_ff2,din_add_c_temp_ff2,din_add_b_temp_ff2,din_add_a_temp_ff2,1'b0};
186
187     always  @(posedge clk or negedge rst_n)begin
188         if(rst_n==1'b0)begin
189             din_temp_ff3 <= 20'b0;
190         end
191         else begin
192             din_temp_ff3 <= din_shift_temp_ff2[19:0];
193         end
194     end
195
196     always  @(posedge clk or negedge rst_n)begin
197         if(rst_n==1'b0)begin
198             dout_vld_temp_ff3 <= 1'b0;
199         end
200         else begin
201             dout_vld_temp_ff3 <= dout_vld_temp_ff2;
202         end
203     end
204     assign  din_a_temp_ff3     = din_temp_ff3[ 7: 0]                                             ;
205     assign  din_b_temp_ff3     = din_temp_ff3[11: 8]                                             ;
206     assign  din_c_temp_ff3     = din_temp_ff3[15:12]                                             ;
207     assign  din_d_temp_ff3     = din_temp_ff3[19:16]                                             ;
208     assign  din_add_a_temp_ff3 = din_a_temp_ff3                                                  ;
209     assign  din_add_b_temp_ff3 = din_b_temp_ff3 + ((din_b_temp_ff3>=5)?4'd3:4'd0)                ;
210     assign  din_add_c_temp_ff3 = din_c_temp_ff3 + ((din_c_temp_ff3>=5)?4'd3:4'd0)                ;
211     assign  din_add_d_temp_ff3 = din_d_temp_ff3 + ((din_d_temp_ff3>=5)?4'd3:4'd0)                ;
212     assign  din_shift_temp_ff3 = {din_add_d_temp_ff3,din_add_c_temp_ff3,din_add_b_temp_ff3,din_add_a_temp_ff3,1'b0};
213
214     always  @(posedge clk or negedge rst_n)begin
215         if(rst_n==1'b0)begin
216             din_temp_ff4 <= 20'b0;
217         end
218         else begin
219             din_temp_ff4 <= din_shift_temp_ff3[19:0];
220         end
221     end
222
223     always  @(posedge clk or negedge rst_n)begin
224         if(rst_n==1'b0)begin
225             dout_vld_temp_ff4 <= 1'b0;
226         end
227         else begin
228             dout_vld_temp_ff4 <= dout_vld_temp_ff3;
229         end
230     end
231     assign  dout     = din_temp_ff4[19:8];
232     assign  dout_vld = dout_vld_temp_ff4 ;
233 endmodule
234     
235     
236     
237     

数码管显示模块代码

  1 module  seg_disp(
  2                  rst_n                    ,
  3                  clk                      ,
  4                  din                      ,
  5                  seg_sel                  , 
  6                  segment                  , 
  7                  bcd_ms                   ,
  8                  bcd_s          
  9     );
 10
 11     parameter  SEG_WID   =  8             ;
 12     parameter  SEG_NUM   =  8             ;
 13     parameter  CNT_WID   =  10            ;
 14     parameter  TIME_20US =  10'd1000      ;
 15               //dp,g,f,e,d,c,b,a,
 16     parameter  NUM_0     =  8'b1100_0000  ;
 17     parameter  NUM_1     =  8'b1111_1001  ;
 18     parameter  NUM_2     =  8'b1010_0100  ;
 19     parameter  NUM_3     =  8'b1011_0000  ;
 20     parameter  NUM_4     =  8'b1001_1001  ;
 21     parameter  NUM_5     =  8'b1001_0010  ;
 22     parameter  NUM_6     =  8'b1000_0010  ;
 23     parameter  NUM_7     =  8'b1111_1000  ;
 24     parameter  NUM_8     =  8'b1000_0000  ;
 25     parameter  NUM_9     =  8'b1001_0000  ;
 26     parameter  NUM_ERR   =  8'b1111_1111  ;
 27     
 28     input  [7:0]            bcd_ms        ;
 29     input  [7:0]            bcd_s         ;
 30     input                   clk           ;
 31     input                   rst_n         ;
 32     input  [SEG_NUM*4-1:0]  din           ;
 33     output [SEG_WID - 1:0]  seg_sel       ;
 34     output [SEG_WID - 1:0]  segment       ;
 35     
 36     reg    [SEG_WID - 1:0]  seg_sel       ;
 37     reg    [SEG_WID - 1:0]  segment       ;
 38     
 39     reg    [CNT_WID - 1:0]  cnt_20us      ;
 40     reg    [SEG_NUM - 1:0]  sel_cnt       ;
 41     
 42     reg    [ 4 - 1 :    0]  seg_tmp       ;
 43     
 44     wire                    add_cnt_20us  ;
 45     wire                    end_cnt_20us  ;
 46     wire                    add_sel_cnt   ;
 47     wire                    end_sel_cnt   ;
 48     
 49     always  @(posedge clk or negedge rst_n)begin
 50         if(rst_n==1'b0)begin
 51             cnt_20us <= 0;
 52         end
 53         else if(add_cnt_20us)begin
 54             if(end_cnt_20us)
 55                 cnt_20us <= 0;
 56             else 
 57                 cnt_20us <= cnt_20us + 1'b1;
 58         end
 59     end
 60     assign add_cnt_20us = 1;
 61     assign end_cnt_20us = add_cnt_20us && cnt_20us == TIME_20US-1;
 62     
 63     always  @(posedge clk or negedge rst_n)begin
 64         if(rst_n==1'b0)begin
 65             sel_cnt <= 0;
 66         end
 67         else if(add_sel_cnt)begin
 68             if(end_sel_cnt)
 69                 sel_cnt <= 0;
 70             else
 71                 sel_cnt <= sel_cnt + 1'b1;
 72         end
 73     end
 74     assign add_sel_cnt = end_cnt_20us;
 75     assign end_sel_cnt = add_sel_cnt && sel_cnt == SEG_NUM-1;
 76     
 77     always  @(posedge clk or negedge rst_n)begin
 78         if(rst_n==1'b0)begin
 79             seg_sel <= {SEG_NUM{1'b1}};
 80         end
 81         else begin
 82             seg_sel <= ~(1'b1 << sel_cnt);
 83         end
 84     end
 85     
 86     always  @(*)begin
 87         seg_tmp = din[(sel_cnt+1)*4-1 -:4]; 
 88     end
 89     
 90     always@(posedge clk or negedge rst_n)begin
 91         if(rst_n==1'b0)begin
 92             segment<=NUM_0;
 93         end
 94         else  begin
 95             case (seg_tmp)
 96                 0 : segment <= NUM_0;
 97                 1 : segment <= NUM_1;
 98                 2 : segment <= NUM_2;
 99                 3 : segment <= NUM_3;
100                 4 : segment <= NUM_4;
101                 5 : segment <= NUM_5;
102                 6 : segment <= NUM_6;
103                 7 : segment <= NUM_7;
104                 8 : segment <= NUM_8;
105                 9 : segment <= NUM_9;
106                 default : segment <= NUM_ERR;
107             endcase
108         end
109     end
110 endmodule


技术交流QQ群:544453837 

了解>>>至简设计法

   拓展阅读