[SugerTangYL] 时钟管理(分频器、倍频器、锁相环)Verilog

目录

前言 

一、偶分频

二、奇分频

三、倍频器 

四、锁相环(PLL)

1. 模拟锁相环

(1)鉴相器 

(2)环路滤波器 

(3)压控振荡器

2.全数字锁相环

总结 


前言 

       数字电路中,时钟是十分重要的。我们经常需要各种频率的时钟,比如UART串口需要各种比特率等等,因此今天主要讲讲如何使用Verilog生成不同频率的时钟。


一、整数分频

整数分频最直接的方法是采用计数器分频。假设时钟分频系数为N,则计数器 <= (N/2) 时输出高电平,计数器>0时输出低电平,并在计数器==N后同步清0,从而实现将时钟进行 (N+1) 分频。

module ns_clkdiv(
    input    wire    [19:0]    clk_update_N    ,
    input    wire              clkdiv_en       ,
    input    wire              clk_i           ,
    output   wire              clk_out         ,
    input    wire              rst_n            
);
wire             clkdiv_clr;
wire             clk_update_N_zero;
wire             clk_out_high;
wire             clk_out_nxt;
wire   [19:0]    clk_cnt_nxt;
reg    [19:0]    clk_cnt_r;
reg              clk_out_r;

assign clkdiv_clr = (clk_cnt_r == clk_update_N);
assign clk_cnt_nxt = clkdiv_clr ? 20'b0 : clk_cnt_r + 20'b1;
always@(posedge clk or negedge rst_n)
    if(!rst_n)
        clk_cnt_r <= 20'b0;
    else begin
        if(clkdiv_en)
            clk_cnt_r <= clk_cnt_nxt;
    end

assign clk_update_N_zero = ~(| clk_update_N);
assign clk_out_high = (clk_cnt_r <= (clk_update_N > 1));
assign clk_out_nxt = clk_update_N_zero ? clk_i : clk_out_high;

always@(posedge clk_i or negedge rst_n)
    if(!rst_n)
        clk_out_r <= 1'b0;
    else begin
        if(clkdiv_en)
            clk_out_r <= clk_out_nxt;
    end

assign clk_out = clk_out_r;

endmodule

(一)偶分频

        所谓偶分频,是将基准时钟分频至原来的1\(2n),基本思路是每计满n个基准时钟(计数器0到n-1),使输出端翻转。这种分频方法一般能满足大部分的分频需求,实现起来也较为简单。例如下面代码,是将50MHz的基准时钟分频成100KHz的时钟信号,则计数器需计满249时翻转。

module divider(clk_Reference,reset_n,qout);
input clk_Reference;//基准时钟
input reset_n;//复位信号,可删去。
output reg qout;//输出分频时钟信号
reg [7:0] cnt;//分配的存储单元,位宽随需求变化。
parameter Frequency_Reference = 50_000_000;//输入基准时钟的频率
parameter Frequency_Demand = 100_000;//所需时钟的频率
parameter Number_Flip = Frequency_Reference/(2*Frequency_Demand)-1;//经计算后的计满翻转数

always @(posedge clk_Reference or negedge reset_n) begin
	if(!reset_n) cnt <= 8'b0;
	else begin
		if(cnt == Number_Flip) begin
			cnt <= 8'b0;
			qout <= ~qout;//翻转
		end
		else cnt <= cnt + 1'b1;
	end
end
endmodule

        上述代码声明了参数,只需要在模块调用时修改参数值,便能获得其他频率的时钟,不过基准频率得是输出频率的偶数倍,具体调用形式为:

divider divider_1(clk_Reference,reset_n,qout);

defparam divider_1.Frequency_Demand = 300_000;//采用层次命名法可以精准修改某一模块的参数

        其仿真波形如下: 

