实战!Verilog时钟分频的5.3版本解析
input rstn ,
input clk,
output clk_div3p5
);
//计数器
parameter MUL2_DIV_CLK = 7 ;
reg [3:0] cnt ;
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
cnt <= 'b0 ;
end
else if (cnt == MUL2_DIV_CLK-1) begin //计数2倍分频比
cnt <= 'b0 ;
end
else begin
cnt <= cnt + 1'b1 ;
end
end
reg clk_ave_r ;
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
clk_ave_r <= 1'b0 ;
end
//first cycle: 4 source clk cycle
else if (cnt == 0) begin
clk_ave_r <= 1 ;
end
//2nd cycle: 3 source clk cycle
else if (cnt == (MUL2_DIV_CLK/2)+1) begin
clk_ave_r <= 1 ;
end
else begin
clk_ave_r <= 0 ;
end
end
//adjust
reg clk_adjust_r ;
always @(negedge clk or negedge rstn) begin
if (!rstn) begin
clk_adjust_r <= 1'b0 ;
end
//本次时钟只为调整一致的占空比
else if (cnt == 1) begin
clk_adjust_r <= 1 ;
end
//本次时钟只为调整一致的精确分频比
else if (cnt == (MUL2_DIV_CLK/2)+1 ) begin
clk_adjust_r <= 1 ;
end
else begin
clk_adjust_r <= 0 ;
end
end
assign clk_div3p5 = clk_adjust_r | clk_ave_r ;
endmodule
仿真结果如下。
小数分频
基本原理
不规整的小数分频不能做到分频后的每个时钟周期都是源时钟周期的小数分频倍,更不能做到分频后的时钟占空比均为 50%,因为 Verilog 不能对时钟进行小数计数。和半整数分频中第一次分频时引入的"平均频率"概念类似,小数分频也是基于可变分频和多次平均的方法实现的。
例如进行 7.6 倍分频,则保证源时钟 76 个周期的时间等于分频时钟 10 个周期的时间即可。此时需要在 76 个源时钟周期内进行 6 次 8 分频,4 次 7 分频。再例如进行 5.76 分频,需要在 576 个源时钟周期内进行 76 次 6 分频,24 次 5 分频。
下面阐述下这些分频参数的计算过程。
当进行 7 分频时,可以理解为 70 个源时钟周期内进行 10 次 7 分频。在 76 个源时钟周期内仍然进行 10 次分频,相当于将多余的 6 个源时钟周期增加、分配到 70 个源时钟周期内,即完成了 7.6 倍分频操作。分频过程中必然有 6 个分频时钟是 8 分频得到的,剩下的 4 个分频时钟则仍然会保持原有的 7 分频状态。
很多地方给出了计算这些分频参数的两元一次方程组,如下所示。其原理和上述分析一致,建议掌握上述计算过程。
7N + 8M = 76 N + M = 10
其中 7 为整数分频,N 整数分频的次数;8 与 M 为整数分频加一后的分频系数及其分频次数。
平均原理
以 7.6 倍分频为例,7 分频和 8 分频的实现顺序一般有以下 4 种:
- (1) 先进行 4 次 7 分频,再进行 6 次 8 分频;
- (2) 先进行 6 次 8 分频,再进行 4 次 7 分频;
- (3) 将 4 次 7 分频平均的插入到 6 次 8 分频中;
- (4) 将 6 次 8 分频平均的插入到 4 次 7 分频中。
前两种方法时钟频率不均匀,相位抖动较大,所以一般会采用后两种平均插入的方法进行小数分频操作。
平均插入可以通过分频次数差累计的方法实现,7.6 分频的实现过程如下:
- (1) 第一次分频次数差值为 76-10*7 = 6
- (2) 第二次差值累加结果为 6+6=12 > 10,第二次使用 8 分频,同时差值修改为 12-10=2。
- (3) 第三次差值累加结果为 2+6=8
- (4) 第四次差值累加结果为 8+6=14 > 10,第四次使用 8 分频,差值修改为 14-10=4。
以此类推,完成将 6 次 8 分频平均插入到 4 次 7 分频的过程。
下表展示了平均插入法的分频过程。
分频次数 | 差值累加 | 差值修改 | 分频周期 |
---|---|---|---|
1 | 6 | 6 | 7 |
2 | 6+6=12 | 2 | 8 |
3 | 2+6=8 | 8 | 7 |
4 | 8+6=14 | 4 | 8 |
5 | 4+6=10 | 0 | 8 |
6 | 6 | 6 | 7 |
7 | 6+6=12 | 2 | 8 |
8 | 2+6=8 | 8 | 7 |
9 | 8+6=14 | 4 | 8 |
10 | 4+6=10 | 0 | 8 |
设计仿真
基于上述小数分频实现方法的 Verilog 描述如下。