FPGA学习日志——分频与降频divider

分频与降频

偶分频——六分频器divider_six

实验框图与波形图

在这里插入图片描述

实验原理

当实现一个N分频的模块(N为偶数),当复位信号无效时,每个时钟上升沿到来时,计数器cnt便开始计数(注意,计数器0也占用一个时钟周期),数值依次累加1,直到计数器cnt等于N/2-1时,对输出信号取反,便实现了一个基础的偶分频模块功能。

实验代码
module divider_six
(
    input   wire    sys_clk,
    input   wire    sys_rst_n,
  	output  reg     clk_out     
);
reg [2:0] cnt;
 always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n==1'b0)
        cnt<=2'd0;
    else if (cnt==2'd2)
            cnt<=2'd0;
        else cnt<=cnt+2'd1;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n==1'b0)
        clk_out<=1'd0;
    else    if(cnt==2'd2)
            clk_out<=~clk_out;
            else    clk_out<=clk_out; 
endmodule

奇分频——五分频器divider_fie

实验原理

按照偶分频的思想,当计数器到一半取反时,会发现计数器为2.5并且向下取整为2,这将导致分频后的时钟不能保持50%的占空比。

实验框图与波形图
在这里插入图片描述

解决方案

步骤1:
增加两个变量clk_out1与clk_out2,当sys_clk上升沿并且cnt为2的时候,拉高clk_out1,当cnt为4时拉低信号clk_out1,其余时刻保持不变。同时当sys_clk下降沿时重复操作,得到clk_out2。
步骤2:
对采集到的clk_out1与clk_out2进行或操作,便可以得到占空比为50%的clk_out3,实现实验目标。

实验代码
module divider_five
(
    input   wire    sys_clk,
    input   wire    sys_rst_n,
    output  wire     clk_out 
);
reg  [3:0]  cnt;
reg     clk_out1;
reg     clk_out2; 
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n==1'b0)
        clk_out1<=1'd0;
    else    if(cnt==3'd2)
            clk_out1<=~clk_out1;
            else    if(cnt==3'd4)
            clk_out1<=~clk_out1;
            else clk_out1<=clk_out1;   
always@(negedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n==1'b0)
        clk_out2<=1'd0;
    else    if(cnt==3'd2)
            clk_out2<=~clk_out2;
            else    if(cnt==3'd4)
            clk_out2<=~clk_out2;
            else clk_out2<=clk_out2; 
assign clk_out=(clk_out1|clk_out2);//这里的输出信号采用组合逻辑赋值,就不会延迟一个时钟周期 
endmodule

降频

实验原理

当要实现一个N分频的模块,我们可以直接让计数器cnt计数到N-1,在系统时钟上升沿拉高一个周期的高电平,此时得到的就算降频后的信号。

降频后的波形图

在这里插入图片描述
在这里插入图片描述

使用降频的五/六降频代码
//divider_six
module divider_six
(
    input   wire    sys_clk,
    input   wire    sys_rst_n,
    output reg  clk_flag
);
reg [2:0] cnt;
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n==1'b0)
        cnt<=3'd0;
    else if (cnt==3'd5)
            cnt<=3'd0;
        else cnt<=cnt+3'd1;
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n==1'b0)        
        clk_flag<=1'b0;
    else    if(cnt==3'd4)
            clk_flag<=1'b1;
            else clk_flag<=1'b0;

endmodule

//divider_five
module divider_five
(
    input   wire    sys_clk,
    input   wire    sys_rst_n,
    output  reg    clk_flag
);
reg  [3:0]  cnt;
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n==1'b0)
        cnt<=3'd0;
    else    if(cnt==3'd4)
                cnt<=3'd0;
            else  cnt<=cnt+3'd1;
always@(posedge sys_clk or negedge sys_rst_n)    
        if(sys_rst_n==1'b0)
            clk_flag<=1'b0;
        else    if(cnt==3'd3)
                clk_flag<=1'b1;
                else    clk_flag<=1'b0;
 endmodule

可以看到无论是奇分频还是偶分频此时输出都是一个标志信号,而且编写格式相同并且不用考虑占空比的问题。

两种方式的调用

分频调用,直接使用输出信号作为后续模块时钟

//分频调用
always@(posedge clk_out or negedge sys_rst_n)        
        if(sys_rst_n==1'b0)
        a<=1'b0;
        else    a<=a+1'b1;

降频调用,使用系统时钟,当标志信号来临时后续信号才产生变化

always@(posedge sys_clk or negedge sys_rst_n)        
        if(sys_rst_n==1'b0)
        a<=1'b0;
        else    if(clk_flag==1'b1)    
        a<=a+1'b1; 

第二种方式的信号是在系统时候的控制下,相对于第一种对时钟控制更为严格。

总结

在高速系统设计中,尽量采用降频方式,其中涉及到了全局时钟树的概念,简单来说,降频可以保证更低的时钟偏移skew抖动jitter。其中所谓的时钟偏移,指的是从同一时钟源发出的时钟脉冲,通过不同的路径到达每个触发器的时间不同而产生的偏差称为时钟偏移。

总之:降频优于分频方式。

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chendy_00

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值