(二)奇分频

         首先看一个三分频的波形时序图,按照之前的思路,我们需要在基准时钟的1.5个周期时翻转,但想要计数器计小数比较麻烦。所以我采用基准时钟的上升沿和下降沿分别产生脉冲信号,然后将两信号相或,就得到了奇分频的信号。利用下降沿脉冲相比上升沿脉冲滞后半个基准时钟周期的特点,我们得到1.5个基准时钟周期的高低电平。

        对于两个子信号,要求高电平时间比低电平时间少一个基准时钟周期,如此才能得到占空比为50%的时钟信号。

         综上,Verilog代码如下:

module divider(clk_Reference,reset_n,qout);
input clk_Reference;//基准时钟
input reset_n;//复位信号
output qout;//分频时钟
parameter N = 3;//分频系数

reg [7:0] cnt_p;
reg clk_p;
//产生上升沿子时钟
always @(posedge clk_Reference or negedge reset_n) begin
	if(!reset_n) cnt_p <= 8'b0;
	else begin
		if(cnt_p == (( N-1 )/2)-1) clk_p <= 1'b1;
		else if(cnt_p == N-2) clk_p <= 1'b0;
		else ;
		
		if(cnt_p == N-1) cnt_p <= 8'b0;
		else cnt_p <= cnt_p + 1'b1;
	end
end

reg [7:0] cnt_n;
reg clk_n;
//产生下降沿子时钟
always @(negedge clk_Reference or negedge reset_n) begin
	if(!reset_n) cnt_n <= 8'b0;
	else begin
		if(cnt_n == (( N-1 )/2)-1) clk_n <= 1'b1;
		else if(cnt_n == N-2) clk_n <= 1'b0;
		else;
		
		if(cnt_n == N-1) cnt_n <= 8'b0;
		else cnt_n <= cnt_n + 1'b1;
	end
end

assign qout = clk_p | clk_n;//两子时钟相或
endmodule

        此例程也做了参数化,可修改分频系数这一参数来得到其他奇分频时钟信号,具体实例化方法同上文。 仿真波形图如下,可见与设想波形相同。

二、小数分频 

        小数分频的本质是在一段时间内平均的结果。因此会出现时钟抖动。可参考:

三、倍频器 

        由于在数字电路中,想要使得信号发生变化,前提往往需要出现边沿。而我们的基准时钟,一个周期内只有一个上升沿和一个下降沿,如果将基准时钟倍频两倍,则需要在上升沿和下降沿之间出现一个边沿。于是,我们采取电路延迟的方式获得这一个边沿。时序图如下:

        如果想要占空比为50%的时钟的话,只需要调节延迟时间为基准时钟周期的1/4即可,时序图如下:

         综上,输出倍频时钟由基准时钟和延迟时钟异或得到。Verilog代码如下:

module divider(clk_Reference,reset_n,qout,clk_d);
input clk_Reference;//基准时钟
input reset_n;//复位信号
output qout;//倍频时钟

output reg clk_d;
always @(posedge clk_Reference or negedge reset_n) begin
	if(!reset_n) ;
	else  clk_d <= #5 ~clk_d;
end

assign qout = clk_Reference ^ clk_d; 
endmodule

        从原理看得出,这种方法利用的是门延迟,但是在实际情况下门延迟很难控制,这种方法的可靠性并不高,且需要后端实现。因此常采用锁相环倍频电路来实现倍频。

四、锁相环(PLL)

1. 模拟锁相环

         锁相环(Phase Locked Loop)是一种反馈控制电路,由鉴相器(PD)、环路滤波器(LPF)和压控振荡器组成。特点是利用外部输入的参考时钟控制环路内部振荡信号的频率和相位。锁相环在工作过程中,当输出信号的频率与输入信号频率相等时,环路被锁定,称为入锁。维持锁定的直流控制电压由鉴相器提供,因此鉴相器的两个输入信号间留有一定的相位差。电路结构如下:

image:bk070532w-1.jpg

