tag 标签: 时序收敛

相关博文
  • 热度 22
    2015-4-29 17:41
    3200 次阅读|
    1 个评论
    TimeQuest Timing Analyzer 工具使用一例 作者: RyudoYang   工具版本: Quartus II 13.1+ TimeQuest Timing Analyzer 同事在进行 SDR SDRAM 时序约束时遇到工具使用和概念上的诸多问题,有些问题具有代表性,这里一并总结。 (1)     问题抽象 图 1 SDR SDRAM 约束问题抽象 图 1 是 SDR SDRAM 接口电路的抽象(以输入数据为例进行分析)。 由 PLL 产生 2 个 133MHz 的时钟,其中 C0 输出作为 SDR SDRAM 的芯片时钟使用,另一个时钟经过 270 °的移相,作为 SDR SDRAM 输入数据的锁存时钟使用。注意,这里时钟的用法也是解决很多时序问题的技巧之一。 以上是该问题的抽象,不需要过多解释。   (2)     TimeQuest Timing Analyzer 使用与分析过程 对图 1 所示的小工程进行全编译之后,打开 TimeQuest Timing Analyzer (以下简称为 TQ )进行分析。 首先进行时钟设置。 图 2 时钟约束 第 2 步,对 SDR SDRAM 用到的时钟进行约束,该时钟是通过 PLL 的 C0 输出得到的。采用的约束是: create_generated_clock -name clkout -source }] ,然后更新网表,检查约束是否生效。 图 2 新的时钟约束已经生效 第 3 步,对外部输入延时进行设置,为了简化,采用的约束是: set_input_delay -clock { clkout } 5 ,生效后检查建立时间,发现违规。   图 3 建立时间违规 通过分析得出,违规路径有三个参数延时很大,分别是时钟延时,外部固有延时,数据输入延时。在一般情况中,外部固有延时是固定的,可更改的余地有限,主要是通过减小另外两个延时来达到时序收敛。这里假设另外两个延时也不可以更改,那么如何达到时序收敛呢?通过观察违规波形,发现如果使用 锁存时钟的第 3 个时钟沿 来锁存数据是可以满足时序收敛的,带来的影响就是必须对设计进行调整,使用锁存时钟的第 3 个时钟沿锁存的数据来进行后续处理,简单来说就是增加了有效数据的潜伏期。 第 4 步,更改设计之后重新进行时序分析,这里必须使用多周期约束把设计意图告知 TQ ,使其能够进行正确的时序分析。采用的约束是: set_multicycle_path -from -to -setup -end 3 。生效后重新检查结果,发现已经符合预期。 图 4 时序已经收敛   (3)     问题总结 通过以上例子,总结一下使用 TQ 时应该注意的问题: 第一,使用 TQ 之前必须弄清楚相关概念的含义与他们之间的关系,比如 Setup Time 、 Hold Time 、 Data Arrival Time 、 Data Required Time 等概念,这样才能看懂 TQ 生成的波形图; 第二,先抽象出电路,再开始约束。约束对象往往比较复杂纷繁,先把其实际表达的电路,尤其是电路路径抽象出来,可以很好的辅助分析; 第三,开始约束之后,首先约束的内容必须是时钟,这些时钟包含由 PLL 直接产生的时钟以及各类派生时钟和虚拟时钟,只有时钟建立正确,后面的结果才有分析的价值与意义; 第四,约束必须符合设计意图,违背设计意图的约束即使达到了时序收敛,也毫无意义。这里以上面的多周期约束为例,通过分析违规时序可知必须更改设计,完成修改之后,必须把这一设计意图通过多周期约束告知 TQ ,使其按设计意图进行约束,否则 TQ 还会按默认的“单周期”进行约束,结果就是无论如何都不能达到时序收敛。
  • 热度 16
    2014-1-12 09:57
    1361 次阅读|
    0 个评论
    在上一个部分中,说明了几种自己总结的利于设计出高速电路的代码风格。这里其实暗含着下面这样的场景:电路已经设计好了,而且已经很棒,只是需要用风格良好的 HDL 代码进行输入,以保证综合出的电路和设计的一样好。   而在这一部分中,想讨论一下怎样设计高速电路。可以说,是进行 HDL 输入前的工作。   最初的时候,是没有这个部分的。原因是这部分并非是自己总结的内容,更多还是从前辈们那儿吸取的经验。不过,少了这个部分,感觉有点缺乏完整性。毕竟 PART3 和 PART4 的内容,只是一些小技巧。而且我想了一下,将获取的知识再整理整理,也没有什么不好的。   因此,这部分内容是我对 Steve Kilts 的《高级 FPGA 设计:结构、实现和优化》第 1 章 1.3 节(4 至 13 页)的总结。读过这本书的朋友可以跳过这个部分了。 其中的例子大都是我自己归纳后想出的简单例子,可能还有些不妥之处,还请各位朋友指出。   这里强烈推荐这本书。一般的 FPGA 书中,讲流程、接口的多,讲电路结构的感觉比较少,而这本书涉及的还挺多的;而比起 Parhi 的《VLSI 数字信号处理系统:设计与实现》这种比较纯粹的 IC 设计的专著(当然这本也很好),这本书又和 FPGA 有着非常紧密的联系。   1 增加寄存器层次   通过在组合逻辑中插入一级寄存器来优化关键路径。   考虑下图所示的三输入加法器。此时电路的关键路径为两个加法器的门延时。       以下是代码片段: always @ (posedge clk) begin      // 第一层      a_d = a;      b_d = b;      c_d = c;      // 第二层      s = m+c_d; end assign m = a_d+b_d; 通过在两个加法器之间引入一级寄存器,能够将关键路径缩短为一个加法器的门延时。 当然,这会带来一个周期的时延,同时也引入了多余的寄存器,增加了电路面积。       以下是代码片段: always @ (posedge clk) begin           // 第一层      a_d = a;      b_d = b;      c_d = c;      // 第二层      c_2d = c_d;      m = a_d+c_d;      // 第三层      s = m+c_2d; end 2 并行结构   与通常所说的通过增加并行路数从而提高吞吐量的并行架构不同,这里指的是通过重新组织组合逻辑的结构,来优化关键路径。   考虑一个链状的四输入加法器电路。其关键路径为三个加法器的门延时。       以下是代码片段: assign m1 = a+b; assign m2 = c+m1; assign s  = d+m2; 如果采用树状结构,则关键路径仅为两个加法器的门延时。       以下是代码片段: assign m1 = a+b; assign m2 = c+d; assign s  = m1+m2; 3 去除电路中的优先级编码   这点就是 PART3 中所说的“尽量不要使用多层嵌套的条件判断语句”。   考虑一个四状态的独热码状态机,采用优先级编码的电路有四层组合逻辑。     以下是代码片段:      reg sta;      always@(posedge clk)      if (sta ) ...;      end else if (sta ) ...;      end else if (sta ) ...;      end else if (sta ) ...; 而如果使用 case 语句,并在【综合选项】中设置好对应的项目(见 PART2),得到的非优先级编码电路则是并行结构,速度更快。     以下是代码片段:      reg sta;      always@(posedge clk)      case(1'b1)      sta : ...;      sta : ...;      sta : ...;      sta : ...;      endcase 这里需要强调的是,如果电路的逻辑确实需要优先级,还应该使用嵌套的条件判断语句,而不该盲目采用无优先级的电路。 4 寄存器平衡(重定时)   电路的速度,是由关键路径决定的。 因此在设计电路时,如果有一条路径的门延时特别长,其它路径的门延时再短,该电路的速度也仍然很慢。因此,设计电路时,可以通过改变寄存器的位置,使得各路径的门延时变得平均,以达到提高电路速度的目的。   考虑下面的五输入加法器。可以看到,第一级寄存器和第二级寄存器之间的路径长度是一个加法器的门延时,而第二级寄存器和第三级寄存器之间的关键路径长度是三个加法器的门延时。因此,整个电路的关键路径长度是三个加法器的门延时。     以下是代码片段: always @ (posedge clk) begin      // 第一层      a_d = a;      b_d = b;      c_d = c;      d_d = d;      e_d = e;      // 第二层      m1 = a_d+b_d;      c_2d = c_d;      d_2d = d_d;      e_2d = e_d;      // 第三层      s = m4; end assign m2 = m1+c_2d; assign m3 = m2+d_2d; assign m4 = m3+e_2d; 经过寄存器平衡后,输入输出之间的逻辑关系没有改变,但两条路径的长度都变为两个加法器的时延,整个电路的关键路径长度缩短为两个加法器的时延。     以下是代码片段: always @ (posedge clk) begin      // 第一层      a_d = a;      b_d = b;      c_d = c;      d_d = d;      e_d = e;      // 第二层      m2 = m1+c_d;      d_2d = d_d;      e_2d = e_d;      // 第三层      s = m4; end assign m1 = a_d+b_d; assign m3 = m2+d_2d; assign m4 = m3+e_2d; 在《高级 FPGA 设计:结构、实现和优化》中,还有一种“重新安排路径”的策略。对于这点,可能我的理解还不够深,感觉这一策略和上面第二种策略类似:都是通过重新组织组合逻辑的结构,以提升电路速度。此处就不对这种策略进行详细的说明了。   总结   最基本的策略:在组合逻辑中插入寄存器,通过引入时延与增大电路面积来提升电路速度。 组合电路设计策略:提升组合逻辑的并行度,缩短门延时。 条件判断电路设计策略:不需要优先级编码的话,采用无优先级的电路。 整体设计策略:移动寄存器位置,平衡各组合逻辑路径的门延时。
  • 热度 18
    2014-1-1 12:50
    1539 次阅读|
    4 个评论
    原来的引子不知道为什么不见了,补上。     第一次做比较大型的设计,结果真的很悲剧。   布局布线以后,静态时序分析的结果和自己的预期相差很远,和综合后XST的估值也相差很远。时延里面,route时延占了绝大部分(logic占20%,route占80%)。   恶补了一些资料,给自己的设计总结了三个可能的问题:有些控制信号的扇出太大,没有做位置约束,不好的代码风格。   决定在这里记录自己通向时序收敛的过程。这不是一条平坦的路吧。  
相关资源