FPGA——IDELAY应用

1、输入延迟资源(IDELAY)

赛灵思7系列的原语IDELAY,通常用于对输入时钟数据进行时延,以满足代码时序需要。如果对FPGA代码进行时序约束,idelay会自动添加。如果没有进行时序约束就需要手动添加idleay以满足时序要求。例如在写以太网RGMII数据链路层接收端时就需要用到IDELAY对双沿时钟延时,以使得数据能够正常的被时钟采集到。
首先要说明一下IDELAY所在位置,xilinx 7系列有两种bank,分别是HR BANK和HP BANK,HP I/O BANK电压最高可以达到1.8V,主要用于高速存储器和芯片间的数据传输,HR I/O BANK可以支持更大范围的电压,最高可以达到3.3V。由图可知,从引脚(PAD)到输入输出缓冲器(IOB)就是IDELAY输入延时资源。7系统FPGA的每个BANK都有输入延时资源,而输出延时资源只有HP BANK有。

2、IDELAY原语

2.1 原语概述



打开vivado的language template就可以搜到IDELAY2原语例化模板

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

IDELAY延时有两种模式,一种是固定的(即编译后延时多少就是多少不可改变),另外一种是动态配置延时的(即编译后可以动态配置延时多少)
CINVCTRL_SEL:用于动态配置时钟极性
DELAY_SRC:IDATAIN,表示I/O口输入对I/O延时,DATAIN,FPGA内部信号输入对内部信号延时
IDELAY_TYPE:IDELAY模式,固定模式和动态模式(动态模式有三种,VARIABLE, VAR_LOAD, VAR_LOAD_PIPE)
IDELAY_VALUE:延时值tap的分辨率是(TIDELAYRESOLUTION=1/(32x 2 x REFCLK)),tap为0时也有0.6ns的延时,用于固定模式,如果是VARIABLE模式会被作为初值加载进去,其他模式则没有用给0即可。
PIPE_SEL:选择流水线模式
REFCLK_FREQUENCY:参考时钟频率,这个参考时钟需要通过IDELAYCTRL配置
SIGNAL_PATTERN:延时信号选择,数据或者时钟

2.2 固定模式

module delay_mod(
    clk     ,
    rst_n   ,
    dat_i   ,
    dat_o    
);
input   clk     ;
input   rst_n   ;
input   dat_i   ;
output  dat_o   ;

IDELAYCTRL idleayctrl (
    .RDY(RDY),          // 1-bit output: Ready output
    .REFCLK(clk),       // 1-bit input: Reference clock input
    .RST(!rst_n)        // 1-bit input: Active high reset input
);

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(20),                // 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
)
idelay (
    .CNTVALUEOUT(), // 5-bit output: Counter value output
    .DATAOUT(dat_o),         // 1-bit output: Delayed data output
    .C(1'b0),                     // 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(1'b0),   // 5-bit input: Counter value input
    .DATAIN(1'b0),           // 1-bit input: Internal delay data input
    .IDATAIN(dat_i),         // 1-bit input: Data input from the I/O
    .INC(1'b0),                 // 1-bit input: Increment / Decrement tap delay input
    .LD(1'b0),                   // 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
);

endmodule

tap = 20;

延迟了2.16ns

2.3 动态模式

2.3.1 VARIABLE


要用到的参数有,C(时钟,一个bank的的delay时钟必须相同),LD(在此模式会将IDELAY_VALUE参数的值加载给TAP,相当于复位TAP),CE(是INC的使能),INC(为1时TAP值随时钟加1,为0时TAP值随时钟减1)

module delay_variable_mod(
    clk     ,
    rst_n   ,
    dat_i   ,
    dat_o    
);

input   clk     ;
input   rst_n   ;
input   dat_i   ;
output  dat_o   ;

//IDELAYE signal
wire    [5-1:0]     tapvalue    ;
reg                 ce          = 0;
reg                 ld          = 0;
reg                 inc         = 0;

//cnt signal
reg     [4-1:0]     cnt_strt     ;
wire                add_cnt_strt ;
wire                end_cnt_strt ;

reg     [2-1:0]     cnt_stage    ;
wire                add_cnt_stage;
wire                end_cnt_stage;

IDELAYCTRL idleayctrl (
    .RDY(RDY),          // 1-bit output: Ready output
    .REFCLK(clk),       // 1-bit input: Reference clock input
    .RST(!rst_n)        // 1-bit input: Active high reset input
);

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("VARIABLE"),           // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
    .IDELAY_VALUE(20),                // 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
)
idelay (
    .CNTVALUEOUT(tapvalue), // 5-bit output: Counter value output
    .DATAOUT(dat_o),         // 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(1'b0),   // 5-bit input: Counter value input
    .DATAIN(1'b0),           // 1-bit input: Internal delay data input
    .IDATAIN(dat_i),         // 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(1'b0),       // 1-bit input: Enable PIPELINE register to load data input
    .REGRST(1'b0)            // 1-bit input: Active-high reset tap-delay input
);


always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt_strt <= 0;
    end
    else if(add_cnt_strt)begin
        if(end_cnt_strt)
            cnt_strt <= 0;
        else
            cnt_strt <= cnt_strt + 1;
        end
end
assign add_cnt_strt = 1;
assign end_cnt_strt = add_cnt_strt && cnt_strt == 16 - 1;

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        cnt_stage <= 0;
    end
    else if(add_cnt_stage)begin
        if(end_cnt_stage)
            cnt_stage <= 0;
        else
            cnt_stage <= cnt_stage + 1;
        end
end
assign add_cnt_stage = end_cnt_strt;
assign end_cnt_stage = add_cnt_stage && cnt_stage == 3 - 1;

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        ce <= 0;
        inc <= 0;
        ld <= 0;
    end
    else if(cnt_stage == 0)begin
        ce <= 1;
        inc <= 1;
        ld <= 0;
    end
    else if(cnt_stage == 1)begin
        ce <= 1;
        inc <= 0;
        ld <= 0;
    end
    else if(end_cnt_stage)begin
        ce <= 0;
        inc <= 0;
        ld <= 1;
    end
    else begin
        ce <= 0;
        inc <= 0;
        ld <= 0;
    end
end

endmodule

2.3.2 VAR_LOAD


要用到的参数有,C(时钟,一个bank的的delay时钟必须相同),LD(在此模式会将CNTVALUEIN参数的值加载给TAP,相当于复位TAP),CE(是INC的使能),INC(为1时TAP值随时钟加1,为0时TAP值随时钟减1)
该模式只是在VARIABLE模式基础上将固定的加载值IDELAY_VALUE改为可动态配置的值CNTVALUEIN,也就是 CNTVALUEIN 约等于 IDELAY_VALUE,没有用LD,TAP的初始值默认为0

2.3.3 VAR_LOAD_PIPE


可以看到使用流水线,会延迟10拍,这样时序更好

3、IDELAYCTRL原语


如果要用到idelay必须先例化IDELAYCTRL
如果有多个Idelay的时候,需要使用"IODELAY_GROUP"将两者绑定起来,一个时钟域只能有一个Idelayctrl存在

4、参考资料

posted @ 2022-03-04 00:02  AdriftCore  阅读(3327)  评论(0编辑  收藏  举报