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

关注、星标公众号,精彩内容每日送达
来源:网络素材

1. 7系列IO资源HR bank

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

2. IDELAY 原语

2.1 IDELAY 的延时值

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

2.2 IDELAYCTRL 原语

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

2.3 IDELAY 原语的使用

  IDELAY原语的结构如下所示:
33a27149c414766d9d39575fb460d127.png
   例化模板如下:

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 模式
    a04c8ffcf35d7450d8494cb7c76f8165.png
    860aadf282567cbcebb57bdff8193227.png

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

  • VAR_LOAD模式
    3d85700bdf938376e79ee6aedb237432.png
    bc218cf5ef9e88ad775097f71aebd1bc.png
      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的延时。
    a5b4019678ea54bd5007e5f8b18e3f4f.png
      然后在导入延时系数之后,可以看到此时原语的检测抽头系数的值发生了变化。延时抽头系数的值,编程了通过在load信号为有效的时候,加载的值。
    d904919ccc80df9234b801db3005cb87.png
      此时可以看到延时值已经变成了1.848ns。计算一下抽头系数,乘上分辨率为:16 x 0.078 = 1.248ns。再加上Idelay本身的延时,刚好就是本次的延时值,1.848ns。
    110c1fa2bdd9c7254d6b1ce5a5b45f46.png
      最后一次加载的抽头系数是31,可以看到当前的延时的值,已经变成了3.018ns。31 x 0.078+0.6 = 3,018ns;
    0507d1ff056ddc00c390b89a838b4e52.png

09472700f0373f8bdc0d966d28a53b40.jpeg

想要了解FPGA吗?这里有实例分享,ZYNQ设计,关注我们的公众号,探索

Simultaneous, on-chip FPGA delay measurement is a powerful technique for characterizing the performance of FPGA designs. However, there are several pitfalls and tradeoffs that must be considered when using this technique. One pitfall is the potential for measurement errors due to coupling between measurement signals and other signals on the FPGA. This coupling can lead to inaccurate measurements and must be carefully controlled through proper design techniques. Another tradeoff is the tradeoff between measurement accuracy and measurement speed. More accurate measurements require longer measurement times, which can impact overall system performance. Therefore, it is important to carefully balance measurement accuracy and measurement speed to obtain the best overall system performance. Additionally, the choice of measurement technique can also impact the accuracy and speed of on-chip FPGA delay measurement. For example, pulse width measurement techniques may be faster but less accurate than time interval measurement techniques. Finally, the choice of measurement circuitry can also impact the accuracy and speed of on-chip FPGA delay measurement. Careful consideration must be given to the design of the measurement circuitry to ensure accurate and reliable measurements. Overall, simultaneous, on-chip FPGA delay measurement is a powerful technique for characterizing FPGA designs, but careful consideration must be given to the potential pitfalls and tradeoffs to obtain accurate and reliable measurements.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值