• 数字IC手撕代码50题(11-20)


    十一、偶数分频--二分频|四分频|八分频

            所有的分频器其实属于计数器电路中的一种,这篇文章主要讲这个类型的题目。

    11.1 题目描述与分析

            实现二分频|四分频|八分频电路,满足50%占空比。

           一、寄存器级联法能实现2^N的偶数分频,具体是采用寄存器结构的电路,每当时钟上升沿到来的时候输出结果进行翻转,以此来实现偶数分频。

            二、计数器法可以实现任意偶数分频,以八分频为例,电路需要实现的是:计数器从0开始计数至3,当clock上升沿取到clock=3时,输出clock进行翻转。

            这里我们用寄存器级联法实现。(一个触发器的输出做下一级触发器的时钟)

      11.2 寄存器实现2^N的偶数分频

    1. module even_divide(clk,rst_n,clk2,clk4,clk8);
    2. input clk;
    3. input rst_n;
    4. output reg clk2;
    5. output reg clk4;
    6. output reg clk8;
    7. always@(posedge clk or negedge rst_n)
    8. begin
    9. if(!rst_n)
    10. clk2 <= 1'b0;
    11. else
    12. clk2 <= !clk2;
    13. end
    14. always@(posedge clk2 or negedge rst_n)
    15. begin
    16. if(!rst_n)
    17. clk4 <= 1'b0;
    18. else
    19. clk4 <= !clk4;
    20. end
    21. always@(posedge clk4 or negedge rst_n)
    22. begin
    23. if(!rst_n)
    24. clk8 <= 1'b0;
    25. else
    26. clk8 <= !clk8;
    27. end
    28. endmodule

    十二、任意偶数分频--占空比50%

    12.1 题目描述与分析

            实现6分频电路,占空比为50%。

            由上面的分析可知,计数器法可以实现任意偶数分频。

            以六分频为例,电路需要实现的是:计数器从0开始计数至3=2,当clock上升沿取到clock=2时,输出clock进行翻转。

    12.2 计数器法实现六分频

    1. module moduleName (
    2. input clk,
    3. input rst_n,
    4. output reg clk_6
    5. );
    6. reg [1:0] cnt6;
    7. always @(posedge clk or negedge rst_n) begin
    8. if(!rst_n)
    9. cnt6 <= 2'd0;
    10. else if(cnt6 == 2'd2)
    11. cnt6 <= 2'd0;
    12. else
    13. cnt6 <= cnt6 + 2'd1;
    14. end
    15. always @(posedge clk or negedge rst_n) begin
    16. if(!rst_n)
    17. clk_6 <= 1'b0;
    18. else if(cnt6 == 2'd2)
    19. clk_6 <= ~clk_6;
    20. else
    21. clk_6 <= clk_6;
    22. end
    23. endmodule

    十三、奇数分频--不要求占空比

            不要求占空比,比较好实现。比如实现五分频,可以对5个时钟周期计数,比如1高4低,2高3低等等。

            再举个例子。如图,可以发现,假如Clock是输入的时钟信号,Clock2是输出的50%占空比的三分频信号,那么对于计数器,Clock2实现的操作是:当采样边沿每次遇到count=0的时候进行翻转,每次遇到1的时候再次完成翻转,根据此,加上复位信号,我们即可完成RTL代码。

    1. module moduleName (
    2. input clk,
    3. input rst_n,
    4. output reg clk_5
    5. );
    6. reg [1:0] cnt5;
    7. always @(posedge clk or negedge rst_n) begin
    8. if(!rst_n)
    9. cnt5 <= 2'd0;
    10. else if(cnt5 == 2'd4)
    11. cnt5 <= 2'd0;
    12. else
    13. cnt5 <= cnt5 + 2'd1;
    14. end
    15. always @(posedge clk or negedge rst_n) begin
    16. if(!rst_n)
    17. clk_5 <= 1'b0;
    18. else if(cnt5 == 2'd0 || cnt5 == 2'd1) // 这样写是1 - 4 1 - 6 万能写法
    19. clk_5 <= ~clk_5;
    20. else
    21. clk_5 <= clk_5;
    22. end
    23. endmodule

    十四、奇数分频--50%的占空比

      14.1 题目描述与分析 

            实现奇数分频,50%的占空比。

            分析:如果要实现占空比为50%的三分频时钟,可以通过待分频时钟下降沿触发计数,和上升沿同样的方法计数进行三分频,然后下降沿产生的三分频时钟和上升沿产生的时钟进行相或运算,即可得到占空比为50%的三分频时钟。这种方法可以实现任意的奇数分频。

            归类为一般的方法为:对于实现占空比为50%的N倍奇数分频,首先进行上升沿触发进行模N计数,计数选定到某一个值进行输出时钟翻转,然后经过(N-1)/2再次进行翻转得到一个占空比非50%奇数n分频时钟。(0翻转一次,(3-1)/2 = 1,翻转一次)再者同时进行下降沿触发的模N计数,到和上升沿触发输出时钟翻转选定值相同值时,进行输出时钟时钟翻转,同样经过(N-1)/2时,输出时钟再次翻转生成占空比非50%的奇数n分频时钟。两个占空比非50%的n分频时钟相或运算,得到占空比为50%的奇数n分频时钟。

            可以理解为生成两个占空比非50%的n分频,再进行相或运算。

    14.2 三分频电路的RTL实现

    1. module f3(clk, rst_n,clk2);
    2. input clk;
    3. input rst_n;
    4. output clk2;
    5. reg [2:0] negedge_count;
    6. reg [2:0] posedge_count;
    7. reg posedge_clk2;
    8. reg negedge_clk2;
    9. parameter N = 3;
    10. always@(posedge clk or negedge rst_n)
    11. begin
    12. if(!rst_n || posedge_count == N-1)
    13. posedge_count <= 3'd0;
    14. else
    15. posedge_count <= posedge_count +1'd1;
    16. end
    17. always@(negedge clk or negedge rst_n)
    18. begin
    19. if(!rst_n || negedge_count == N-1)
    20. negedge_count <= 3'd0;
    21. else
    22. negedge_count <= negedge_count +1'd1;
    23. end
    24. always@(posedge clk or negedge rst_n)
    25. begin
    26. if(!rst_n)
    27. posedge_clk2 <= 3'd0;
    28. else if (posedge_count == 3'd1 || posedge_count == 3'd0)
    29. posedge_clk2 <= !posedge_clk2;
    30. else
    31. posedge_clk2 <= posedge_clk2;
    32. end
    33. always@(negedge clk or negedge rst_n)
    34. begin
    35. if(!rst_n)
    36. negedge_clk2 <= 3'd0;
    37. else if (negedge_count == 3'd1 || negedge_count == 3'd0)
    38. negedge_clk2 <= !negedge_clk2;
    39. else
    40. negedge_clk2 <= negedge_clk2;
    41. end
    42. assign clk2 = posedge_clk2 || negedge_clk2;

            

  • 相关阅读:
    YOLOv5改进Neck系列:新颖的Gather-and-Distribute机制,特征新颖融合,增强了多尺度特征融合能力,实现了延迟和准确性的理想平衡
    微电子领域常见概念(九)势垒层
    c++继承
    去除IDEA中代码的波浪线(黄色警示线)
    Cplex求解教程(基于OPL语言,可作为大规模运算输入参考)
    QT QThread 多线程操作
    Android 应用程序通过MediaPipe 图片识别
    网络安全管理员高级工理论题库(持续更新中)
    不同图像工具读取图片的区别
    【C++ 实战】概论 | 代码风格 | 类
  • 原文地址:https://blog.csdn.net/lgk1996/article/details/126008178