时钟分频器
- 偶数分频
- 奇数分频(占空比50%)
- 非整数分频(占空比也非50%)
本文参考《硬件架构的艺术》,主要介绍偶数分频时钟,计数分频(3,5分频),以及非整数分频(4.5分频)
1、偶数分频
偶数分频比较容易实现。实现一个N分频(N为偶数),每隔N/2个源时钟,分频时钟信号翻转一次。比如N=6时,在计数器等于2时,源时钟上升沿使信号翻转。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29module 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分频时钟。
设计代码如下:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40`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位进行或操作。
代码如下:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51`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
最后
以上就是矮小柚子最近收集整理的关于时钟分频的全部内容,更多相关时钟分频内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复