概述
时钟分频器
- 偶数分频
- 奇数分频(占空比50%)
- 非整数分频(占空比也非50%)
本文参考《硬件架构的艺术》,主要介绍偶数分频时钟,计数分频(3,5分频),以及非整数分频(4.5分频)
1、偶数分频
偶数分频比较容易实现。实现一个N分频(N为偶数),每隔N/2个源时钟,分频时钟信号翻转一次。比如N=6时,在计数器等于2时,源时钟上升沿使信号翻转。
module even_clk_div#(
parameter N=8
)
(
input sys_clk,
input rst_n,
output reg div_clk
);
//===================================
reg [15:0]clk_cnt;
always@(posedge sys_clk,negedge rst_n)begin
if(~rst_n)
clk_cnt <= 'h0;
else if(clk_cnt == (N/2-1))
clk_cnt <= 'h0;
else
clk_cnt <= clk_cnt + 1'b1;
end
always@(posedge sys_clk,negedge rst_n)begin
if(~rst_n)
div_clk <= 'b0;
else if(clk_cnt == (N/2-1))
div_clk <= ~div_clk;
end
endmodule
仿真波形图如下:
2、奇数分频
奇数分频要复杂一些,但原理是一样的。N(奇数),即在2N个时钟周期内,分频信号翻转四次。以N=3为例,如图2所示
先产生一个6分频时钟div1,然后在将div1移动270度相位,得到div2时钟,最后将div1与div2进行异或,得到3分频时钟。
设计代码如下:
`timescale 1ns/1ns
module odd_clk_div#(
parameter N=3
)
(
input sys_clk,
input rst_n,
output div_clk
);
reg [15:0] div_cnt;
always@(posedge sys_clk,negedge rst_n)begin
if(~rst_n)
div_cnt <= 'h0;
else if(div_cnt == 2*N-1)
div_cnt <= 'h0;
else
div_cnt <= div_cnt + 1'b1;
end
reg div1;
reg div2;
always@(posedge sys_clk,negedge rst_n)begin
if(~rst_n)
div1 <= 1'b0;
else if((div_cnt == 2*N-1)||(div_cnt==N-1))
div1=~div1;
end
always@(negedge sys_clk,negedge rst_n)begin
if(~rst_n)
div2 <= 1'b0;
else if(div_cnt==(N-1)/2||div_cnt==(3*N-1)/2)
div2=~div2;
end
assign div_clk = div1^div2;
endmodule
3、非整数分频(占空比非50%)
经常会使用N分频电路来产生于参考时钟不同步的时钟。设计N为非整数的分频电路并不想看起来那样难。对1.5分频,简单来说,就是每三个参考时钟包含两个对称的脉冲。
本节介绍一种不产生毛刺的分频方法。
使用4.5倍分频为例子,即每9个参考时钟包含2个对称脉冲。
步骤1:使用复位值为000000001的9位移位寄存器,可以在每个时钟上升沿使移位寄存器循环左移一位。
步骤2:要产生第1个脉冲,必须在半周期是移动第1位并将第1位与第2位进行或操作。
步骤3:要产生第2个脉冲,第5位和第6位必须在半周期是移动并与原始第6位进行或操作。
代码如下:
`timescale 1ns/1ns
module Nointer_clk_div#(
parameter Double_N=4.5
)(
input sys_clk,
input rst_n,
output div_clk
);
//localparam Double_N=2*N;
reg [Double_N-1:0] count;
always@(posedge sys_clk,negedge rst_n)begin
if(~rst_n)
count <= 'h1;
else if(count[Double_N-1]==1)
count <= 'h1;
else
count <= count<<1;
end
reg div1,div2,div3;
always@(negedge sys_clk,negedge rst_n)begin
if(~rst_n)
div1 <= 1'b0;
else if(count[0]==1)
div1 <= ~div1;
else if(count[1]==1)
div1 <= ~div1;
end
always@(negedge sys_clk,negedge rst_n)begin
if(~rst_n)
div2 <= 1'b0;
else if(count[4]==1)
div2 <= ~div2;
else if(count[5]==1)
div2 <= ~div2;
end
always@(negedge sys_clk,negedge rst_n)begin
if(~rst_n)
div3 <= 1'b0;
else if(count[5]==1)
div3 <= ~div3;
else if(count[6]==1)
div3 <= ~div3;
end
assign div_clk = (count[0]||count[1]||div1)||(div2||div3);
endmodule
最后
以上就是矮小柚子为你收集整理的时钟分频的全部内容,希望文章能够帮你解决时钟分频所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复