赞
踩
一般来讲fpga采样数据是在上升沿时进行,但是也有些器件为了增加传输速率会采用上升沿与下降沿都传输的数据。而直接使用fpga进行双沿采样可能会导致时许很差,无法通信,因此采用iddr来对数据进行处理,让双沿信号经过iddr后变成上升沿可以采样的信号。
如图所示,D为数据输入,CE为信号的有效位,C为时钟,S,R分别为置位与复位。Q1与Q2为输出信号,及输入的双沿信号被转成两个上升沿可采样的信号。
注意:此处D、Q1与Q2都为1位。
iddr 有 三 种 工 作 模 式 , 三 种 模 式 分 别 为 :
OPPOSITE_EDGE 、 SAME_EDGE 、SAME_EDGE_PIPELINED。
从图中可以看出三种模式的区别在于Q1与Q2的输出时序的不同。模式三中Q1与Q2同时输出,输出位一组双沿信号,此模式为更多人使用。
使用RGMII协议给PHY与FPGA通信时RGMII输出信号为双沿信号,需要写一个模块将双沿信号转成上升沿信号。查看历程代码如下:
下面展示一些 内联代码片
。
generate genvar i; for(i=0;i<4;i=i+1) begin IDDR #( .DDR_CLK_EDGE("SAME_EDGE_PIPELINED"), // "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_rxd_inst ( .Q1(rxd[i]), // 1-bit output for positive edge of clock .Q2(rxd[i+4]), // 1-bit output for negative edge of clock .C(rx_clk_90), // 1-bit clock input .CE(1'b1), // 1-bit clock enable input .D(rx_dat[i]), // 1-bit DDR data input .R(1'b0), // 1-bit reset .S(1'b0) // 1-bit set ); end endgenerate IDDR #( .DDR_CLK_EDGE("SAME_EDGE_PIPELINED"), // "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_rxctrl_inst ( .Q1(rxdv), // 1-bit output for positive edge of clock .Q2(rxerr), // 1-bit output for negative edge of clock .C(rx_clk_90), // 1-bit clock input .CE(1'b1), // 1-bit clock enable input .D(rx_ctrl), // 1-bit DDR data input .R(1'b0), // 1-bit reset .S(1'b0) // 1-bit set );
代码补充说明:上述代码中RGMII上升沿传输4位数据,下降沿传输4位数据。
从代码中可以看出iddr被例化使用了五次(for循环中四次,下边还有一次)。
才开始学的时候很纠结为啥要例化五次,一次不就ok了吗?
后边才发现iddr中D、Q1与Q2都为1位,因此使用时用四个iddr处理PHY传输过来的四位双沿数据信号,再使用一次iddr处理控制信号(DV与ERR信号)。
如图所示,PHY通过RGMII传输的信号处理四位双沿数据之外还有一个双沿有效信号位RX_CTL。上升沿时为DV数据有效信号,下降沿时为ERR信号出错信号。
本人fpga小白,才开始学习fpga,同时也是最近才开始尝试写csdn,文章为了巩固所学知识,如有错误之处求指导,感谢。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。