n分频器 verilog_verilog奇偶分频

本文介绍了偶数分频和奇数分频电路的设计,分别从简单的分频介绍开始,延伸到任意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;

always@(posedge 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的值即可

always@(posedge 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;

always@(posedge 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

always@(negedge 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

end

assign 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一定要为奇数

always@(posedge 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;

end

always@(negedge clk_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;

end

assign clk_out=clk_div3p|clk_div3n;

endmodule

经ModleSim6.5仿真后的图形如下图

2012-5-13


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部