FPGA系统性学习笔记连载_Day11【奇分频、偶分频】

2021-04-07 14:27:24 浏览数 (1)

FPGA系统性学习笔记连载_Day11【奇分频、偶分频】之【设计原理、verilog代码实现及示波器验证】

本系列为FPGA系统性学习学员学习笔记整理分享,如有学习或者购买开发板意向,可加交流群联系群主。

连载《叁芯智能fpga设计与研发-第11天》 【奇分频、偶分频】之【设计原理、verilog代码实现及示波器验证】

原创作者:紫枫术河 转载请联系群主授权,否则追究责任 这篇文章记录奇分频、偶分频的设计原理、verilog代码实现及示波器验证

一、时钟

时钟:是一个占空比为50%的周期信号,在数字电路中用这个信号来做时间基准,下图展示一个50MHz的时钟信号

二、时钟分频

时钟分频:分为奇分频和偶分频,意思是分频系数是奇数还是偶数。

三、奇分频

奇分频:意思对一个时钟进行奇数次分频

假如:我们有一个50MHz的基准信号,我们要得到10MHz信号,该怎么做?

1、首先我们要清楚频率和周期的概念

周期:事物在运动、变化过程中,某些特征多次重复出现,其连续两次出现所经过的时间叫“周期”。

频率:是单位时间内完成周期性变化的次数。

综上:从图中看,周期描述了脉冲的间隔时间,频率描述了周期电平变化的快慢。

2、频率与周期关系

从课本上可知:T=1/f、f = 1/T,但是我还是从50Mhz时钟来举列子理解

1)、50Mhz:我们知道这是一个频率,代表在1秒内一个周期电平变化了50_000_000 次

2)、周期:基于上面那个变化次数,可以得出一个周期的电平时间=20ns

3)、周期电平

概念:上面一直提到周期电平,意思是一个周期内电平由从低到高或者从高到底的完整变化,称为周期电平。即10ns电平改变一次。

3、50Mhz分频为10Mhz

1)、首先我们要进行5分频

5分频:分频后的周期为之前的5个周期电平。

2)、如果周期电平确定为5个,那么我们就需要2.5个周期就改变一次电平状态,才能满足5分频。

3)、实现:在FPGA中,我们没有小数,也就没法实现2.5个周期时,进行电平翻转

4、我们可以将50Mhz分2次计数

1)、上升沿计数:计数周期为5,当计数为2时,翻转电平,当计数为5时,翻转电平

2)、下降沿计数:计数周期为5,当计数为2时,翻转电平,当计数为5时,翻转电平

3)、将2次得出的电平结果,相或就得出了想要的5分频时钟(10MHz),如下图。

4)、从图中还可以看出,A、B分频时 高电平周期为 2个,低电平为3个,即高电平比低电平少1个。

那么对以任意的N奇分频,都有 n (n 1)= N,则 n = (N-1)/2

5、verilog代码实现 div_freq.v

代码语言:javascript复制
module div_freq(
    input           clk,
    input           rst_n,
     
    output      clk_div,
    output      clk_s
);
 
    reg     [25:0]  cnt1;
    reg     [25:0]  cnt2;  
     
    reg     clk_H;
    reg     clk_L;
     
    parameter   clk_cpu = 50_000_000;
    parameter   clk_dst = 10_000_000;
    parameter   div_cnt = clk_cpu/clk_dst;
     
    //上升沿分频计数
    always@(posedge clk,negedge rst_n)begin
        if(!rst_n)begin
                cnt1 <= 0;
                clk_H <= 1;
            end
        else if(cnt1 == ((div_cnt-1)/2 -1))begin
                //第二个上升沿拉低
                clk_H <= 1'b0;
                cnt1 <= cnt1   1'b1;
            end
        else    if(cnt1 == div_cnt -1)begin
                //第5个上升沿拉高
                clk_H <= 1'b1;
                cnt1 <= 0;
            end
        else
            begin
                cnt1 <= cnt1   1'b1;
                clk_H <= clk_H;
            end
    end
 
    //下降沿分频计数
    always@(negedge clk,negedge rst_n)begin
        if(!rst_n)begin
                cnt2 <= 0;
                clk_L <= 1;
            end
        else if(cnt2 == ((div_cnt-1)/2 -1))begin
                //第二个上升沿拉低
                clk_L <= 1'b0;
                cnt2 <= cnt2   1'b1;
            end
        else    if(cnt2 == div_cnt -1)begin
                //第5个上升沿拉高
                clk_L <= 1'b1;
                cnt2 <= 0;
            end
        else
            begin
                cnt2 <= cnt2   1'b1;
                clk_L <= clk_L;
            end
    end
     
    //得到最终的分频时钟
    assign clk_div = clk_H | clk_L;
    //导出系统时钟,便于示波器观察信号
    assign clk_s    = clk;
     
endmodule

6、仿真脚本div_freq_tb.v

代码语言:javascript复制
`timescale 1ns/1ps
 
module div_freq_tb();
    reg         clk;
    reg         rst_n;
     
    wire            clk_div;
    wire            clk_s;
     
    div_freq    div_freq_inst(
        .clk            (clk),
        .rst_n      (rst_n),
         
        .clk_div        (clk_div),
        .clk_s      (clk_s)
    );
 
    always #10 clk = ~clk;
     
    initial begin
        clk = 0;
        rst_n = 0;
        #20;
        rst_n = 1;
        #50000000;
        $stop;
    end
     
endmodule

7、仿真结果

结果正确

8、同理,我们可以3分频,得到一个无法除尽的频率16.666....如图

三、偶分频

偶分频:比较简单,只需要N/2作电平翻转即可

四、下板验证(intel Cycle IV)

我们需要一个系统时钟clk、2个GPIO输出clk来对比原始频率和分频后频率

我用的是叁芯智能的开发板(intel Cycle IV:EP4CE6E22C8)

1)、复位引脚rest = PIN24

2)、时钟引脚 clk = PIN23

3、gpio引脚 gpio3=PIN3 gpio13 = PIN7

4、打开Pin Planner引脚分配工具,具体方法,参考我之前的博客

5、示波器验证效果

【QQ交流群】

群号:173560979,进群暗语:FPGA技术江湖粉丝。

多年的FPGA企业开发经验,各种通俗易懂的学习资料以及学习方法,浓厚的交流学习氛围,QQ群目前已有1000多名志同道合的小伙伴,无广告纯净模式,给技术交流一片净土,从初学小白到行业精英业界大佬等,从军工领域到民用企业等,从通信、图像处理到人工智能等各个方向应有尽有。

【微信交流群】

现微信交流群已建立09群,人数已达数千人,欢迎关注“FPGA技术江湖”微信公众号,可获取进群方式。

后续会持续更新,带来Vivado、 ISE、Quartus II 、candence等安装相关设计教程,学习资源、项目资源、好文推荐等,希望大侠持续关注。

江湖偌大,继续闯荡,愿大侠一切安好,有缘再见!

0 人点赞