当前位置:   article > 正文

[SugerTangYL] 简易电子时钟Verilog设计_简易电子时钟设计

简易电子时钟设计

目录

前言

一、简易电子时钟的功能要求

二、设计思路&整体框架

三、完整代码

四、仿真

总结


前言

来分享第一个案例了!简易电子时钟的Verilog设计,电子时钟应该算是走嵌入式和FPGA开发的敲门砖了叭(也可能是流水灯)。本次设计实现的平台是Altera的DE2开发板。


一、简易电子时钟的功能要求

        一个简易的电子时钟应该包含以下功能:

  • 正常显示时分秒
  • 可调节时间

        在此基础上也还可以继续扩展功能,本次由于刚入门,便只实现了基本功能。 

菜的安详(小企鹅表情包)_企鹅_安详表情

二、设计思路&整体框架

        要正常计时,我们需要一个1Hz的信号。在Verilog中采用分频器对基准时钟进行分频,使用这个1Hz信号进行计数,便可以产生时分秒。再将时分秒用数码管显示出来,第一个功能成功实现;在第一个基础上,设置一个拨码开关,用以区分正常模式和调时模式。当电子时钟处于调时模式时,最低位数码管闪烁,按下增1按键时数字加1;按下移位按键时闪烁位向高位移动。当模式调回正常模式时,从修改后的时间开始计时。

        综上,需要一个分频器、一个时间管理模块、需要六个数码管显示译码器。整体框图如下:

         对于分频器这一ip,之后会出文详述,此处使用的是占空比50%的偶分频。数码管显示译码模块属于较为简单的模块,读者在看其Verilog代码时很容易便理解。

