zoukankan      html  css  js  c++  java
  • RGMII_PHY测试笔记1 基于开发板MiS603-X25

    RGMII_PHY测试笔记1 基于开发板MiS603-X25

    作者:汤金元

    日期:20150817

    公司:南京米联电子科技有限公司

    博客:http://blog.chinaaet.com/detail/46639

    论坛:www.osrc.cn

    网址:www.milinker.com

    网店:http://osrc.taobao.com

    网络通信对于本人来说一直很神秘,没有搞过10M网络,也没有搞过100M网络,更没有搞过千兆网络,更不要说RGMII了。但是今天本人成功了,实现0到RGMII突破。如果,兄弟你觉得有难度,我告诉你,你也行的,下面就开始见证本人徒步学习RGMII千兆网络部分的苦逼经历。今天主要完成PHY的测试。

    何为RGMII ?

    RGMII(Reduced Gigabit Media Independent Interface)是Reduced GMII(吉比特介质独立接口)。RGMII均采用4位数据接口,工作时钟125MHz,并且在上升沿和下降沿同时传输数据,因此传输速率可达1000Mbps。同时兼容MII所规定的10/100 Mbps工作方式,支持传输速率:10M/100M/1000Mb/s ,其对应clk 信号分别为:2.5MHz/25MHz/125MHz。RGMII数据结构符合IEEE以太网标准,接口定义见IEEE 802.3-2000。

    采用RGMII的目的是降低电路成本,使实现这种接口的器件的引脚数从25个减少到14个。

    RGMII接口定义?

    发送器:

    ◎ GTX_CLK——吉比特TX..信号的时钟信号(125MHz)

    ◎ TXD[3..0]——被发送数据

    ◎ TX_CTL——发送控制

    注:在千兆速率下,向PHY提供GTX_CLK信号,TXD、TXEN、TXER信号与此时钟信号同步。否则,在10/100M速率下,PHY提供 TXCLK时钟信号,其它信号与此信号同步。其工作频率为25MHz(100M网络)或2.5MHz(10M网络)。

    接收器:

    ◎ RX_CLK——接收时钟信号(从收到的数据中提取,因此与GTXCLK无关联)

    ◎ RXD[3..0]——接收数据

    ◎ RX_CTL——接收控制

    ◎ COL——冲突检测(仅用于半双工状态)

    ◎ CRS——载波监听

    管理配置(控制和状态信息):

    ◎ MDC——配置接口时钟

    ◎ MDIO——配置接口I/O

    RGMII接口相对于GMII接口,在TXD和RXD上总共减少8根数据线。

    RGMII通信时序?

    wpsBA4B.tmp

    发送器:

    ◎ TX_CLK

    吉比特TX..信号的时钟信号(125MHz)

    ◎ TXD[3..0]

    发送数据

    TX_CLK高电平输出数据低4位,低电平输出数据高四位。

    ◎ TX_CTL

    —发送控制

    TX_CLK高电平期间为1表示发送使能,TX_CLK低电平期间为1表示发送正确

    接收器:

    ◎ RX_CLK

    吉比特RX..信号的时钟信号(125MHz)

    ◎ RXD[3..0]

    接收数据

    RX_CLK高电平接收数据低4位,低电平接收数据高四位。

    ◎ RX_CTL

    —接收控制

    RX_CLK高电平期间为1表示接收使能,RX_CLK低电平期间为1表示接收正确

    TX_CTL和RX_CTL是数据同步机制,可以理解为同步信号

    RGMII 硬件方案-VSC8601

    VITESSE公司的VSC8601是一颗支持10/100/1000M PHY的RGMII MAC接口芯片,此芯片价格便宜,淘宝价格大概十几元一颗,另外封装是TQFP64 封装,只有64个PIN外围简单,焊接调试方便,功耗低,支持3.3V的IO接口,算是RGMII方案中首选无二的IC了。

    VSC8601应用方案

    wpsBA4C.tmp

    RGMII 硬件接口

    wpsBA5D.tmp

    硬件电路原理图

    wpsBA6D.tmp

    由于时钟速度125MHZ 双边沿采样,对硬件要求很高,PCB必须等长布线

    wpsBA7E.tmp

    好了,具备这些硬件知识就可以设计程序了。

    一下本人把一些设计要点列出来,读者具体看程序

    1、产生至少1MS 复位信号,如果没有产生这个信号,那么PHY芯片不会工作

    //generate PHY reset signal

    reg[22:0]rgmii_rst_cnt=0;

    assign rgmii_rst_n_o=rgmii_rst_cnt[22];

    always @(posedge CLK_50MHZ_i)begin

    if(!rgmii_rst_cnt[22])rgmii_rst_cnt<=rgmii_rst_cnt+1'b1;

    End

    2、为了实现上下沿都进行采样,关于一些原语的基础知识

    ILOGIC2资源

    图ILOGIC2逻辑框图,它可支持以下功能。

    边沿触发D型触发器。

    IDDR(NONE、C0或C1)模式。

    锁存器。

    异步/组合逻辑。

    wpsBA7F.tmp

    (1) 异步/组合逻辑。

    当有下列情况之一时,软件会自动生成组合通路,使输入驱动器与FPGA内部逻辑资源直接连接。

    FPGA的输入数据与内部逻辑直接相连,而没有用寄存器。

    “打包I/O寄存器/锁存器到IOB中”的属性设置为OFF。

    (2) IDDR模式。

    Spartan-6器件的ILOGIC2中有专用寄存器来实现输入双倍数据速率(DDR)寄存器。可以通过例化IDDR2的原语来使用此功能。

    DDR2的属性DDR_ALIGNMENT有3种模式:NONE、C0和C1。

    在NONE模式下,输入DDR时序如图2-40所示。寄存器在C0上升沿将输入数据D寄存到Q0,C1上升沿将下一输入数据D寄存到Q1。

    · · wpsBA8F.tmp

    图2-40 DDR_ALIGNMENT=NONE时输入DDR时序示意图

    在某些情况下,输入数据必须同步到一个时钟域里,通常C0同步。但是在频率比较高的情况下,这种同步相对比较困难,因为有效时间仅为时钟周期的一半(50%占空比的情况下)。Spartan-6器件中的IDDR2包含了专用的逻辑,可以在ILOGIC2内部进行时钟域的同步。

    当DDR_ALIGNMENT为C0(或C1),信号Q0(Q1)在C1(C0)再次寄存,通过内部互联将输入数据同步到同一时钟域。时序图如图2-41所示。

    wpsBA90.tmp

    图2-41 DDR_ALIGNMENT=C0C1 的输入DDR

    IDDR 的原语如图2-42 所示。

    · · wpsBAA1.tmp

    图2-42 IDDR2 的原语

    OLOGIC2 资源

    如图2-43所示,OLOGIC2主要由两部分组成,分别是输出数据路径和三态控制路径。

    这两个部分可以配置成以下模式。

    边沿触发D 型触发器。

    DDR 模式(NONE、C0 或C1 同步方式)。

    电平敏感锁存器。

    异步/组合逻辑。

    wpsBAA2.tmp

    图2-43 OLOGIC2 逻辑模块

    (1) 组合数据输出和三态控制路径。

    当有下列情况之一时,软件会自动生成组合通路,将FPGA 内部数据直接输出到输出驱动器或驱动器的控制端。

    “打包I/O 寄存器/锁存器到IOB 中”的属性设置为OFF。

    (2) ODDR模式。

    Spartan-6器件的OLOGIC2中具有专用寄存器,用来实现DDR输出寄存器。例化ODDR2原语可以使用此功能。当使用OLOGIC2时,会自动使用多路复用器,多路复用器的控制端产生于时钟信号,不需要手动控制。ODDR2 有两个时钟输入,相位差180°。

    ODDR2 支持以下操作模式。

    NONE 模式:允许设计人员在C0 和C1 时钟的上升沿将两个数据通过DDR多路复用器送

    至输出引脚,如图2-44所示。·

    wpsBAB3.tmp

    图2-44 DDR_ALIGNMENT=NONE 下的ODDR2

    C0模式:在时钟C0上升沿时,将两个数据通过DDR多路复用器送至输出引脚。

    C1模式:在时钟C1上升沿时,将两个数据通过DDR多路复用器送至输出引脚。

    ODDR原语如图2-45所示。

    wpsBAB4.tmp· ·

    图2-45 ODDR原语

    原语应用-双边沿采样

    //use IDDR2 sample data with poseadge and negadge

    IDDR2 #(

    .DDR_ALIGNMENT("C0"),

    .INIT_Q0(1'b0),

    .INIT_Q1(1'b0),

    .SRTYPE("SYNC")

    )

    Iddr2_0(

          .Q0(gmii_rxd[4]), // 1-bit output captured with C0 clock

          .Q1(gmii_rxd[0]), // 1-bit output captured with C1 clock

          .C0(rgmii_rxclk_n), // 1-bit clock input

          .C1(rgmii_rxclk_i), // 1-bit clock input

          .CE(1'b1), // 1-bit clock enable input

          .D(rgmii_rxd_i[0]),   // 1-bit ddr data input

          .R(1'b0),   // 1-bit reset input

          .S(1'b0)    // 1-bit set input

       );

    原语应用双边沿输出

    //usb ODDR2 output data with posadge and neadge

    assign rgmii_txdv_o = gmii_txdv;

    ODDR2 #(

    .DDR_ALIGNMENT("C0"), // Sets output alignment to "NONE", "C0" or "C1"

    .INIT(1'b0),    // Sets initial state of the Q output to 1'b0 or 1'b1

    .SRTYPE("ASYNC") // Specifies "SYNC" or "ASYNC" set/reset

    )

    ODDR2_0 (

    .Q(rgmii_txd_o[0]),   // 1-bit DDR output data

    .C0(rgmii_txclk),   // 1-bit clock input

    .C1(rgmii_txclk_n),   // 1-bit clock input

    .CE(1'b1), // 1-bit clock enable input

    .D0(gmii_txd[0]), // 1-bit data input (associated with C0)

    .D1(gmii_txd[4]), // 1-bit data input (associated with C1)

    .R(1'b0),   // 1-bit reset input

    .S(1'b0)    // 1-bit set input

    );

    为了实现数据的发送和接收的对比需要准备2块MIS603开发板

    测试数据发送:

    原理:发送数据从0~255 不停循环

    //计数器循环累加,当gmii_txdv_cnt[8]为0时将数据输出

    reg [8:0]gmii_txdv_cnt;

    assign gmii_txd_ts  = gmii_txdv_cnt[8] ?  7'd0  : gmii_txdv_cnt[7:0];

    //数据有效标志

    assign gmii_txdv_ts = ((~gmii_txdv_cnt[8])||(gmii_txdv_cnt==256)||(gmii_txdv_cnt==257)) ?  1'b1  : 1'b0;

    //循环计数器

    always @(posedge rgmii_txclk_ts)

    if(~rst_n)begin

    gmii_txdv_cnt <= 9'd0;

    end

    else begin

    gmii_txdv_cnt <= gmii_txdv_cnt +1'b1;

    end

    测试数据接收对比:

    原来采用了一个状态机首先识别0x55 识别2个0x55后,后面就是有效数据,如果是从0~255不停累加就代表正确。

    reg [7:0]gmii_rxd_next;

    //比较数据

    assign rxd_error= (rxd_s==2'd2) ? ((gmii_rxd_next==gmii_rxd_ts) ? 1'b0 : 1'b1 ) : 1'b0;

    reg [1:0] rxd_s;

    //下一个数据被比较数据准备

    always @(posedge rgmii_rxclk_ts)begin

    if((~rst_n)||(gmii_rxdv_ts!=2'b11))begin

    gmii_rxd_next<=8'd1;

    rxd_s<=2'd0;

    end

    else if(gmii_rxdv_ts==2'b11)begin

    case(rxd_s)

    0:

    if(gmii_rxd_ts==8'h55)//接收第一个55

    rxd_s <= rxd_s + 1'b1;//0x55

    1:

    if(gmii_rxd_ts==8'h55)//接收第二个55

    rxd_s <= rxd_s + 1'b1;

    else

    rxd_s <= 2'd0;

    2: begin //计算下一个比较数据

    gmii_rxd_next <= gmii_rxd_ts+1'b1;

    if(gmii_rxd_ts==8'd255)

    rxd_s <= 2'd0;

    end

    endcase

    end

    end

    测试结果:

    PHY板对板测试,48小时以上没有任何错误。

    源码下载地址:

    http://pan.baidu.com/s/1pwSnc

    转载:http://blog.chinaaet.com/whilebreak/p/46639

    http://xilinx.eetrend.com/blog/1949

  • 相关阅读:
    基础算法:两数之和
    adb常用命令食用方法
    C语言面试题
    C语言经典笔试题目
    嵌入式01 51单片机实验02 sfr和sbit bit和int char
    C语言 01 volatile关键字
    C++ 01 基础知识点
    嵌入式02 STM32 实验11 NVIC和中断总结
    嵌入式02 STM32 实验10 定时器中断
    嵌入式02 STM32 实验09 独立/窗口看门狗
  • 原文地址:https://www.cnblogs.com/chengqi521/p/9386429.html
Copyright © 2011-2022 走看看