当前位置:   article > 正文

fpga 原语学习(iddr)

iddr

学习内容:

  • fpga 原语学习(iddr)
  • 对于项目中使用源于代码理解(初学者的疑惑)

一.fpga 原语学习(iddr)

1.iddr相关介绍:

①iddr作用.

一般来讲fpga采样数据是在上升沿时进行,但是也有些器件为了增加传输速率会采用上升沿与下降沿都传输的数据。而直接使用fpga进行双沿采样可能会导致时许很差,无法通信,因此采用iddr来对数据进行处理,让双沿信号经过iddr后变成上升沿可以采样的信号。

②iddr的原理与使用.

在这里插入图片描述
如图所示,D为数据输入,CE为信号的有效位,C为时钟,S,R分别为置位与复位。Q1与Q2为输出信号,及输入的双沿信号被转成两个上升沿可采样的信号。
注意:此处D、Q1与Q2都为1位。
iddr 有 三 种 工 作 模 式 , 三 种 模 式 分 别 为 :
OPPOSITE_EDGE 、 SAME_EDGE 、SAME_EDGE_PIPELINED。

③模式配置图:

在这里插入图片描述

④模式一: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
   );
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

代码补充说明:上述代码中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,文章为了巩固所学知识,如有错误之处求指导,感谢。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/在线问答5/article/detail/739149
推荐阅读
相关标签
  

闽ICP备14008679号