分频器是指使输出信号频率为输入信号频率整数分之一的电子电路。
偶分频计数器
偶分频比较简单,假设为N分频,只需计数到N/2-1,然后时钟翻转、计数清零,如此循环就可以得到N(偶)分频。代码如下:
module even_divider(
clk_in,
Rst_n,
even_en,//偶分频使能信号,方便后续设计任意分频计数器
div,
clk_out
);
input clk_in;//时钟输入
input Rst_n;//异步复位 低有效
input even_en;//偶分频使能信号,方便后续设计任意分频计数器
input [3:0]div;//分频值,此处设计分频范围为1-63
output reg clk_out;//分频后,时钟输出
reg [3:0]div_cnt;//分频计数器
always@(posedge clk_in or negedge Rst_n)
if(!Rst_n) begin
div_cnt <= 4'd0;
clk_out <= 0;
end
else if(even_en) begin
if(div_cnt == (div/2 - 1'b1)) begin
div_cnt <= 4'd0;
clk_out <= ~clk_out;
end
else begin
div_cnt <= div_cnt + 1'b1;
clk_out <= clk_out;
end
end
else begin
div_cnt <= 4'd0;
clk_out <= 0;
end
endmodule
奇分频计数器
实现奇数N分频,分别用上升沿计数到(N-1)/2,时钟翻转,再计数到N-1,时钟翻转;用下降沿计数到(N-1)/2,时钟翻转,再计数到N-1,时钟翻转,得到两个波形,然后把它们相或即可得到N分频。代码如下:
module odd_divider(
clk_in,
Rst_n,
odd_en,
div,
clk_p,
clk_n,
clk_out
);
input clk_in;//时钟输入
input Rst_n;//异步复位,低电平有效
input odd_en;//奇分频使能信号
input [3:0]div;//分频系数
output reg clk_p;//上升沿计数,时钟输出
output reg clk_n;//下降沿计数,时钟输出
output clk_out;//奇分频时钟输出
reg [3:0]cnt_p,cnt_n;//分频计数器
always@(posedge clk_in or negedge Rst_n)
if(!Rst_n)
cnt_p <= 4'd0;
else if(odd_en == 1) begin
if(cnt_p == (div - 1'b1))
cnt_p <= 4'd0;
else
cnt_p <= cnt_p + 1'b1;
end
else
cnt_p <= 4'd0;
always@(posedge clk_in or negedge Rst_n)
if(!Rst_n)
clk_p <= 0;
else if(cnt_p == (div-1'b1)/2)
clk_p <= ~clk_p;
else if(cnt_p == (div-1'b1))
clk_p <= ~clk_p;
else
clk_p <= clk_p;
always@(negedge clk_in or negedge Rst_n)
if(!Rst_n)
cnt_n <= 4'd0;
else if(odd_en == 1) begin
if(cnt_n == (div - 1'b1))
cnt_n <= 4'd0;
else
cnt_n <= cnt_n + 1'b1;
end
else
cnt_n <= 4'd0;
always@(negedge clk_in or negedge Rst_n)
if(!Rst_n)
clk_n <= 0;
else if(cnt_n== (div-1'b1)/2)
clk_n <= ~clk_n;
else if(cnt_n == (div-1'b1))
clk_n <= ~clk_n;
else
clk_n <= clk_n;
assign clk_out = clk_p | clk_n;
endmodule
任意分频计数器
通过顶层文件例化上述偶分频计数器模块和奇分频计数器模块即可实现任意分频。
module clk_divider(
clk,
Rst_n,
div,
clk_div
);
input clk;
input Rst_n;
input [3:0]div;
output clk_div;
wire odd_en;
wire clk_even;
wire clk_odd;
assign odd_en = div[0]?1'b1:1'b0;//判断分频系数的奇偶
assign clk_div = div[0]?clk_odd:clk_even;//根据分频奇偶确定输出
even_divider even_divider(
.clk_in(clk),
.Rst_n(Rst_n),
.even_en(!odd_en),
.div(div),
.clk_out(clk_even)
);
odd_divider odd_divider(
.clk_in(clk),
.Rst_n(Rst_n),
.odd_en(odd_en),
.div(div),
.clk_p(),
.clk_n(),
.clk_out(clk_odd)
);
endmodule
RTL视图