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存在