50%占空比任意分频器verilog实现方法与其SGDC约束

概述:

        我们都知道,时钟和复位在IC设计中是非常重要的。有时候需要对时钟进行一些逻辑变化后再作时钟使用(注意时钟最好不要作为除时钟之外的任何信号使用),这些逻辑有的可以做低功耗,有的可以做DFT中的OCC。像是拔牙操作一类的分频我们今天不讨论。今天讨论的任意分频器在许多的数字IC设计与FPGA面试笔试题中都有考察,所以在实(tou)现(xue)了以后做本次学习记录,供大家参考。

1. 先入为主

        我们来宏观的看本次分频器的内容,会比较容易理解。关键功能点的电路如图1所示:

图一
图1

         电路图结合波形(时序)图来看,我们以三分频为例,如图2

图2

         可以看到:

                    clk=1 select max_clk(D1)     

                    clk=0 select min_clk(D0)

        光一个奇数分频可能不够,我们再来一个偶数分频——二分频,如图3 

图3

        mux出来的信号clk_out是一个三分频时钟。那么,这个minimize(min_clk) 和 maxmize(max_clk) 又是怎么确定的呢?任意分频是怎么实现的呢?我们继续往下看。

2. minimize & maxmize

        首先来谈下相对比较难的,奇分频。把上面图2的时序图拿来看 

图2

         从图中可以发现min/max clk有两点不一样:

                1. 占空比 

                2. 变化的时钟沿

        来看它们的区别:

        三分频的  高电平持续时间:低电平持续时间  分为2:1和1:2。可以看到max_clk 的占空比为2:1而min_clk的占空比是1:2。max/min clk只需要控制它们岔开半个周期(因为奇数分频会在源时钟的上升沿和下降沿交替变化)即可。

        奇分频看完,偶分频就简单了,以二分频为例,高电平持续时间:低电平持续时间 只能是1:1。此时max/min clk 除了相位不同外,其他都相同,如图3。

图3

         总结一下,任意分频时要区分奇分频和偶分频。

                输入一个数N为奇数时,要控制max_clk 高低电平占空比为

                        (N+1)/2 : (N-1)/2

                        如7分频,要控制高低电平占空比为4:3。min_clk则相反。

                输入一个数N为偶数时,要控制max_clk与min_clk 的高低电平占空比同时为 N/2 : N/2。

                        如8分频,要控制高低电平占空比为4:4

        我们现在知道min_clk和max_clk是要控制成什么样子才能做分频了。但是如何控制呢?我们来看下面。

3. 控制min_clk与max_clk

         控制min_clk与max_clk是通过计数器来控制的。而min与max需要在奇数偶数上做区分。这个感觉自己讲的不是很明白,直接上代码。(话说代码段没有verilog是什么鬼)

module fre
(
    input [5:0] N, //分频系数
    input clk,
    input rst_n,
    output clk_out
);

reg min_clk;
reg max_clk;
reg min_clk_pre; // min_clk前一拍,为什么有它波形中可以得到解释
reg [5:0]num; // 分频系数寄存
reg [5:0]cnt; // 计数器
reg latch_en; // 1分频时用ckgen直接通clk

// CLOCK GETING CELL
always@(*)
    if(~clk)
        latch_en = (N == 1);

// 存N进num
always@(posedge clk or negedge rst_n) begin
    if(!rst_n)
        num <= 6'd0;
    else
        num <= N;
end

// cnt计数
always@(posedge clk or negedge rst_n) begin
    if(!rst_n)
        cnt <= 6'd0;
    else if(cnt == num -1'b1)
        cnt <= 6'd0;
    else if(N == 1)
        cnt <= 6'd0;
    else
        cnt <= cnt + 1'b1;
end

wire [5:0]min,max; // min_clk 和 max_clk 的变化由这两个数控制

assign min = (num >> 1) - 1'b1; // n/2-1
assign max = min[4:0] + num[0]; // n/2-1 + (num == 奇数? 1'b1 : 1'b0)

//min_clk_pre logic
always@(negedge clk or negedge rst_n) begin
    if(!rst_n)
        min_clk_pre <= 1'd0;
    else
        min_clk_pre <= (cnt <= min);
end

//min_clk logic
always@(negedge clk or negedge rst_n) begin
    if(!rst_n)
        min_clk <= 1'b0;
    else
        min_clk <= min_clk_pre;
end     

//max_clk logic
always@(posedge clk or negedge rst_n) begin
    if(!rst_n)
        max_clk <= 1'b0;
    else
        max_clk <= (cnt <= max);
end

assign clk_out = (N != 1) ? (clk ? max_clk : min_clk) : clk;  // clk_out mux

endmodule

         我们和仿真的波形一起来看,以三分频为例,如图4:

图4

         当看完代码(注释)和波形图之后,你应该理解了怎么控制min_clk 和 max_clk了。此时功能是实现了,但是时序呢?我们做的这个东西是要做为时钟使用的,所以我们一定要严谨严谨再严谨。我们来看时序。(只为笔试撕代码的小伙伴可以到此结束)

4. 时序问题

        可能你并不知道时序有什么问题,或者说时序是什么。首先你需要明白setup time 和 hold time的概念。这是很基础的概念,所以如果你不明白,快去看看其他大佬的文章。然后我们来看这个分频器的时序问题,如图5

图5

         可以看到,如此紧凑的变化频繁的组合逻辑,是很容易产生毛刺的(图中红条部分),时钟一旦有了毛刺,那么这个电路的后果将不可想象。所以我们在做时序分析时,我们的工具也给了我们解决办法:

                       set_clock_gating_check

        这是一种对时钟做逻辑时都可以用到的约束,它的option有以下两组:   

                -low -high

                -setup -hold

        -setup -hold 好理解,-low -high是它的两种情况。我们来介绍它的两种情况:

4.1 与情况(-high)

        

         可以看到。当EN = 1时,CLK才可以通过与门,但是为了完整的把CLK的高电平时间全部通过(而不是只通过其中一部分)我们需要EN信号在CLK上升沿到来之前一段时间内(setup time)就做好准备,同样的,EN信号为了使CLK高电平完整的通过,需要在CLK拉低时,再保持一段时间即hold time。

4.2 或情况(-low)

        或情况同理,不做赘述,图供大家理解。 

4.3 回到分频器

        我们了解了set_clock_gating_check以及它的option后。我们来看怎么做,能让我们分频出来的时钟安安稳稳,没有毛刺。以二分频为例,如图6

图6

         可以看到,我们小小的分频器两种情况都有,在图中已经标出。大家对号入座是可以看到上述两种情况在我们的分频器中的位置的。

        所以,答案也就有了,我们要在约束中加入:

set_clock_gating_check -setup 0.05 -hold 0.05 -high [get_pins max_clk]         set_clock_gating_check -setup 0.05 -hold 0.05 -low [get_pins min_clk]

        至此,我们的分频器出来的信号就是一个稳定的时钟了。

5. 总结

        实现功能固然重要,但是如果只沉浸在实现功能的乐趣中而不去管它的时序,那么对于一个芯片,一个公司来说,那将会是非常危险的事情。FPGA相对来说成本较低,但是如果是ASIC 乃至SOC的话,流片一次的成本是非常高的,所以做IC最重要的应该是慎重和严谨。稍有不慎,公司的资金和长时间的努力将付之一炬。第一次写博客,不足之处也希望大家指出,我也在走往严谨的路上!

(需要testbench请私信)

  • 6
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值