查看: 3061|回复: 2

【软件篇】FPGA verilog 实现任意分频

[复制链接]
  • TA的每日心情

    2013-8-6 23:08
  • 签到天数: 9 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2013-1-26 21:07:56 | 显示全部楼层 |阅读模式
    分享到:
         分频器是指使输出信号频率为输入信号频率整数分之一的电子电路。在许多电子设备中如电子钟、频率合成器等,需要各种不同频率的信号协同工作,常用的方法是以稳定度高的晶体振荡器为主振源,通过变换得到所需要的各种频率成分,分频器是一种主要变换手段。早期的分频器多为正弦分频器,随着数字集成电路的发展,脉冲分频器(又称数字分频器)逐渐取代了正弦分频器。下面以Verilog HDL 语言为基础介绍占空比为50%的分频器。
    1 偶分频
    偶分频比较简单,假设为N分频,只需计数到N/2-1,然后时钟翻转、计数清零,如此循环就可以得到N(偶)分频。代码如下。
    module fp_even(clk_out,clk_in,rst);
    output clk_out;
    input clk_in;
    input rst;
    reg [1:0] cnt;
    reg clk_out;
    parameter N=6;

    always @ (posedge clk_in or negedge rst)
    begin
    if(!rst)
           begin
                  cnt <= 0;
                  clk_out <= 0;
           end
    else begin
            if(cnt==N/2-1)
                  begin clk_out <= !clk_out; cnt<=0; end
            else
                  cnt <= cnt + 1;
            end
    end
    endmodule
    可以通过改变参量N的值和计数变量cnt的位宽实现任意偶分频。
    偶分频(N=6)的RTL原理图:
    偶分频(N=6)的行为仿真结果:
    2 奇分频
    实现奇数(N)分频,分别用上升沿计数到(N-1)/2,再计数到N-1;用下降沿计数到(N-1)/2,再计数到N-1,得到两个波形,然后把它们相或即可得到N分频。代码如下:
    module fp_odd(clk_out,clk_p,clk_n,clk_in,rst);
    output clk_out;
    output clk_p,clk_n;
    input clk_in,rst;

    reg [2:0] cnt_p,cnt_n;
    reg clk_p,clk_n;
    parameter N=5;

    always @ (posedge clk_in or negedge rst)
    begin
           if(!rst)     cnt_p <= 0;
           else  if(cnt_p==N-1)    cnt_p <=0;
                    else cnt_p <= cnt_p + 1;
    end

    always @ (posedge clk_in or negedge rst)
    begin
        if(!rst) clk_p <= 0;
        else if(cnt_p==(N-1)/2)
                   clk_p <= !clk_p;
           else if(cnt_p==N-1)
                   clk_p <= !clk_p;
    end

    always @ (negedge clk_in or negedge rst)
    begin
           if(!rst)     cnt_n <= 0;
           else  if(cnt_n==N-1)    cnt_n <=0;
                    else cnt_n <= cnt_n + 1;
    end

    always @ (negedge clk_in or negedge rst)
    begin
        if(!rst) clk_n <= 0;
        else if(cnt_n==(N-1)/2)
                   clk_n <= !clk_n;
           else if(cnt_n==N-1)
                   clk_n <= !clk_n;
    end

    assign clk_out = clk_p | clk_n;
    endmodule

    RTL Schematic:


    Simulate Behavioral Model:
    同理,可以通过改变参量N的值和计数变量cnt_p和cnt_n的位宽实现任意奇分频。

    3 任意占空比的任意分频
    在verilog程序设计中,我们往往要对一个频率进行任意分频,而且占空比也有一定的要求这样的话,对于程序有一定的要求,现在在前面两个实验的基础上做一个简单的总结,实现对一个频率的任意占空比的任意分频。
    比如: FPGA系统时钟是50M Hz,而我们要产生的频率是880Hz,那么,我们需要对系统时钟进行分频。很容易想到用计数的方式来分频:50000000/880 = 56818。显然这个数字不是2的整幂次方,那么我们可以设定一个参数,让它到56818的时候重新计数就可以实现了。程序如下:
    module div(clk, clk_div);
    input clk;
    output clk_div;
    reg [15:0] counter;
    always @(posedge clk)
    if(counter==56817) counter <= 0;
    else counter <= counter+1;
    assign clk_div = counter[15];
    endmodule
    分频的应用很广泛,一般的做法是先用高频时钟计数,然后使用计数器的某一位输出作为工作时钟进行其他的逻辑设计,上面的程序就是一个体现。
    下面我们来算一下它的占空比:我们清楚地知道,这个输出波形在counter为0到32767的时候为低,在32768到56817的时候为高,占空比为40%多一些,如果我们需要占空比为50%,那么我们需要再设定一个参数,使它为56817的一半,使达到它的时候波形翻转,就可以实现结果了。程序如下:
    module div(clk, clk_div);
    input clk;
    output clk_div;
    reg [14:0] counter;
    always @(posedge clk)
    if(counter==28408) counter <= 0;
    else counter <= counter+1;
    reg clk_div;
    always @(posedge clk)
           if(counter==28408) clk_div <= ~clk_div;
    endmodule
    继续让我们来看如何实现任意占空比,比如还是由50 M分频产生880Hz,而分频得到的信号的占空比为30%。
    56818×30%=17045
    module div(clk,reset,clk_div,counter);
    input clk,reset;
    output clk_div;
    output [15:0] counter;
    reg [15:0] counter;
    reg clk_div;
    always @(posedge clk)
    if(!reset) counter <= 0;
    else if(counter==56817) counter <= 0;
    else counter <= counter+1;
    always @(posedge clk)
    if(!reset) clk_div <= 0;
    else if(counter<17045) clk_div <= 1;
    else clk_div <= 0;
    endmodule
    RTL级描述:

    仿真结果:

    4 小结
    通过以上几个例子对比不难发现,借助计数器来实现任意点空比的任意分频的方法简单,且用verilog语言进行行为描述时,代码简洁、易懂、通用。通过以上的学习,对分频器有了比较深刻的认识,将在以后的学习中会有广泛的应用。


    回复

    举报

  • TA的每日心情
    无聊
    2015-8-17 09:38
  • 签到天数: 361 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2013-1-26 22:16:47 | 显示全部楼层
    再进一步可以研究下通用定时器的做法,设置总线接口和寄存器,实现多路可配置的时钟或PWM
    回复 支持 反对

    举报

  • TA的每日心情
    开心
    2015-8-7 21:35
  • 签到天数: 340 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2013-1-27 10:36:32 | 显示全部楼层
    支持一下……
    回复 支持 反对

    举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 1/3 下一条

    【预约|参会享"豪"礼】2025慕尼黑上海设备展
    “2025慕尼黑上海电子生产设备展”将于2025年03月26-28日上海新国际博览中心开幕诚邀您的光临!

    查看 »

    手机版|小黑屋|与非网

    GMT+8, 2025-3-9 13:01 , Processed in 0.114990 second(s), 18 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.