当前位置:   article > 正文

数字时钟——FPGA_仿真器频率fpgazl设置

仿真器频率fpgazl设置

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

 

 


设计要求

用FPGA实现一个数字时钟——用veirlog语言


一、如何分频(即生成想要频率的时钟信号)?

  • 源时钟信号 clk 的频率为:f=50MHz
  • 假设想要得到时钟信号 clk_1 频率为:f1
  • 用一个寄存器变量 count 记录 clk 的 x 个时钟上升沿
  • 此时,clk 进行了 x 个周期
  • 令 clk_1 反转(即clk_1<=~clk_1),相当于 clk_1 进行了二分之一个周期
  • 所以可以得出: x=f/(2*f1)

二、利用视觉暂留

来自百科:物体在快速运动时, 当人眼所看到的影像消失后,人眼仍能继续保留其影像0.1-0.4秒左右的图像,这种现象被称为视觉暂留现象。是人眼具有的一种性质。人眼观看物体时,成像于视网膜上,并由视神经输入人脑,感觉到物体的像。但当物体移去时,视神经对物体的印象不会立即消失,而要延续0.1 -0.4秒的时间,人眼的这种性质被称为"眼睛的视觉暂留"。

也就是说,只要使FPGA上的六个数码管轮流亮起(并且同一个数码管亮起的时间间隔小于视觉暂留时间),就可以实现“动态”。


三、数码管显示数字原理

 


其中,高位到低位依次是:DP_G F E _D C B A, 共阴极数码管——输入为高电平亮!

下图为,共阴极数码管的编码表

共阴极数码管的编码表

 


