目录
一、前言
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资源