赞
踩
最近在调试一个源同步的接口,为了时序能够动态调节,需要对输入的数据进行微调。刚好,在Xilinx FPGA中,有用于调整延时的原语。所以记录一下这个原语的使用。
在7系列FPGA中,其HR bank的IO结构如下图所示。其中在HR bank的IO都会有如下的结构部分,分别是信号输入输出的pad,然后会经过IOB,在HR bank中有用于输入延时的资源 IDELAYE2 这个结构。在HR bank中,没有用于输出的延时结构。最后是输入输出的逻辑或者串并转换的Serdes。
首先看一下手册上是怎么来描述这个原语的。每个I/O都包含一个IDELAYE2的可编程的原语。IDELAY可以连接到后续的模块。
IDLEAYE2可以根据抽头系数来调整延时。这个抽头系数对应的最小分辨率可以根据7系列的手册上来看。
从手册上来看,抽头系数的分辨率是和用于IO delay的这个参考时钟有关系。计算公式就是上面那个写着的。可以看到根据参考时钟的不同,具体delay的分辨率不同。对于200M的参考时钟其抽头系数的分辨率为78ps。参考时钟为300M的时候,分辨率为52ps。参考时钟为400M的时候,分辨率为39ps。
从参考手册上来看,还需要有个参考时钟。其实在实际使用中IDELAY这个原语的时候,还需要一个IDELAYCTRL这个原语配合使用。
这个原语比较简单,一般都是配合着I/ODELAY原语来使用的。手册上写着,如果使用了IDELAYE2或者ODELAYE2原语,那么IDELAYCTRL原语必须被例化。IDLAYCTRL使用用户提供的REFCLK来校准IDELAY和ODELAY。也就是前面说的,具体的延时的值,是根据输入到IDELAYCTRL的参考时钟来确定的。
这个原语的使用也比较简单,只需给一个参考时钟和复位信号。如下面的时序图所示:
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 );
属性 | 描述 |
---|---|
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 | 确定延时的是时钟还是数据,以确定不同路径上的抖动 |
端口 | 描述 |
---|---|
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明白了各自的作用了 |
当时钟上升沿有效的时候,在LD为高电平的时候TAP值写入,如果LD为低,且使能了CE信号和INC,那么TAP值就会加1,如果CE为1且INC为0,那么Tap值就会减1。
`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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。