基于FPGA的篮球倒计时的设计和实现_FPGA倒计时模块应用_明德扬资料

2017-08-02  FPGA培训

篮球倒计时

1功能概述

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

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

具体功能要求:

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

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

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

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

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

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

 

2 设计思路

我们把本项目设计划分成三个模块:倒计时模块、BCD译码模块和数码管显示模块。如下:

    顶层模块的信号列表如下:

信号名

I/O

位宽

说明

clk

I

1

系统工作时钟50MHz。

rst_n

I

1

系统复位信号,低电平有效。

key_vld

I

2

独立按键

segment

O

8

数码管段选

seg_sel

O

8

数码管位选

 

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

本模块的信号列表如下:

信号名

I/O

位宽

说明

clk

I

1

系统工作时钟50MHz。

rst_n

I

1

系统复位信号,低电平有效。

cnt_s

O

8

秒计数器

cnt_ms

O

8

毫秒计数器

key_vld

I

2

两个独立按键

din_vld

O

1

输出数据有效指示信号

 

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

本模块的信号列表如下:

信号名

I/O

位宽

说明

clk

I

1

系统工作时钟50MHz。

rst_n

I

1

系统复位信号,低电平有效。

din

I

32

输入要译码的数据

din_vld

I

1

输入数据有效指示信号

dout

O

12

输出的BCD数据,共12比特,每4比特一组,分别表示百、十、个位的值

dout_vld

O

1

输出数据有效指示信号

 

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

本模块的信号列表如下:

信号名

I/O

位宽

说明

clk

I

1

系统工作时钟50MHz。

rst_n

I

1

系统复位信号,低电平有效。

din

I

32

每个数码管的时间数据

seg_sel

O

8

数码管位选

segment

O

8

数码管段选

 

 

 

3   程序设计

顶层模块代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

module top(

              clk                 ,

              rst_n               ,

              key_vld             ,

              seg_sel             ,

              segment  

      );

 

      parameter  SEG_NUM   =    8   ;

 

      input                   clk      ;

      input                   rst_n    ;

      input   [1:0]           key_vld   ;

      output  [7:0]           seg_sel    ;

      output  [7:0]           segment   ;

 

      wire                    din_vld  ;

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

      wire    [7:0]           cnt_ms   ;

      wire    [7:0]           cnt_s     ;

      wire    [7:0]           bcd_ms   ;

      wire    [7:0]           bcd_s    ;

 

 

      cnt_down  U1(

          .clk        (clk    )  ,

              .rst_n      (rst_n  )   ,

          .key_vld    (key_vld)  ,

          .cnt_ms     (cnt_ms )  ,

          .cnt_s      (cnt_s  )  ,

          .din_vld    (din_vld)

      );

 

      seg_disp #(.SEG_NUM(4))  U2(

          .clk        (clk    )  ,

              .rst_n      (rst_n  )   ,

          .seg_sel    (seg_sel)   ,

          .segment    (segment)  ,

          .din        ({bcd_s,bcd_ms})

      );

 

      bcd_water U3(

      .clk       (clk    )  ,

              .rst_n     (rst_n  )   ,

              .din       (cnt_ms )  ,

              .din_vld   (din_vld)   ,

              .dout      (bcd_ms )  ,

              .dout_vld  (dout_vld )

      );

 

      bcd_water U4(

  .clk     (clk    ) ,

              .rst_n   (rst_n  ) ,

              .din     (cnt_s  ) ,

              .din_vld (din_vld) ,

              .dout    (bcd_s  ) ,

              .dout_vld(dout_vld)

      );

endmodule

 

倒计时模块代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

module cnt_down(

clk                       ,

rst_n                      ,

cnt_s                     ,

cnt_ms                    ,

key_vld                   ,

din_vld  

    );

    parameter  TIME_10MS = 20'd500_000  ;

    parameter  TIME_20MS =   500000    ;

 

    input  clk                    ;

    input  rst_n                  ;

    input  [ 1: 0]  key_vld                ;

 

    output [ 7: 0]  cnt_s                  ;

    output [ 7: 0]  cnt_ms                ;

    output       din_vld                ;

 

    reg   [ 7: 0]  cnt_s                 ;

