分频器实现
分频在数字设计中应用广泛,通常可以使用锁相环PLL和计数器实现。本文介绍的分频器是基于计数器实现的,由于使用的是DFF(D触发器),这实际上是行波计数器(一串DFF级联,上级的输出作为下级的时钟)的推广,在同步实现中,一般不使用这种分频后的波形(因为DFF的Tco会逐级积累,使得分频前后的时钟不是100%同步,若将DFF的输出信号作为其他DFF的时钟,第一,极限情况容易违反Tsu和Thold,进而产生亚稳态;第二,这为STA和插入扫描链增加了难度)。但是,作为一种分频的思想,还是有讨论的价值的,或者说,在低频电路中,使用起来也不会对电路造成太大问题(不要多级级联,即不要将得到的时钟信号在进行分频作为其他模块的时钟)。
NOTE:扫描链(Scan chain)是可测试性设计的一种实现技术。它通过植入移位寄存器,使得测试人员可以从外部控制和观测电路内部触发器的信号值。
一、50%占空比整数分频
这是计数器分频中最简单最基础的分频方式。一般可分为奇数分频和偶数分频。
1.1 奇数分频器
1.1.1 方法1:2N分频上下沿波形相异或
生成2N分频的上升沿和下降沿触发的波形(正交),二者异或可得到N奇数分频波形。
具体方法:N为奇数
Step1:生成标志信号
上升沿波形翻转标志信号:
tff1_en = (clk_cnt == 0);
下降沿波形翻转标志信号:
tff2_en = (clk_cnt == (N + 1) / 2);
Step2:在DFF中翻转(div1、div2位2N个clk,计数到N-1清零)
always @ (posedge clk) If (tff1_en) Div1 <= ~div1;
always @ (negedge clk) If (tff2_en) Div2 <= ~div2;
Step3:异或得到N奇分频波形
assign div_odd = div1 ^ div2;
1.1.2 方法2:N分频上下沿波形相或(输出初始态为0)
在N分频波形内进行操作。
具体操作:
Step1:产生上升/下降沿波形翻转标志
tff1_en = (clk_cntp == (N – 1) / 2 | clk_cntp == N – 1); // clk_cntp为上升沿计数器
tff2_en = (clk_cntn == (N – 1) / 2 | clk_cntn == N – 1); // clk_cntn 为下降沿计数器
Step2:(div1、2为N个clk,计数到N-1清零)
always @ (posedge clk) if (Tff1_en) div1 <= ~div1;
always @ (negedge clk) if (Tff2_en) div2 <= ~div2;
Step3:div1与div2相或(初始态为0)、相与(初始态为1)
assign div_odd = (div1 | div2); / Div_odd = (div1 & div2);
推荐采用方法1,只需要一个上升沿计数器即可。
1.2 偶数分频器
N为偶数,如下操作:
Step1:计数值一半时,产生翻转标志
<