原语是 Xilinx 器件底层硬件中的功能模块,它使用专用的资源来实现一系列的功能。相比于 IP 核,原语的调用方法更简单,但是一般只用于实现一些简单的功能。 本文主要讲解 BUFG、 BUFIO、 IDDR、 ODDR、IDELAYE2 和 IDELAYCTRL。
一、BUFG
BUFG: 全局缓冲, BUFG 的输出到达 FPGA 内部的 IOB、 CLB、块 RAM 的时钟延迟和抖动最小。 BUFG原语模板如下:
1 BUFG BUFG_inst ( 2 .O(O), // 1-bit output: Clock output 3 .I(I) // 1-bit input: Clock input 4 );
除了 BUFG 外,常用的还有 BUFR, BUFR 是 regional 时钟网络,它的驱动范围只能局限在一个 clock region 的逻辑。 BUFR 相比 BUFG 的最大优势是偏斜和功耗都比较小。
二、BUFIO
BUFIO: BUFIO 是 IO 时钟网络, 其独立于全局时钟资源,适合采集源同步数据。 它只能驱动 IO Block里面的逻辑,不能驱动 CLB 里面的 LUT, REG 等逻辑。 BUFIO 原语模板如下:
1 BUFIO BUFIO_inst ( 2 .O(O), // 1-bit output: Clock output (connect to I/O clock loads). 3 .I(I) // 1-bit input: Clock input (connect to an IBUF or BUFMR). 4 );
BUFIO 在采集源同步 IO 数据时,提供非常小的延时,因此非常适合采集比如 RGMII 接收侧的数据,但是由于其不能驱动 FPGA 的内部逻辑,因此需要 BUFIO 和 BUFG 配合使用,以达到最佳性能。如ETH_RXC的时钟经过 BUFIO,用来采集端口数据; ETH_RXC 经过 BUFG,用来作为除端口采集外的其他模块的操作时钟。
三、IDDR
IDDR: 在7系列设备的ILOGIC block中有专属的registers来实现input double-data-rate(IDDR) registers,将输入的上下边沿 DDR 信号,转换成两位单边沿 SDR 信号。 IDDR 的原语结构图如下图所示:
C:输入的同步时钟;
D:输入的 1 位 DDR 数据;
Q1 和 Q2:分别是“C”时钟上升沿和下降沿同步输出的 SDR 数据。
CE:时钟使能信号;
S/R:置位/复位信号,这两个信号不能同时拉高。
IDDR 原语模板如下:
1 IDDR #( 2 .DDR_CLK_EDGE("OPPOSITE_EDGE"), // "OPPOSITE_EDGE", "SAME_EDGE" 3 // or "SAME_EDGE_PIPELINED" 4 .INIT_Q1(1'b0), // Initial value of Q1: 1'b0 or 1'b1 5 .INIT_Q2(1'b0), // Initial value of Q2: 1'b0 or 1'b1 6 .SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC" 7 ) IDDR_inst ( 8 .Q1(Q1), // 1-bit output for positive edge of clock 9 .Q2(Q2), // 1-bit output for negative edge of clock 10 .C(C), // 1-bit clock input 11 .CE(CE), // 1-bit clock enable input 12 .D(D), // 1-bit DDR data input 13 .R(R), // 1-bit reset 14 .S(S) // 1-bit set 15 );
DDR_CLK_EDGE 参数为 IDDR 的三种采集模式,分别为“OPPOSITE_EDGE”、“SAME_EDGE”和“SAME_EDGE_PIPELINED”模式。OPPOSITE_EDGE 模式的时序图如下图所示:
OPPOSITE_EDGE 模式下, 在时钟的上升沿输出的 Q1, 时钟的下降沿输出 Q2。
SAME_EDGE 模式的时序图如下图所示:
图 27.1.17 IDDR“SAME_EDGE”模式时序图
SAME_EDGE 模式下,在时钟的上升沿输出 Q1 和 Q2,但 Q1 和 Q2 不在同一个 cycle 输出。
SAME_EDGE_PIPELINED 模式的时序图如下图所示:
SAME_EDGE_PIPELINED 模式下,在时钟的上升沿输出 Q1 和 Q2, Q1 和 Q2 虽然在同一个 cycle 输出,但整体延时了一个时钟周期。在使用 IDDR 时,一般采用此种模式。
四、ODDR
ODDR: 通过 ODDR 把两路单端的数据合并到一路上输出,上下沿同时输出数据,上升沿输出 a 路,下降沿输出 b 路;如果两路输入信号一路固定为 1, 另外一路固定为 0,那么输出的信号实际上是时钟信号。
ODDR 的原语结构图如下图所示:
C:输入的同步时钟;
Q:输出的 1 位 DDR 数据;
D1 和 D2:分别是“C”时钟上升沿和下降沿同步输入的 SDR 数据。
CE:时钟使能信号;
S/R:置位/复位信号,这两个信号不能同时拉高。
ODDR 原语模板如下:
1 ODDR #( 2 .DDR_CLK_EDGE("OPPOSITE_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE" 3 .INIT(1'b0), // Initial value of Q: 1'b0 or 1'b1 4 .SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC" 5 ) ODDR_inst ( 6 .Q(Q), // 1-bit DDR output 7 .C(C), // 1-bit clock input 8 .CE(CE), // 1-bit clock enable input 9 .D1(D1), // 1-bit data input (positive edge) 10 .D2(D2), // 1-bit data input (negative edge) 11 .R(R), // 1-bit reset 12 .S(S) // 1-bit set 13 );
DDR_CLK_EDGE 参数为 ODDR 的两种输出模式,分别为“OPPOSITE_EDGE”和“SAME_EDGE”模式。
OPPOSITE_EDGE 模式的时序图如下图所示:
此种模式下, 在 FPGA 内部需要两个反相时钟来同步 D1 和 D2, 此种模式使用较少。
SAME_EDGE 模式的时序图如下图所示:
此种模式下,数据可以在相同的时钟边沿输出到 Q,一般采用此种模式。
五、IDELAYE2
IDELAYE2: IO 延时原语,用于在信号通过引脚进入芯片内部之前,进行延时调节,一般高速端口信号由于走线延时等原因,需要通过 IDELAYE2 原语对数据做微调。 IDELAYE2 原语模板如下:
1 IDELAYE2 #( 2 .CINVCTRL_SEL("FALSE"), // Enable dynamic clock inversion (FALSE, TRUE) 3 .DELAY_SRC("IDATAIN"), // Delay input (IDATAIN, DATAIN) 4 .HIGH_PERFORMANCE_MODE("FALSE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE") 5 .IDELAY_TYPE("FIXED"), // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE 6 .IDELAY_VALUE(0), // Input delay tap setting (0-31) 7 .PIPE_SEL("FALSE"), // Select pipelined mode, FALSE, TRUE 8 .REFCLK_FREQUENCY(200.0), // IDELAYCTRL clock input frequency in MHz 9 .SIGNAL_PATTERN("DATA") // DATA, CLOCK input signal 10 ) 11 IDELAYE2_inst ( 12 .CNTVALUEOUT(CNTVALUEOUT), // 5-bit output: Counter value output 13 .DATAOUT(DATAOUT), // 1-bit output: Delayed data output 14 .C(C), // 1-bit input: Clock input 15 .CE(CE), // 1-bit input: Active high enable increment/decrement input 16 .CINVCTRL(CINVCTRL), // 1-bit input: Dynamic clock inversion input 17 .CNTVALUEIN(CNTVALUEIN), // 5-bit input: Counter value input 18 .DATAIN(DATAIN), // 1-bit input: Internal delay data input 19 .IDATAIN(IDATAIN), // 1-bit input: Data input from the I/O 20 .INC(INC), // 1-bit input: Increment / Decrement tap delay input 21 .LD(LD), // 1-bit input: Load IDELAY_VALUE input 22 .LDPIPEEN(LDPIPEEN), // 1-bit input: Enable PIPELINE register to load data input 23 .REGRST(REGRST) // 1-bit input: Active-high reset tap-delay input 24 );
IDATAIN 为延时前的输入信号, DATAOUT 为延时后的输出信号。
REFCLK_FREQUENCY 参数为 IDELAYCTRL 原语的参考时钟频率,一般为 200Mhz;IDELAY_VALUE参数用来设置延时的 tap 数,范围为 1~31,每个 tap 数的延时时间和参考时钟频率有关。
和 IDELAYE2 对应的还有 ODELAYE2,由于 A7 系列没有 ODELAYE2 原语, 故此处不做讨论。
六、IDELAYCTRL
IDELAYCTRL: IDELAYCTRL 和 IDELAYE2 一般同时使用, IDELAYCTRL 对 IDELAYE2 延时进行校准。
IDELAYCTRL原语如下:
1 (* IODELAY_GROUP = <iodelay_group_name> *) 2 IDELAYCTRL IDELAYCTRL_inst ( 3 .RDY(RDY), // 1-bit output: Ready output 4 .REFCLK(REFCLK), // 1-bit input: Reference clock input 5 .RST(RST) // 1-bit input: Active high reset input 6 );
IODELAY_GROUP 为延时 IO 分组,一般数据接口位于多个 BANK 时,才需要分组。
IDELAYCTRL 通过参考时钟 REFCLK 来校准 IDELAY2 每个 tap 的延时值,可用的 REFCLK 频率为190Mhz~210Mhz 或者 290Mhz~310Mhz。时钟频率越高对应的 tap 延时平均值越小,即延时调节精度越高。
当参考时钟为 200Mhz 时,一个 tap 为 78ps。
七、参考资料
1、1_领航者ZYNQ之FPGA开发指南_V1.3,以太网 ARP 测试实验