声明:本博客并非严格的、完整的技术型文章,只是将本人所接触到的内容作学习记录,如有错误欢迎大家在评论区指正。如果这篇博客对你有帮助的话,请给我点一个免费的赞或关注,谢谢。本篇博客内容参考xilinx官方文档与知乎Lingo大神。
如果是第一次学习IDELAYE2原语,强烈建议仔细读一下该原语的四种工作模式,不要直接看通用的使用方法。
引言
如下图所示,信号从PAD管脚通过IOB模块后,可以进入IDELAY2模块,该模块主要就是对输入信号进行延迟,常用在源同步输入的时序对齐过程中,以延迟最长的信号为基准,将其余信号进行延迟对齐。而IDELAY2原语必须和IDELAYCTL一起使用,后面对这两个原语的参数和端口信号进行讲解。
这里补充说明一下上面一段话提到的源同步输入概念,下图所示就是典型的源同步接口,即FPGA输入或输出数据信号时有相应的随路时钟。
IDELAYE
IDELAYE2是一款具有校准抽头分辨率的31抽头、环绕式延迟原语。FPGA的每个引脚都有一个IDELAYE2进行对应,可以对外部输入管脚的信号或者FPGA内部逻辑生成的信号进行延迟。
下图是IDELAYE2的原语框图,输入信号较多,输出信号就两个,一个是延迟后的信号,另一个是现在输出信号相对于输入信号的延迟系数是多少(即多少个tap)。
IDELAYE2原语的端口信号如下表所示。
IDELAYE2原语的所有控制输入(REGRST、LD、CE 和 INC)均与时钟输入C同步。C可以局部反转,并且必须由全局或区域时钟缓冲器提供。如果ODELAYE2原语与IDELAYE2原语在同一I/O Bank中使用,则C必须为两者使用相同的时钟网络。(这里有一些内容涉及到FPGA底层结构中的时钟,会在本人博客中更新)。
IDELAYE2原语的参数如下表所示,对应参数的可用取值如下表,含义在后文表后进行解释。
IDELAY_TYPE是IDELAYE2的四种工作模式,其中FIXED模式下延时为IDELAY_VALUE的固定数值,不能修改。
VARIABLE模式下延时初始值为IDELAY_VALUE,在时钟C上升沿可以通过CE和INC信号,使延时递增或递减,调整方式如下表所示,实现动态调整,被称为可变抽头模式。时钟为低电平时,对应值不变,时钟上升沿时,如果LD为高电平,则将延时变为IDELAY_VALUE。如果使能信号CE有效,则根据INC的状态进行递增或递减。
VARIABLE模式对应时序图如上图所示,当LD为高电平时,将IDELAY_VALUE数值加载到内部,输出信号延时变为IDELAY_VALUE,当CE和INC同时拉高时,输出信号的延时加1,变为tap1。
VAR_LOAD模式与VARIABLE模式相似,区别在于VARIABLE模式为高电平时,是加载IDELAY_VALUE的值到内部作为延时数据,而VAR_LOAD模式在LD为高电平时,加载输入信号CNTVALUEIN的值作为内部新的延时数据,其余均一致,下表为VAR_LOAD模式的控制信号真值表。
上述四个模式的延时参数取值范围0~31,总共32个延时级别(tap),每个等级延时具体是多少,与REFCLK_FREQUENCY的时钟频率有关。(这里的具体延时可以查看xilinx的手册,在官网可以找到)。
这里介绍一下1个tap对应的延时计算方法:(10^6)/(32×2×F_ref),计算结果的单位是ps,F_ref是参考时钟,单位是MHz。注意参考时钟通常用200MHz,需要接到IDELAYCTRL中后面会提到。
例子:如果参考时钟为200MHz,则1个tap对应的延迟为78ps。但是要注意取值为0时,输出相对延迟600ps。因此总延迟 = 600 + n * 78,单位为ps。这个可以通过实际行为级的仿真波形查看,建议第一次使用该原语的读者亲自仿真体会一下。
IDELAYCTRL
如果使用IDELAYE2或ODELAYE2原语,就必须使用IDELAYCTRL模块。 IDELAYCTRL模块连续校准其区域内的各个IDELAY/ODELAY,以减少工艺、电压和温度变化的影响。IDELAYCTRL模块使用用户提供的REFCLK校准IDELAY和ODELAY,(相当于让在200MHz参考时钟下每个tap的延迟为更精准的78ps,而不要因为其他原因产生偏差),下面是其框图。
采用异步高电平进行复位,必须在配置后且时钟REFCLK稳定后进行复位,复位时间必须大于上上一个图片中的TIDELAYCTRL_RPW=59.28ns。
参考时钟 (REFCLK)必须由全局或水平时钟缓冲器(BUFG或BUFH)驱动。 REFCLK必须FIDELAYCTRL_REF ± 10,以保证指定的IDELAY和ODELAY分辨率(TIDELAYRESOLUTION)。
RDY信号为高电平时,IDELAY和ODELAY延时才有效(因此RDY信号取反后常用来做后续ISERDES2的复位信号)。如果REFCLK保持高电平或低电平超过一个时钟周期,则RDY信号置为低电平无效。如果RDY无效,则必须重置IDELAYCTRL模块。RDY和RST的时序关系如下图所示。
在复位信号RST有效过程中,RDY输出低电平,复位信号RST拉低经过TIDELAYCTRL_RDY后,RDY拉高,表示IDELAY延时有效,当检查到参考时钟信号REFCLK高电平持续时间过长时,RDY拉低,表示IDELAY延时无效。
IDELAYCTRL模块存在于每个时钟区域的每个I/O列中,如下图所示(这里可以结合后文的走线布局图理解),IDELAYCTRL模块校准其时钟区域内的所有IDELAYE2和ODELAYE2模块。
综合布线后的走线布局图
对于本小节中和上文内容中有关FPGA底层结构的内容,本人的博客后续会更新一些相关的内容方便大家结合着一起理解,下面开始介绍本小节的内容。
将工程综合、分配引脚、实现后,打开Default Layout视图,找到din信号的输入管脚,其旁边就是IOB模块左边或右边就是其对应的IDELAYE2模块,如下图所示。外部信号进入FPGA管脚后,只有经过ilogic(包括绕过)才能被FPGA内部逻辑所使用(这句话如果不理解的话,也要有个印象),也就是说IOB输出的信号经过IDATAIN端口输入IDELAYE2,IDELAYE2输出的信号DATAOUT通过ILOGICE上半部分的组合逻辑路径进入FPGA内部。
下面图显示了FPGA底层中的IDELAYCTRL的位置。
一种通用的IDELAY的使用方法
我们对IDELAYE2中LD=1,其余为0,即在外部使用CNTVALUEIN输入来控制延时。即下面的代码块中只需要改变delay_in的值即可改变到想用的延时tap,这样就减少了对CE、INC、LD的控制逻辑。
IDELAYCTRL u1_IDELAYCTRL (
.RDY (rdy ),// 1-bit output: Ready output
.REFCLK (ref_clk ),// 1-bit input: Reference clock input
.RST (~rst_n ) // 1-bit input: Active high reset input
);
IDELAYE2 #(
.DELAY_SRC ("IDATAIN" ),// Delay input (IDATAIN, DATAIN)
.HIGH_PERFORMANCE_MODE ("TRUE" ),// Reduced jitter ("TRUE"), Reduced power ("FALSE")
.IDELAY_TYPE ("VAR_LOAD" ),// FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
.IDELAY_VALUE (0 ),// Input delay tap setting (0-31)
.REFCLK_FREQUENCY (200.0 ) // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0).
)
u1_IDELAYE2
(
.CNTVALUEOUT (delay_out ),// 5-bit output: Counter value output
.DATAOUT (tx_data_b_d ),// 1-bit output: Delayed data output
.C (rx_clk_div ),// 1-bit input: Clock input
.CE (1'b0 ),// 1-bit input: Active high enable increment/decrement input
.CINVCTRL (1'b0 ),// 1-bit input: Dynamic clock inversion input
.CNTVALUEIN (delay_in ),// 5-bit input: Counter value input
.DATAIN (1'b0 ),// 1-bit input: Internal delay data input
.IDATAIN (tx_data_b ),// 1-bit input: Data input from the I/O
.INC (1'b0 ),// 1-bit input: Increment / Decrement tap delay input
.LD (1'b1 ),// 1-bit input: Load IDELAY_VALUE input
.LDPIPEEN (1'b0 ),// 1-bit input: Enable PIPELINE register to load data input
.REGRST (1'b0 ) // 1-bit input: Active-high reset tap-delay input
);
注意:在vivado对应原语中 (* IODELAY_GROUP = <iodelay_group_ name> *) 的分组名要与IDELAYCTL的分组名保持一致,绑定两个模块。这个属性的作用是确保在同一个 IODELAY_GROUP 中的 IDELAYE2 和 IDELAYCTRL 原语共享相同的参考时钟和复位信号。在进行布局布线时,Vivado 会根据 IODELAY_GROUP 属性自动将相关的原语放置在物理上相邻的位置,以确保信号完整性。在同一个设计中,每个 IODELAY_GROUP 名称必须是唯一的。(如果不需要的话可以不使用这个综合属性,一般情况下vivado综合实现都不会出错)。