四、设计流程

  1. 所需端口以及变量定义
    1. input clk; //系统时钟频率50MHz
    2. output [5:0]wei; //片选数码管
    3. output [7:0]duan; //段选发光二极管
    4. reg[5:0]wei;
    5. reg[7:0]duan;
    6. integer count; //计数实现1Hz的时钟clk_1hz
    7. reg clk_1hz; //计时时钟
    8. integer count2; //计数实现扫描时钟clk_scan->利用视觉暂留实现动态
    9. reg clk_scan; //扫描时钟
    10. reg [2:0]select; //用于扫描时选择显示位码
    11. reg[3:0]sec_ge; //秒的个位BCD码 0~9
    12. reg[2:0]sec_shi; //秒的十位BCD码 0~5
    13. reg[3:0]min_ge; //分的个位BCD码 0~9
    14. reg[2:0]min_shi; //分的十位BCD码 0~5
    15. //reg[1:0]hour_ge; //时的个位 0~3
    16. reg[3:0] hour_ge; //时的十位 0~9 (也表达0~3)
    17. reg[1:0]hour_shi; //时的十位 0~2

     

  2. 产生频率为1的累计时钟信号
    1. //生成1Hz的时钟clk_1hz
    2. always@(posedge clk)
    3. begin
    4. if(count==25000000)
    5. begin
    6. count<=0;
    7. clk_1hz<=~clk_1hz;
    8. end
    9. else
    10. count<=count+1'b1;
    11. end

     

  3. 秒、分、时 各个位数的累加
    用Draw.io画的秒时分各位累加流程图
    1. //秒、分、时 各个位数的累加
    2. always @(posedge clk_1hz)//秒分时各位累加功能进程
    3. begin
    4. if(sec_ge==4'b1001) //秒的个位等于9
    5. begin
    6. sec_ge<=4'b0000;
    7. if(sec_shi==3'b101) //秒的十位等于5
    8. begin
    9. sec_shi<=3'b000;
    10. if(min_ge==4'b1001) //分的个位等于9
    11. begin
    12. min_ge<=4'b0000;
    13. if(min_shi==3'b101) //分的十位等于5
    14. begin
    15. min_shi<=3'b000;
    16. if(hour_shi==2'b00) //时的十位等于0
    17. begin
    18. if(hour_ge==4'b1001) //时的个位等于9
    19. begin
    20. hour_ge<=0;
    21. hour_shi<=hour_shi+1'b1;
    22. end
    23. else
    24. hour_ge<=hour_ge+1'b1;
    25. end
    26. else
    27. if(hour_shi==2'b01) //判断 时的十位等于1
    28. begin
    29. if(hour_ge==4'b1001) //判断 时的十位等于9
    30. begin
    31. hour_ge<=0;
    32. hour_shi<=hour_shi+1'b1;
    33. end
    34. end
    35. else //时的十位不等于0,也不等于1, 即等于2
    36. if(hour_ge==4'b0011) //判断 时的个位等于3
    37. begin
    38. hour_ge<=0;
    39. hour_shi<=0;
    40. end
    41. else
    42. hour_ge<=hour_ge+1'b1;
    43. end
    44. else
    45. min_shi<=min_shi+1'b1;
    46. end
    47. else
    48. min_ge<=min_ge+1'b1;
    49. end
    50. else
    51. sec_shi<=sec_shi+1'b1;
    52. end
    53. else
    54. sec_ge<=sec_ge+1'b1;
    55. end

     

  4. 产生数码管扫描时钟信号
    1. //产生数码管扫描时钟
    2. always @(posedge clk)
    3. begin
    4. if(count2==10000)
    5. //if(count2==25000000) //测试视觉暂留
    6. begin
    7. count2<=0;
    8. clk_scan<=~clk_scan;
    9. end
    10. else
    11. count2<=count2+1;
    12. end

     

  5. 扫描时实现片选,以便利用视觉暂留
    1. //扫描时实现片选 视觉暂留
    2. always @(posedge clk_scan)
    3. begin
    4. if(select==3'b110)
    5. select<=3'b000;
    6. else
    7. select<=select+1'b1;
    8. end

     

  6. 显示数字(注意分隔点DP的点亮与否)
    1. //显示数字
    2. always @(sec_ge or sec_shi or min_ge or min_shi or hour_ge or hour_shi or select)//敏感信号列表
    3. begin
    4. if(select==3'b001)
    5. begin
    6. wei<=6'b111110;//秒个位数显示 不显示点
    7. case(sec_ge)
    8. 4'b0000:begin duan<=8'b0_011_1111;end // 显示0
    9. 4'b0001:begin duan<=8'b0_000_0110;end // 显示1
    10. 4'b0010:begin duan<=8'b0_101_1011;end // 显示2
    11. 4'b0011:begin duan<=8'b0_100_1111;end // 显示3
    12. 4'b0100:begin duan<=8'b0_110_0110;end // 显示4
    13. 4'b0101:begin duan<=8'b0_110_1101;end // 显示5
    14. 4'b0110:begin duan<=8'b0_111_1101;end // 显示6
    15. 4'b0111:begin duan<=8'b0_000_0111;end // 显示7
    16. 4'b1000:begin duan<=8'b0_111_1111;end // 显示8
    17. 4'b1001:begin duan<=8'b0_110_1111;end // 显示9
    18. default duan<=8'bx;
    19. endcase
    20. end
    21. else if(select==3'b010)
    22. begin
    23. wei<=6'b111101;//秒十位数显示 不显示点
    24. case(sec_shi)
    25. 3'b000:duan<=8'b0_011_1111; // 显示0
    26. 3'b001:duan<=8'b0_000_0110; // 显示1
    27. 3'b010:duan<=8'b0_101_1011; // 显示2
    28. 3'b011:duan<=8'b0_100_1111; // 显示3
    29. 3'b100:duan<=8'b0_110_0110; // 显示4
    30. 3'b101:duan<=8'b0_110_1101; // 显示5
    31. //3'b110:duan<=8'b1111_1101; // 显示6
    32. default duan<=8'bx;
    33. endcase
    34. end
    35. else if(select==3'b011)
    36. begin
    37. wei<=6'b111011;//分钟个位数显示数字 显示点
    38. case(min_ge)
    39. 4'b0000:begin duan<=8'b1_011_1111;end // 显示0
    40. 4'b0001:begin duan<=8'b1_000_0110;end // 显示1
    41. 4'b0010:begin duan<=8'b1_101_1011;end // 显示2
    42. 4'b0011:begin duan<=8'b1_100_1111;end // 显示3
    43. 4'b0100:begin duan<=8'b1_110_0110;end // 显示4
    44. 4'b0101:begin duan<=8'b1_110_1101;end // 显示5
    45. 4'b0110:begin duan<=8'b1_111_1101;end // 显示6
    46. 4'b0111:begin duan<=8'b1_000_0111;end // 显示7
    47. 4'b1000:begin duan<=8'b1_111_1111;end // 显示8
    48. 4'b1001:begin duan<=8'b1_110_1111;end // 显示9
    49. default duan<=8'bx;
    50. endcase
    51. end
    52. else if(select==3'b100)
    53. begin
    54. wei<=6'b110111;//分钟十位数显示 不显示点
    55. case(min_shi)
    56. 3'b000:duan<=8'b0_011_1111; // 显示0
    57. 3'b001:duan<=8'b0_000_0110; // 显示1
    58. 3'b010:duan<=8'b0_101_1011; // 显示2
    59. 3'b011:duan<=8'b0_100_1111; // 显示3
    60. 3'b100:duan<=8'b0_110_0110; // 显示4
    61. 3'b101:duan<=8'b0_110_1101; // 显示5
    62. //3'b110:duan<=8'b1111_1101; // 显示6
    63. default duan<=8'bx;
    64. endcase
    65. end
    66. else if(select==3'b101)
    67. begin
    68. wei<=6'b101111;//时钟个位数显示 显示点
    69. case(hour_ge)
    70. 4'b0000:begin duan<=8'b1_011_1111;end // 显示0
    71. 4'b0001:begin duan<=8'b1_000_0110;end // 显示1
    72. 4'b0010:begin duan<=8'b1_101_1011;end // 显示2
    73. 4'b0011:begin duan<=8'b1_100_1111;end // 显示3
    74. 4'b0100:begin duan<=8'b1_110_0110;end // 显示4
    75. 4'b0101:begin duan<=8'b1_110_1101;end // 显示5
    76. 4'b0110:begin duan<=8'b1_111_1101;end // 显示6
    77. 4'b0111:begin duan<=8'b1_000_0111;end // 显示7
    78. 4'b1000:begin duan<=8'b1_111_1111;end // 显示8
    79. 4'b1001:begin duan<=8'b1_110_1111;end // 显示9
    80. default duan<=8'bx;
    81. endcase
    82. end
    83. else
    84. begin
    85. wei<=6'b011111;//时钟十位数显示 不显示点
    86. case(hour_shi)
    87. 3'b000:duan<=8'b0_011_1111; // 显示0
    88. 3'b001:duan<=8'b0_000_0110; // 显示1
    89. 3'b010:duan<=8'b0_101_1011; // 显示2
    90. default duan<=8'bx;
    91. endcase
    92. end
    93. end

     


五、板上实现

 

 


补充:初始化数据——测试功能是否完善

  1. //初始化:从 235954 开始计时,测试功能
  2. initial
  3. begin
  4. hour_shi<=2;
  5. hour_ge<=3;
  6. min_shi<=5;
  7. min_ge<=9;
  8. sec_shi<=5;
  9. sec_ge<=4;
  10. end

 

 

 

总结

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/993531
推荐阅读
相关标签
  

闽ICP备14008679号