所有的分频器其实属于计数器电路中的一种,这篇文章主要讲这个类型的题目。
实现二分频|四分频|八分频电路,满足50%占空比。
一、寄存器级联法能实现2^N的偶数分频,具体是采用寄存器结构的电路,每当时钟上升沿到来的时候输出结果进行翻转,以此来实现偶数分频。
二、计数器法可以实现任意偶数分频,以八分频为例,电路需要实现的是:计数器从0开始计数至3,当clock上升沿取到clock=3时,输出clock进行翻转。
这里我们用寄存器级联法实现。(一个触发器的输出做下一级触发器的时钟)
- module even_divide(clk,rst_n,clk2,clk4,clk8);
-
- input clk;
- input rst_n;
- output reg clk2;
- output reg clk4;
- output reg clk8;
-
- always@(posedge clk or negedge rst_n)
- begin
- if(!rst_n)
- clk2 <= 1'b0;
- else
- clk2 <= !clk2;
- end
-
- always@(posedge clk2 or negedge rst_n)
- begin
- if(!rst_n)
- clk4 <= 1'b0;
- else
- clk4 <= !clk4;
- end
-
- always@(posedge clk4 or negedge rst_n)
- begin
- if(!rst_n)
- clk8 <= 1'b0;
- else
- clk8 <= !clk8;
- end
-
- endmodule
-
实现6分频电路,占空比为50%。
由上面的分析可知,计数器法可以实现任意偶数分频。
以六分频为例,电路需要实现的是:计数器从0开始计数至3=2,当clock上升沿取到clock=2时,输出clock进行翻转。
- module moduleName (
- input clk,
- input rst_n,
- output reg clk_6
- );
- reg [1:0] cnt6;
- always @(posedge clk or negedge rst_n) begin
- if(!rst_n)
- cnt6 <= 2'd0;
- else if(cnt6 == 2'd2)
- cnt6 <= 2'd0;
- else
- cnt6 <= cnt6 + 2'd1;
- end
- always @(posedge clk or negedge rst_n) begin
- if(!rst_n)
- clk_6 <= 1'b0;
- else if(cnt6 == 2'd2)
- clk_6 <= ~clk_6;
- else
- clk_6 <= clk_6;
- end
- endmodule
不要求占空比,比较好实现。比如实现五分频,可以对5个时钟周期计数,比如1高4低,2高3低等等。
再举个例子。如图,可以发现,假如Clock是输入的时钟信号,Clock2是输出的50%占空比的三分频信号,那么对于计数器,Clock2实现的操作是:当采样边沿每次遇到count=0的时候进行翻转,每次遇到1的时候再次完成翻转,根据此,加上复位信号,我们即可完成RTL代码。
- module moduleName (
- input clk,
- input rst_n,
- output reg clk_5
- );
- reg [1:0] cnt5;
- always @(posedge clk or negedge rst_n) begin
- if(!rst_n)
- cnt5 <= 2'd0;
- else if(cnt5 == 2'd4)
- cnt5 <= 2'd0;
- else
- cnt5 <= cnt5 + 2'd1;
- end
- always @(posedge clk or negedge rst_n) begin
- if(!rst_n)
- clk_5 <= 1'b0;
- else if(cnt5 == 2'd0 || cnt5 == 2'd1) // 这样写是1 - 4 1 - 6 万能写法
- clk_5 <= ~clk_5;
- else
- clk_5 <= clk_5;
- end
- endmodule
实现奇数分频,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实现
- module f3(clk, rst_n,clk2);
-
- input clk;
- input rst_n;
- output clk2;
-
-
- reg [2:0] negedge_count;
- reg [2:0] posedge_count;
- reg posedge_clk2;
- reg negedge_clk2;
- parameter N = 3;
-
-
- always@(posedge clk or negedge rst_n)
- begin
- if(!rst_n || posedge_count == N-1)
- posedge_count <= 3'd0;
- else
- posedge_count <= posedge_count +1'd1;
- end
-
-
- always@(negedge clk or negedge rst_n)
- begin
- if(!rst_n || negedge_count == N-1)
- negedge_count <= 3'd0;
- else
- negedge_count <= negedge_count +1'd1;
- end
-
- always@(posedge clk or negedge rst_n)
- begin
- if(!rst_n)
- posedge_clk2 <= 3'd0;
- else if (posedge_count == 3'd1 || posedge_count == 3'd0)
- posedge_clk2 <= !posedge_clk2;
- else
- posedge_clk2 <= posedge_clk2;
- end
-
-
- always@(negedge clk or negedge rst_n)
- begin
- if(!rst_n)
- negedge_clk2 <= 3'd0;
- else if (negedge_count == 3'd1 || negedge_count == 3'd0)
- negedge_clk2 <= !negedge_clk2;
- else
- negedge_clk2 <= negedge_clk2;
- end
-
- assign clk2 = posedge_clk2 || negedge_clk2;
-