reg   [ 7: 0]  cnt_ms                ;

    reg          din_vld               ;

    reg   [19: 0]  cnt_10ms             ;

    reg   [25: 0]  cnt                  ;

    reg      flag                 ;

    reg          flag1                 ;

    reg   [19:0]  shake_cnt             ;

    reg   [1 :0]  key                  ;

 

    wire         add_shake_cnt        ;

    wire         end_shake_cnt        ;

    wire    add_cnt_s           ;

    wire    end_cnt_s           ;

    wire    add_cnt_ms          ;

    wire    end_cnt_ms          ;

    wire    add_cnt_10ms        ;

    wire    end_cnt_10ms        ;

 

    always @(posedge clk or negedge rst_n)begin

if(rst_n==1'b0)begin

cnt_10ms <= 20'b0;

end

else if(add_cnt_10ms)begin

if(end_cnt_10ms)

cnt_10ms <= 20'b0;

else

    cnt_10ms <= cnt_10ms + 1'b1;

end

    end

    assign add_cnt_10ms= flag;

    assign end_cnt_10ms= (add_cnt_10ms && cnt_10ms == TIME_10MS - 1)||key[1];

 

    always  @(posedge clk or negedge rst_n)begin

        if(rst_n==1'b0)begin

            shake_cnt <= 0;

        end

        else if(add_shake_cnt)begin

            if(end_shake_cnt)

                shake_cnt <= 0;

            else

                shake_cnt <= shake_cnt + 1;

        end

        else begin

            shake_cnt <= 0;

        end

    end

    assign  add_shake_cnt = key_vld!=0 && flag1==0;

    assign  end_shake_cnt = add_shake_cnt && shake_cnt==TIME_20MS-1;

 

    always  @(posedge clk or negedge rst_n)begin

        if(rst_n==1'b0)begin

            flag1 <= 0;

        end

        else if(end_shake_cnt)begin

            flag1 <= 1;

        end

        else if(key_vld==0)begin

            flag1 <= 0;

        end

    end

 

    always  @(posedge clk or negedge rst_n)begin

        if(rst_n==1'b0)begin

            key <= 0;

        end

        else if(end_shake_cnt)begin

            key <= key_vld;

        end

        else begin

            key <= 0;

        end

    end

 

    always @(posedge clk or negedge rst_n)begin

if(rst_n==1'b0)begin

flag <= 1'b0;

end

       else if(key[1]||end_cnt_s)begin  

flag <= 1'b0;

end

else if(key[0])begin

flag <= ~flag;

end

    end

 

    always @(posedge clk or negedge rst_n)begin

if(rst_n==1'b0)begin

cnt_ms <= 8'd99;

end

else if(add_cnt_ms)begin

if(end_cnt_ms)

cnt_ms <= 8'd99;

else

    cnt_ms <= cnt_ms - 1'b1;

end

    end

    assign add_cnt_ms = end_cnt_10ms;

    assign end_cnt_ms = (add_cnt_ms && cnt_ms == 0)||key[1];

 

    always @(posedge clk or negedge rst_n)begin

if(rst_n==1'b0)begin

cnt_s <= 8'd23;

end

else if(add_cnt_s)begin

if(end_cnt_s)

cnt_s <= 8'd23;

else

   cnt_s <= cnt_s - 1'b1;

end

    end

    assign add_cnt_s = end_cnt_ms;

    assign end_cnt_s = (add_cnt_s && cnt_s== 8'd0)||key[1];

 

    always @(posedge clk or negedge rst_n)begin

if(rst_n==1'b0)begin

din_vld <= 1'd1;

end

else if(end_cnt_10ms)begin  

din_vld <= 1'd1;

end

else begin

din_vld <= 1'd0;

end

    end

endmodule

 

BCD译码模块代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

 

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

 

130

 

131

 

132

 

133

134

135

136

137

138

139

140

141

142

143

144

145146

147

148

149

150

151

152

153

154

155

156

 

157

 

158

 

159

 

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

 

184

 

185

 

186

 

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

 

211

 

212

 

213

 

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

module bcd_water(

                 clk                ,

                 rst_n              ,

                 din               ,

                 din_vld            ,

                 dout              ,

                 dout_vld

    );

 

    input         clk               ;

    input         rst_n             ;

    input  [ 7:0]   din              ;

    input         din_vld           ;

output [11:0]   dout             ;

    wire   [11:0]  dout             ;

    output        dout_vld          ;

    wire          dout_vld         ;

    reg    [19:0]  din_temp         ;

    reg    [19:0]  din_temp_ff0      ;

    reg    [19:0]  din_temp_ff1      ;

    reg    [19:0]  din_temp_ff2      ;

    reg    [19:0]  din_temp_ff3      ;

    reg    [19:0]  din_temp_ff4      ;

    wire   [20:0]  din_shift_temp     ;

    wire   [20:0]  din_shift_temp_ff0  ;

    wire   [20:0]  din_shift_temp_ff1  ;

    wire   [20:0]  din_shift_temp_ff2  ;

    wire   [20:0]  din_shift_temp_ff3  ;

    wire   [ 7:0]  din_a_temp        ;

    wire   [ 3:0]  din_b_temp        ;

    wire   [ 3:0]  din_c_temp        ;

    wire   [ 3:0]  din_d_temp        ;

    wire   [ 7:0]  din_add_a_temp    ;

    wire   [ 3:0]  din_add_b_temp    ;

    wire   [ 3:0]  din_add_c_temp    ;

    wire   [ 3:0]  din_add_d_temp    ;

 

    wire   [ 7:0]  din_a_temp_ff0      ;

    wire   [ 3:0]  din_b_temp_ff0      ;

    wire   [ 3:0]  din_c_temp_ff0      ;

    wire   [ 3:0]  din_d_temp_ff0      ;

    wire   [ 7:0]  din_a_temp_ff1      ;

    wire   [ 3:0]  din_b_temp_ff1      ;

    wire   [ 3:0]  din_c_temp_ff1      ;

    wire   [ 3:0]  din_d_temp_ff1      ;

    wire   [ 7:0]  din_a_temp_ff2      ;

    wire   [ 3:0]  din_b_temp_ff2      ;

    wire   [ 3:0]  din_c_temp_ff2      ;

    wire   [ 3:0]  din_d_temp_ff2      ;

    wire   [ 7:0]  din_a_temp_ff3      ;

    wire   [ 3:0]  din_b_temp_ff3      ;

    wire   [ 3:0]  din_c_temp_ff3      ;

    wire   [ 3:0]  din_d_temp_ff3      ;

    wire   [ 7:0]  din_add_a_temp_ff0  ;

    wire   [ 3:0]  din_add_b_temp_ff0  ;

    wire   [ 3:0]  din_add_c_temp_ff0  ;

    wire   [ 3:0]  din_add_d_temp_ff0  ;

    wire   [ 7:0]  din_add_a_temp_ff1  ;

    wire   [ 3:0]  din_add_b_temp_ff1  ;

    wire   [ 3:0]  din_add_c_temp_ff1  ;

    wire   [ 3:0]  din_add_d_temp_ff1  ;

    wire   [ 7:0]  din_add_a_temp_ff2  ;

    wire   [ 3:0]  din_add_b_temp_ff2  ;

    wire   [ 3:0]  din_add_c_temp_ff2  ;

    wire   [ 3:0]  din_add_d_temp_ff2  ;

    wire   [ 7:0]  din_add_a_temp_ff3  ;

    wire   [ 3:0]  din_add_b_temp_ff3  ;

    wire   [ 3:0]  din_add_c_temp_ff3  ;

    wire   [ 3:0]  din_add_d_temp_ff3  ;

    reg          dout_vld_temp       ;

    reg          dout_vld_temp_ff0   ;

    reg          dout_vld_temp_ff1   ;

    reg          dout_vld_temp_ff2   ;

    reg          dout_vld_temp_ff3   ;

    reg          dout_vld_temp_ff4   ;

    always  @(posedge clk or negedge rst_n)begin

        if(rst_n==1'b0)begin

            din_temp <= 20'b0;

        end

        else if(din_vld)begin

            din_temp <= {9'b0,din,3'b0};

        end

    end

 

    always  @(posedge clk or negedge rst_n)begin

        if(rst_n==1'b0)begin

            dout_vld_temp <= 1'b0;

        end

        else if(din_vld)begin

            dout_vld_temp <= 1'b1;

        end

        else begin

            dout_vld_temp <= 1'b0;

        end

    end

assigndin_a_temp      = din_temp[7: 0] ;

    assign  din_b_temp    = din_temp[11: 8]  ;

    assign  din_c_temp    = din_temp[15:12] ;

    assign  din_d_temp    = din_temp[19:16;

    assign  din_add_a_temp = din_a_temp   ;

    assign  din_add_b_temp = din_b_temp + ((din_b_temp>=5)?4'd3:4'd0) ;

    assign  din_add_c_temp = din_c_temp + ((din_c_temp>=5)?4'd3:4'd0)  ;

    assign  din_add_d_temp = din_d_temp + ((din_d_temp>=5)?4'd3:4'd0)  ;

assign  din_shift_temp = {din_add_d_temp,din_add_c_temp,

din_add_b_temp,din_add_a_temp,1'b0} ;

 

    always  @(posedge clk or negedge rst_n)begin

        if(rst_n==1'b0)begin

            din_temp_ff0 <= 20'b0;

        end

        else begin

            din_temp_ff0 <= din_shift_temp[19:0];

        end

end

 

    always  @(posedge clk or negedge rst_n)begin

        if(rst_n==1'b0)begin

            dout_vld_temp_ff0 <= 1'b0 ;

        end

        else begin

            dout_vld_temp_ff0 <= dout_vld_temp;

        end

    end

    assign  din_a_temp_ff0     = din_temp_ff0[ 7: 0] ;

    assign  din_b_temp_ff0     = din_temp_ff0[11: 8]  ;

    assign  din_c_temp_ff0     = din_temp_ff0[15:12]  ;

    assign  din_d_temp_ff0     = din_temp_ff0[19:16];

    assign  din_add_a_temp_ff0 = din_a_temp_ff0      ;

assign  din_add_b_temp_ff0 = din_b_temp_ff0 +

 ((din_b_temp_ff0>=5)?4'd3:4'd0) ;

assign  din_add_c_temp_ff0 = din_c_temp_ff0 +

((din_c_temp_ff0>=5)?4'd3:4'd0) ;

assign  din_add_d_temp_ff0 = din_d_temp_ff0 +

 ((din_d_temp_ff0>=5)?4'd3:4'd0);

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};

 

    always  @(posedge clk or negedge rst_n)begin

        if(rst_n==1'b0)begin

            din_temp_ff1 <= 20'b0;

        end

        else begin

            din_temp_ff1 <= din_shift_temp_ff0[19:0];

        end

end

 

    always  @(posedge clk or negedge rst_n)begin

        if(rst_n==1'b0)begin

            dout_vld_temp_ff1 <= 1'b0;

        end

        else begin

            dout_vld_temp_ff1 <= dout_vld_temp_ff0;

        end

    end

    assign  din_a_temp_ff1     = din_temp_ff1[ 7: 0] ;

    assign  din_b_temp_ff1     = din_temp_ff1[11: 8]  ;

    assign  din_c_temp_ff1     = din_temp_ff1[15:12]  ;

    assign  din_d_temp_ff1     = din_temp_ff1[19:16]  ;

    assign  din_add_a_temp_ff1 = din_a_temp_ff1     ;

assign  din_add_b_temp_ff1 = din_b_temp_ff1 +

 ((din_b_temp_ff1>=5)?4'd3:4'd0) ;

assign  din_add_c_temp_ff1 = din_c_temp_ff1 +

 ((din_c_temp_ff1>=5)?4'd3:4'd0);

assign  din_add_d_temp_ff1 = din_d_temp_ff1 +

 ((din_d_temp_ff1>=5)?4'd3:4'd0);

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};

 

    always  @(posedge clk or negedge rst_n)begin

        if(rst_n==1'b0)begin

            din_temp_ff2 <= 20'b0;

        end

        else begin

            din_temp_ff2 <= din_shift_temp_ff1[19:0];

        end

    end

 

    always  @(posedge clk or negedge rst_n)begin

        if(rst_n==1'b0)begin

            dout_vld_temp_ff2 <= 1'b0;

        end

        else begin

            dout_vld_temp_ff2 <= dout_vld_temp_ff1;

        end

    end

    assign  din_a_temp_ff2     = din_temp_ff2[ 7: 0];

    assign  din_b_temp_ff2     = din_temp_ff2[11: 8]  ;

    assign  din_c_temp_ff2     = din_temp_ff2[15:12]  ;

    assign  din_d_temp_ff2     = din_temp_ff2[19:16] ;

    assign  din_add_a_temp_ff2 = din_a_temp_ff2     ;

assign  din_add_b_temp_ff2 = din_b_temp_ff2 +

((din_b_temp_ff2>=5)?4'd3:4'd0);

assign  din_add_c_temp_ff2 = din_c_temp_ff2 +

((din_c_temp_ff2>=5)?4'd3:4'd0);

assign  din_add_d_temp_ff2 = din_d_temp_ff2 +

((din_d_temp_ff2>=5)?4'd3:4'd0);

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};

 

    always  @(posedge clk or negedge rst_n)begin

        if(rst_n==1'b0)begin

            din_temp_ff3 <= 20'b0;

        end

        else begin

            din_temp_ff3 <= din_shift_temp_ff2[19:0];

        end

    end

 

    always  @(posedge clk or negedge rst_n)begin

        if(rst_n==1'b0)begin

            dout_vld_temp_ff3 <= 1'b0;

        end

        else begin

            dout_vld_temp_ff3 <= dout_vld_temp_ff2;

        end

    end

    assign  din_a_temp_ff3     = din_temp_ff3[ 7: 0]   ;

    assign  din_b_temp_ff3     = din_temp_ff3[11: 8]  ;

    assign  din_c_temp_ff3     = din_temp_ff3[15:12]  ;

    assign  din_d_temp_ff3     = din_temp_ff3[19:16]  ;

    assign  din_add_a_temp_ff3 = din_a_temp_ff3      ;

assign  din_add_b_temp_ff3 = din_b_temp_ff3 +

((din_b_temp_ff3>=5)?4'd3:4'd0);

assign  din_add_c_temp_ff3 = din_c_temp_ff3 +

((din_c_temp_ff3>=5)?4'd3:4'd0);

assign  din_add_d_temp_ff3 = din_d_temp_ff3 +

((din_d_temp_ff3>=5)?4'd3:4'd0);

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};

 

    always  @(posedge clk or negedge rst_n)begin

        if(rst_n==1'b0)begin

            din_temp_ff4 <= 20'b0;

        end

        else begin

            din_temp_ff4 <= din_shift_temp_ff3[19:0];

        end

    end

 

    always  @(posedge clk or negedge rst_n)begin

        if(rst_n==1'b0)begin

            dout_vld_temp_ff4 <= 1'b0;

        end

        else begin

            dout_vld_temp_ff4 <= dout_vld_temp_ff3;

        end

    end

    assign  dout     = din_temp_ff4[19:8];

    assign  dout_vld = dout_vld_temp_ff4 ;

endmodule

 

 

数码管显示模块代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

module  seg_disp(

                 rst_n                    ,

                 clk                      ,

                 din                      ,

                 seg_sel                  ,

                 segment                  ,

 bcd_ms               ,

 bcd_s          

    );

 

    parameter  SEG_WID   =  8             ;

    parameter  SEG_NUM   =  8            ;

    parameter  CNT_WID   =  10            ;

    parameter  TIME_20US =  10'd1000      ;

 

    parameter  NUM_0     =  8'b1100_0000  ;

    parameter  NUM_1     =  8'b1111_1001  ;

    parameter  NUM_2     =  8'b1010_0100  ;

    parameter  NUM_3     =  8'b1011_0000  ;

    parameter  NUM_4     =  8'b1001_1001  ;

    parameter  NUM_5     =  8'b1001_0010  ;

    parameter  NUM_6     =  8'b1000_0010  ;

    parameter  NUM_7     =  8'b1111_1000  ;

    parameter  NUM_8     =  8'b1000_0000  ;

    parameter  NUM_9     =  8'b1001_0000  ;

    parameter  NUM_ERR   =  8'b1111_1111 ;

 

    input  [7:0]            bcd_ms          ;

    input  [7:0]            bcd_s           ;

    input                  clk             ;

    input                  rst_n           ;

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

 

    output [SEG_WID - 1:0]  seg_sel         ;

    output [SEG_WID - 1:0]  segment        ;

 

    reg    [SEG_WID - 1:0]  seg_sel        ;

    reg    [SEG_WID - 1:0]  segment       ;    

    reg    [CNT_WID - 1:0]  cnt_20us      ;

    reg    [SEG_NUM - 1:0]  sel_cnt       ;

    reg    [ 4 - 1 :    0]     seg_tmp       ;

 

    wire                  add_cnt_20us   ;

    wire                  end_cnt_20us   ;

    wire                  add_sel_cnt    ;

    wire                  end_sel_cnt    ;

 

    always  @(posedge clk or negedge rst_n)begin

        if(rst_n==1'b0)begin

            cnt_20us <= 0;

        end

        else if(add_cnt_20us)begin

            if(end_cnt_20us)

                cnt_20us <= 0;

            else

                cnt_20us <= cnt_20us + 1'b1;

        end

    end

    assign add_cnt_20us = 1;

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

 

    always  @(posedge clk or negedge rst_n)begin

        if(rst_n==1'b0)begin

            sel_cnt <= 0;

        end

        else if(add_sel_cnt)begin

            if(end_sel_cnt)

                sel_cnt <= 0;

            else

                sel_cnt <= sel_cnt + 1'b1;

        end

    end

    assign add_sel_cnt = end_cnt_20us;

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

 

    always  @(posedge clk or negedge rst_n)begin

        if(rst_n==1'b0)begin

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

        end

        else begin

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

        end

    end

 

    always  @(*)begin

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

    end

 

    always@(posedge clk or negedge rst_n)begin

        if(rst_n==1'b0)begin

            segment<=NUM_0;

        end

        else  begin

            case (seg_tmp)

                0 : segment <= NUM_0;

                1 : segment <= NUM_1;

                2 : segment <= NUM_2;

                3 : segment <= NUM_3;

                4 : segment <= NUM_4;

                5 : segment <= NUM_5;

                6 : segment <= NUM_6;

                7 : segment <= NUM_7;

                8 : segment <= NUM_8;

                9 : segment <= NUM_9;

                default : segment <= NUM_ERR;

            endcase

        end

    end

endmodule

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。如发现有害或侵权内容,请点击这里 或 拨打24小时举报电话:4000070609 与我们联系。

    猜你喜欢

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多
    喜欢该文的人也喜欢 更多