新闻  |   论坛  |   博客  |   在线研讨会
基于FPGA的verilog万年历程序_万年历设计_明德扬资料
billow兔 | 2017-08-03 09:21:02    阅读:695   发布文章

 

 

 

 

 

 

 

 

 

 

至简设计法--万年历

明德扬科技教育有限公司

 

 

 

 

官  网:www.mdy-edu.com

淘  宝:mdy-edu.taobao.com

QQ  群:544453837

QQ咨询:158063679


 

万年历

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 设计思路

首先根据所需要的功能,列出工程顶层的输入输出信号列表。如下表:

信号名

I/O

位宽

说明

clk

I

1

系统工作时钟100MHz。

rst_n

I

1

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

key_col

I

4

矩阵键盘按键列信号

key_row

O

4

矩阵键盘按键行信号

segment

O

8

数码管段选信号

seg_sel

O

8

数码管位选信号

 

我们可以把工程划分成三个模块,分别是万年历计数模块、按键模块和数码管显示模块。

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得到年份。本模块还自动计算当年是否是平闰年。

信号列表如下:

信号名

I/O

位宽

说明

clk

I

1

系统工作时钟50MHz。

rst_n

I

1

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

key_num

I

4

输入按键值

key_vld

I

1

按键输入有效指示

dout

O

24

时钟数据输出

 

2. 按键模块——4x4矩阵键盘,实现了矩阵键盘的扫描并使用按键消抖功能。

信号列表如下:

信号名

I/O

位宽

说明

clk

I

1

系统工作时钟50MHz。

rst_n

I

1

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

key_col

I

4

矩阵键盘列信号

key_row

O

4

矩阵键盘行信号

key_out

O

4

按键位置信号

key_vld

O

1

按键有效信号

 

3. 数码管模块——实现将年月日的信息显示在数码管上。

信号列表如下:

信号名

I/O

位宽

说明

clk

I

1

系统工作时钟50MHz。

rst_n

I

1

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

din

I

32

每个数码管的时间数据

din_vld

I

8

数据有效信号

seg_sel

O

8

数码管位选信号

seg_ment

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

module calendar_top(

                   clk         ,

                   rst_n       ,

                   key_col     ,

                   key_row    ,

                   segment    ,

                   seg_sel

      );

 

      parameter   SEG_NUM =     8      ;

      parameter   SEG_W   =       8    ;

      parameter   TIME_1S =50_000_000  ;

 

      input                  clk       ;

      input                    rst_n      ;

      input  [3:0]           key_col     ;

 

      output [SEG_W-1:0]     segment ;

      output [SEG_NUM-1:0]   seg_sel ;

      output [3:0]            key_row ;

 

      wire   [SEG_W-1:0]     segment ;

      wire   [SEG_NUM-1:0]   seg_sel ;

 

      wire   [3:0]           key_num ;

      wire                   key_vld ;

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

      wire   [SEG_NUM-1:0]   din_vld ;

 

      assign din_vld = 8'b11111111   ;

 

      key_scan      u_key_scan(

                             .clk    (clk      )           ,

                             .rst_n  (rst_n    )            ,

                             .key_col(key_col)           ,

                               .key_row(key_row)          ,

                               .key_out(key_num)          ,

                               .key_vld(key_vld)  

                            );

 

      seg_display   u_seg_display(

                             .clk     (clk       )         ,

                             .rst_n   (rst_n     )          ,

                             .din     (data_out)         ,

                             .din_vld   (din_vld )          ,       

                             .segment (segment )         ,

                             .seg_sel   (seg_sel )

                        );

 

      counter #(.TIME_1S(TIME_1S))      u_counter(

                            .clk          (clk          ),

                            .rst_n         (rst_n          ),

                            .key_vld      (key_vld      ),

                            .key_num      (key_num      ),

                            .dout          (data_out       )

                         );

 

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

