1. 偶分频电路
倍数K = f1/f2;
常数N = K/2;
设计思路1:
- 主要通过计数器累加到N-1
- 当累加到N-1时信号翻转
设计思路2: - 计数器累加到K-1
- 时钟分别在N-1和K-1上取反
module even_divider(
clk_in, //1024HZ
rst_n,
clk_out);//1HZ
parameter N = 512;
input wire clk_in, rst_n;
output reg clk_out;
integer count;
always @ (posedge clk_in or negedge rst_n) begin
if (!rst_n)
count <= 0;
else if (count == N-1)
count <= 0;
else
count <= count + 1;
end
always @ (posedge clk_in or negedge rst_n) begin
if (!rst_n)
clk_out <= 'b0;
else if (count == N -1)
clk_out <= ~clk_out;
else
clk_out <= clk_out;
end
endmodule
2. 奇分频电路
- 注意计数器直接加到K-1
- 分别在上升沿和下降沿累加
- 时钟反转的条件为N-1和K-1
- N=K/2向下取整时,clk_out = clk0&clk1 ; 向上取整时,clk_out= clk0|clk1;注意这个与或还与复位时clk取0或者1有关。只有当N=K/2向下取整时,并且clk复位时为0,才会用&。除此之外改变其中任意一个条件就用或。
module odd_divider(
clk_in,
rst_n,
clk_out);
input wire clk_in, rst_n;
output wire clk_out;
reg clk0, clk1;
parameter K = 15;
parameter N = 7;
integer count0, count1;
always @ (posedge clk_in or negedge rst_n) begin
if (!rst_n)
count0 <= 0;
else if (count0 == K-1)
count0 <= 0;
else
count0 <= count0 + 1;
end
always @ (negedge clk_in or negedge rst_n) begin
if (!rst_n)
count1 <= 0;
else if (count1 == K-1)
count1 <= 0;
else
count1 <= count1 + 1;
end
always @ (posedge clk_in or negedge rst_n) begin
if (!rst_n)
clk0 <= 0;
else if (count0 == N-1 || count0 == K-1)
clk0 <= ~clk0;
else
clk0 <= clk0;
end
always @ (negedge clk_in or negedge rst_n) begin
if (!rst_n)
clk1 <= 0;
else if (count1 == N-1 || count1 == K-1)
clk1 <= ~clk1;
else
clk1 <= clk1;
end
assign clk_out = clk0 & clk1;//如果另K=8,那么clk_out = clk0 | clk1
endmodule
3. 3分频电路的的电路结构
- 用一个计数器在上升沿计数,每次计数到1翻转一次,每次计数到3再翻转一次,然后周期重复得到信号clkp1,它的周期就是clk的3倍,但是它的占空比不是50%
- 用一个下降沿的D触发器锁存clkp1得到信号clkn1,把信号clkp1和信号clkn1做逻辑“与”就得到了占空比50%的3分频时钟信号clkout。
##4. N+0.5分频电路 - 首先半分频电路是无法做到占空比为50%,因此我们需要做到两个时钟,然后它的站空比都为(N+1)/(2N+1),一个基于上升沿,一个基于下降沿,并且时钟的初始值是相反的,然后时钟相与就可以得到N.5的分频电路了,如下N=4时的时序图
可以明显的看到,首先两计数器的站空比都是6//11,只不过一个是前半段,一个是后半段,然后进行相与,就可以得到5.5分配的时钟。
设计思路:
- 两个计数器,分别是上升沿计数和下降沿计数。
- 占空比为5/9,注意高电平是包含了低电平的。因此开始0-4个计数器的上升沿是高电平,下降沿计数0-3表示低电平。
- 两个信号相与
module cj_div_clk(
clk,
rst_n,
clk_out);
//4.5 div
input wire clk, rst_n;
output wire clk_out;
parameter N=4;
parameter K = 9; //2*N+1
reg [3:0] cnt1, cnt2;
reg div1, div2;
always @(posedge clk or negedge rst_n) begin
if (~rst_n)
cnt1 <= 'd0;
else if (cnt1 == K-1)
cnt1 <= 'd0;
else
cnt1 <= cnt1 + 1'b1;
end
always @(negedge clk or negedge rst_n) begin
if (~rst_n)
cnt2 <= 'd0;
else if (cnt2 == K-1)
cnt2 <= 'd0;
else
cnt2 <= cnt2 + 1'b1;
end
always @(posedge clk or negedge rst_n) begin
if (~rst_n)
div1 <= 1'b1;
else if (cnt1 == N || cnt1 == K-1)
div1 <= ~div1;
else
div1 <= div1;
end
always @(negedge clk or negedge rst_n) begin
if (~rst_n)
div2 <= 1'b0;
else if (cnt2 == N-1 || cnt2 == K-1)
div2 <= ~div2;
else
div2 <= div2;
end
assign clk_out = div1&div2;
endmodule
5. 分数分频
分数分频也叫小数分频器,比如8.7分频。因为没办法用计数器表示0.7这种数字,所以就用一个等效的概念来进行8.7分频,原时钟87个周期的总时间等于分频后的时钟10个周期的总时间;
如下图所示:一个小数分频器就有两部分组成:ZN和ZN+1为分频系数的多路分频器,还有一个ACC计数器。分频器在输入信号enout=0的时候是ZN分频;分频器在输入信号enout=1的时候是ZN+1分频;
6. 任意分频-基于相位累加器原理
注意:任意分频只是近似计算。
相位累加器主要用在直接数字频率合成器(DDS)中,其中的几个主要的参数为输入频率fc,输出频率fo,计数器位宽N,频率控制字K(即计数器递增步长)。它们之间的关系为:fo=(fcK)/(2^N)。假设输入频率fc为50MHz,计数器位宽N为32,要产生1kHz的信号,则K=(fo * 2^N) / fc=85.9fo=85900。当计数值小于等于((2^N)/2)时,输出低电平,当计数值大于(2 ^ N ) /2)时,输出高电平,依次循环,就可以产生占空比为50%的1kHz信号了。据此可以设计如下程序:
其中最重要的一点是要计算步长
/***************************************
晶振频率 fc = 50MHz
输出频率 fo = 1kHz(根据需要可以设为任意值)
控制参数 K = (fo*2^N)/fc
参数 N = 2^32,(32为计数器的位宽)
****************************************/
module div_free(clk_out, clk, rst_n);
input clk, rst_n;
output clk_out;
reg clk_out;
reg [31:0] cnt;
always @(posedge clk or negedge rst_n)
if(!rst_n)
cnt <= 0;
else cnt <= cnt + 32'd85900; //计数器步长 K
always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
clk_out <= 1'b0;
end
else if(cnt < 32'h7FFF_FFFF)
clk_out <= 1'b0;
else clk_out <= 1'b1;
endmodule