ET创芯网论坛(EETOP)

找回密码

  登录   注册  

搜帖子
汽车电子资料大全(下载奖励300信元)
楼主: Timme

[讨论] 自己写的DDR2控制器(含PHY)在FPGA上跑到1066了【27楼更新手动PR/时钟树介绍】

[复制链接]
发表于 2012-8-15 10:24:03 | 显示全部楼层
回复 20# Timme


    PHY也是自己写的吗???
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-8-15 11:09:19 | 显示全部楼层


   
回复  Timme


    PHY也是自己写的吗???
wangyingwei 发表于 2012-8-15 10:24



对,是搭的5级延时链,用set_net_delay约束每级延时200ps。板上证明这个PHY从400到1066都跑得很欢。
回复 支持 反对

使用道具 举报

发表于 2012-8-15 11:53:52 | 显示全部楼层
那PHY与DRAM间那些电气连接怎么处理的呢? 使用ALTERA的开发板吗?频率高了的话,PHY与DDR间的布线会对稳定性有较大影响
我记得IP中的PHY会在上电后根据频率发些读写校验操作,来自动调整读写的相位,好像是LEVEL操作吧?当时就没怎么看懂,问下LZ是怎么实现的?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-8-15 14:49:19 | 显示全部楼层


   
那PHY与DRAM间那些电气连接怎么处理的呢? 使用ALTERA的开发板吗?频率高了的话,PHY与DDR间的布线会对稳定 ...
wangyingwei 发表于 2012-8-15 11:53



PHY连在DQS上,DQS出去直接调用带OCT的差分I/O就可以了。板子是自己这边的人布的,遵循Microstrip阻抗匹配规范即可。

读写校验在上电完做,先往0地址写55AA作校验码,然后控制PHY作5级延时分别读5次,看读对了几次,选择读对那几次中间的延时固定住,然后开始响应正常的读写请求。
回复 支持 反对

使用道具 举报

发表于 2012-8-16 16:48:45 | 显示全部楼层
请问大神,如何手动布局、手动时钟树啊?我做了4年多了,一直不会啊。也找不到这方面的教程。请求大神指导!
回复 支持 反对

使用道具 举报

发表于 2012-8-16 20:16:20 | 显示全部楼层
quartus如何约束dff的位置啊,ise中很好约束
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-8-16 20:34:21 | 显示全部楼层
本帖最后由 Timme 于 2012-8-17 00:38 编辑




以Quartus为例(延时数据为Stratix III器件典型延时):

::手动布局::


   

        

                
  1. module top(input clk,din,output dout);

  2. reg din_ff,din_ff2;

  3. always@(posedge clk)
  4.    begin
  5.              din_ff  <= din;
  6.              din_ff2 <= din_ff;
  7.    end

  8. assign dout = din_ff2;

  9. 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出来的延时如下:


   

        

                

  1. CLKCTRL -> din_ff|clk  平均延时2ns(min 1.5ns,max 2.5ns)
  2. CLKCTRL -> din_ff2|clk 平均延时2ns(min 1.5ns,max 2.5ns)

  3.         

   

    复制代码

工具先修Hold Time,din_ff到din_ff2的最快路径为(我们假定Tco(min)+线延时(min)-Th =250ps):



   

        

                

  1. Data(early):CLKCTRL ----1.5ns----> din_ff|clk ----250ps----> din_ff2|d

  2.         

   

    复制代码
din_ff2的最慢时钟路径为:



   

        

                

  1. Clock(late):CLKCTRL ----2.5ns----> din_ff2|clk

  2.         

   

    复制代码

(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):



   

        

                

  1. Data(late): CLKCTRL ----2.5ns----> din_ff|clk ----350ps+950ps=1.3ns----> din_ff2|d

  2.         

   

    复制代码

din_ff2的最快时钟路径为:



   

        

                

  1. Clock(early): CLKCTRL ----1.5ns----> din_ff2|clk

  2.         

   

    复制代码


