如何手动布局、手动时钟树
来源:互联网 发布:中科大软件学院怎么样 编辑:程序博客网 时间:2024/05/20 00:35
</pre><p>以Quartus为例(延时数据为Stratix III器件典型延时)</p><p>手动布局:</p><p></p><pre name="code" class="cpp"><span style="font-family: Arial, Helvetica, sans-serif;">module top(input clk,din,output dout);</span>
reg din_ff,din_ff2;always@(posedge clk) begin din_ff <= din; din_ff2 <= din_ff; endassign dout = din_ff2;endmodule
忽略IO时序,怎样使这个电路跑到最快?在FPGA中线延时占主导,因此我们首先需要把din_ff和din_ff2两个寄存器邻近摆放。在Assignment Editor中,新增Location规则,目标选择din_ff或din_ff2,位置选择“LAB”,再选择你希望的LAB坐标(在此例中具体坐标在哪不重要)。将这两个寄存器摆到同一个LAB内,就实现了数据路径上的最优化。 这就是所谓的“手动布局”。
一个寄存器的Tsu/Th大概是50ps,Tco大概85ps,同一个LAB的互联延时大概200ps,忽略Minimum Pulse Width约束,是否意味着这个电路的最小周期是335ps即能跑3GHz呢?注意,此时数据路径上已经没有瓶颈了。
****************........我是分割线.......*****************
::基于OCV的fmax计算::
查看Timequest报告,你会发现报出的fmax远小于期望的3GHz,为什么呢?
在Quartus自动PR时,时钟通常会被拉到全局缓冲CLKCTRL(这有时是不可避免的,如PLL输出),再拉到每个DFF。虽然全局时钟到每个DFF的平均Skew较小,但绝对延时是比较大的(ns级)。而Timequest的分析是基于OCV的(简单来说,就是所有延时都有min和max),延时的绝对值越大,min和max的差值也越大。比如,假定CLKCTRL出来的延时如下:
CLKCTRL -> din_ff|clk 平均延时2ns(min 1.5ns,max 2.5ns)CLKCTRL -> din_ff2|clk 平均延时2ns(min 1.5ns,max 2.5ns)工具先修Hold Time,din_ff到din_ff2的最快路径为(我们假定Tco(min)+线延时(min)-Th =250ps):
Data(early):CLKCTRL ----1.5ns----> din_ff|clk ----250ps----> din_ff2|ddin_ff2的最慢时钟路径为:
Clock(late):CLKCTRL ----2.5ns----> din_ff2|clk(1.5ns+250ps<2.5ns)此时工具发现需要在din_ff后面插750ps(min)的Buffer才能使Hold Time无违规(FPGA中不插Delay Cell,一般是绕线)。插完Buffer后,我们来看看此时能达到的最小周期(计算Setup Time):
din_ff到din_ff2的最慢路径为(我们假定Tco(max)+线延时 (max)+Tsu = 350ps,插的Buffer(max)=950ps):
Data(late): CLKCTRL ----2.5ns----> din_ff|clk ----350ps+950ps=1.3ns----> din_ff2|ddin_ff2的最快时钟路径为:
Clock(early): CLKCTRL ----1.5ns----> din_ff2|clk数据路径相对于时钟的延时为(2.5ns+1.3ns-1.5ns=2.3ns),所以最小时钟周期2.3ns,对应fmax为435MHz,与一开始预测的3GHz差别巨大。
细心的朋友会发现,这个最小周期值非常接近于CLKCTRL延时(max-min)的两倍。
****************........我是分割线.......*****************
::手动时钟树 -- 创建共同时钟路径::
OCV的计算引擎会对共同时钟路径不计算min/max,因为物理上同一段路径的延时是固定的,这个在Quartus中称为CCPP,在Cadence中称为CPPR,在Synopsys中称为CRPR。。。
既然CLKCTRL延时巨大,那我们可以在CLKCTRL到两个寄存器这段路径上创建共同时钟路径,减小CLKCTRL延时(max-min)对时序的冲击。我们对原代码作以下修改:
module top(input clk,din,output dout);wire clk_buf/*synthesis keep*/;assign clk_buf = clk;reg din_ff,din_ff2;always@(posedge clk_buf) begin din_ff <= din; din_ff2 <= din_ff; endassign dout = din_ff2;endmodule通过Location规则把clk_buf节点放在与两个寄存器同一个LAB内,取得最大的共同时钟路径和最小的分离时钟路径。此时再计算一下Hold Time(假定clk_buf到寄存器时钟端的延时min=300ps,max=400ps):
Data(early):clk_buf ----300ps----> din_ff|clk ----250ps----> din_ff2|dClock(late):clk_buf ----400ps----> din_ff2|clk(300ps+250ps>400ps)可见Hold Time无违规,不需要插Buffer。此时计算Setup余量:
Data(late):clk_buf ----400ps----> din_ff|clk ----350ps----> din_ff2|dClock(early):clk_buf ----300ps----> din_ff2|clk数据路径相对延时为(400ps+350ps-300ps=450ps),如不考虑Minimum Pulse Width约束,则最小周期450ps,fmax为2.2GHz。这就是手动时钟树 -- 创建共同时钟路径的威力。
****************........我是分割线.......*****************
::手动时钟树 -- 手动Skew调整::
Quartus的Fitter中有很多优化Clock Skew的选项,其实选了根本没有任何效果。。。Quartus自动PR对时钟的优化就是这么弱。
我们还能进一步对时序进行优化,那就是Clock Skew手工调整,平衡(Tco+线延时+Tsu/-Th)那段250ps~350ps的数据延时。代码继续修改如下:
module top(input clk,din,output dout);wire clk_buf/*synthesis keep*/;wire clk_buf2/*synthesis keep*/;assign clk_buf = clk;assign clk_buf2 = clk_buf;reg din_ff,din_ff2;always@(posedge clk_buf) din_ff <= din;always@(posedge clk_buf2) din_ff2 <= din_ff;assign dout = din_ff2;endmodule假定clk_buf到clk_buf2的延时为250ps~300ps(如需更大Skew,在SDC中用set_net_delay -min/max对clk_buf到clk_buf2的延时进行约束即可):
Data(early):clk_buf ----300ps----> din_ff|clk ----250ps----> din_ff2|dClock(late):clk_buf ----300ps----> clk_buf2 ----400ps----> din_ff2|clk(300ps+250ps<300ps+400ps)可见Hold Time违规,工具需要插150ps(min)的Buffer。假设Buffer的延时为150ps~200ps,此时计算Setup余量
Data(late):clk_buf ----400ps----> din_ff|clk ----350ps+200ps----> din_ff2|dClock(early):clk_buf ----250ps----> clk_buf2 ----300ps----> din_ff2|clk(400ps+350ps+200ps-250ps-300ps=400ps), 如不考虑Minimum Pulse Width约束, 则最小周期缩短到400ps,fmax可达2.5GHz。
这就是手动时钟树 -- 手动Skew调整,这个手段在优化对外控制器模块时非常有用,用于平衡内部时钟输出到Pad的巨大延时。
****************........我是分割线.......*****************
在顶楼的DDR2-1066控制器实现过程中,大量应用了“手动布局、手动时钟树 -- 创建共同时钟路径、手动时钟树 -- 手动Skew调整”三项PR技术,使得用内部ALUT搭的控制器/PHY电路,最高频率得以赶超片内硬核。
altera亚太支持中心应用工程师宋健(Jean Song)的email
JSONG@altera.com
0 0
- 如何手动布局、手动时钟树
- STM32F4手动调整时钟
- Android手动添加布局
- Qt之手动布局
- 自动布局与手动布局
- 活动——如何手动创建活动,布局,注册,并运行
- 如何控制手动inline
- 如何手动整理注册表
- 如何手动注册mscomm
- 如何手动升级ownCloud
- 如何手动解析CrashLog
- 如何手动解析CrashLog
- 如何手动解析CrashLog
- 如何手动解析CrashLog
- 如何手动更新Joomla!
- 如何手动添加gitignore
- 如何手动安装MySql
- 如何手动输入EOF
- C# 事件和Unity3D
- vb(不是vb.net)字符串多行书写
- 主题:QUI框架V3.3版本正式发布!
- 如何在Android应用中加入广告
- HDU - 1686 Oulipo (KMP)
- 如何手动布局、手动时钟树
- 何时会发生db file sequential read等待事件
- Servlet生命周期与工作原理
- 5种服务器网络编程模型讲解
- 中断、DMA、通道
- js获取最近几天
- 在Unity3D的网络游戏中实现资源动态加载
- 网络原理以及对VM中VMnet0,VMnet1,VMnet8的理解
- spring事务 整理