数字时钟计数器(内含模60计数器以及8421BCD码计数器设计代码)

数字时钟计数器

简单的数字时钟计数器,其实现方法也是通过计数器的级联,由两个模60计数器和一个模24计数器子模块共同构成,下面的这段代码采用结构性描述方法,U1,U2,U3为调用的两个模60计数器和一个模24计数器子模块,模60计数器实现分秒的计数,模24计数器实现小时的计数。

在进行设计数字时钟计数器之前,分别介绍模60计数器count60以及8421BCD计数器count24

1、模60计数器的verilog设计代码如下:

1. module counter60(clk, rst_n, en, dout, co);  

2.     input clk, rst_n, en;  

3.     output co;  

4.     output [7:0] dout;  

5.     wire co10_1, co10, co6;  

6.     wire [3:0] dout10, dout6;  

7.     count10 U1(.clk(clk), .rst_n(rst_n), .en(en), .dout(dout10), .co(co10_1));  

8.     count6 U2(.clk(clk), .rst_n(rst_n), .en(co10), .dout(dout6), .co(co6));  

9.     and U3(co, co10, co6);  

10.     and U4(co10, en, co10_1);  

11.     assign dout = {dout6, dout10};  

12. endmodule  

13.   

14. //模10计数器  

15. module count10(clk, rst_n, en, dout, co);  

16.     input clk, rst_n, en;  

17.     output co;  

18.     output [3:0] dout;  

19.     reg [3:0] dout;  

20.       

21.     always @ (posedge clk or negedge rst_n)  

22.         begin  

23.             if(!rst_n)  

24.                 dout <= 4'b0000;  

