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存在
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!