module seg_display(

                  clk      ,

                  rst_n  ,

                  din    ,

                  din_vld,

                  segment,

                  seg_sel

      );

 

      `include "clogb2.v"

 

      parameter      SEG_W     =         8          ;

      parameter      SEG_NUM   =        8         ;

      parameter      DIS_NUM   =        10          ;

      parameter      TIME_20US =   1000          ;

      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      SEG_NUM_C  = clogb2(SEG_NUM)-1;

 

 

      input                 clk      ;

      input                 rst_n    ;

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

      input[SEG_NUM-1:0]      din_vld  ;

 

      output                segment ;

      output                  seg_sel  ;

 

      reg   [SEG_W-1:0]     segment ;

      reg   [SEG_NUM-1:0]   seg_sel    ;

 

      wire  [3:0]           seg_tmp  ;

      reg   [4*SEG_NUM-1:0]   din_ff0  ;

      reg   [9:0]           clk_cnt  ;

      reg   [2:0]           sel_cnt  ;

      integer               i        ;    

 

      wire                clk_cnt_add;

      wire                clk_cnt_end;

      wire                sel_cnt_add;

      wire                sel_cnt_end;

 

      always  @(posedge clk or negedge   rst_n)begin

        if(rst_n==1'b0)begin

            segment <= NUM_0;

        end

        else begin

            case(seg_tmp)

                4'd0 : segment <=   NUM_0   ;

                4'd1 : segment <=   NUM_1   ;

                  4'd2 : segment   <= NUM_2   ;

                4'd3 : segment <=   NUM_3   ;

                4'd4 : segment <=   NUM_4   ;

                4'd5 : segment <=   NUM_5   ;

                4'd6 : segment <=   NUM_6   ;

                4'd7 : segment <= NUM_7   ;

                4'd8 : segment <=   NUM_8   ;

                4'd9 : segment <=   NUM_9   ;

                default : segment <=   NUM_0;

            endcase

        end

      end

 

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

 

      always  @(posedge clk or negedge   rst_n)begin

        if(rst_n==1'b0)begin

            din_ff0 <= 0;

        end

        else begin

            for(i=0;i<SEG_NUM;i=i+1)begin

                if(din_vld[i]==1'b1)begin

                    din_ff0[(i+1)*4-1 -:4]   <= din[(i+1)*4-1 -:4];

                end

                else begin

                    din_ff0[(i+1)*4-1 -:4]   <= din_ff0[(i+1)*4-1 -:4];

                end

            end

        end

      end

      

      always @(posedge clk or negedge rst_n)begin

        if (!rst_n)begin

            clk_cnt <= 0;

        end

        else if(clk_cnt_add)begin

            if(clk_cnt_end)

                clk_cnt <= 0;

            else

                clk_cnt <= clk_cnt + 1;

        end

      end

      assign clk_cnt_add = 1;     

      assign clk_cnt_end = clk_cnt_add && clk_cnt == TIME_20US -   1;         

 

      always @(posedge clk or negedge rst_n)begin

        if (!rst_n)begin

            sel_cnt <= 0;

        end

        else if(sel_cnt_add)begin

            if(sel_cnt_end)

                sel_cnt <= 0;

            else

                sel_cnt <= sel_cnt + 1;

        end

      end

      assign sel_cnt_add = clk_cnt_end;     

      assign sel_cnt_end = sel_cnt_add && 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

 

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

146

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

module  key_scan(

                 clk    ,

                 rst_n  ,

                 key_col,

                 key_row,

                 key_out,

                 key_vld  

               );

 

 

      parameter      KEY_W    =     4 ;

      parameter      COL      =     0 ;

      parameter      ROW      =     1 ;

      parameter      DLY      =     2 ;

      parameter      FIN      =     3 ;

      parameter      COL_CNT  =     16;

      parameter      TIME_20MS=   1000000;

 

      input               clk    ;

      input               rst_n  ;

      input  [3:0]        key_col;

 

      output              key_vld;

      output[3:0]         key_out;

      output[KEY_W-1:0]   key_row;

 

      reg   [3:0]         key_out;

      reg   [KEY_W-1:0]   key_row;

      reg                 key_vld;

 

      reg   [ 3:0]        key_col_ff0   ;

      reg   [ 3:0]        key_col_ff1   ;

      reg   [ 1:0]        key_col_get   ;

      reg                   shake_flag    ;

      reg                   shake_flag_ff0;

      reg   [ 3:0]        state_c       ;

      reg   [19:0]        shake_cnt     ;

      reg   [ 3:0]        state_n       ;

      reg   [ 1:0]        row_index     ;

      reg   [15:0]        row_cnt       ;

       reg   [ 2:0]        x             ;

 

 

      always  @(posedge clk or negedge   rst_n)begin

        if(rst_n==1'b0)begin

            key_col_ff0 <= 4'b1111;

            key_col_ff1 <= 4'b1111;

        end

        else begin

            key_col_ff0 <= key_col    ;

            key_col_ff1 <= key_col_ff0;

        end

      end

 

      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_col_ff1!=4'hf && shake_flag==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

            shake_flag <= 0;

        end

        else if(end_shake_cnt) begin

            shake_flag <= 1'b1;

        end

        else if(key_col_ff1==4'hf) begin

            shake_flag <= 1'b0;

        end

      end

 

      always  @(posedge clk or negedge   rst_n)begin

        if(rst_n==1'b0)begin

            state_c <= COL;

        end

        else begin

            state_c <= state_n;

        end

      end

 

      always@(*)begin

        case(state_c)

            COL:begin

                if(col2row_start)begin

                    state_n = ROW;

                end

                else begin

                    state_n = state_c;

                end

            end

            ROW:begin

                if(row2dly_start)begin

                    state_n = DLY;

                end

                else begin

                    state_n = state_c;

                end

            end

            DLY:begin

                if(dly2fin_start)begin

                    state_n = FIN;

                end

                else begin

                    state_n = state_c;

                end

            end

            FIN:begin

                if(fin2col_start)begin

                    state_n = COL;

                end

                else begin

                    state_n = state_c;

                end

            end

            default:begin

                state_n = COL;

            end

        endcase

      end

 

      assign  col2row_start =   state_c==COL && end_shake_cnt;

      assign  row2dly_start =   state_c==ROW && end_row_index;

      assign  dly2fin_start =   state_c==DLY && end_row_index;

      assign  fin2col_start =   state_c==FIN && key_col_ff1==4'hf;

 

      always  @(posedge clk or negedge   rst_n)begin

        if(rst_n==1'b0)begin

            key_row <= 4'b0;

        end

        else if(state_c==ROW)begin

            key_row <= ~(1'b1 <<   row_index);

        end

        else begin

            key_row <= 4'b0;

        end

      end

 

      always  @(posedge clk or negedge   rst_n)begin

        if(rst_n==1'b0)begin

            row_cnt <= 0;

        end

        else if(add_row_cnt) begin

            if(end_row_cnt)

                row_cnt <= 0;

            else

                row_cnt <= row_cnt + 1;

        end

      end

      assign add_row_cnt = state_c==ROW || state_c==DLY;

      assign end_row_cnt = add_row_cnt && row_cnt==COL_CNT-1;

 

      always  @(posedge clk or negedge   rst_n)begin

        if(rst_n==1'b0)begin

              row_index <= 0;

        end

        else if(add_row_index) begin

            if(end_row_index)

                row_index <= 0;

            else

                row_index <= row_index +   1;

        end

      end

      assign add_row_index = end_row_cnt;

      assign end_row_index = add_row_index && row_index==x-1;

 

      always  @(*)begin

        if(state_c==ROW)

            x = 4;

        else

            x = 1;

      end

 

      always  @(posedge clk or negedge   rst_n)begin

        if(rst_n==1'b0)begin

            key_col_get <= 0;

        end

        else if(col2row_start) begin

            if(key_col_ff1==4'b1110)

                key_col_get <= 0;

            else if(key_col_ff1==4'b1101)

                key_col_get <= 1;

            else if(key_col_ff1==4'b1011)

                key_col_get <= 2;

            else

                key_col_get <= 3;

        end

      end

 

      always  @(posedge clk or negedge   rst_n)begin

        if(rst_n==1'b0)begin

            key_out <= 0;

          end

        else if(state_c==ROW &&   end_row_cnt)begin

            key_out <=   {row_index,key_col_get};

        end

        else begin

            key_out <= 0;

        end

      end

 

      always  @(posedge clk or negedge   rst_n)begin

        if(rst_n==1'b0)begin

            key_vld <= 1'b0;

        end

        else if(state_c==ROW &&   end_row_cnt && key_col_ff1[key_col_get]==1'b0)begin

            key_vld <= 1'b1;

        end

        else begin

            key_vld <= 1'b0;

        end

      end

 

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

146

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

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

module counter(

                clk     ,

                rst_n   ,

                key_vld ,

                key_num ,

                dout   

);

 

 

      parameter      DATA_W    =         32;

      parameter      TIME_1S   = 50_000_000;

 

      input               clk              ;

      input               rst_n            ;

      input               key_vld          ;

      input[3:0]           key_num          ;

 

      output              dout            ;

 

      reg   [DATA_W-1:0]  dout            ;

 

      wire                  start_set        ;

      wire                  stop_set        ;

      reg                   flag_set         ;

      reg  [25:0]          clk_cnt          ;

      wire                  clk_cnt_add      ;

      wire                  clk_cnt_end      ;

      reg  [4 :0]          dat_cnt          ;

      wire [4 :0]           dat_cnt_tmp      ;

      wire                  dat_cnt_add      ;

      wire                  dat_cnt_end      ;

       wire   [3 :0]           dat_one          ;

      wire [3 :0]           dat_ten          ;

      wire                  mon_cnt_h        ;

      wire                  mon_cnt_l        ;

      wire                mon_2_l          ;

      wire                mon_2_h          ;

      reg  [3 :0]           mon_cnt          ;

      wire [3 :0]           mon_cnt_tmp      ;

      wire                  mon_cnt_add      ;

      wire                  mon_cnt_end      ;

      wire [3 :0]           mon_one          ;

      wire [3 :0]           mon_ten          ;

      reg  [3 :0]           yea_one          ;

      wire                  yea_one_add      ;

      wire                yea_one_end      ;

      reg  [3 :0]          yea_ten          ;

      wire                  yea_ten_add      ;

      wire                  yea_ten_end      ;

      reg  [3 :0]          yea_hun          ;

      wire                  yea_hun_add      ;

      wire                yea_hun_end      ;

      reg  [3 :0]          yea_tho          ;

      wire                  yea_tho_add      ;

      wire                  yea_tho_end      ;

      reg  [13:0]          yea_cnt1000      ;

      reg  [10:0]          yea_cnt100       ;

      reg  [7 :0]          yea_cnt10        ;

      reg  [13:0]          yea_cnt_tol      ;

      reg  [6 :0]          yea_cnt_tol_100  ;

      wire [13:0]          yea_mult4        ;

      wire [13:0]          yea_mult100_tmp  ;

      reg  [13:0]          yea_mult100      ;

      wire [13:0]          yea_cnt400       ;

      reg  [13:0]          yea_mult400      ;

      wire                yea_leap         ;

      reg  [2 :0]          set_cnt          ;

      wire                  set_cnt_add      ;

      wire                  set_cnt_end      ;

      wire                set_dat          ;

      wire                set_mon          ;

      wire                  set_yea_one      ;

      wire                  set_yea_ten      ;

      wire                  set_yea_hun      ;

      wire                  set_yea_tho      ;

      reg  [4 :0]          set_num          ;

      wire                  set_num_add      ;

      wire                  set_num_end      ;

      reg  [4 :0]          x                ;

 

 

      always  @(posedge clk or negedge   rst_n)begin

        if(rst_n==1'b0)begin

            flag_set <= 0;

        end

        else if(start_set)begin

            flag_set <= 1;

        end

        else if(stop_set)begin

            flag_set <= 0;

        end

      end

      assign start_set = flag_set==0 && key_vld==1 &&   key_num==0;

      assign stop_set  = flag_set==1   && key_vld==1 && key_num==0;

 

      always @(posedge clk or negedge rst_n)begin

        if (!rst_n)begin

            clk_cnt <= 0;

        end

        else if(clk_cnt_add)begin

            if(clk_cnt_end)

                clk_cnt <= 0;

            else

                clk_cnt <= clk_cnt + 1;

        end

      end

      assign clk_cnt_add = flag_set == 0;      

      assign clk_cnt_end = clk_cnt_add && clk_cnt == TIME_1S - 1;

 

      always @(posedge clk or negedge rst_n)begin

        if(!rst_n)begin

            dat_cnt <= 0;

        end

        else if(dat_cnt_add)begin

            if(dat_cnt_end)

                dat_cnt <= 0;

            else

                dat_cnt <= dat_cnt + 1;

        end

        else if(set_dat)begin

            dat_cnt <= set_num;

        end

      end

      assign dat_cnt_add = clk_cnt_end;      

      assign dat_cnt_end = dat_cnt_add && dat_cnt == x - 1;

 

      assign dat_cnt_tmp = dat_cnt + 1;

 

      assign dat_ten = dat_cnt_tmp/10;

      assign dat_one = dat_cnt_tmp%10;

 

      always @(posedge clk or negedge rst_n)begin

        if(!rst_n)begin

            mon_cnt <= 0;

        end

        else if(mon_cnt_add)begin

            if(mon_cnt_end)

                mon_cnt <= 0;

            else

                mon_cnt <= mon_cnt + 1;

        end

        else if(set_mon)begin

            mon_cnt <= set_num;

        end

      end

      assign mon_cnt_add = dat_cnt_end;       

      assign mon_cnt_end = mon_cnt_add && mon_cnt == 12 - 1;     

 

      assign mon_cnt_tmp = mon_cnt + 1;

 

      assign mon_ten = mon_cnt_tmp/10;

      assign mon_one = mon_cnt_tmp%10;

      

       always  @(*)begin

        if(mon_cnt_h)

            x = 31;

        else if(mon_cnt_l)

            x = 30;

        else if(mon_2_h)

            x = 29;

        else

            x = 28;

      end

      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;

      assign mon_cnt_l =   mon_cnt_tmp==4||mon_cnt_tmp==6||mon_cnt_tmp==9||mon_cnt_tmp==11;

      assign mon_2_h   =   yea_leap==1   &&mon_cnt_tmp==2;

      assign mon_2_l   =   yea_leap==0   &&mon_cnt_tmp==2;

 

      always @(posedge clk or negedge rst_n)begin

        if(!rst_n)begin

            yea_one <= 0;

        end

        else if(yea_one_add)begin

            if(yea_one_end)

                yea_one <= 0;

            else

                yea_one <= yea_one + 1;

        end

        else if(set_yea_one)begin

            yea_one <= set_num;

        end

      end

      assign yea_one_add = mon_cnt_end;       

      assign yea_one_end = yea_one_add && yea_one == 10 - 1;    

 

 

      always @(posedge clk or negedge rst_n)begin

        if(!rst_n)begin

            yea_ten <= 0;

        end

        else if(yea_ten_add)begin

            if(yea_ten_end)

                yea_ten <= 0;

            else

                yea_ten <= yea_ten + 1;

        end

        else if(set_yea_ten)begin

            yea_ten <= set_num;

        end

      end

      assign yea_ten_add = yea_one_end;       

      assign yea_ten_end = yea_ten_add && yea_ten == 10 - 1;     

 

 

      always @(posedge clk or negedge rst_n)begin

        if(!rst_n)begin

            yea_hun <= 0;

        end

        else if(yea_hun_add)begin

            if(yea_hun_end)

                yea_hun <= 0;

            else

                yea_hun <= yea_hun + 1;

        end

        else if(set_yea_hun)begin

            yea_hun <= set_num;

        end

      end

      assign yea_hun_add = yea_ten_end;       

      assign yea_hun_end = yea_hun_add && yea_hun == 10 - 1;      

 

      always @(posedge clk or negedge rst_n)begin

        if(!rst_n)begin

            yea_tho <= 0;

        end

        else if(yea_tho_add)begin

            if(yea_tho_end)

                yea_tho <= 0;

            else

                yea_tho <= yea_tho + 1;

        end

        else if(set_yea_tho)begin

            yea_tho <= set_num;

        end

      end

      assign yea_tho_add = yea_hun_end;       

      assign yea_tho_end = yea_tho_add && yea_tho == 10 - 1;     

 

      always  @(posedge clk or negedge   rst_n)begin

        if(rst_n==1'b0)begin

            yea_cnt1000 <= 0;

        end

        else begin

            yea_cnt1000 <= yea_tho*1000;

        end

      end

 

      always  @(posedge clk or negedge   rst_n)begin

        if(rst_n==1'b0)begin

            yea_cnt100 <= 0;

        end

        else begin

            yea_cnt100 <= yea_hun*100;

        end

      end

 

      always  @(posedge clk or negedge   rst_n)begin

        if(rst_n==1'b0)begin

            yea_cnt10 <= 0;

        end

        else begin

            yea_cnt10 <= yea_ten*10;

        end

      end

 

      always  @(posedge clk or negedge   rst_n)begin

        if(rst_n==1'b0)begin

            yea_cnt_tol <= 0;

        end

        else begin

            yea_cnt_tol <= yea_cnt1000 +   yea_cnt100 + yea_cnt10 + yea_one;

        end

      end

 

      always  @(posedge clk or negedge   rst_n)begin

        if(rst_n==1'b0)begin

            yea_cnt_tol_100 <= 0;

        end

        else begin

            yea_cnt_tol_100 <=  yea_tho*10+ yea_hun;

        end

      end

 

      assign yea_mult4       =   {yea_cnt_tol>>2,2'b00};  

      assign yea_mult100_tmp = yea_cnt1000 + yea_cnt100;

      assign yea_cnt400      =   {yea_cnt_tol_100>>2,2'b00};

 

      always  @(posedge clk or negedge   rst_n)begin

        if(rst_n==1'b0)begin

            yea_mult100 <= 0;

        end

        else begin

            yea_mult100 <=   yea_mult100_tmp;

        end

      end

 

      always  @(posedge clk or negedge   rst_n)begin

        if(rst_n==1'b0)begin

            yea_mult400 <= 0;

        end

        else begin

            yea_mult400 <= yea_cnt400*100;

        end

      end

 

      assign yea_leap =   (yea_cnt_tol==yea_mult400)||(yea_cnt_tol==yea_mult4&&yea_cnt_tol!=yea_mult100);

 

      always @(posedge clk or negedge rst_n)begin

        if(!rst_n)begin

            set_cnt <= 0;

        end

        else if(set_cnt_add)begin

            if(set_cnt_end)

                set_cnt <= 0;

            else

                set_cnt <= set_cnt + 1;

        end

        else if(stop_set)begin

            set_cnt <= 0;

        end

      end

      assign set_cnt_add = flag_set == 1 && key_vld == 1 &&   key_num == 1;     

      assign set_cnt_end = set_cnt_add && set_cnt == 8 - 1              ;     

 

      assign set_dat     = set_num_add   && set_cnt == 1-1                  ;

      assign set_mon     = set_num_add   && set_cnt == 3-1                  ;

      assign set_yea_one = set_num_add && set_cnt == 5-1                ;

      assign set_yea_ten = set_num_add && set_cnt == 6-1                ;

      assign set_yea_hun = set_num_add && set_cnt == 7-1                ;

      assign set_yea_tho = set_num_add && set_cnt == 8-1                ;

 

      reg [4:0]    y_temp                                                 ;

      wire[4:0]    y_temp2                                                ;

 

      assign set_num_add = flag_set == 1 && key_vld == 1 &&   key_num == 2;    

 

      always  @(*)begin

        if(set_dat)

            y_temp = dat_cnt;

        else if(set_mon)

            y_temp = mon_cnt;

        else if(set_yea_one)

            y_temp = yea_one;

        else if(set_yea_ten)

            y_temp = yea_ten;

        else if(set_yea_hun)

            y_temp = yea_hun;

        else   

            y_temp = yea_tho;

 

      end

 

      assign y_temp2 = y_temp + 1;

 

      always  @(*)begin

        if(set_dat)begin

            if(y_temp2>=x)

                set_num = 0;

            else

                set_num = y_temp2;

        end

        else if(set_num)begin

            if(y_temp2>=12)

                set_num = 0;

            else

                set_num = y_temp2;

        end

        else begin

            if(y_temp2>9)

                set_num = 0;

            else

                set_num = y_temp2;

        end

      end

 

      always  @(posedge clk or negedge   rst_n)begin

        if(rst_n==1'b0)begin

            dout <= 0;

        end

        else begin

            dout <=   {yea_tho,yea_hun,yea_ten,yea_one,mon_ten,mon_one,dat_ten,dat_one};

        end

      end

 

endmodule

 


*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
lantu  2017-08-03 09:58:47 

排排版 好不好

推荐文章
最近访客