赞
踩
本文参考XILINX手册UG471
参考xilinx手册UG471
IDDR #( .DDR_CLK_EDGE ("SAME_EDGE_PIPELINED" ), .INIT_Q1 (1'b0 ), .INIT_Q2 (1'b0 ), .SRTYPE ("SYNC" ) ) IDDR_u0 ( .Q1 (w_rec_data[rxd_i] ), // 1-bit output for positive edge of clock .Q2 (w_rec_data[rxd_i +4] ), // 1-bit output for negative edge of clock .C (w_rxc_bufio ), .CE (1 ), .D (w_rxd_idly[rxd_i] ), .R (0 ), .S (0 ) );
在数据的传输过程中,我们经常可以碰见双沿传输数据到FPGA,或者FPGA传输双沿数据给外部芯片,最常见的例子就是DDR芯片。这里说明一下,FPGA内部处理的数据都是单沿数据,那么双沿数据的变换只能发生在FPGA的IOB上面,这里有特定的硬件结构可以实现上面单沿变双沿的方法,也就是使用原语进行一些列的操作。
D:为输入的双倍速率的数据,即D在时钟的上升沿和下降沿都会发生切换,一个时钟周期发送2bit数据,
CE:为时钟使能信号
C:为时钟信号
S,R:为复位和置位信号
Q1,Q2:为单倍速率的输出数据
IDDR主要有三种工作模式,分别是:OPPOSITE_EDGE, SAME_EDGE,SAME_EDGE_PIPELINED ,代码里采用的是第三种方式。
ODDR #(
.DDR_CLK_EDGE ("OPPOSITE_EDGE" ),
.INIT (1'b0 ),
.SRTYPE ("SYNC" )
)
ODDR_u
(
.Q (o_txd[txd_i] ),
.C (w_txc ),
.CE (1 ),
.D1 (w_send_d1[txd_i] ),
.D2 (w_send_d2[txd_i] ),
.R (0 ),
.S (0 )
);
接口与IDDR一致,就是输入输出相反而已,有OPPOSITE_EDGE模式和SAME_EDGE俩种方式,代码里采用OPPOSITE_EDGE模式
IDELAYCTRL其实是个辅助模块,只要咱们使用了IDELAY或者ODELAY,IDELAYCTRL必须被使用,要不然就无法正常工作。因为IDELAY或者ODELAY的延迟精度是由IDELAYCTRL的输入时钟决定的,它会不断矫正IDELAY2和ODELAY2,将误差限制在一定范围,一般为200MHz。
(* IODELAY_GROUP = "rgmii_rx_delay" *)
IDELAYCTRL IDELAYCTRL_inst (
.RDY(), // 1-bit output: Ready output
.REFCLK(idelay_clk), // 1-bit input: Reference clock input
.RST(1'b0) // 1-bit input: Active high reset input
);
IDELAY被称为信号延迟模块,它的作用就是把信号延迟一段时间。对于一些需要对齐的输入信号来说,这至关重要。在7系列FPGA中,它被称为IDELAYE2。IDELAYE2可以将信号延迟0~31节,在这区间任意可调,并且在参考时钟为200M时,每节的延迟精度为78ps(1/(32×2×FREF),FREF为IDELAYCTRL的参考时钟)。
(* IODELAY_GROUP = "rgmii" *) 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 (0 ), // Input delay tap setting (0-31) 0.15625 .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 (), // 5-bit output: Counter value output .DATAOUT (w_rxc_idelay ), // 1-bit output: Delayed data output .C (), // 1-bit input: Clock input .CE (), // 1-bit input: Active high enable increment/decrement input .CINVCTRL (), // 1-bit input: Dynamic clock inversion input .CNTVALUEIN (), // 5-bit input: Counter value input .DATAIN (), // 1-bit input: Internal delay data input .IDATAIN (i_rxc ), // 1-bit input: Data input from the I/O .INC (), // 1-bit input: Increment / Decrement tap delay input .LD (), // 1-bit input: Load IDELAY_VALUE input .LDPIPEEN (), // 1-bit input: Enable PIPELINE register to load data input .REGRST () // 1-bit input: Active-high reset tap-delay input );
VARIABLE:动态调节延时值,由输入管脚值决定,与时钟C同步
VAR_LOAD_PIPE: 与VAR_LOAD模式类似,并CNTVALUEIN值
1、VARIABLE模式时序图
2、VAR_LOAD模式时序图
ODELAY和IDEALY的使用方式差不多,只不过ODELAY是用作输出信号的延迟。另外,HR BANK内没有ODELAY,HP BANK才有,被称为ODELAYE2。使用ODELAYE2时同样需要例化IDELAYCTRL。