文章来源:数字站
如图1所示,信号从PAD管脚通过IOB模块后,可以进入IDELAY2模块,该模块主要就是对输入信号进行延迟,常用在源同步输入的时序对齐过程中,以延迟最长的信号为基准,将其余信号进行延迟对齐。
而IDELAY2原语必须和IDELAYCTL一起使用,后面对这两个原语的参数和端口信号进行讲解,并对该原语进行仿真。
图1 7系列IO模块(左侧HP bank,右侧HR bank)
IDELAYE信号及参数
IDELAYE2是一款具有校准抽头分辨率的31抽头、环绕式延迟原语。FPGA的每个引脚都有一个IDELAYE2进行对应,可以对外部输入管脚的信号或者FPGA内部逻辑生成的信号进行延迟。
IDELAYE2在FPGA中的分布如下,左侧是FPGA的IOB模块,FPGA的管脚PAD在IOB模块内,这个IOB在左侧会有对应的ILOGIC(内部包含IDDR、触发器)、IDELAY2、OLOGIC2。
图2 IDELAYE2在FPGA中的位置
图3是IDELAYE2的原语框图,输入信号较多,输出信号就两个,一个是延迟后的信号,另一个是现在输出信号相对于输入信号的延迟系数是多少。
图3 IDELAYE2原语框图
IDELAYE2原语信号端口
IDELAYE2原语的端口信号如下表1所示。
IDELAYE2原语的所有控制输入(REGRST、LD、CE 和 INC)均与时钟输入(C)同步。C可以局部反转,并且必须由全局或区域时钟缓冲器提供。如果ODELAYE2原语与IDELAYE2原语在同一I/O Bank中使用,则C必须为两者使用相同的时钟网络。
IDELAYE原语参数
IDELAYE2原语的参数如下表2所示,对应参数的可用取值如下表,含义在后文表后进行解释。
IDELAY_TYPE是IDELAYE2的四种工作模式,其中FIXED模式下延时为IDELAY_VALUE的固定数值,不能修改。下图4是其时序图,输出信号延时就是IDELAY_VALUE对应的延时值。
图4 FIXED模式时序图
VARIABLE模式下延时初始值为IDELAY_VALUE,在时钟C上升沿可以通过CE和INC信号,使延时递增或递减,调整方式如表3所示,实现动态调整,被称为可变抽头模式。
时钟为低电平时,对应值不变,时钟上升沿时,如果LD为高电平,则将延时变为IDELAY_V ALUE。如果使能信号CE有效,则根据INC的状态进行递增或递减。
VARIABLE模式对应时序图如图5所示,当LD为高电平时,将IDELAY_VALUE数值加载到内部,输出信号延时变为IDELAY_VALUE,当CE和INC同时拉高时,输出信号的延时加1,变为tap1。
图5 VARIABLE模式时序图
VAR_LOAD模式与VARIABLE模式相似,区别在于VARIABLE模式为高电平时,是加载IDELAY_VALUE的值到内部作为延时数据,而VAR_LOAD模式在LD为高电平时,加载输入信号CNTVALUEIN的值作为内部新的延时数据,其余均一致,下表4为VAR_LOAD模式的控制信号真值表。
VAR_LOAD模式对应的时序图如图6所示,在时钟上升沿时,LD为高电平时,IDELAY加载CNTVALEIN的值5‘b00010作为输出信号的延时数据,当CE和INC同时拉高时,输出信号的延时加1,变为5’b00011。
图6 VAR_LOAD模式时序图
VAR_LOAD模式和VAR_LOAD_PIPE模式类似, 只是VAR_LOAD_PIPE模式内部多了一个寄存器,会将CNTVALEIN的值先存入寄存器,LD为高电平时,直接将寄存器中的值作为输出信号的延时数据。而LDPIPEEN信号为高电平时,将CNTVALUEIN的数据寄存到内部的寄存器,该模式的时序图如图7所示。
上述四个模式的延时参数取值范围0~31,总共32个延时级别,每个等级延时具体是多少,与REFCLK_FREQUENCY的时钟频率有关。通过查阅手册,如图8所示。
图8 输入/输出延时切换特性
取值为0时,输出相对输入延迟600ps,而其余情况的延时根据1/(32*2*FREF)得到,FREF的取值就是参数REFCLK_FREQUENCY值。一般使用200MHz,图中黄字表示1个单位延迟78ps。例如延时参数设为5,那输出信号相比输入信号的延时为600ps+5*78ps=990ps。
IDELAYCTRL原语
如果使用IDELAYE2或ODELAYE2原语,就必须使用IDELAYCTRL模块。IDELAYCTRL模块连续校准其区域内的各个IDELAY/ODELAY,以减少工艺、电压和温度变化的影响。IDELAYCTRL模块使用用户提供的REFCLK校准IDELAY和ODEL AY,如图9是其框图。
图9 IDELAYCTRL框图
采用异步高电平进行复位,必须在配置后且时钟REFCLK稳定后进行复位,复位时间必须大于图8中的TIDELAYCTRL_RPW=59.28ns。
参考时钟 (REFCLK)必须由全局或水平时钟缓冲器(BUFG或BUFH)驱动。REFCLK必须FIDEL AYCTRL_REF ± 10,以保证指定的IDELAY和ODELAY分辨率(TIDELAYRESOLUTION)。
RDY信号为高电平时,IDELAY和ODELAY延时才有效。如果REFCLK保持高电平或低电平超过一个时钟周期,则RDY信号置为低电平无效。如果RDY无效,则必须重置IDELAYCTRL模块。RDY和RST的时序关系如图10所示。
图10 RST与RDY的时序关系
在复位信号RST有效过程中,RDY输出低电平,复位信号RST拉低经过TIDELAYCTRL_RDY(通过图8可知该值为3.67us)后,RDY拉高,表示IDELAY延时有效,当检查到参考时钟信号REFC LK高电平持续时间过长时,RDY拉低,表示IDE LAY延时无效。
IDELAYCTRL模块存在于每个时钟区域的每个I/O列中,如图11所示,IDELAYCTRL模块校准其时钟区域内的所有IDELAYE2和ODELAYE2模块。
该模块在FPGA内部的结构图,如图12所示,
图12 IDELAYCTRL在芯片中的结构
IDELAY2与IDELAYCTRL仿真
在vivado中获取原语模板的方法如图13所示,在Tools选项卡下点击Language Templates。
图13 vivado获取原语模板
然后如图14所示,搜索IDELAY2选择对应器件的IDELAY原语模板即可。
图14在vivado中获取IDELAYE2原语模板
对应原语模板代码如下所示,其中(* IODELAY_GROUP = <iodelay_group_ name> *)的分组名要与IDELAYCTL的分组名保持一致,绑定两个模块。
(* IODELAY_GROUP = <iodelay_group_name> *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL IDELAYE2 #( .CINVCTRL_SEL("FALSE"), // Enable dynamic clock inversion (FALSE, TRUE) .DELAY_SRC("IDATAIN"), // Delay input (IDATAIN, DATAIN) .HIGH_PERFORMANCE_MODE("FALSE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE") .IDELAY_TYPE("FIXED"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE .IDELAY_VALUE(0), // Input delay tap setting (0-31) .PIPE_SEL("FALSE"), // Select pipelined mode, FALSE, TRUE .REFCLK_FREQUENCY(200.0), // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0). .SIGNAL_PATTERN("DATA") // DATA, CLOCK input signal ) IDELAYE2_inst ( .CNTVALUEOUT(CNTVALUEOUT), // 5-bit output: Counter value output .DATAOUT(DATAOUT), // 1-bit output: Delayed data output .C(C), // 1-bit input: Clock input .CE(CE), // 1-bit input: Active high enable increment/decrement input .CINVCTRL(CINVCTRL), // 1-bit input: Dynamic clock inversion input .CNTVALUEIN(CNTVALUEIN), // 5-bit input: Counter value input .DATAIN(DATAIN), // 1-bit input: Internal delay data input .IDATAIN(IDATAIN), // 1-bit input: Data input from the I/O .INC(INC), // 1-bit input: Increment / Decrement tap delay input .LD(LD), // 1-bit input: Load IDELAY_VALUE input .LDPIPEEN(LDPIPEEN), // 1-bit input: Enable PIPELINE register to load data input .REGRST(REGRST) // 1-bit input: Active-high reset tap-delay input );
然后调用IDELAYCTRL模块的原语,模板如下所示。
(* IODELAY_GROUP = <iodelay_group_name> *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL IDELAYCTRL IDELAYCTRL_inst ( .RDY(RDY), // 1-bit output: Ready output .REFCLK(REFCLK), // 1-bit input: Reference clock input .RST(RST) // 1-bit input: Active high reset input );
对应的参考代码如下所示:
module idelay_ctrl( input clk ,//系统时钟信号,默认200MHZ; input rst ,//系统复位信号,高电平有效; input din ,//输入数据; input ce , input inc , input ld , input ldpipeen , input reg_rst , input [4 : 0] cntvaluein , output [4 : 0] cntalueout , output rdy , output dout //延时后的输出数据; ); wire out ; assign dout = out; (* IODELAY_GROUP = "IDELAY_CTRL" *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL IDELAYE2 #( .CINVCTRL_SEL ("FALSE" ),// Enable dynamic clock inversion (FALSE, TRUE) .DELAY_SRC ("IDATAIN" ),// Delay input (IDATAIN, DATAIN) .HIGH_PERFORMANCE_MODE ("FALSE" ),// Reduced jitter ("TRUE"), Reduced power ("FALSE") .IDELAY_TYPE ("FIXED" ),// FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE .IDELAY_VALUE (0 ),// Input delay tap setting (0-31) .PIPE_SEL ("FALSE" ),// Select pipelined mode, FALSE, TRUE .REFCLK_FREQUENCY (200.0 ),// IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0). .SIGNAL_PATTERN ("DATA" ) // DATA, CLOCK input signal ) IDELAYE2_inst ( .CNTVALUEOUT ( cntalueout ),// 5-bit output: Counter value output .DATAOUT ( out ),// 1-bit output: Delayed data output .C ( clk ),// 1-bit input: Clock input .CE ( ce ),// 1-bit input: Active high enable increment/decrement input .CINVCTRL ( 1'b0 ),// 1-bit input: Dynamic clock inversion input .CNTVALUEIN ( cntvaluein ),// 5-bit input: Counter value input .DATAIN ( 1'b0 ),// 1-bit input: Internal delay data input .IDATAIN ( din ),// 1-bit input: Data input from the I/O .INC ( inc ),// 1-bit input: Increment / Decrement tap delay input .LD ( ld ),// 1-bit input: Load IDELAY_VALUE input .LDPIPEEN ( ldpipeen ),// 1-bit input: Enable PIPELINE register to load data input .REGRST ( reg_rst ) // 1-bit input: Active-high reset tap-delay input ); //例化IDELAYCTRL原语 (* IODELAY_GROUP = "IDELAY_CTRL" *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL IDELAYCTRL IDELAYCTRL_inst ( .RDY ( rdy ),// 1-bit output: Ready output .REFCLK ( clk ),// 1-bit input: Reference clock input .RST ( rst ) // 1-bit input: Active high reset input ); endmodule
对应的TestBench文件如下所示:
`timescale 1 ns/1 psmodule test(); parameter CYCLE = 5 ;//系统时钟周期,单位ns,默认5ns; reg clk ;//系统时钟,默认100MHz; reg rst ;//系统复位,默认高电平有效; reg din ; reg ce ; reg inc ; reg ld ; reg ldpipeen; reg reg_rst ; reg [4 : 0] cntvaluein; wire [4 : 0] cntalueout ; wire rdy ; wire dout ; idelay_ctrl u_idelay_ctrl ( .clk ( clk ), .rst ( rst ), .din ( din ), .ce ( ce ), .inc ( inc ), .ld ( ld ), .ldpipeen ( ldpipeen ), .reg_rst ( reg_rst ), .cntvaluein ( cntvaluein ), .cntalueout ( cntalueout ), .rdy ( rdy ), .dout ( dout ) ); //生成周期为CYCLE数值的系统时钟; initial begin clk = 0; forever #(CYCLE/2) clk = ~clk; end //生成复位信号; initial begin rst = 0; #2; rst = 1;//开始时复位10个时钟; #(10*CYCLE); rst = 0; #(500*CYCLE); $stop;//停止仿真; end initial begin #1;din = 0;//输入数据初始化为0; ce = 0; inc = 0; ld = 0; ldpipeen = 0;reg_rst = 0;cntvaluein = ({$random} % 32); #(15*CYCLE);//延迟10个时钟周期; din = 1'b1; forever begin #(2*CYCLE); ldpipeen = 1; #(CYCLE); ldpipeen = 0; cntvaluein = ({$random} % 32); #(CYCLE); ld = 1'b1; #(CYCLE); ld = 1'b0; #(CYCLE); ce = 1'b1;inc = 1'b1; #(2*CYCLE); ce = 1'b1;inc = 1'b0; #(3*CYCLE); ce = 1'b0;inc = 1'b1; #(CYCLE); ce = 1'b0;inc = 1'b0; end end initial begin #1;din = 0;//输入数据初始化为0; #(15*CYCLE);//延迟10个时钟周期; din = 1'b1; forever begin #((({$random} % 6))*CYCLE/2); din = ({$random} % 2); end endendmodule
图15是IDELAYE2模块工作在FIXED模式下的仿真截图,此时延时参数设置为0(信号cntaueout ==0),而输出信号dout相对输入信号din延迟了0.6ns=600ps。故延迟系数为0时,输出会与输入的延时是600ps。
图15 FIXED模式仿真
图16依旧是FIXED模式下的仿真截图,但把IDEL AY_VALUE值改为5,理论上输出信号在输入信号变化600ps+5*78ps=990ps后变化,与下图仿真一致。
图16 FIXED模式仿真
图17是对VARIABLE模式(修改设计文件第26行IDELAY_TYPE参数即可)的仿真结果,IDELAY_V ALUE值设置为7,LD为高电平时,把IDELAY_V ALUE的值作为输出信号相对输入信号的延时,ce和inc信号同时为高电平时,延时系数递增,inc为低电平时,延时系数在时钟上升沿递减,符合前文该模式的描述。
图17 VARIABLE模式仿真
图18为VAR_LOAD模式(修改设计文件第26行ID ELAY_TYPE参数即可)的仿真,DELAY_VALUE值设置为9,当ld信号为高电平时,时钟上升沿将cntvaluein信号的值30作为输出信号的延时系数,此时DELAY_VALUE的值不起作用,ce、inc控制信号的仿真与VARIABLE模式也是一致的。注意内部系数的寄存器只有5位,所以31后继续累加会溢出变为0。
图18 VAR_LOAD模式仿真
图19为VAR_LOAD_PIPE模式(修改设计文件第26行IDELAY_TYPE参数,将28行修改为TRUE即可)的仿真截图(做到这才发现前面的TestBetch无法完成此模式仿真,所以就改了一下,后面从公众号获取的代码就是修改后,也只将ld信号与ldpipeen信号间隔了一个时钟,其余不变,不影响前文仿真)。
该模式在ldpipeen信号为高电平时,将cntvaluein信号的值6寄存到内部寄存器,ld信号为高电平时,就将内部寄存器的值6作为输出信号延时系数,所以此时cntalueout输出的是6,而不是cntvalein的值27,这就是VAR_LOA D_PIPE与VAR_LOAD的区别。
图19 VAR_LOAD_PIPE模式仿真
综上,仿真了IDELAYE2的四个不同模式的常用方式,几个模式就只有系数变化和加载的方式不同。
IDELAYE综合布线后的走线布局图
将上述工程综合、分配引脚、实现后,打开Default Layout视图,找到din信号的输入管脚,其旁边就是IOB模块左边或右边就是其对应的IDELAYE2模块,如图20所示。
图20 IDELAYE2走线图
将图20中IDELAYE2所在区域放大,如图21所示,IOB输出的信号经过IDATAIN端口空入IDELAYE2,输出信号DATAOUT通过ILOGICE3上半部分的组合逻辑路径进入FPGA内部。
图21 IDELAYE2走线图
在图22中,红色方框里的青线,蓝色方框位置,就可以找到IDELAYCTRL模块。
图22 IDELAYCTRL模块位置
放大IDELAYCTRL得到图23所示结果。
图23 IDELAYCTRL模块
本文到此为止,就将IDELAYE2和IDELAYCTRL原语相关的功能、在芯片中的位置、IDELAYE2的四种模式,及仿真结果进行了讲解。
注意本文的程序没有用作上板使用,所以IDELAYE2的时钟信号和IDELAYE2参考时钟直接使用的外部输入时钟信号,在实际上板的时候,要使用锁相环生成REFCLK_FREQUENCY对应时钟频率的信号作为时钟。