xilinx FPGA中oddr,idelay的用法詳解
我們知道xilinx FPGA的selectio中有ilogic和ologic資源,可以實(shí)現(xiàn)iddr/oddr,idelay和odelay等功能。剛?cè)腴T時(shí)可能對(duì)xilinx的原語(yǔ)不太熟練,在vivado的tools-> language templates中搜索iddr idelay等關(guān)鍵詞,可以看到A7等器件下原語(yǔ)模板。復(fù)制出來(lái)照葫蘆畫(huà)瓢,再仿真一下基本就能學(xué)會(huì)怎么用了。
本文引用地址:http://yuyingmama.com.cn/article/202401/455254.htm1. oddr
oddr和iddr都一樣,以oddr為例,先去templates里把模板復(fù)制出來(lái)。
Add simulation source,建立一個(gè)簡(jiǎn)單的仿真文件。
module simu_oddr(
);
reg clk = 1'd0;
always
forever #2 clk = ~ clk;
ODDR #(
.DDR_CLK_EDGE("OPPOSITE_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE"
.INIT(1'b0), // Initial value of Q: 1'b0 or 1'b1
.SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC"
) ODDR_inst (
.Q(Q), // 1-bit DDR output
.C(clk), // 1-bit clock input
.CE(1'd1), // 1-bit clock enable input
.D1(1'd1), // 1-bit data input (positive edge)
.D2(1'd0), // 1-bit data input (negative edge)
.R(1'd0), // 1-bit reset
.S(1'd0) // 1-bit set
);
endmoduleODDR的使用方法在selectoi中的參考手冊(cè)u(píng)g471中127頁(yè)開(kāi)始有說(shuō)明,使用這些資源首先要參考的都是官方的資源手冊(cè)。

簡(jiǎn)單說(shuō)明:
CE是使能,C是時(shí)鐘,在時(shí)鐘的上升沿下降沿分別輸出D1和D2,Q是輸出,S/R是復(fù)位,R = 1 Q輸出0,S= 1,Q輸出1,默認(rèn)情況應(yīng)該兩個(gè)都等于0 ,兩個(gè)都等于1時(shí),輸出0。"OPPOSITE_EDGE" or "SAME_EDGE" 手冊(cè)中也有說(shuō)明,指明采樣時(shí)刻不同,具體有什么應(yīng)用上區(qū)別我也不知道。

通過(guò)仿真,就可以看到輸出是什么情況,在上升沿輸出1,下降沿輸出0,還可以看到輸出有一點(diǎn)滯后。iddr和oddr在rgmii的接口中就可以方便地接收數(shù)據(jù),轉(zhuǎn)為gmii。一般情況要注意下時(shí)鐘和數(shù)據(jù)的對(duì)齊問(wèn)題,采樣時(shí)鐘可以相位往后一點(diǎn),90° 1//4周期,輸出的時(shí)候時(shí)鐘也相應(yīng)地滯后一點(diǎn),就根據(jù)實(shí)際情況來(lái),125M的DDR還是很容易采樣穩(wěn)定的。
2.idelay
在ug471告訴我們,只有hp bank才有odelay,在ug475中說(shuō)明哪些系列有hp bank,簡(jiǎn)單說(shuō)hp bank速度快很多,支持odelay,電壓只能1.2V- 1.8V。其中A7全系是沒(méi)有odelay的,K7才有(保留意見(jiàn),簡(jiǎn)單看了一下),所以在language templates中搜索odelay是沒(méi)有A系列的原語(yǔ)的。


idelay作用就是實(shí)現(xiàn)輸入延遲,實(shí)際中應(yīng)該有更明確的用法,這里只是我自己學(xué)習(xí)時(shí)的一些介紹。同樣在ug471中對(duì)idelay也有介紹,有固定延時(shí),可變延時(shí),使用時(shí)都要例化idelay ctrl,延時(shí)的精度就可idelay ctrl的接入時(shí)鐘有關(guān)。一個(gè)bank 只有1個(gè)idelay ctrl,同一個(gè)bank 要用idelay或者odelay,延時(shí)精度是一樣的,雖然可以idelay ctrl可以接200Mhz,300Mhz,但同一個(gè)bank只能接1個(gè),也只需要例化一次。多個(gè)bank要用idelay時(shí),就要例化多次。
`timescale 1ns / 1ps
module s(
);
reg clk = 1'd0;
always
forever #2.5 clk = ~ clk;
(* IODELAY_GROUP = "idelay" *)
IDELAYCTRL IDELAYCTRL_inst (
.RDY(), // 1-bit output: Ready output
.REFCLK(clk), // 1-bit input: Reference clock input
.RST(1'd0) // 1-bit input: Active high reset input
);
reg clk2 = 1'd0;
always @(posedge clk)
clk2 <= ~clk2;
wire DATAOUT;
(* IODELAY_GROUP = "idelay" *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL
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(31), // 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(1'd1), // 1-bit input: Clock input
.CE(1'd0), // 1-bit input: Active high enable increment/decrement input
.CINVCTRL(1'd0), // 1-bit input: Dynamic clock inversion input
.CNTVALUEIN(1'd0), // 5-bit input: Counter value input
.DATAIN(1'd0), // 1-bit input: Internal delay data input
.IDATAIN(clk2), // 1-bit input: Data input from the I/O
.INC(1'd0), // 1-bit input: Increment / Decrement tap delay input
.LD(1'd0), // 1-bit input: Load IDELAY_VALUE input
.LDPIPEEN(1'd0), // 1-bit input: Enable PIPELINE register to load data input
.REGRST(1'd0) // 1-bit input: Active-high reset tap-delay input
);
endmodule這里例化了一個(gè)idelay ctrl,是屬于idelay group的,這個(gè)聲明還沒(méi)有研究過(guò)有什么用,不知道是不是指定idelay2和哪個(gè)ctrl是綁定的。idelay ctrl端口很簡(jiǎn)單,仿真時(shí)復(fù)位rst接0就好了,實(shí)際中推薦接輸入時(shí)鐘的pll lock引腳取反,保證在時(shí)鐘鎖定前(lock = 0)idelay ctrl處于復(fù)位狀態(tài)。
idelay2中按推薦配置,從DATAIN還是從IDATAIN輸入?yún)^(qū)別為是內(nèi)部延時(shí)還是從IO輸入,F(xiàn)IXED固定延時(shí),idelay value先輸入0,,時(shí)鐘是200M,其他全部接0。此處,idelay的作用就是把IDATAIN的信號(hào)接入ilogic中,延時(shí)0個(gè)tap再?gòu)腄ATAOUT輸出??勺冄訒r(shí)的使用說(shuō)明ug471上都有,還沒(méi)學(xué)習(xí),有需要了再去看。
idelay 有0-31個(gè)tap,分割200M的半個(gè)周期2.5ns,每個(gè)tap就是2.5ns/32 = 0.078125 ns
value = 0 可以看到輸出延遲了0.6ns,value = 10時(shí),延時(shí)了1.38ns。0.078125 * 10 + 0.6 = 1.38125,大體相近的。
其實(shí)oddr,idelay這些資源應(yīng)該用起來(lái)都比較簡(jiǎn)單,可能我實(shí)際中就用了一下oddr/iddr,也沒(méi)有覺(jué)得有多少難以調(diào)試的地方,本文簡(jiǎn)單介紹了這2個(gè)原語(yǔ)的使用方法,從復(fù)制原語(yǔ),看手冊(cè)介紹到仿真,其他原語(yǔ)也是類似的,學(xué)會(huì)如何去學(xué)習(xí)最重要。
文末再介紹一下generate,一樣的在tools -> language templates中搜索。
genvar; generate for (=0;<;=+1) begin: end endgenerate
用這個(gè)可以很方便地例化出多個(gè)相似的模塊。
genvar i; //genvar i;也可以定義到generate語(yǔ)句里面 generate for(i=0;i<10;i=i+1) begin:mymodule assign a[i]=reg[i]; end endgenerate














評(píng)論