FPGA内部资源(Xilinx) ---- IDELAY(延时)

前言

  最近在调试一个源同步的接口,为了时序能够动态调节,需要对输入的数据进行微调。刚好,在Xilinx FPGA中,有用于调整延时的原语。所以记录一下这个原语的使用。

1. 7系列IO资源HR bank

  在7系列FPGA中,其HR bank的IO结构如下图所示。其中在HR bank的IO都会有如下的结构部分,分别是信号输入输出的pad,然后会经过IOB,在HR bank中有用于输入延时的资源 IDELAYE2 这个结构。在HR bank中,没有用于输出的延时结构。最后是输入输出的逻辑或者串并转换的Serdes。
在这里插入图片描述

2. IDELAY 原语

2.1 IDELAY 的延时值

  首先看一下手册上是怎么来描述这个原语的。每个I/O都包含一个IDELAYE2的可编程的原语。IDELAY可以连接到后续的模块。
  IDLEAYE2可以根据抽头系数来调整延时。这个抽头系数对应的最小分辨率可以根据7系列的手册上来看。
在这里插入图片描述
  从手册上来看,抽头系数的分辨率是和用于IO delay的这个参考时钟有关系。计算公式就是上面那个写着的。可以看到根据参考时钟的不同,具体delay的分辨率不同。对于200M的参考时钟其抽头系数的分辨率为78ps。参考时钟为300M的时候,分辨率为52ps。参考时钟为400M的时候,分辨率为39ps。
在这里插入图片描述
  从参考手册上来看,还需要有个参考时钟。其实在实际使用中IDELAY这个原语的时候,还需要一个IDELAYCTRL这个原语配合使用。

2.2 IDELAYCTRL 原语

  这个原语比较简单,一般都是配合着I/ODELAY原语来使用的。手册上写着,如果使用了IDELAYE2或者ODELAYE2原语,那么IDELAYCTRL原语必须被例化。IDLAYCTRL使用用户提供的REFCLK来校准IDELAY和ODELAY。也就是前面说的,具体的延时的值,是根据输入到IDELAYCTRL的参考时钟来确定的。
在这里插入图片描述
  这个原语的使用也比较简单,只需给一个参考时钟和复位信号。如下面的时序图所示:
在这里插入图片描述

2.3 IDELAY 原语的使用

  IDELAY原语的结构如下所示:
在这里插入图片描述
   例化模板如下:

   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
   );

2.3.1 原语属性

属性描述
CINVCTRL_SEL该属性是来选择是否动态地反转时钟信号C的极性
DELAY_SRC要延时的信号的来源,可以是内部的 信号(DATAIN),也可以是来自管脚的 信号(IDATAIN)
HIGH_PERFORMANCE_MODE是否使用高性能模式,使用高性能模式能够减小抖动
IDELAY_TYPE原语延时的类型,可以是固定的延时值,当选择固定的延时的时候,和下面的 IDELAY_VALUE 一起决定了延时的时间
也可以是动态更改的。当想染IO的延时可以动态更改的时候,一般选择VAR_LOAD的模式,也就是加载延时抽头系数的模式
IDELAY_VALUE延时的值,在fixed模式下有用,在其他模式下,当没有新的延时值得时候,默认为这个延时值,当外部输入新的值得时候,将会改变延时值
PIPE_SEL当使用 VAR_LOAD_PIPE 模式的时候,才选择这个选项
REFCLK_FREQUENCY参考时钟,200M 300M这种
SIGNAL_PATTERN确定延时的是时钟还是数据,以确定不同路径上的抖动

2.3.2 原语端口

