时钟分频的设计,奇数分频和偶数分频。
一、时钟分频
分频的本质是引入一个计数器,到特定的时候指示反转,从而达到分频的效果。
通过控制计数器的动作进而控制占空比,但是奇数分频想通过计数器直接分频出占空比50%的时钟是不可能的,必须要通过中间的临时波形,做一些逻辑 “与” “或” 的动作才能得到占空比50%的分频时钟。
方法有很多种,我的代码中统一使用异或,通过参数化控制可以改变分频系数。至于想改变占空比的话,只要根据需要去调整中间时钟和计数器的动作,然后进行相应逻辑运算即可,可以灵活处理。
二、代码实现
上代码:
module clk(
input clk_in,rst_n,
output reg clk_out_a,
output reg clk_out_b,
output reg clk_out_c,
output reg clk_out_d
);
reg clk1,clk2,clk3,clk4,clk5; // 定义中间时钟,每个时钟的翻转条件都不同
reg [2:0] counter;
parameter N=5; // 参数定义分频系数
always @(posedge clk_in or negedge rst_n)begin // 定义计数器
if(rst_n == 0)begin
counter <= 0;
end
else if(counter == (N-1))begin
counter <= 0;
end
else begin
counter <= counter + 1;
end
end
always@(posedge clk_in or negedge rst_n)begin
if(!rst_n)begin
clk1 <= 0;
end
else if(counter == 0)begin
clk1 <= ~clk1;
end
end
always@(posedge clk_in or negedge rst_n)begin
if(!rst_n)begin
clk2 <= 0;
end
else if(counter == (N-1)/2)begin
clk2 <= ~clk2;
end
end
always@(posedge clk_in or negedge rst_n)begin
if(!rst_n)begin
clk3 <= 0;
end
else if(counter == (N+1)/2)begin
clk3 <= ~clk3;
end
end
always@(negedge clk_in or negedge rst_n)begin
if(!rst_n)begin
clk4 <= 0;
end
else if(counter == (N+1)/2)begin
clk4 <= ~clk4;
end
end
always@(posedge clk_in or negedge rst_n)begin
if(!rst_n)begin
clk5 <= 0;
end
else if(counter == (N-1))begin
clk5 <= ~clk5;
end
end
assign clk_out_a = clk1 ^ clk2; // 奇数占空比<50, 偶数占空比<50(最小)
assign clk_out_b = clk1 ^ clk3; // 奇数占空比>50, 偶数占空比=50
assign clk_out_c = clk1 ^ clk4; // 奇数占空比=50, 偶数占空比<50
assign clk_out_d = clk1 ^ clk5; // 奇数占空比>50, 偶数占空比>50(最大)
endmodule
总共输出四个分频后的时钟。
测试波形,偶数8分频:
测试波形,奇数5分频:
通过控制参数,可以实现任意比例的分频时钟。