数据路径相对于时钟的延时为(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)对时序的冲击。我们对原代码作以下修改:


   

        

                
  1. module top(input clk,din,output dout);

  2. wire clk_buf/*synthesis keep*/;
  3. assign clk_buf = clk;
  4. reg din_ff,din_ff2;

  5. always@(posedge clk_buf)
  6.    begin
  7.              din_ff  <= din;
  8.              din_ff2 <= din_ff;
  9.    end

  10. assign dout = din_ff2;

  11. endmodule
            

   

    复制代码

通过Location规则把clk_buf节点放在与两个寄存器同一个LAB内,取得最大的共同时钟路径和最小的分离时钟路径。此时再计算一下Hold Time(假定clk_buf到寄存器时钟端的延时min=300ps,max=400ps):



   

        

                

  1. Data(early):clk_buf ----300ps----> din_ff|clk ----250ps----> din_ff2|d
  2. Clock(late):clk_buf ----400ps----> din_ff2|clk

  3.         

   

    复制代码

(300ps+250ps>400ps)可见Hold Time无违规,不需要插Buffer。此时计算Setup余量:



   

        

                

  1. Data(late):clk_buf ----400ps----> din_ff|clk ----350ps----> din_ff2|d
  2. Clock(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的数据延时。代码继续修改如下:


   

        

                
  1. module top(input clk,din,output dout);

  2. wire clk_buf/*synthesis keep*/;
  3. wire clk_buf2/*synthesis keep*/;
  4. assign clk_buf = clk;
  5. assign clk_buf2 = clk_buf;
  6. reg din_ff,din_ff2;

  7. always@(posedge clk_buf)
  8.    din_ff  <= din;

  9. always@(posedge clk_buf2)
  10.    din_ff2 <= din_ff;

  11. assign dout = din_ff2;

  12. endmodule
            

   

    复制代码


假定clk_buf到clk_buf2的延时为250ps~300ps(如需更大Skew,在SDC中用set_net_delay -min/max对clk_buf到clk_buf2的延时进行约束即可):



   

        

                


  1. Data(early):clk_buf ----300ps----> din_ff|clk ----250ps----> din_ff2|d
  2. Clock(late):clk_buf ----300ps----> clk_buf2 ----400ps----> din_ff2|clk
            

   

    复制代码



(300ps+250ps<300ps+400ps)可见Hold Time违规,工具需要插150ps(min)的Buffer。假设Buffer的延时为150ps~200ps,此时计算Setup余量:


   

        

                

  1. Data(late):clk_buf ----400ps----> din_ff|clk ----350ps+200ps----> din_ff2|d
  2. Clock(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电路,最高频率得以赶超片内硬核。
回复 支持 反对

使用道具 举报

发表于 2012-8-16 22:29:23 | 显示全部楼层
回复 27# Timme


    有一个问题,你的时钟clk和数据din在端口时满足建立和保持时间要求,然后数据到内部寄存器端口,时钟到达clk_buf,此时两者的相对相位关系应该发生了变化。不一定能满足时序要求。这个为何没有约束呢?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-8-16 22:31:54 | 显示全部楼层
本帖最后由 Timme 于 2012-8-16 22:35 编辑


   
回复  Timme


    有一个问题,你的时钟clk和数据din在端口时满足建立和保持时间要求,然后数据到内部 ...
kaiseradler 发表于 2012-8-16 22:29




第二句话我就说了忽略IO时序。。。OCV加上IO时序三天三夜讲不完了。。。

这些都是举片内电路为例,IO的可以同理类推,手段类似。。。
回复 支持 反对

使用道具 举报

发表于 2012-8-16 22:54:24 | 显示全部楼层
按照你的方法在quartus stratix III里面实验了一下。最小脉宽违规!不知道你怎么通过时序的,可以跑2.5GHz?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐上一条 /3 下一条

关闭

小黑屋|关于我们|联系我们|ET创芯网 ( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2019-11-16 07:39 , Processed in 0.083581 second(s), 8 queries , Gzip On, Redis On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表