本文介绍了偶数分频和奇数分频电路的设计,分别从简单的分频介绍开始,延伸到任意N分频电路的设计,做了详细的说明,并且附有verilog源程序,并有仿真结果。
在数字逻辑电路中,分频器是一种常用电路,通常用来对某个给定的频率进行分频,以得到所需的频率。 1.1、 偶数分频电路 偶数倍分频是最简单的一种分频模式,完全可以通过计数器计数实现,如果要进行N倍(N为偶数)偶数分频,可由待分频的时钟触发计数器计数,当计数器从0计数到N/2—1时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数,以此循环下去。这种方法可以实现任意的偶数分频。下面的程序给出的是一个16分频电路,其他倍数的分频电路可以通过修改计数器的上限值得到。 用Verilog实现一个16分频电路,其源程序如下。module clk_div16(clk_in,reset,clk_out);
input clk_in; input reset; output clk_out; reg clk_out; reg[2:0] cnt; clk_in) begin if(!reset) begin cnt<=0; clk_out<=0; end else if(cnt==7) begin clk_out<=~clk_out; cnt<=0; end else begin cnt<=cnt+1; //clk_out<=clk_out; end end endmodule测试激励程序如下:
module clk_div16_tb;
reg clk_in; reg reset; wire clk_out;clk_div16 uut (
.clk_in(clk_in), .reset(reset), .clk_out(clk_out) );initial begin
// Initialize Inputs clk_in = 0; reset = 0; #10 reset=1; end always #2 clk_in=~clk_in; endmodule上述程序经过Synplify Pro 综合后,其RTL级结构如下图所示
在ModelSim6.5中完成仿真,结果如图所示。总结:如果要实现任意N(偶数)分频电路。其程序如下
module clk_divN(clk_in,reset,clk_out); input clk_in; input reset; output clk_out; reg clk_out; reg[2:0] cnt; parameter N=8;//只需修改N的值即可 clk_in) begin if(!reset) begin cnt<=0; clk_out<=0; end else if(cnt==(N/2-1)) begin clk_out<=~clk_out; cnt<=0; end else begin cnt<=cnt+1; clk_out<=clk_out; end end endmodule 1.2、 奇数分频电路 奇数分频电路有多种实现方式,下面介绍常用的错位“异或”法的原理。如果要进行3分频,通过待分频时钟上升沿触发计数器进行模3计数,当计数器计到邻近值时进行两次翻转。比如在计数器计计数到1时,输出时钟进行翻转;计数到2时,再次翻转,即在邻近的1和2时刻进行两次翻转,在0时刻不翻转。这样实现的3分频占空比为1/3或2/3。如果要实现占空比为50%的3分频时钟,可以通过待分频时钟下降沿触发计数,和上升沿同样的方法计数进行3分频,然后将下降沿产生的3分频时钟和上升沿产生的时钟进行相或运算,即可得到占空比为50%的3分频时钟。 这种错位“异或”法可以推广到实现任意的奇数分频:对于实现占空比为50%的N倍奇数分频,首先进行上升沿触发的模N计数,计数到某一选定值时(0到N—1之间的任意数值,比如在计数为0)进行输出时钟翻转,然后经过(N-1)/2再次翻转,得到一个占空比非50%的奇数N分频电路。再者,同时进行下降触发沿的模N计数,和上升沿触发输出时钟翻转选定值相同的值时,进行输出时钟翻转,同样经过(N-1)/2,输出时钟再次翻转,生成占空比非50%的奇数N分频时钟。将两个占空比非50%的N分频时钟相或运算,得到占空比为50%的奇数N分频时钟。 使用Verilog程序实现3分频电路: module clk_div3(clk_in,reset,clk_out); input clk_in; input reset; output clk_out; integer cnt1,cnt2; reg clk_div3p; reg clk_div3n; clk_in) begin if(!reset) begin clk_div3p<=0; cnt1<=0; end else if(cnt1==2) cnt1<=0; else begin cnt1<=cnt1+1; clk_div3p<=~clk_div3p; end end clk_in) begin if(!reset) begin clk_div3n<=0; cnt2<=0; end else if(cnt2==2) cnt2<=0; else begin cnt2<=cnt2+1; clk_div3n<=~clk_div3n; end endassign clk_out=clk_div3p|clk_div3n;
endmodule
测试激励程序如下:
module clk_div3_tb;// Inputs
reg clk_in; reg reset;// Outputs
wire clk_out;// Instantiate the Unit Under Test (UUT)
clk_div3 uut ( .clk_in(clk_in), .reset(reset), .clk_out(clk_out) );initial begin
// Initialize Inputs clk_in = 0; reset = 0; #10 reset=1; end always #2 clk_in=~clk_in; endmodule经ModleSim6.5仿真后的图形如下图
总结:如果要实现任意N(奇数)分频电路。其程序如下
module clk_divN(clk_in,reset,clk_out); input clk_in; input reset; output clk_out; integer cnt1,cnt2; reg clk_div3p; reg clk_div3n; parameter n=19 ; //N一定要为奇数 clk_in) begin if(!reset) begin clk_div3p<=0; cnt1<=0; end else if(cnt1==(n-1)) cnt1<=0; else if((cnt1==1)|(cnt1==(1+(n-1)/2))) begin cnt1<=cnt1+1; clk_div3p<=~clk_div3p; end else cnt1<=cnt1+1; endclk_in) begin
if(!reset) begin clk_div3n<=0; cnt2<=0; end else if(cnt2==(n-1)) cnt2<=0; else if((cnt2==1)|(cnt2==(1+(n-1)/2))) begin cnt2<=cnt2+1; clk_div3n<=~clk_div3n; end else cnt2<=cnt2+1; endassign clk_out=clk_div3p|clk_div3n;
endmodule
经ModleSim6.5仿真后的图形如下图2012-5-13