FPGA常用资源之IO概述

发布于:2025-08-11 ⋅ 阅读:(15) ⋅ 点赞:(0)

目录

一、前言

二、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资源


网站公告

今日签到

点亮在社区的每一天
去签到