以太网实验1.mdio接口读写实验

以太网常见硬件组成:

fpga首先发送数据到经过udp层、ip层以及mac层的封装
主要有MAC控制器、PHY芯片、网络变压器和RJ45接头组成,有的系统会有DMA控制。一般的系统中CPU和MAC以及DMA控制器都是集成在一块芯片上的,为了节省空间简化设计,很多时候网口的变压器和RJ45的接头集成在一起。
MAC 及 PHY 工作在 OSI 七层模型的数据链路层和物理层。
mii接口(Media Independent Interface):
MII 接口提供了 MAC 与 PHY 之间、PHY 与 STA(Station Management)之间的互联技术。
MII 接口主要包括四个部分。一是从 MAC 层到 PHY 层的发送数据接口,二是从 PHY 层到 MAC 层的接收数据接口,三是从PHY 层到 MAC 层的状态指示信号,四是 MAC 层和 PHY 层之间传送控制和状态信息的 MDIO 接口。

mdio接口

MDIO为双向信号,用来在MAC和PHY芯片之间的传递控制和状态信息。写寄存器MAC驱动,读寄存器时PHY驱动。
数据传输时先传高位(MSB),后传低位(LSB)。输出采用三态电路设计,MDIO需要接1.5K~10K的上拉电阻。通过MDIO线上是否有上拉电阻,来检测MDIO接口是否连接到PHY芯片上。
MDIO前后有两种协议, 包括Clause22 以及之后的Clause45, Clause 45 兼容Clause 22。
在这里插入图片描述
MDIO: 是 PHY 和 STA 之间的双向信号。 它用于在 PHY 和 STA 之间传输控制信息和状态。 控制信息由 STA 同步地针对 MDC 驱动并且由 PHY 同步地采样。 状态信息由 PHY 针对 MDC 同步驱动并由 STA 同步采样。
MDC: 由站管理实体向 PHY 提供,作为在 MDIO 信号上传送信息的定时参考。 MDC 是一种非周期性的信号,没有最高或最低时间。 无论 TX_CLK 和 RX_CLK 的标称周期如何,MDC 的最小高低时间应为 160 ns,MDC 的最小周期为 400 ns。

MDIO-Clause22帧格式:
依次为空闲标志、前导标志、开始标志、操作码、PHY地址、寄存器地址,翻转标志位和数据。
空闲标志(idle):无MDIO帧发送时,MDIO接口输出高阻(外部有上拉电阻,总线上看到的是高电平)。

前导标志(PRE):每帧发送前,MAC通过MDIO连续发送32个MDC周期的高电平1,同时通过MDC输出32个时钟周期。前导的作用是为PHY建立同步提供时间。如果STA能够确定PHY可以接收管理帧,可以压缩前导的发送。

开启标志(st):长度2Bits,必须为01,标志该数据帧开始。

操作码(op):长度2Bits,10标志为读操作,01标志为写操作。

PHY地址(phyad):长度5Bits,表示所访问的PHY地址,一个MDIO总线最大支持32个PHY。

寄存器地址(regad):长度5Bits,表示所访问的寄存器的地址,共计32个寄存器。IEEE802.3协议中对前16个寄存器进行了定义,其中比较常用的如下表。其余为PHY芯片自定寄存器。

翻转标志位(ta):长度2Bits,固定为10。该标志位为PHY芯片地址传输和数据传输处理预留处理时间,设置2bit TA的目的就是为了防止MDIO总线上产生竞争。

数据(data):长度16Bits,操作符为读操作时,该数据为对于地址PHY的特定寄存器的数值;操作符为写时,该数据为对该寄存器写入的数值。

帧格式Clause45:

MDIO Clause45为了访问更多的寄存器在Clause22基础上做了一些扩展,修改如下:

1)ST由01修改为00

2)OP进行了重新定义。00:地址帧 01:写 11:读 10:增量读(Post-read-increment-address)

3)PHYAD域修改名称为PRTAD,端口地址但仍代表PHY地址

4)REGAD修改为DEVAD,Clause45将PHY内部子模块的地址进行细分,这些子模块用DEVAD寻址。子模块内部的寄存器则使用地址帧进行寻址。

mdio时序:
在这里插入图片描述

当MDIO通信出现问题,可依次检查以下方面:

确保MDC工作在合适的频率,MDC以及MDIO有上拉.
PHYAD(PRTAD)没有搞错。
MMD 没有处于复位状态。
适当调整MDC的相位。
有些MMD要求帧与帧之间一定要用高阻态分隔

