龙空技术网

verilog 语言设计时钟分频设计问题全解

电子小资料 193

前言:

现在朋友们对“计数器verilog十进制”大体比较关注,咱们都需要剖析一些“计数器verilog十进制”的相关资讯。那么小编同时在网络上收集了一些对于“计数器verilog十进制””的相关文章,希望朋友们能喜欢,同学们快快来学习一下吧!

#刺猬大学成长计划# #头条之星校园计划# #文史之旅#

时钟信号的处理是FPGA的特色之一,因此分频器也是FPGA设计中使用频率非常高的基本设计之一。一般在FPGA中都有集成的锁相环可以实现各种时钟的分频和倍频设计,但是通过语言设计进行时钟分频是最基本的训练,在对时钟要求不高的设计时也能节省锁相环资源。

分频有两种一种偶分频,一种奇分频。偶分频则意味着M为偶数,奇分频则意味着M为奇数。

如输入时钟为50M,输出时钟为25M,则M=2,N=1。偶分频则意味着M为偶数。

1,偶数分频:偶数倍分频相对简单,比较容易理解。通过计数器计数是完全可以实现的。如进行m倍偶数分频,那么通过时钟触发计数器计数,当计数器从0计数到(M/2)-1时,输出时钟进行翻转,以此循环下去。

首先得到分频系数M和计数器值N。

M = 时钟输入频率 / 时钟输出频率

N = M / 2

以M=4,N=2为例,我们希望得到的输出时钟时序如下:

因此只需要将counter以clk_in为时钟驱动计数,当counter = (N-1)时,clk_out翻转即可。

verilog代码如下

2,奇数分频: 如果要实现占空比为50%的奇数倍分频,不能同偶数分频一样计数器记到一半的时候输出时钟翻转,那样得不到占空比50%的时钟。以待分频时钟CLK为例,如果以偶数分频的方法来做奇数分频,在CLK上升沿触发,将得到不是50%占空比的一个时钟信号(正周期比负周期多一个时钟或者少一个时钟);但是如果在CLK下降沿也触发,又得到另外一个不是50%占空比的时钟信号,这两个时钟相位正好相差半个CLK时钟周期。通过这两个时钟信号进行逻辑运算我们可以巧妙的得到50%占空比的时钟。
总结如下:对于实现占空比为50%的N倍奇数分频,首先进行上升沿触发进行模N计数,计数选定到某一个值进行输出时钟翻转,然后经过(N-1)/2再次进行翻转得到一个占空比非50%奇数n分频时钟。再者同时进行下降沿触发的模N计数,到和上升沿触发输出时钟翻转选定值相同值时,进行输出时钟时钟翻转,同样经过(N-1)/2时,输出时钟再次翻转生成占空比非50%的奇数n分频时钟。两个占空比非50%的n分频时钟进行逻辑运算(正周期多的相与,负周期多的相或),得到占空比为50%的奇数n分频时钟。

奇分频需要通过两个时钟共同得到。首先得到分频系数M和计数器值N。

M = 时钟输入频率 / 时钟输出频率

N = (M-1) / 2

如输入时钟为50M,输出时钟为10M,则M=5,N=2。奇分频则意味着M为奇数。

以M=5,N=2为例,我们希望得到的输出时钟时序如下:


其中clk_out为最终输出时钟,clk_out1和clk_out2为辅助时钟生成。

计数器counter由0技术至(M-1)。

clk_out1在clk_in的上升延跳变,条件是counter==(N-1)或(M-1)。

clk_out2在clk_in的下降延跳变,条件是counter==(N-1)或(M-1)。

之后clk_out = clk_out1 & clk_out2即可得到M分频的时钟。

verilog代码如下


任意整数时钟分频程序如下:

module divide ( clk,rst_n,clkout);

input clk,rst_n; //输入信号,其中clk连接到FPGA的C1脚,频率为12MHz

output clkout; //输出信号,可以连接到LED观察分频的时钟

//parameter是verilog里常数语句

parameter WIDTH = 3; //计数器的位数,计数的最大值为 2**WIDTH-1

parameter N = 5; //分频系数,请确保 N < 2**WIDTH-1,否则计数会溢出

reg [WIDTH-1:0] cnt_p,cnt_n; //cnt_p为上升沿触发时的计数器,cnt_n为下降沿触发时的计数器

reg clk_p,clk_n; //clk_p为上升沿触发时分频时钟,clk_n为下降沿触发时分频时钟

//上升沿触发时计数器的控制

always @ (posedge clk or negedge rst_n ) //posedge和negedge是verilog表示信号上升沿和下降沿

//当clk上升沿来临或者rst_n变低的时候执行一次always里的语句

begin

if(!rst_n)

cnt_p<=0;

else if (cnt_p==(N-1))

cnt_p<=0;

else cnt_p<=cnt_p+1; //计数器一直计数,当计数到N-1的时候清零,这是一个模N的计数器

end

//上升沿触发的分频时钟输出,如果N为奇数得到的时钟占空比不是50%;如果N为偶数得到的时钟占空比为50%

always @ (posedge clk or negedge rst_n)

begin

if(!rst_n)

clk_p<=0;

else if (cnt_p<(N>>1)) //N>>1表示右移一位,相当于除以2去掉余数

clk_p<=0;

else

clk_p<=1; //得到的分频时钟正周期比负周期多一个clk时钟

end

//下降沿触发时计数器的控制

always @ (negedge clk or negedge rst_n)

begin

if(!rst_n)

cnt_n<=0;

else if (cnt_n==(N-1))

cnt_n<=0;

else cnt_n<=cnt_n+1;

end

//下降沿触发的分频时钟输出,和clk_p相差半个时钟

always @ (negedge clk)

begin

if(!rst_n)

clk_n<=0;

else if (cnt_n<(N>>1))

clk_n<=0;

else

clk_n<=1; //得到的分频时钟正周期比负周期多一个clk时钟

end

assign clkout = (N==1)?clk:(N[0])?(clk_p&clk_n):clk_p; //条件判断表达式

//当N=1时,直接输出clk

//当N为偶数也就是N的最低位为0,N(0)=0,输出clk_p

//当N为奇数也就是N最低位为1,N(0)=1,输出clk_p&clk_n。正周期多所以是相与

endmodule

标签: #计数器verilog十进制 #verilog十进制计数器代码 #计数器verilog代码重装值