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

文章目录

    • 分频与降频
      • 偶分频——六分频器divider_six
        • 实验原理
        • 实验代码
      • 奇分频——五分频器divider_fie
        • 实验原理
        • 解决方案
        • 实验代码
      • 降频
        • 实验原理
        • 降频后的波形图
        • 使用降频的五/六降频代码
        • 两种方式的调用
      • 总结

分频与降频

偶分频——六分频器divider_six

实验框图与波形图

FPGA学习日志——分频与降频divider_第1张图片

实验原理

当实现一个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%的占空比。

实验框图与波形图
FPGA学习日志——分频与降频divider_第2张图片

解决方案

步骤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,在系统时钟上升沿拉高一个周期的高电平,此时得到的就算降频后的信号。

降频后的波形图

FPGA学习日志——分频与降频divider_第3张图片
FPGA学习日志——分频与降频divider_第4张图片

使用降频的五/六降频代码

//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。其中所谓的时钟偏移,指的是从同一时钟源发出的时钟脉冲,通过不同的路径到达每个触发器的时间不同而产生的偏差称为时钟偏移。

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

你可能感兴趣的:(FPGA学习日志,fpga开发,学习)