IDELAYCTRL 是 Xilinx FPGA(特别是支持高速 I/O 的系列,如 Virtex-5/6/7、Kintex-7、Artix-7、Spartan-6/7 等)中用于管理和校准输入延迟模块(IDELAYE2/IDELAYE3)的必须存在的参考时钟控制模块。
1 核心功能
IDELAYCTRL 的主要功能是为 IDELAY 模块提供精确的延迟校准。
IDELAY(输入延迟单元)是一个可以以 ~78ps(32 步进)或 ~11ps(512 步进) 的精度对输入信号进行延迟调整的硬件原语。
但是这种延迟的精度依赖于一个参考时钟(REFCLK),该时钟的频率决定了每一步延迟的实际时间。
IDELAYCTRL 模块的作用就是持续监控和校准 IDELAY 的延迟步进,使其不随 PVT(工艺、电压、温度)变化而漂移。
简单说:没有 IDELAYCTRL,IDELAY 的延迟量将不可预测。
2 工作原理
IDELAYCTRL 需要一个稳定且频率匹配的参考时钟 REFCLK
REFCLK 频率要求:
对于 IDELAYE2(7系列、Virtex-6等):
REFCLK 必须为 200 MHz(如果延迟步进为 78ps) 或 300 MHz(如果延迟步进为 52ps,仅部分型号支持)。
通常 200 MHz 对应 78ps 步进,300 MHz 对应 52ps 步进。
但 7 系列中,实际步进为 78ps(200MHz) 或 ~52ps(300MHz),具体需查手册。
对于 IDELAYE3(UltraScale/UltraScale+):
支持更多频率,步进可为 ~10ps 到 ~50ps,需根据选择的步进配置对应频率。
校准机制:
IDELAYCTRL 内部包含一个环形振荡器和校准电路,它通过比较 REFCLK 周期与延迟链的传播时间,动态调整 IDELAY 单元的步进,使其保持恒定。
3 使用场景
IDELAYCTRL 用于以下场合:
比特对齐(通过调整不同 bit 的延迟实现通道对齐)
时序收敛(调整建立/保持时间余量)
通常与 IDELAYE2/IDELAYE3 和 ISERDESE2/ISERDESE3 结合使用。
4 使用规则
一个 IDELAYCTRL 可服务多个 IDELAY:
在同一个区域(通常是一个 Bank 或几个相邻 Bank)内的所有 IDELAY 可以共享一个 IDELAYCTRL 实例。
跨区域需多个 IDELAYCTRL:
不同时钟区域(Clock Region)或不同 IDELAY 类型可能需要独立的 IDELAYCTRL。
必须提供稳定 REFCLK:
REFCLK 必须来自全局时钟资源(如 MMCM/PLL 输出),并且频率精确。
上电后需等待 RDY 信号:
IDELAYCTRL 启动后需要一段时间校准,完成后输出 RDY 信号为高,之后才能使用 IDELAY。
5 原语示例(7系列)
IDELAYCTRL #(
.SIM_DEVICE("7SERIES") // 对于 7 系列,Virtex-6 为 "VIRTEX6"
)
idelayctrl_inst (
.RDY(rdy_out), // 输出:校准就绪信号,高有效
.REFCLK(refclk), // 输入:参考时钟(200 MHz)
.RST(rst) // 输入:复位,高有效,初始化校准
);
idelayctrl_inst : IDELAYCTRL
generic map (
SIM_DEVICE =>"7SERIES"
)
port map (
RDY => rdy_out,
REFCLK => refclk,
RST => rst
);
6 连接方式
在典型设计中:
使用一个 MMCM/PLL 产生精确的 200 MHz 参考时钟。
将该时钟连接到 IDELAYCTRL 的 REFCLK。
将 IDELAYCTRL 的 RDY 信号作为系统中 IDELAY 模块使能的条件(或作为系统复位释放条件)。
同一区域的所有 IDELAYE2 共享此 IDELAYCTRL。
必须使用 IDELAYCTRL:
只要使用了 IDELAYE2/IDELAYE3,就必须例化并正确连接 IDELAYCTRL,否则延迟值会随环境变化,导致接口不稳定。
REFCLK 频率必须精确:
如果 REFCLK 频率偏差大,校准后的延迟步进误差也会增大。
复位和就绪:
上电或复位后,需等待 RDY 变高才能使用 IDELAY。
7 与 IDELAYE2 的连接示例
// 1. 先产生 200 MHz 参考时钟(例如从 100 MHz 系统时钟倍频)
clk_wiz_inst (
.clk_in1(sys_clk),
.clk_out1(refclk_200m) // 200 MHz
);
// 2. 实例化 IDELAYCTRL
IDELAYCTRL idelayctrl_inst (
.RDY(rdy),
.REFCLK(refclk_200m),
.RST(~pll_locked) // PLL 锁定时释放复位
);
// 3. 使用 IDELAYE2(需要延迟的输入信号)
IDELAYE2 #(
.DELAY_SRC("IDATAIN"),
.IDELAY_TYPE("VAR_LOAD"), // 或 "FIXED", "VARIABLE"
.IDELAY_VALUE(0),
.REFCLK_FREQUENCY(200.0)
)
idelaye2_inst (
.IDATAIN(data_in),
.DATAOUT(data_delayed),
.C(refclk_200m), // 时钟,用于加载新延迟值
.CE(ce),
.INC(inc),
.LD(load),
.LDPIPEEN(1'b0),
.CNTVALUEIN(cntvaluein), // 动态加载的延迟值
.CNTVALUEOUT(cntvalueout),
.REGRST(1'b0)
);
// 4. 在系统中,确保在 rdy 为高后才使能 IDELAY 操作
// 时钟生成
clk_wiz_inst u_clk_wiz (
.clk_in1(sys_clk),
.clk_out1(refclk_200m),
.locked(pll_locked)
);
// IDELAYCTRL 实例化
wire idelayctrl_rdy;
IDELAYCTRL u_idelayctrl (
.RDY(idelayctrl_rdy),
.REFCLK(refclk_200m),
.RST(~pll_locked)
);
// 等待 IDELAYCTRL 就绪
reg idelay_ready;
always @(posedge refclk_200m) begin
idelay_ready <= idelayctrl_rdy;
end
// IDELAYE2 实例化
wire [4:0] cntvalueout;
IDELAYE2 #(
.DELAY_SRC("IDATAIN"),
.IDELAY_TYPE("VAR_LOAD"),
.IDELAY_VALUE(0),
.REFCLK_FREQUENCY(200.0)
) u_idelaye2 (
.IDATAIN(data_in),
.DATAOUT(data_delayed),
.C(refclk_200m),
.CE(idelay_ready ? ce_signal :1'b0), // 门控 CE
.INC(inc_signal),
.LD(idelay_ready ? load_signal : 1'b0), // 门控 LD
.LDPIPEEN(1'b0),
.CNTVALUEIN(cntvaluein),
.CNTVALUEOUT(cntvalueout),
.REGRST(~idelay_ready) // 未就绪时复位
);
// 示例:在就绪后加载初始延迟值
reg load_init;
always @(posedge refclk_200m) begin
if (~idelay_ready) begin
load_init <= 1'b0;
cntvaluein <=5'b0;
end else if (idelay_ready && ~load_init) begin
// 第一次就绪时加载默认延迟
load_init <= 1'b1;
cntvaluein <=5'b01000; // 8个步进,约624ps
load_signal <= 1'b1;
end else begin
load_signal <=1'b0;
// ... 正常操作
end
end
必须等待 RDY:在 RDY 为高之前,不应操作 IDELAYE2
门控控制信号:CE、LD 等信号应在 RDY 有效后才使能
位管理:可以使用 ~RDY 作为 REGRST 或系统复位条件
上电时序:整个系统应等待 PLL_LOCKED + IDELAYCTRL_RDY 后才开始工作。
165
