通过MDIO(输入输出数据引脚,可以读取,也可以写入,需要三态门控制)和MDC(时钟)两个引脚对PHY芯片进行配置信息,读取信息(包括读取速度,连接状态等)。在用以太网时,PHY芯片首先要进行自协商,确定对方接口速度(千兆/百兆,向下协商自适应)

PHY addres PHY ADDRESS_笔记

1. MDIO协议时序(上图下面部分)

协议格式如下:

PHY addres PHY ADDRESS_笔记_02

1.Pre:前导码,32bit 全是1,用来同步通信                                                                 32bit

2.Start:开始字段,01表示开始通信                                                                               2bit

3.Read OP(operation):用来标识都还是写,读:10;写:01                                       2bit

4.PHY Address:PHY地址(用来标识链接哪一个PHY芯片),查看原理图                  5bit

5.Reg Address:寄存器地址(包括状态寄存器等多种类型,RO:只读;RW:可读可写) 5bit

6.Turn Around:转变,Z0,高阻态低电平,双向数据线,需要Z来缓冲。MAC代表主机,在发送完寄存器地址后,想要读取对方的PHY芯片,此时主机方的数据线要拉成高阻态(挂一个上拉电阻),这样对对方PHY芯片没有影响,PHY芯片从高阻态拉低以后就可以传输数据。因为就一根数据线,这两个bit相当于起到缓冲作用。                                                                                   2bit

PHY addres PHY ADDRESS_笔记_03

7.Reg Data:数据,写入数据或读出数据。                                                                   16bit

8.idle:空闲                                                                                                                     1bit

一共65bit

协议时序如下:

PHY addres PHY ADDRESS_笔记_04

需要操作的寄存器:

1.读出Link状态:BMSR(base mode status regester,状态寄存器):0x01,协议格式中Reg_Data第三个bit代表连接状态

PHY addres PHY ADDRESS_udp_05

2.读出自协商的结果:BMCR(base mode control regester,控制寄存器):0x00(16bit),协议格式中Reg_Data的第6和13位代表速度

PHY addres PHY ADDRESS_PHY addres_06

PHY addres PHY ADDRESS_学习_07

 更正:真值表中10状态代表1000Mbps.


 代码架构

PHY addres PHY ADDRESS_udp_08

两个部分:MDIO驱动模块:产生数据,并以串行方式发送出去;MDIO数据控制模块;两个模块间会有数据交互:

控制模块向驱动模块的信号有:1.Phy_addr 2.Reg_addr 3.WriteH_ReadL(读写状态) 4.写操作的话要有Reg_write_data 

5.操作有效信号Operation_valid

驱动模块向控制模块的信号有:1.读操作的话有Reg_read_data 2.操作准备信号Operation_ready(和上面的5作为握手信号)

将两个模块封装,下面介绍封装好后大模块信号:

i_clk:输入时钟信号

i_rst:输入复位信号

o_phy_link:反馈网卡链接状态信号

o_phy_speed:网卡速度

o_valid:指示当前link和speed两个状态是有效的(可有可无)

Phy_mdio:输出PHY芯片的数据

Phy_mdc:输出PHY芯片的时钟

输入参数信号:

CLK_DIV_NUMBER:输入时钟分频值,在FPGA中,PLL最小可以分频出1Mhz时钟,但MDIO总线速率一般在几十K左右,因此要对1M时钟进一步分频

OPERATION_NUMBER:操作周期,读取PHY芯片的时间间隔

另外要增加一个模块:

PHY addres PHY ADDRESS_学习_09

CLK_180_Shift模块: 因为在FPGA中,时钟上升沿和数据改变是同沿的,不满足PHY芯片的时序关系,因此要在内部i_clk时钟有一个180°的反相,输出phy_MDC;而i_clk要连接MDIO驱动模块Mdio_clk,保证相位不变。因此phy_MDC和Mdio_clk相位相差180°,保证PHY芯片时钟上升沿时刻,数据在中间稳定状态,不会出现亚稳态。

PHY addres PHY ADDRESS_硬件架构_10


代码部分

1.Phy_Init_module: 顶层模块,调用Phy_drive,可以包含很多PHY芯片进行配置

2.Phy_drive:            mdio控制模块,对一个以太网PHY芯片进行配置,调用Mdio_Drive

3.Mdio_Drive:          mdio驱动模块,产生MDIO时序

设计方法:从最底层开始设计


debug心得

PHY addres PHY ADDRESS_硬件架构_11

这里是自保持,应该是寄存器本身信号,不要粗心。

PHY addres PHY ADDRESS_PHY addres_12

 Phy_drive的握手信号这里,应该是寄存器的有效保持(作为mdio_drive的输入信号r_operation_act,表明phy_drive读有效,不要写成mdio_drive的读有效信号w_reg_read_vaild);和写准备好(是mdio_drive的输出信号),谨记,要搞清楚有效信号。

PHY addres PHY ADDRESS_学习_13

PHY芯片的时钟与mdio时钟差 180°,不要忘记。

PHY addres PHY ADDRESS_PHY addres_14

 延迟一拍的一种写法,可以学习一下。

以及三态门控制信号,不要忘记一次操作结束后的归0条件,读的话,到第46位就结束,写的话到65位结束。

PHY addres PHY ADDRESS_笔记_15

三态门的一种写法,控制信号为1时,正常输出,控制信号为0时,输出高组态。

PHY addres PHY ADDRESS_笔记_16

三态门的第二种写法,使用原语 

PHY addres PHY ADDRESS_PHY addres_17

经典三段式状态机写法:

先对current和next进行时序打拍,然后组合逻辑对current进行状态分析,然后对每个状态涉及到的信号进行设计。

PHY addres PHY ADDRESS_udp_18

每个状态单独计数的一种计数器写法,当current与next状态不同,即跳变的时候,计数器清零,否则自加一。

PHY addres PHY ADDRESS_udp_19

PHY addres PHY ADDRESS_udp_20

例化模块的一类输入信号,在写时序逻辑的时候,可以一块进行编写。其他的一般单独写控制信号。

PHY addres PHY ADDRESS_学习_21

PHY addres PHY ADDRESS_学习_22

 

握手成功后,对寄存器进行初始化,也就是按照协议格式填写65bit,操作运行时,左移位寄存器,最高位输出给1位output寄存器。

PHY addres PHY ADDRESS_udp_23

读取数据也是左移位寄存器,与写入类似。

PHY addres PHY ADDRESS_udp_24

模块的输出信号要有与之对应的寄存器连接,或者在定义输出信号的时候,就定义为reg型,如:output reg o_reg_read_vaild。

每个寄存器定义以后,要记住后面要对该寄存器进行操作。