(1)鉴相器 

        鉴相器通常由模拟乘法器组成,设外界输入的信号电压和压控振荡器输出端反馈电压分别为:

        反馈电压中的ω0为压控振荡器的固有频率。则经过乘法器后,乘法器输出电压uD(t)为:

(2)环路滤波器 

        环路滤波器是一种低通滤波器。它的作用是滤除掉来自鉴相器输出电压中的高频分量和噪声分量。在上面uD(t)的式子中,和频分量(高频分量)对我们无用,因此此处使用滤波器,来获得干净的差频分量 uc(t)。

(3)压控振荡器

        压控振荡器是一种以电压输入来控制振荡频率的震荡器。其输出角频率与输入电压之间的关系如下:

        其中ko为压控灵敏度。因此可通过控制电压来提升或降低压控振荡器的输出频率。改变后的电压再作为反馈信号输入到鉴相器中,重复多次即可使得压控振荡器输出电压频率与鉴相器输入的基准电压频率相同。

         综上,我们只需要在反馈回路中加入N分频器,使得反馈信号变为原来的1/N,再利用锁相环的特性,就能得到N倍频率的时钟信号。电路图如下:

         在使用Quartus做FPGA开发时,可以调用ip核来直接使用锁相环。具体调用操作流程别人有很详细的教程,此处就不解释啦。

          

2.全数字锁相环

         对于全数字锁相环,是将连续信号离散化处理,故由鉴相器、数据缓冲器和数控振荡器组成。其中的数控振荡器一般是调节分频系数或调节DDS查表步长的方式实现,但这些都需要一个系统基准时钟,因此无法实现将基准时钟做到倍频,只能实现在最高频率时钟内的全数字锁相环。下边的转载博客提供给有需求的同学。

        https://blog.csdn.net/DBLLLLLLLL/article/details/84395583

        锁相环原理及数字化,用FPGA实现全数字高阶锁相环_锁相环技术原理及fpga实现_红蓝心的博客-CSDN博客 


总结

         时钟对数字电路的重要性不言而喻,特此总结讲述了在Verilog中对时钟调控的多种方法。

  • 15
    点赞
  • 138
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一种基于FPGA的任意分频器设计与实现,可以通过利用FPGA的可编程性和灵活性来实现任意的分频比。FPGA(Field-Programmable Gate Array)是一种可编程逻辑设备,可以通过重新配置其内部的逻辑门阵列和时序元件来实现不同的功能。 首先,我们需要确定所需的分频比,并计算出分频比的细分数,也就是将输入时钟信号分成多少份。接下来,我们通过FPGA的时钟管理资源来生成所需的分频时钟信号。FPGA中的时钟管理资源通常包括时钟分配器和锁相环(Phase-Locked Loop, PLL)等。其中,时钟分配器可以将输入时钟信号分配到不同的逻辑模块,而PLL可以通过调节其内部的控制参数来实现不同的倍频和分频功能。 在设计中,我们可以使用FPGA开发工具(如Xilinx ISE或Vivado)来进行设计和仿真。首先,我们需要在FPGA开发工具中创建一个新的项目,并添加所需的时钟管理资源和逻辑模块。然后,我们可以使用硬件描述语言(如VHDL或Verilog)来实现分频器的功能。在实现时,我们需要根据所需的分频比和细分数,利用逻辑门、触发器和时序元件等基本的FPGA元素来设计一个适合的电路。最后,我们可以使用仿真工具来验证设计的正确性。 实现后,我们需要将设计烧录到FPGA芯片中。通过连接FPGA芯片的开发板和计算机,我们可以使用烧录工具将设计下载到FPGA芯片中,并在开发板上测试分频器的功能。在测试中,我们可以输入一个特定的时钟信号,并观察输出的分频时钟信号是否符合我们所设计的分频比。 总之,基于FPGA的任意分频器设计与实现利用了FPGA的可编程性和灵活性,可以根据实际需求实现不同的分频比。通过适当的设计和验证,我们可以实现一个满足要求的任意分频器

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值