端口描述
CNTVALUEOUT延时系数的输出,输入的延时系数,可以通过这个端口来观察,可以表示当前原语的工作状态
DATAIN , IDATAIN需要延时的数据,DATAIN是内部的数据, IDATAIN是来自IO的数据
DATAOUT经过延时后的数据
C时钟,当不是fixed模式的时候,必须要提供时钟,来更新延时的抽头系数值
CINVCTRL允许更改时钟的极性,也就是时钟极性反转
CNTVALUEIN动态更改延时抽头系数的时候,使用这个值来进行更改,5bit,最大为31,也就是最大的延时值就是32*分辨率,
对于200M的参考时钟,最大的参考时钟是2.5ns左右
LDPIPEEN将输入的延时值加载到流水线当中
REGRST复位,只在 VAR_LOAD_PIPE 模式下有效
CE, INC, LD这三个信号来控制抽头系数的变化。放在一起考虑,看几个时序图一下就i明白了各自的作用了

2.3.4 端口的工作模式

  • Fixed 模式
    就是固定的延时值。
  • VARIABLE 模式
    在这里插入图片描述
    在这里插入图片描述

  当时钟上升沿有效的时候,在LD为高电平的时候TAP值写入,如果LD为低,且使能了CE信号和INC,那么TAP值就会加1,如果CE为1且INC为0,那么Tap值就会减1。

  • VAR_LOAD模式
    在这里插入图片描述
    在这里插入图片描述
      load模式下可以多次的加载延时的系数,从而动态的修改延时的值。

3. 验证一下