25.             else if(en == 1'b1)  

26.                 begin  

27.                     if(dout == 4'b1001)  

28.                         dout <= 4'b0000;  

29.                     else   

30.                         dout <= dout + 1'b1;  

31.                 end  

32.             else  

33.                 dout <= dout;  

34.         end  

35.           

36.     assign co = dout[0] & dout[3];  

37. endmodule  

38.   

39. //模6计数器  

40. module count6(clk, rst_n, en, dout, co);  

41.     input clk, rst_n, en;  

42.     output co;  

43.     output [3:0] dout;  

44.     reg [3:0] dout;  

45.     always @(posedge clk or negedge rst_n)  

46.         begin  

47.         if(!rst_n)  

48.             dout <= 4'b0000;  

49.         else if(en == 1'b1)  

50.             begin  

51.                 if(dout == 4'b0101)  

52.                     dout <= 4'b0000;  

53.                 else  

54.                     dout <= dout + 1;  

55.             end  

56.         else  

57.             dout <= dout;  

58.         end  

59.     assign co = dout[0] & dout[2];  

60. endmodule  

综合工具综合而出的电路如下:


 

 

2、248421BCD码计数器

 

计数器实现的模制为24clr为异步清零信号,当时钟上升沿到来或clr下降沿到来,

clr = 0时,计数器清零为0000_0000。该计数器的计数过程为,当输出信号的低4位(即 dout[3:0])从0000计数到1001后(即十进制的0 ~ 9),高4位(即dout[3:4])计数加1,当计数计到23时(即0010_0011),计数器又清零为0000_0000,然后重新开始计数。

 

verilog HDL代码如下:

1. module count24(clk, clr, en, dout);  

2.     input clk; //时钟信号  

3.     input clr; //异步清零信号  

4.     input en; //计数使能信号  

5.     output [7:0] dout; //计数输出信号  

6.     reg [7:0] dout;  

7.     always @(posedge clk or negedge clr) //敏感信号源  

8.         begin  

9.             if(clr == 1'b0) //异步清零信号有效时,计数输出为0  

10.                 dout <= 8'b0000_0000;  

11.             else if(en == 1'b0) //计数使能信号无效时,计数停止  

12.                 dout <= dout;  

13.             else if((dout[7:4] == 4'b0010)&&(dout[3:0] == 4'b0011)) //当计数到达23时,输出清零  

14.                 dout <= 8'b0000_0000;  

15.             else if(dout[3:0] == 4'b1001) //当低4位为9时,低4位清零,高4位加1  

16.                 begin  

17.                     dout[3:0] <= 4'b0000;  

18.                     dout[7:4] <= dout[7:4] + 1'b1;  

19.                 end  

20.             else //排除以上所有情况,高4位  

21.                 begin  

22.                     dout[7:4] <= dout[7:4];  

23.                     dout[3:0] <= dout[3:0] + 1'b1;  

24.                 end  

25.         end  

26. endmodule  

 

其测试文件为:

 

1. `timescale 1ns/1ps  

2. module count24_tb;  

3.     reg clk, clr, en;  

4.     wire [7:0] dout;  

5.     always  

6.         begin  

7.             #10 clk = ~clk;  

8.         end  

9.     initial  

10.         begin  

11.             clk = 1'b0;  

12.             clr = 1'b1;  

13.             en = 1'b0;  

14.             #20 clr = 1'b0;  

15.             #10 clr = 1'b1;  

16.             #30 en = 1'b1;  

17.             #100;  

18.         end  

19.           

20.     count24 U1(.clk(clk), .clr(clr), .en(en), .dout(dout));  

21. endmodule  

Modelsim中仿真得到的波形为:(为了能看清,截了一部分图片)

 

下面正式给出数字时钟计数器的verilog HDL代码:

1. module digital_clock(hour, min, sec, clk, rst_n, en);  

2.     input clk, rst_n, en;  

3.     output [7:0] hour, min, sec;  

4.     wire co_sec1, co_sec, co_min, co_min1;  

5.       

6.     count60 U1(.clk(clk), .rst_n(rst_n), .en(en), .dout(sec), .co(co_sec1));  

7.     count60 U2(.clk(clk), .rst_n(rst_n), .en(co_sec), .dout(min), .co(co_min1));  

8.     count24 U3(.clk(clk), .clr(rst_n), .en(co_min), .dout(hour));  

9.       

10.     and U4(co_min, co_sec, co_min1);  

11.     and U5(co_sec, en, co_sec1);  

12.   

13. endmodule  

14.   

15. module count60(clk, rst_n, en, dout, co);  

16.     input clk, rst_n, en;  

17.     output co;  

18.     output [7:0] dout;  

19.     wire co10_1, co10, co6;  

20.     wire [3:0] dout10, dout6;  

21.     count10 U1(.clk(clk), .rst_n(rst_n), .en(en), .dout(dout10), .co(co10_1));  

22.     count6 U2(.clk(clk), .rst_n(rst_n), .en(co10), .dout(dout6), .co(co6));  

23.     and U3(co, co10, co6);  

24.     and U4(co10, en, co10_1);  

25.     assign dout = {dout6, dout10};  

26. endmodule  

27.   

28. //模10计数器  

29. module count10(clk, rst_n, en, dout, co);  

30.     input clk, rst_n, en;  

31.     output co;  

32.     output [3:0] dout;  

33.     reg [3:0] dout;  

34.       

35.     always @ (posedge clk or negedge rst_n)  

36.         begin  

37.             if(!rst_n)  

38.                 dout <= 4'b0000;  

39.             else if(en == 1'b1)  

40.                 begin  

41.                     if(dout == 4'b1001)  

42.                         dout <= 4'b0000;  

43.                     else   

44.                         dout <= dout + 1'b1;  

45.                 end  

46.             else  

47.                 dout <= dout;  

48.         end  

49.           

50.     assign co = dout[0] & dout[3];  

51. endmodule  

52.   

53. //模6计数器  

54. module count6(clk, rst_n, en, dout, co);  

55.     input clk, rst_n, en;  

56.     output co;  

57.     output [3:0] dout;  

58.     reg [3:0] dout;  

59.     always @(posedge clk or negedge rst_n)  

60.         begin  

61.         if(!rst_n)  

62.             dout <= 4'b0000;  

63.         else if(en == 1'b1)  

64.             begin  

65.                 if(dout == 4'b0101)  

66.                     dout <= 4'b0000;  

67.                 else  

68.                     dout <= dout + 1;  

69.             end  

70.         else  

71.             dout <= dout;  

72.         end  

73.     assign co = dout[0] & dout[2];  

74. endmodule  

75.   

76. //模24计数器  

77. module count24(clk, clr, en, dout);  

78.     input clk; //时钟信号  

79.     input clr; //异步清零信号  

80.     input en; //计数使能信号  

81.     output [7:0] dout; //计数输出信号  

82.     reg [7:0] dout;  

83.     always @(posedge clk or negedge clr) //敏感信号源  

84.         begin  

85.             if(clr == 1'b0) //异步清零信号有效时,计数输出为0  

86.                 dout <= 8'b0000_0000;  

87.             else if(en == 1'b0) //计数使能信号无效时,计数停止  

88.                 dout <= dout;  

89.             else if((dout[7:4] == 4'b0010)&&(dout[3:0] == 4'b0011)) //当计数到达23时,输出清零  

90.                 dout <= 8'b0000_0000;  

91.             else if(dout[3:0] == 4'b1001) //当低4位为9时,低4位清零,高4位加1  

92.                 begin  

93.                     dout[3:0] <= 4'b0000;  

94.                     dout[7:4] <= dout[7:4] + 1'b1;  

95.                 end  

96.             else //排除以上所有情况,高4位  

97.                 begin  

98.                     dout[7:4] <= dout[7:4];  

99.                     dout[3:0] <= dout[3:0] + 1'b1;  

100.                 end  

101.         end  

102. endmodule   

其测试代码为:

1. `timescale 1ns/1ps  

2. module digital_clock_tb;  

3.     reg clk, rst_n, en;  

4.     wire [7:0] hour, min, sec;  

5.       

6.     always  

7.         begin  

8.             #10 clk = ~clk;  

9.         end  

10.       

11.     initial  

12.         begin  

13.             clk = 1'b0;  

14.             rst_n = 1'b1;  

15.             en = 1'b0;  

16.             #20 rst_n = 1'b0;  

17.             #20 rst_n = 1'b1;  

18.             en = 1'b1;  

19.             #100;  

20.         end  

21.           

22.     digital_clock U1(.hour(hour), .min(min), .sec(sec), .clk(clk), .rst_n(rst_n), .en(en));  

23. endmodule  

Modelsim中仿真得到如下波形图:

 

用综合工具综合后的数字时钟:

 

猜你喜欢

转载自blog.csdn.net/reborn_lee/article/details/80373163
今日推荐