分频器
rst一般不与clk的时钟沿同步,所以时钟分频的第一个周期不是整周期,从0开始计数略小,从1开始计数略大。一般选0开始,时钟开始之后第一个上升沿开始操作。
- 偶数分频(2N)
模为N的计数器,实现50%占空比的时钟信号,每次计数到N。
module Clk_div4(clk_in,clk_out,rst);
input clk_in;
input rst;
output clk_out;
reg [2:0] cnt;
reg clk_out;
parameter N=4;
always @ (posedge clk_in or negedge rst)
begin
if(!rst)
begin
cnt <= 0;
clk_out <= 0;
end
else begin
if(cnt==N/2-1)
begin clk_out <= !clk_out; cnt<=0; end
else
cnt <= cnt + 1;
end
end
endmodule
- 奇数分频(2N+1)
- 用模为(2N+1)的计数器,让输出时钟在(x-1)在1~2N-1之间和2N时各翻转一次,但占空比不一定是50%。(x/(2N+1))
- 实现奇数(N)分频,分别用上升沿计数到(N-1)/2,再计数到N-1;用下降沿计数到(N-1)/2,再计数到N-1,得到两个波形,然后把它们相或即可得到N分频。
module Clk_div15(clk_out,clk_in,rst);
output clk_out;
input clk_in,rst;
reg [3:0] cnt_p,cnt_n;
reg clk_p,clk_n;
parameter N=15;
always @ (posedge clk_in or negedge rst)
begin
if(!rst) cnt_p <= 0;
else if(cnt_p==N-1) cnt_p <=0;
else cnt_p <= cnt_p + 1;
end
always @ (posedge clk_in or negedge rst)
begin
if(!rst) clk_p <= 0;
else if(cnt_p==(N-1)/2)
clk_p <= !clk_p;
else if(cnt_p==N-1)
clk_p <= !clk_p;
end
always @ (negedge clk_in or negedge rst)
begin
if(!rst) cnt_n <= 0;
else if(cnt_n==N-1) cnt_n <=0;
else cnt_n <= cnt_n + 1;
end
always @ (negedge clk_in or negedge rst)
begin
if(!rst) clk_n <= 0;
else if(cnt_n==(N-1)/2)
clk_n <= !clk_n;
else if(cnt_n==N-1)
clk_n <= !clk_n;
end
assign clk_out = clk_p | clk_n;
endmodule
- N-0.5分频
采用模 N 计数器可以实现。具体如下:计数器从0 开始上升沿计数,计数达到N-1 上升沿时,输出时钟需翻转,由于分频值为N-0.5,所以在时钟翻转后经历0.5 个周期时,计数器输出时钟必须进行再次翻转,即当CLK 为下降沿时计数器的输入端应为上升沿脉冲,使计数器计数达到N 而复位为0 重新开始计数同时输出时钟翻转。输出与时钟异或。
注:精确分频用DLL。