最近调试的ADC的时钟和信号不同源了,导致采集的数据有时候会出现同一个位相反的情况。准备使用IDELAY来控制输入的数据信号,以保证采集到正确的数据。
具体内容见7 Series FPGAs SelectIO Resources UG471
目录
7系列FPGA资源介绍
7系列FPGA的IO资源非常丰富,包括以下内容
- 组合逻辑输入输出
- 三态输入输出
- 寄存器输入输出
- 寄存器三态输出控制
- 双数据速率DDR的输入输出
- DDR输出三态控制
- IDELAY输入延迟
- ODELAY输出延迟
- 同边沿输出DDR模式
在7系列FPGA中,SelectIO的输入,输出和三态驱动位于IOB(输入输出缓冲)中。在HP BANK中拥有独立的IDELAY和ODELAY块。在HR BANK中只拥有IDELAY。
ILOGIC
输入信号处理逻辑。紧挨着IOB,ILOGIC用于将外界输入FPGA的数据等同步。7系列FPGA中。在HP BANK中,ILOGIC被称为ILOGIC2,在HP BANK中,ILOGIC被称为ILOGIC3。
Input delay resources(IDELAY)
每一个IO上都包含一个IDELAY的可编程延迟语句。IDELAY的作用是将信号延迟一段时间,但是这个时间不大,对于200mhz主时钟来说,可以将输入信号延迟半个周期左右。对于低速信号这点并不能改变时序。但是对于高速信号来说,这是非常重要的。
在UG471上面介绍了IDELAY2的原语的结构
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
);
IDELAY2端口介绍
端口名字 | 方向 | 位宽 | 功能 |
C | I | 1 | 时钟 |
REGRST | I | 1 | 复位,只在 VAR_LOAD_PIPE 模式下有效 |
LD | I | 1 | 置一载入系数。具体用法见原语模式表。 |
CE | I | 1 | 内部Tap增减。 |
INC | I | 1 | VARIABLE模式下。CE=1时,INC=1增加,INC=0减少 |
CINVCTRL | I | 1 | 改变C脚时钟极性 |
CNTVALUEIN | I | 5 | 改变Tap的值来改变延迟时的大小,最大31。这会根据你输入的参考频率有关。200mhz参考时钟延迟值一般为2.5ns左右。 计算公式为:Tap延时值*系数 |
IDATAN | I | 1 | IBUF数据输入 |
DATAIN | I | 1 | FPGA逻辑数据输入 |
LDPIPEEN | I | 1 | 当为1时,将CNTVALUEIN的值加载到pipeline寄存器中(在VAR_LOAD_PIPE模式下有效) |
DATAOUT | O | 1 | 延迟输出 |
CNTVALUEOUT | O | 5 | 延迟系数输出 |
具体的功能还需要仔细阅读ug471,我们这里只做简单的使用。
原语属性,即例化模板上的属性。
属性 | 说明 |
CINVCTRL_SEL | 时钟极性 |
DELAY_SRC | 选择延迟信号的来源为IDATAIN或者 DATAIN |
HIGH_PERFORMANCE_MODE | 减小抖动 ("TRUE"), 减小功耗 ("FALSE") |
IDELAY_TYPE | 四种模式 |
IDELAY_VALUE | 默认延时值 |
PIPE_SEL | 选择pipelined模式, FALSE, TRUE |
REFCLK_FREQUENCY | 参考时钟 |
SIGNAL_PATTERN | 确定延时的是时钟还是数据 |
这里说明一下,IDELAY有四种模式。
FIXED | 固定模式,延迟值由IDELAY_VALUE确定。工作中不能改变。 |
VARIABLE | 延时可变模式。延时初值由IDELAY_VALUE确定,在工作时,在C时钟作用下,当CE=1时,由INC引脚控制延时值的增加(INC=1)或者减少(INC=0)。范围为0-31。超出范围自动移动到0或者31。 |
VAR_LOAD | 可填入初值模式。在LD=1时,把CNTVALUEIN的值填入延迟。 |
VAR_LOAD_PIPE | 可预填入模式。即在(LDPIPEEN=1)时,把延时值先写入PIPE寄存器里面。等待LD=1时在写入到Tap。 |
显然固定模式下不可能一次就将这个延时信息调试正常。所以我们这里首先使用VAR_LOAD模式。这里配置需要的延迟参数。
如果已经例化IDELAYE2或ODELAYE2,就必须使用IDELAYCTRL原语。此原语是对(IDELAY/ODELAY的校准。使用用户提供的参考时钟,来校准IDELAY和ODELAY。
IDELAYCTRL的原语结构
端口名字 | 方向 | 位宽 | 功能 |
REFCLK | I | 1 | 参考时钟 |
RST | I | 1 | 复位 |
RDY | O | 1 | 在参考时钟出现一段连续的高或者低时RDY就会置低。如果RDY置低。则必须重置IDELAYCTRL模块。 |
使用和仿真
直接打开原语库。
搜索IDELAY
VAR_LOAD模式
下面是VAR_LOAD模式下具体的代码
// *********************************************************************************/
// Project Name :
// Author : i_huyi
// Email : i_huyi@qq.com
// Creat Time : 2022/4/8 10:46:35
// File Name : .v
// Module Name :
// Called By :
// Abstract :
//
// CopyRight(c) 2020, xxx xxx xxx Co., Ltd..
// All Rights Reserved
//
// *********************************************************************************/
// Modification History:
// 1. initial
// *********************************************************************************/
// *************************
// MODULE DEFINITION
// *************************
`timescale 1 ns / 1 ps
module idelay#(
parameter U_DLY = 1
)
(
input wire clk ,//200
input wire rst ,
//需要延时的信号
input wire data_in ,
//延迟数据
output wire data_out ,
//
input wire[4:0] delay_data ,//延迟值
input wire delay_valid //延迟值有效
);
//--------------------------------------
// localparam
//--------------------------------------
//--------------------------------------
// register
//--------------------------------------
//--------------------------------------
// wire
//--------------------------------------
wire rdy ;
wire[4:0] delay_data_out;
//--------------------------------------
// assign
//--------------------------------------
//------------------------------------------------------------
//------------------------------------------------------------
//
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
);
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 (
.CNTVALUEOUT (delay_data_out ),// 5-bit output: Counter value output
.DATAOUT (data_out ),// 1-bit output: Delayed data output
.C (clk ),// 1-bit input: Clock input
.CE (1'b0 ),// 1-bit input: Active high enable increment/decrement input,VAR_LOAD模式下不使用
.CINVCTRL (1'b0 ),// 1-bit input: Dynamic clock inversion input,时钟极性不变
.CNTVALUEIN (delay_data ),// 5-bit input: Counter value input
.DATAIN (1'b0 ),// 1-bit input: Internal delay data input,ibuf数据不输入
.IDATAIN (data_in ),// 1-bit input: Data input from the I/O
.INC (1'b0 ),// 1-bit input: Increment / Decrement tap delay input,VAR_LOAD模式下不使用
.LD (delay_valid ),// 1-bit input: Load IDELAY_VALUE input
.LDPIPEEN (1'b0 ),// 1-bit input: Enable PIPELINE register to load data input,VAR_LOAD模式下不使用
.REGRST (1'b0 )// 1-bit input: Active-high reset tap-delay input,VAR_LOAD模式下不使用
);
//------------------------------------------------------------
//------------------------------------------------------------
//------------------------------------------------------------
//------------------------------------------------------------
endmodule
下面是仿真tb
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/04/08 11:30:06
// Design Name:
// Module Name: vtf_idelay
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module vtf_idelay;
//input
//
reg clk;
reg rst;
reg data_in;
reg [4:0] delay_data;
reg delay_valid;
//output
wire data_out;
//例化
idelay u_idelay(
.clk (clk ),
.rst (rst ),
//需要延时的信号
.data_in (data_in ),
//延迟数据
.data_out (data_out ),
//
.delay_data (delay_data ),
.delay_valid (delay_valid ));
initial
begin
clk = 0 ;
rst = 1 ;
data_in = 0;
delay_data = 0;
delay_valid = 0;
#100;
rst = 0;
#1000;
delay_data = 5'd1;
delay_valid = 1;
#10;
delay_valid = 0;
#1000;
delay_data = 5'd15;
delay_valid = 1;
#10;
delay_valid = 0;
#1000;
delay_data = 5'd31;
delay_valid = 1;
#10;
delay_valid = 0;
end
always #2.5 clk = ~clk;
always #10 data_in = ~data_in;
endmodule
下面看一下仿真截图。在默认初值为零的情况下。输入信号经过IDELAY后系统延迟为0.6ns。
设置IDELAY模式为VAR_LOAD模式。写入延迟值1,后输入信号的延迟值为0.6ns+78ps=0.678ns
写入延迟值15,后输入信号的延迟值为0.6ns+78ps*15=1.770ns
写入延迟值31,后输入信号的延迟值为0.6ns+78ps*31=3.018ns
VARIABLE模式
在VARIABLE模式下设置为。CE为1,开启延时值增减。在INC为1的情况下累加。在INC为0的情况下累减。
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
);
IDELAYE2 #(
.CINVCTRL_SEL ("FALSE" ),// Enable dynamic clock inversion (FALSE, TRUE)
.DELAY_SRC ("DATAIN" ),// 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_TYPE ("VARIABLE" ),// 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 (delay_data_out ),// 5-bit output: Counter value output
.DATAOUT (data_out ),// 1-bit output: Delayed data output
.C (clk ),// 1-bit input: Clock input
// .CE (1'b0 ),// 1-bit input: Active high enable increment/decrement input,VAR_LOAD模式下不使用
.CE (1'b1 ),// 1-bit input: Active high enable increment/decrement input,VAR_LOAD模式下不使用
.CINVCTRL (1'b0 ),// 1-bit input: Dynamic clock inversion input,时钟极性不变
.CNTVALUEIN (delay_data ),// 5-bit input: Counter value input
.DATAIN (data_in ),// 1-bit input: Internal delay data input,ibuf数据不输入
.IDATAIN (1'b0 ),// 1-bit input: Data input from the I/O
.INC (1'b1 ),// 1-bit input: Increment / Decrement tap delay input,VAR_LOAD模式下不使用
.LD (delay_valid ),// 1-bit input: Load IDELAY_VALUE input
.LDPIPEEN (1'b0 ),// 1-bit input: Enable PIPELINE register to load data input,VAR_LOAD模式下不使用
.REGRST (1'b0 )// 1-bit input: Active-high reset tap-delay input,VAR_LOAD模式下不使用
);
VAR_LOAD_PIPE模式。
用于预存功能,数据在LDPIPEEN使能下写入PIEPE寄存器预存。之后,在LD使能下将数据更新。
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
);
IDELAYE2 #(
.CINVCTRL_SEL ("FALSE" ),// Enable dynamic clock inversion (FALSE, TRUE)
.DELAY_SRC ("DATAIN" ),// 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_TYPE ("VAR_LOAD_PIPE" ),// FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
.IDELAY_VALUE (0 ),// Input delay tap setting (0-31)
.PIPE_SEL ("TRUE" ),// 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 (delay_data_out ),// 5-bit output: Counter value output
.DATAOUT (data_out ),// 1-bit output: Delayed data output
.C (clk ),// 1-bit input: Clock input
// .CE (1'b0 ),// 1-bit input: Active high enable increment/decrement input,VAR_LOAD模式下不使用
.CE (1'b0 ),// 1-bit input: Active high enable increment/decrement input,VAR_LOAD模式下不使用
.CINVCTRL (1'b0 ),// 1-bit input: Dynamic clock inversion input,时钟极性不变
.CNTVALUEIN (delay_data ),// 5-bit input: Counter value input
.DATAIN (data_in ),// 1-bit input: Internal delay data input,ibuf数据不输入
.IDATAIN (1'b0 ),// 1-bit input: Data input from the I/O
.INC (1'b0 ),// 1-bit input: Increment / Decrement tap delay input,VAR_LOAD模式下不使用
.LD (delay_valid ),// 1-bit input: Load IDELAY_VALUE input
// .LDPIPEEN (1'b0 ),// 1-bit input: Enable PIPELINE register to load data input,VAR_LOAD模式下不使用
.LDPIPEEN (delay_pipe_en ),// 1-bit input: Enable PIPELINE register to load data input,VAR_LOAD模式下不使用
.REGRST (1'b0 )// 1-bit input: Active-high reset tap-delay input,VAR_LOAD模式下不使用
);
仿真tb。
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/04/08 11:30:06
// Design Name:
// Module Name: vtf_idelay
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module vtf_idelay;
//input
//
reg clk;
reg rst;
reg data_in;
reg delay_pipe_en;
reg [4:0] delay_data;
reg delay_valid;
//output
wire data_out;
//例化
idelay u_idelay(
.clk (clk ),
.rst (rst ),
//需要延时的信号
.data_in (data_in ),
//延迟数据
.data_out (data_out ),
//
.delay_pipe_en (delay_pipe_en ),
.delay_data (delay_data ),
.delay_valid (delay_valid ));
initial
begin
clk = 0 ;
rst = 1 ;
data_in = 0;
delay_pipe_en =0 ;
delay_data = 0;
delay_valid = 0;
#100;
rst = 0;
#1000;
delay_data = 5'd1;
#100;
delay_pipe_en = 1;
#10;
delay_pipe_en =0;
delay_data = 5'd0;
#50;
delay_valid = 1;
#8;
delay_valid = 0;
#1000;
delay_data = 5'd15;
#100;
delay_pipe_en = 1;
#10;
delay_pipe_en =0;
delay_data = 5'd0;
#50;
delay_valid = 1;
#8;
delay_valid = 0;
#1000;
delay_data = 5'd31;
#100;
delay_pipe_en = 1;
#10;
delay_pipe_en =0;
delay_data = 5'd0;
#50;
delay_valid = 1;
#8;
delay_valid = 0;
end
always #2.5 clk = ~clk;
always #2.5 data_in = ~data_in;
endmodule