打印
[VHDL]

玩转VHDL021-万能分频器

[复制链接]
1437|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ucx|  楼主 | 2018-4-13 21:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 ucx 于 2018-4-14 21:22 编辑

DF_general.rar (1.21 KB)

020帖介绍了8B10B编码器,接下来应该讲8B10B解码以及编解码实际应用举例。我们把这件事先放一放,转而介绍一下人尽皆知的分频器。

万能分频器性能
关于分频器的应用和必要性,不打算在此浪费笔墨介绍。分频器分为整数分频和小数分频,小数分频也称为分数分频。前一段时间,本人需要一个由50M产生1843200=115200×16的频率信号,用来实现和115200波特率的串口通信,设计制作了一个DF_general通用分频器,和大家分享一下。

如果一个分频器同时满足以下4个条件:
1. 只要给出时钟频率和输出频率就能生成相应的分频电路。
2. 消耗的资源最少,或者某些情况下比精心定制设计消耗资源略高一点。
3. 输出抖动频率最小:整数分频时钟无抖动,分数分频时始终小于一个时钟周期。
4. 适用于任何输出频率小于时钟频率的情况。
那么,我们是不是可以说这个分频器叫万能分频器呢?DF_general恰好满足这4个条件,故称之为万能分频器。
分数分频原理
实现分数分频方式不同,阐述原理的方法也不同。本帖用带分数的形式实现分数分频,所以先把时钟clock频率与输出q频率的比值用带分数表示。
记clk_frq和q_frq为时钟频率和输出频率。令clk_frq/q_frq= qut + num/den。式中num和den互素,且num<den。num==0时为整数qut分频。下面叙述num!=0的情况。
1. 设计一个模qut的受控计数器cn_qut,时钟使用clock,控制信号为enQut。
2. enQut==0时cn_qut要停一拍计数,所以称enQut==0为停拍脉冲,并称cn_qut的周期为整周期。一个整周期内最多存在一个停拍脉冲,存在停拍脉冲的整周期称为慢周期,不存在停拍脉冲的整周期为快周期。显然,快周期长度是qut个时钟周期,慢周期是qut+1个时钟周期。此时令整周期的溢出率为输出频率。那么,全部是快周期时为qut整数分频,快慢周期交替时,则输出平均速率为(qut, qu+1)内的分数分频。快周期比例高则输出频率接近qut整数分频,慢周期比重高则接近qut+1分频。
3. 在den个整周期内,溢出次数为den。如果选取num个作为慢周期,则den个整周期的总时间为den×qut + num个时钟周期。此时,时钟频率与溢出率的比值刚好是qut + num/den,即实现了clk_frq/q_frq分频。
4. 通过以上分析,定义一个分母计数器den_cn,完成以整周期的溢出信号ov_qut为使能的模den计数。剩下的问题是在den个整周期内如何均匀选取num个周期。
5. 对于num==1的简单情况,选取den_cn == 0的整周期为慢周期即可,同样当num == den-1时只有den_cn == 0为快周期,其他为慢周期即可。
6. 再去掉num==2和num==den-2两种简单情况。选取2个周期为慢周期或快周期。
7. 其他情况,den一定>=7且num>=3且num <=den-3,采用DDS办法均匀选取num个周期作为慢周期。
7.1 确定表示den-1的二进制整数的位长den_len。
7.2 定义一个位长为den_len的DDS累加器DDS_acc。
7.3 计算DDS累加字DDS_frq=2**den_len * num / den。式中**表示幂运算。
7.4 累加器在den个整周期开始装载den-1值(整周期溢出时刻),否则在其他整周期溢出时累加DDS_frq计数。那么,累加器在den个整周期时间刚好均匀溢出num次。
到此,万能分频器就诞生了。下面简单说说DF_general的具体实现步骤。


万能分频器设计实现
模块以VHDL语言形式表示如下。
Entity DF_general is generic(
         clk_frq               : integer := 50e6;
         q_frq                  : integer := 1843200);
         Port(
         clock                            : in std_logic;
         q                                   : outstd_logic
         );
参数clk_frq默认为50MHz,参数q_frq默认为115200×16=1843200Hz
为了使dennum互素,需要编写一个供编译器使用的求最大公约数函数gcd(a, b)
为实现步骤7.3并确保×运算不溢出,设计一个函数cal_frq(f, fs)
然后定义常数如下:
const  int  qut= clk_frq / q_frq;
const  int  residu= clk_frq % q_frq;
const  int  den= q_frq / gcd(q_frq, residu);
const  int  num= residu / gcd(q_frq, residu);
const  int qut_len= LOG2(qut-1)+1;
#if qut==1         //整数部分为1时不需要cn_qut
         ov_qut = enQut;      
#elsif qut==2    //此时,cn_qut退化为一个比特
         @clock if(enQut) cn_qut = ~cn_qut;            //步骤1
         ov_qut = ~cn_qut;
#else
cn_qut[0 : qut_len-1];
         @clock if(enQut) cn_qut = cn_qut==qut-1? 0 : cn_qut+1;           //步骤1, 相当于cn_qut =( cn_qut+1)%qut,
         @clock ov_qut = ~ov_qut && cn_qut==0; //确保一个整周期一次溢出
#endif
#if residu==0                                                                     //整数分频,不需要den计数
         enQut =1;
#else
         const int den_len= LOG2(den-1)+1;
         const  int  DDS_frq=cal_frq(num,den);
         DDS_nxt[0 : den_len];
         DDS_acc[0 :den_len-1];
         den_dis,y_dis,ld_dds;
         #if num==1 ||num==den-1                                 // 步骤5
                   @clock  if(ov_qut) den_dis = (den_cn==0) != num;
         #elsif num==2 ||num==den-2                            //步骤6
                   @clock  if(ov_qut) den_dis = (den_cn==0 || den_cn==den/2) !=( num!=2);
         #else
                   DDS_nxt =DDS_acc+DDS_frq;
                   @clock  if(ov_qut) {
                            ld_dds= den_cn==0;
                            DDS_acc= ld_dds ?den-1: DDS_nxt(1 to den_len);      //步骤7.4
                            den_dis= DDS_nxt[0];
                   }
         #endif
         @clock if(ov_qut) den_cn= den_cn==den-1? 0 : den_cn+1; //步骤3中模den计数
         @clock y_dis = qut==1?~y_dis&&den_dis:  ~ov_qut;
         enQut = y_dis ||~den_dis;      //与上一行一起确保停拍脉冲不连续
#endif

万能分频器应用举例
例:用50M时钟osc50M产生2.048M的时钟信号clk2M
DF_general generic map(50e6, 4096e3) port map(osc50M, en);
@osc50M if(en) clk2M <= ~clk2M;
是不是很万能呢?
DF_general.vhd完整代码见附件。
DF_general的应用限制
clk_frqq_frq是静态参数,不可动态配置。

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

ucx

28

主题

85

帖子

5

粉丝