三、完整代码

         开门见山!先上整个完整能编译的Verilog代码!

  1. module simple_electronic_clock(clk,key_add,key_displace,switch_mode,hour_decode,min_decode,sec_decode);
  2. input clk;//基准时钟50MHz
  3. input key_add;//增一按键
  4. input key_displace;//移位按键
  5. input switch_mode;//模式开关
  6. output [13:0] hour_decode;//小时译码
  7. output [13:0] min_decode;//分钟译码
  8. output [13:0] sec_decode;//秒译码
  9. wire clk_1Hz,clk_2Hz;//分频后的1Hz、2Hz信号
  10. wire [1:0] mode_cnt;//调时的闪烁位
  11. wire [7:0] hour,min,sec;//时,分,秒
  12. divider(clk_2Hz,clk_1Hz,clk);//分频器
  13. time_management(clk_1Hz,switch_mode,key_add,key_displace,hour,min,sec,mode_cnt);//时间管理模块
  14. digital_tube_decode(clk_2Hz,mode_cnt,hour,min,sec,hour_decode,min_decode,sec_decode);//数码管显示译码模块
  15. endmodule
  16. module divider(clk_2Hz,clk_1Hz,clk);//分频器
  17. output reg clk_1Hz,clk_2Hz;
  18. input clk;
  19. reg [24:0] count,count2;//内部计数单元
  20. //count计满24999999时信号反向,产生1Hz信号
  21. always@(posedge clk) begin
  22. if(count==25'd24999999)
  23. begin
  24. count<=25'b0;
  25. clk_1Hz<=~clk_1Hz;
  26. end
  27. else
  28. count<=count+1'b1;
  29. end
  30. //count2计满12499999时信号反向,产生2Hz信号
  31. always@(posedge clk) begin
  32. if(count==25'd12499999)
  33. begin
  34. count2<=25'b0;
  35. clk_2Hz<=~clk_2Hz;
  36. end
  37. else
  38. count2<=count2+1'b1;
  39. end
  40. endmodule
  41. module time_management(clk_1Hz,switch_mode,key_add,key_displace,hour,min,sec,mode_cnt);//时间管理模块
  42. input clk_1Hz,switch_mode,key_add,key_displace;
  43. output reg [7:0] hour,min,sec;
  44. output reg [1:0] mode_cnt;//调时的闪烁位标志
  45. //时间计时&调时
  46. always @(posedge clk_1Hz) begin
  47. case (switch_mode)
  48. 1'b0:sec[3:0] <= sec[3:0] + 1'b1;//正常模式计时
  49. 1'b1:begin //调时模式
  50. if(key_add) begin
  51. case (mode_cnt)
  52. 2'b00:sec[3:0] <= sec[3:0] + 1'b1;//秒时间加一
  53. 2'b01:min[3:0] <= min[3:0] + 1'b1;//分时间加一
  54. 2'b10:hour[3:0] <= hour[3:0] + 1'b1;//时时间加一
  55. default:;
  56. endcase
  57. end
  58. end
  59. default:;
  60. endcase
  61. //以下为进位条件判断
  62. if(sec[3:0] == 4'd10) begin
  63. sec[3:0] <= 4'b0;
  64. sec[7:4] <= sec[7:4] + 1'b1;
  65. end
  66. if(sec[7:4] == 4'd6) begin
  67. sec[7:4] <= 4'b0;
  68. min[3:0] <= min[3:0] + 1'b1;
  69. end
  70. if(min[3:0] == 4'd10) begin
  71. min[3:0] <= 4'b0;
  72. min[7:4] <= min[7:4] + 1'b1;
  73. end
  74. if(min[7:4] == 4'd6) begin
  75. min[7:4] <= 4'b0;
  76. hour[3:0] <= hour[3:0] + 1'b1;
  77. end
  78. if(hour[3:0] == 4'd10) begin
  79. hour[3:0] <= 4'b0;
  80. hour[7:4] <= hour[7:4] + 1'b1;
  81. end
  82. if(hour[3:0] == 4'd4 && hour[7:4] == 4'd2) begin
  83. hour[3:0] <= 4'b0;
  84. hour[7:4] <= 4'b0;
  85. end
  86. end
  87. //移位按键触发移位
  88. always @(posedge key_displace) begin
  89. if(switch_mode) begin
  90. if(mode_cnt == 2'b10) mode_cnt <= 2'b0;
  91. else mode_cnt <= mode_cnt + 1'b1;
  92. end
  93. end
  94. endmodule
  95. module digital_tube_decode(clk_2Hz,mode_cnt,hour,min,sec,hour_decode,min_decode,sec_decode);
  96. input clk_2Hz;
  97. input [1:0] mode_cnt;
  98. input [7:0] hour,min,sec;
  99. output reg [13:0] hour_decode,min_decode,sec_decode;
  100. reg flag;
  101. //闪烁产生
  102. always @(posedge clk_2Hz) begin
  103. flag <= ~flag;
  104. end
  105. //显示译码
  106. always @(posedge clk_2Hz) begin
  107. case (mode_cnt) //根据闪烁位标志,使得闪烁位数字闪烁
  108. 2'b00:begin
  109. hour_decode[6:0] <= decode(hour[3:0]);
  110. hour_decode[13:7] <= decode(hour[7:4]);
  111. min_decode[6:0] <= decode(min[3:0]);
  112. min_decode[13:7] <= decode(min[3:0]);
  113. if(flag) begin
  114. sec_decode[6:0] <= decode(sec[3:0]);
  115. sec_decode[13:7] <= decode(sec[3:0]);
  116. end
  117. else begin //7'b1111111为数码管全灭,下面同理
  118. sec_decode[6:0] <= 7'b1111111;
  119. sec_decode[13:7] <= 7'b1111111;
  120. end
  121. end
  122. 2'b01:begin
  123. hour_decode[6:0] <= decode(hour[3:0]);
  124. hour_decode[13:7] <= decode(hour[7:4]);
  125. sec_decode[6:0] <= decode(sec[3:0]);
  126. sec_decode[13:7] <= decode(sec[7:4]);
  127. if(flag) begin
  128. min_decode[6:0] <= decode(min[3:0]);
  129. min_decode[13:7] <= decode(min[7:4]);
  130. end
  131. else begin
  132. min_decode[6:0] <= 7'b1111111;
  133. min_decode[13:7] <= 7'b1111111;
  134. end
  135. end
  136. 2'b10:begin
  137. sec_decode[6:0] <= decode(sec[3:0]);
  138. sec_decode[13:7] <= decode(sec[7:4]);
  139. min_decode[6:0] <= decode(min[3:0]);
  140. min_decode[13:7] <= decode(min[7:4]);
  141. if(flag) begin
  142. hour_decode[6:0] <= decode(hour[3:0]);
  143. hour_decode[13:7] <= decode(hour[7:4]);
  144. end
  145. else begin
  146. hour_decode[6:0] <= 7'b1111111;
  147. hour_decode[13:7] <= 7'b1111111;
  148. end
  149. end
  150. default:;
  151. endcase
  152. end
  153. //译码函数,便于重复调用
  154. function [6:0] decode;
  155. input [3:0] num;
  156. begin
  157. case (num)
  158. 4'd0:decode=7'b1000000;
  159. 4'd1:decode=7'b1111001;
  160. 4'd2:decode=7'b0100100;
  161. 4'd3:decode=7'b0110000;
  162. 4'd4:decode=7'b0011001;
  163. 4'd5:decode=7'b0010010;
  164. 4'd6:decode=7'b0000010;
  165. 4'd7:decode=7'b1111000;
  166. 4'd8:decode=7'b0000000;
  167. 4'd9:decode=7'b0010000;
  168. default: decode=7'b1111111;
  169. endcase
  170. end
  171. endfunction
  172. endmodule

四、仿真

仿真就等我之后有空再弄叭(dog)。


总结

这篇文是我第一个Verilog案例,主要讲解设计思路,当然还有更好的电子时钟例码,我这个算是无脑编写QaQ

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号