分频器的设计——奇偶分频
1、2的n次方分频实现
如下电路可以实现对CLK的2分频。原理很简单,上电复位先给寄存器一个初始值,然后只有在CLK上升沿CLK_DIV2才会翻转一次。因此CLK两个上升沿之后,CLK_DIV2才完成两次翻转。
要实现2的n次方分频可以通过复用n次这个电路。如下所示。
2、偶数倍分频
方式一:如下所示。通过移位寄存器实现分频。例如要实现2n倍分频,则需要用n个寄存器。
优点:不需要其它任何控制逻辑,只需要寄存器加一个反相器。
缺点:当分频倍数很大时,需要的寄存器也是倍增。当然你也可以采用复用的方式去减少所需寄存器数目,例如,36分频,可以做两个6分频器相连,则所需寄存器为6个,需要的寄存器数大大减少。
方式二:如下图所示,通过计数器来实现分频。比如,做一个2n分频器,则计数器计数从0到n-1,CLK_DIV就翻转一次。
代码如下(分频数为DIV_NUM=20):
module fre_div #(
parameter DIV_NUM = 20, // 分频数为20
parameter CNT_W_L = 8 // 计数器位宽为8
)
(
input clk,
input rst_n,
output reg div_clk
);
reg [CNT_W_L - 1 : 0] div_cnt;
// 计数器
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
div_cnt <= 'h0;
end
else if(div_cnt != DIV_NUM / 2 - 1)
begin
div_cnt <= div_cnt + 1'b1;
end
else
begin
div_cnt <= 'h0;
end
end
// 分频器
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
div_clk <= 1'b0;
end
else if(div_cnt == DIV_NUM / 2 -1)
begin
div_clk <= ~div_clk;
end
end
endmodule
仿真波形:
3、奇数倍分频
如上方式只能实现偶数倍分频,是因为寄存器都是源时钟CLK上升沿触发的,因此DIV_CLK只能在上升沿去发生跳转,这导致DIV_CLK必定只能是CLK的偶数倍分频关系(CLK跳转两次,DIV_CLK才可能跳转一次)。
奇数倍分频的一种实现方式如下。一路计数器用CLK的非CLK_N控制,一路用CLK控制。最后将两路的输出分频波形相亦或,得到最后的分频输出。如果难以理解可以对着最后的波形去看。
Verilog实现如下(分频数为DIV_NUM=9):
module fre_div #(
parameter DIV_NUM = 20, // 分频数为20
parameter CNT_W_L = 8 // 计数器位宽为8
)
(
input clk,
input rst_n,
output reg div_clk
);
reg [CNT_W_L - 1 : 0] div_cnt;
// 计数器
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
div_cnt <= 'h0;
end
else if(div_cnt != DIV_NUM / 2 - 1)
begin
div_cnt <= div_cnt + 1'b1;
end
else
begin
div_cnt <= 'h0;
end
end
// 分频器
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
div_clk <= 1'b0;
end
else if(div_cnt == DIV_NUM / 2 -1)
begin
div_clk <= ~div_clk;
end
end
endmodule
仿真波形如下:
在完成这个博客的过程中看到一大佬写的博客,可以细细研究一下,以下是链接。