以太网芯片YT8511支持两种复位方式,一种是硬件复位,另外一种是软件复位。硬件复位时通过ETH_RST_N引脚实现对PHY芯片的复位,当ETH_RST_N引脚持续10ms的低电平时,即可实现对PHY芯片的复位。软件复位通过向寄存器地址0x00的Bit[15]写入1进行复位,并且在完成复位后,该位会自动清零。YT8511共有22位寄存器,有些寄存器是仅可读的,有些寄存器是仅可写的,还有些寄存器是可读可写的,当然在程序设计中我们不需要把这些寄存器全部都用上,一般来说寄存器0x00、0x01、0x1F是3个最常用的寄存器,即基本控制寄存器、基本状态寄存器、PHY控制寄存器。

对基本控制寄存器有个软复位操作,即MAC控制器可以通过MDIO协议向PHY发送软复位请求,在大多数情况下软复位一次后,即可读取到正确的自协商结果。

对基本状态寄存器,用户通过MDIO协议从PHY中读取该寄存器的值,即可从16位的寄存器值中判断目前自协商状态,注意到寄存器的第5位为1时,代表自协商完成,为0时代表自协商未完成;寄存器的第5位为1时,代表网线的物理层连接成功,为0时代表连接失败。

对PHY控制寄存器,通过MDIO协议从PHY中读取该寄存器的值,即可从16位的寄存器值中判断自协商后连接速度,注意到寄存器的第6位为1时,代表千兆速度;寄存器的第5位为1时,代表百兆速度;而寄存器的第4位为1时,代表十兆速

首先每隔一段时间通过MDIO接口从PHY内部寄存器中读取基本状态寄存器(BMSR)和特定状态寄存器(PHYSR)的值,从而获取到自协商完成状态、连接状态和连接速度,将网口的连接速度通过LED灯进行指示;当FPGA检测到TPAD触摸按键按下时,开始通过MDIO接口对PHY进行软复位,在软复位完成后,PHY会重新开始自协商,此时LED灯会定时获取当前网口的连接状态以及连接速度。
mdio驱动模块代码:

module mdio_driver
  (input clk,input rstn,
   input en,input wl_rh,input[4:0]addr,
   input [15:0]wr_data,
   output reg rd_ack,op_done,dri_clk,eth_mdc,
   output reg[15:0]rd_data,inout eth_mdio);
  parameter  PHY_ADDR = 5'b00001,//PHY地址
             CLK_DIV  = 6'd10 ;   //分频系数
  localparam st_idle    = 6'b00_0001,  //空闲状态
             st_pre     = 6'b00_0010,  //发送PRE(前导码)
             st_start   = 6'b00_0100,  //开始状态,发送ST(开始)+OP(操作码)
             st_addr    = 6'b00_1000,  //写地址,发送PHY地址+寄存器地址
             st_wr_data = 6'b01_0000,  //TA+写数据
             st_rd_data = 6'b10_0000;  //TA+读数据
  reg[5:0]cstate,nstate,clk_cnt;
  reg[6:0]cnt;
  reg[15:0]wr_data_d0,rd_data_d0;
  reg[1:0]op_code;
  reg mdio_dir,mdio_out;
  reg[4:0]addr_d0;
  wire[5:0]clk_divide;
  reg done_flag;
  wire mdio_in;
  assign mdio_in=eth_mdio,
         eth_mdio=mdio_dir?mdio_out:1'bz,
         clk_divide = CLK_DIV >> 2;

  always @(posedge clk or negedge rstn)
  begin
    if(!rstn)
    begin
      dri_clk='d0;
      clk_cnt<='d0;
    end
    else if(clk_cnt==clk_divide-'d1)
    begin
      clk_cnt<='d0;
      dri_clk<=~dri_clk;
    end
    else
      clk_cnt<=clk_cnt+'d1;
  end
  always @(posedge dri_clk or negedge rstn)
  begin
    if(!rstn)
      eth_mdc<='d1;
    else if(cnt[0]=='d0)
      eth_mdc<='d1;
    else
      eth_mdc<='d0;
  end
  always @(posedge dri_clk or negedge rstn)
  begin
    if(!rstn)
      cstate<=st_idle;
    else
      cstate<=nstate;
  end
  always @(*)
  begin
   
    case(cstate)
      st_idle:
        if(en)
          nstate=st_pre;
        else
          nstate=st_idle;
      st_pre:
        if(do
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值