目錄
一、前言
二、I/O資源
2.1 I/O端口資源
2.1.1 IOB
2.1.2 ILOGIC/OLOGIC
2.2 ZHOLD
2.3 IDDR/ODDR
2.4 IDELAY
2.5 ISERDES/OSERDES
2.6?IO Logic Resource連接
2.7 Device示意圖
三、工程示例
3.1 工程代碼
3.2 Device結果
一、前言
????????FPGA芯片從內部結構看主要由CLM,可編程IO,可編程的互連線資源,數字信號處理單元DSP,存儲單元BRAM,軟核與硬核組成,本文對其中的可編程I/O結合開發工具Vivado進行基礎的介紹。
二、I/O資源
2.1 I/O端口資源
??????????Xilinx 7系列器件的I/O資源由I/O塊(IOB)和邏輯資源(ILOGIC和OLOGIC)兩部分組成,每個IOB都有一個直接連接的ILOGIC或OLOGIC。以器件xc7k420tffv1156-2為例,IOB和ILOGIC/OLOGIC如下圖
2.1.1 IOB
??????????7系列的IOB分為HP IOB和HR IOB兩類,HP IOB/HR IOB內又可分為單端IOB和雙端IOB,HP IOB的引腳結構圖如下
??????????單端的HR IOB結構圖,相比HP IOB,少了一個DCITERMDISABLE輸入,因為DCI是HP bank所具有的功能。
??????????對于雙端的HP IOB,會多一個差分輸入DIFFI_IN,也即會使用到兩個IOB,雙端的HR IOB類似。
2.1.2 ILOGIC/OLOGIC
??????????以ILOGIC為例,在HP?I/O bank中的為ILOGICE2,在HR I/O bank中的為ILOGICE3,區別是ILOGICE3多了一個零保持延時單元ZHOLD, ILOGICE2的結構圖如下
ILOGICE3的結構圖如下
??????????lLOGIC支持邊沿觸發的D觸發器,IDDR模式,電平觸發的鎖存器以及異步/組合操作
2.2 ZHOLD
?????????ZHOLD延遲會自動與內部延遲相匹配時鐘分布延遲,當使用時,確保pad到pad的保持時間為零。ILOGIC在輸入端支持可選的靜態無補償零保持(ZHOLD)延遲線,以補償時鐘插入延遲。ZHOLD功能經過優化,可補償時鐘路徑直接來自來自同一bank或相鄰bank的BUFG/BUFGCE。ZHOLD是默認情況下啟用,除非時鐘源是MMCM或PLL,或者IOBDELAY屬性在Xilinx設計約束(XDC)中設置。
2.3 IDDR/ODDR
??????????IDDR(Input Double Data Rate)和ODDR(Output Double Data Rate),IDDR(輸入雙數據速率)主要用于接收數據,它能夠在每個時鐘邊沿捕獲數據,從而實現雙倍數據速率的數據傳輸。當外部數據源的速率高于內部處理速度時,IDDR可以有效地提高數據吞吐率。IDDR的原語如下圖,一路輸入D,兩路輸出Q1,Q2分別在時鐘的上升沿和下降沿。
IDDR #(.DDR_CLK_EDGE("OPPOSITE_EDGE"), // "OPPOSITE_EDGE", "SAME_EDGE" // ? ?or "SAME_EDGE_PIPELINED" .INIT_Q1(1'b0), // Initial value of Q1: 1'b0 or 1'b1.INIT_Q2(1'b0), // Initial value of Q2: 1'b0 or 1'b1.SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC" ) IDDR_inst (.Q1(Q1), // 1-bit output for positive edge of clock.Q2(Q2), // 1-bit output for negative edge of clock.C(C), ? // 1-bit clock input.CE(CE), // 1-bit clock enable input.D(D), ? // 1-bit DDR data input.R(R), ? // 1-bit reset.S(S) ? ?// 1-bit set);
??????????ODDR(輸出雙數據速率)則用于產生雙倍數據速率的輸出信號。與IDDR類似,ODDR在每個時鐘邊沿都可以驅動數據,提高了輸出數據的速率。ODDR在設計時需要特別關注數據的輸出時序和時鐘的相位關系,以確保在正確的時間點上提供有效的數據。
ODDR原語如下圖所示,與IDDR類似,包括時鐘輸入、數據輸入、使能信號、復位信號和輸出信號等。不同之處在于,ODDR有兩個數據輸入端口D1和D2,分別對應于時鐘的正邊沿和負邊沿。
? 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(C), ? // 1-bit clock input.CE(CE), // 1-bit clock enable input.D1(D1), // 1-bit data input (positive edge).D2(D2), // 1-bit data input (negative edge).R(R), ? // 1-bit reset.S(S) ? ?// 1-bit set);
??????????ODDR原語同樣有多種工作模式,其中最常見的是“OPPOSITE_EDGE”模式。在此模式下,兩個數據輸入端口D1和D2的數據會被合成到一個時鐘周期內,分別在時鐘的正邊沿和負邊沿輸出。
2.4 IDELAY
??????????以IDELAY為例,每個I/O塊都包含一個名為IDELAYE2的可編程延遲單元。IDELAY可以連接到ILOGICE2/ISERDES2或ILOGICE3/ISERDESE2塊。IDELAYE2是一個31抽頭、環繞式具有校準的抽頭分辨率的延遲單元。它可以應用于組合輸入路徑、寄存輸入路徑或兩者同時使用。它也可以直接從FPGA邏輯中獲取。IDELAY可以在單個輸入引腳的基礎上延遲輸入信號,抽頭延遲精度通過使用IDELAYCTRL參考時鐘進行控制,IDELAYE2的端口如下圖
2.5 ISERDES/OSERDES
??????????FPGA中的ISERESE2是一個專用的串行到并行轉換器,具有特定的時鐘和邏輯功能,用于實現高速源同步。在接收到來自外部的高速串行數據(如ADC輸入、高速串行通信接口),將其解串為FPGA內部可處理的并行數據,ISERDES的端口圖如下
??????????OSERDES作用相反,實現并行轉串行輸出,用于驅動高速接口(如LVDS、HDMI、DDR存儲器接口等),將FPGA內部的并行數據轉換為串行數據流輸出。OSERDES的端口圖如下
2.6?IO Logic Resource連接
??????????當同時存在IDELAY和ILOGICE3,ISERDES,OSERDES等單元,位于HR Bank時,連接關系如下圖
當位于HP Bank時,連接關系如下圖
2.7 Device示意圖
??????????在Device圖中,每一對IOB對應的LOGIC由三個部分組成,ILOGICE3,IDELAYE2,
OLOGICE3。ILOGICE3如下圖,可以放置ZHOLD_DELAY以及IDDR以及觸發器。
IDELAYE2單元如下圖所示,放置DELAY模塊
OLOGICE3模塊如下圖,可以放置ODDR、OSERDES模塊
三、工程示例
3.1 工程代碼
以ODDR/IDDR/OSERDES為例
module IOB_resource(D1,D2,CE,C,R,S,RST,T,D3,D4,D5,D6,D7,D8,CLK,CLKDIV,O,IO1,IO2,out1,out2 );
input D1,D2,CE,C,R,S,RST,T;
input D3,D4,D5,D6,D7,D8,CLK,CLKDIV;
output O;
inout IO1,IO2;
output out1,out2;wire n_oddr,n_iobuf;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(n_oddr), ? // 1-bit DDR output.C(C), ? // 1-bit clock input.CE(CE), // 1-bit clock enable input.D1(D1), // 1-bit data input (positive edge).D2(D2), // 1-bit data input (negative edge).R(), ? // 1-bit reset.S(S) ? ?// 1-bit set);IOBUF #(.DRIVE(12), // Specify the output drive strength.IBUF_LOW_PWR("TRUE"), ?// Low Power - "TRUE", High Performance = "FALSE" .IOSTANDARD("DEFAULT"), // Specify the I/O standard.SLEW("SLOW") // Specify the output slew rate) IOBUF_inst (.O(n_iobuf), ? ? // Buffer output.IO(IO1), ? // Buffer inout port (connect directly to top-level port).I(n_oddr), ? ? // Buffer input.T(T) ? ? ?// 3-state enable input, high=input, low=output);IDDR #(.DDR_CLK_EDGE("OPPOSITE_EDGE"), // "OPPOSITE_EDGE", "SAME_EDGE" // ? ?or "SAME_EDGE_PIPELINED" .INIT_Q1(1'b0), // Initial value of Q1: 1'b0 or 1'b1.INIT_Q2(1'b0), // Initial value of Q2: 1'b0 or 1'b1.SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC" ) IDDR_inst (.Q1(out1), // 1-bit output for positive edge of clock.Q2(out2), // 1-bit output for negative edge of clock.C(C), ? // 1-bit clock input.CE(CE), // 1-bit clock enable input.D(n_iobuf), ? // 1-bit DDR data input.R(R), ? // 1-bit reset.S(S) ? ?// 1-bit set);OSERDESE2 #(.DATA_RATE_OQ("DDR"), ? // DDR, SDR.DATA_RATE_TQ("DDR"), ? // DDR, BUF, SDR.DATA_WIDTH(4), ? ? ? ? // Parallel data width (2-8,10,14).INIT_OQ(1'b0), ? ? ? ? // Initial value of OQ output (1'b0,1'b1).INIT_TQ(1'b0), ? ? ? ? // Initial value of TQ output (1'b0,1'b1).SERDES_MODE("MASTER"), // MASTER, SLAVE.SRVAL_OQ(1'b0), ? ? ? ?// OQ output value when SR is used (1'b0,1'b1).SRVAL_TQ(1'b0), ? ? ? ?// TQ output value when SR is used (1'b0,1'b1).TBYTE_CTL("FALSE"), ? ?// Enable tristate byte operation (FALSE, TRUE).TBYTE_SRC("FALSE"), ? ?// Tristate byte source (FALSE, TRUE).TRISTATE_WIDTH(4) ? ? ?// 3-state converter width (1,4))OSERDESE2_inst (.TQ(n_tq), ? ? ? ? ? ? ? // 1-bi.OQ(n_oserdes), ? ? ? ? ? ? ? // 1-bit output: Data path output.CLK(CLK), ? ? ? ? ? ? // 1-bit input: High speed clock.CLKDIV(CLKDIV), ? ? ? // 1-bit input: Divided clock// D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each).D1(D1),.D2(D2),.D3(D3),.D4(D4),.D5(D5),.D6(D6),.D7(D7),.D8(D8),.OCE(CE), ? ? ? ? ? ? // 1-bit input: Output data clock enable.RST(RST), ? ? ? ? ? ? // 1-bit input: Reset.TCE(CE) ? ? ? ? ? ? ?// 1-bit input: 3-state clock enable);IOBUF #(.DRIVE(12), // Specify the output drive strength.IBUF_LOW_PWR("TRUE"), ?// Low Power - "TRUE", High Performance = "FALSE" .IOSTANDARD("DEFAULT"), // Specify the I/O standard.SLEW("SLOW") // Specify the output slew rate) IOBUF_inst2 (.O(O), ? ? // Buffer output.IO(IO2), ? // Buffer inout port (connect directly to top-level port).I(n_oserdes), ? ? // Buffer input.T(n_tq) ? ? ?// 3-state enable input, high=input, low=output);
endmodule
3.2 Device結果
IDDR_inst布局在ILOGICE2上
ODDR_inst單元布局在OLOGICE2上
OSERDESE2_inst布局位置如下,和ODDR占用相同的Device資源