`timescale 1ns / 1ps
module tb_idelay();

	// Test signals
	reg 			ref_clk 		;
	reg 			rst 			;
	wire 			rdy 			;
	reg [11:0]		rx_data_buf		;
	reg 			rx_frame_buf	;

	wire [11:0]		rx_data_delay	;
	wire 			rx_frame_delay	;
	reg [4:0]		delay_value 	;
	reg  [12:0]		delay_load_en	;
	wire [4:0]		mon_delay_frame ;
	wire [4:0]		mon_delay_data	;

	//generate clock 200M 
	initial begin
        ref_clk = 0;
        forever #(2.5) ref_clk = ~ref_clk;
    end
	
	// generate source data and frame
    initial begin 
    	rst = 1;
    	rx_frame_buf = 0;
    	rx_data_buf = 0;
    	repeat(50)@(posedge ref_clk);
    	rst = 0;
    	repeat(100)@(posedge ref_clk);
    	gen_test_data;
    end
	
	// generate delay value and load signal
    initial begin 
    	delay_load_en = 1'b0;
    	delay_value = 5'd0;
    	@(negedge rx_frame_buf);
    	@(negedge ref_clk);
    	delay_value = 5'd16;
    	delay_load_en =  {13{1'b1}};
    	@(negedge ref_clk);
    	delay_load_en = {13{1'b0}};
    	delay_value = 5'd0;

    	@(negedge rx_frame_buf);
    	@(negedge ref_clk);
    	delay_value = 5'd31;
    	delay_load_en =  {13{1'b1}};
    	@(negedge ref_clk);
    	delay_load_en = {13{1'b1}};
    	delay_value = 5'd31;
    end

    task gen_test_data();
    	integer k,j; begin 
    		for (k = 0; k < 3; k = k + 1) begin
    			rx_frame_buf  = 1'b1;
    			for (j = 0; j < 512; j = j + 1) begin
    				rx_data_buf = j[11:0];
    				@(posedge ref_clk);
    			end
    			rx_frame_buf = 1'b0;
    			repeat(50)@(posedge ref_clk); 
    		end
    	end
    endtask 


genvar i;

// IDELAYCTRL module
IDELAYCTRL IDELAYCTRL_inst (
  	.RDY(rdy),       // 1-bit output: Ready output
  	.REFCLK(ref_clk),// 1-bit input: Reference clock input
  	.RST(rst)        // 1-bit input: Active high reset input
);
// delay frame
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("VAR_LOAD"),        // 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_frame_delay (
  	.CNTVALUEOUT(mon_delay_frame),// 5-bit output: Counter value output
  	.DATAOUT(rx_frame_delay),	  // 1-bit output: Delayed data output
  	.C(ref_clk),	              // 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_value),  	  // 5-bit input: Counter value input
  	.DATAIN(1'b0),         	   	  // 1-bit input: Internal delay data input
  	.IDATAIN(rx_frame_buf),    	  // 1-bit input: Data input from the I/O
  	.INC(1'b0),                	  // 1-bit input: Increment / Decrement tap delay input
  	.LD(delay_load_en[12]),       // 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
);

//delay data
generate
	for (i = 0; i < 12; i = i + 1)
	begin:data_delay
		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("VAR_LOAD"),        // 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_data_delay (
		  	.CNTVALUEOUT(mon_delay_data),// 5-bit output: Counter value output
		  	.DATAOUT(rx_data_delay[i]),	 // 1-bit output: Delayed data output
		  	.C(ref_clk),	             // 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_value),	 // 5-bit input: Counter value input
		  	.DATAIN(1'b0),         	 	 // 1-bit input: Internal delay data input
		  	.IDATAIN(rx_data_buf[i]),	 // 1-bit input: Data input from the I/O
		  	.INC(1'b0),              	 // 1-bit input: Increment / Decrement tap delay input
		  	.LD(delay_load_en[i]),       // 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
		);
	end
endgenerate
endmodule
  • 测试结果
    测试发现一个有意思的事情,只要通过了idelay这个原语,都会先增加一个0.6ns的延时。如下图所示,可以看到此时没有添加延时值,并且初始的抽头系数的值也是0。但是当数据经过IDELAY原语后,增加了一个0.6ns的延时。
    在这里插入图片描述
      然后在导入延时系数之后,可以看到此时原语的检测抽头系数的值发生了变化。延时抽头系数的值,编程了通过在load信号为有效的时候,加载的值。
    在这里插入图片描述
      此时可以看到延时值已经变成了1.848ns。计算一下抽头系数,乘上分辨率为:16 x 0.078 = 1.248ns。再加上Idelay本身的延时,刚好就是本次的延时值,1.848ns。
    在这里插入图片描述
      最后一次加载的抽头系数是31,可以看到当前的延时的值,已经变成了3.018ns。31 x 0.078+0.6 = 3,018ns;
    在这里插入图片描述
    ___FINE ___
    参考:
    UG471
    Artix-7 datasheet
  • 44
    点赞
  • 350
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
FPGA (Field-Programmable Gate Array)是一种可编程的逻辑器件,可以通过重新编程来实现各种不同的数字电路设计。在FPGA设计中,iDelay是一种常用的元件,用于延迟一个电路信号的到达时间。 FPGA iDelay仿真是指对于使用了iDelay元件的FPGA设计进行的仿真过程。在仿真过程中,我们使用仿真工具模拟和验证FPGA设计的功能和性能,以确保在实际硬件中的正确运行。 仿真过程中,首先需要创建FPGA设计的模型,包括所有的元件、逻辑和连接。然后,我们需要定义输入信号的时序和值,并将其应用到FPGA模型的输入端口上。 接下来,我们可以运行仿真工具来模拟信号在FPGA设计中的传播和延迟。仿真工具会根据输入信号的时序和FPGA模型的逻辑,计算出输出信号的时序和值,并生成仿真波形。 在iDelay仿真中,我们特别关注信号的延迟效应。通过改变iDelay元件的延迟参数,我们可以模拟不同延迟条件下的FPGA设计的行为。这可以帮助我们评估系统对信号延迟的容忍程度,并为进行性能优化提供参考。 通过iDelay仿真,我们可以验证FPGA设计在不同延迟条件下的正确性和稳定性。同时,仿真结果还可以用于调整和优化iDelay元件的设置,以满足设计的需求和性能要求。 综上所述,FPGA iDelay仿真是一种通过仿真工具对FPGA设计中的iDelay元件进行验证和优化的过程,可帮助我们评估和改进FPGA系统的延迟性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值