当前位置:首页 > 新闻资讯 > FPGA之家动态 >

FPGA设计千兆以太网MAC(1)——通过MDIO接口配置与检测PHY芯片

时间:2024-07-28      来源:网络搜集 关于我们 0

关注、星标公众,直达精彩内容

来源:https://www.cnblogs.com/moluoqishi/p/9118283.html

一、前言 

  本文设计思想采用明德扬至简设计法。以太网这一高效实用的数据传输方式应用于各个领域,如网络交换设备,高速网络相机等。虽然各FPGA厂商都提供MAC IP核,但大多收费,有时无法破解。不同厂家之间无法移植,而且为了通用性考虑牺牲了效率,因此自己动手写一个以太网MAC是个不错的选择。

  本博文讨论通过MDIO接口管理PHY芯片来验证其正确工作,为在此基础上设计MAC逻辑开个头。PHY芯片采用RTL8211EGVB,选用GMII接口与MAC连接。下面我们来开始第一步,在此之前明确设计目的:检测PHY芯片是否完成自动协商 链路速率是否达到1000M。所以要从datasheet中了解到芯片引脚 寄存器地址 接口时序。

二、设计分析

  管理帧格式如下:

  读写操作时序:

   MDC为MAC驱动时钟信号,MDIO是串行数据总线,需要连接上拉电阻保证idle状态下高电平。其中前导码包含32个比特“1”,PHY地址根据芯片引脚连接而定,此处为01.turn around域是为了防止读操作时数据冲突,在读操作过程中MAC和PHY均在第1比特处进入高阻态,PHY在第2比特处驱动MDIO接口为低电平以占据总线控制权。注意两点:第一如果时钟信号在读写操作后停止,时钟必须保证至少7个时钟周期持续翻转且MDIO高电平从而保证之前的操作完成。故在设计中可以等待一段时间后再拉低时钟使能信号。第二两个操作之间至少一个idle比特。

   正确驱动接口时序需要关注AC characterisics.

           

  很明显MAC驱动总线时,在MDC下降沿更新数据。而PHY驱动总线时,MDC上升沿后更新数据。根据datasheet中的timing参数设定MDC时钟周期是800ns,MAC接收PHY数据时下降沿采样。

  接下来关注要访问的内部寄存器地址,首先读取PHY寄存器数据以检测其工作状态,若发现异常再考虑写入数据。这里读取基本模式状态寄存器0X01的bit5,若为1说明自动协商完成。第二个寄存器是PHY特定状态寄存器0X11中的[15:14]和13,分别是当前速率和全/半双工通信模式。若检测到自动协商完成,且工作在1000M全双工模式下,说明工作正确。

三、硬件架构与状态机设计

  所有准备工作完成,现在开始设计。按照“自顶向下”设计原则,规划好整体结构和模块间接口,再设计内部状态机一步步实现逻辑功能。

   Mdio_ctrl模块负责完成PHY芯片的配置与检测逻辑,Mdio接口模块完成读写操作时序。此处仅通过读操作简单检测PHY状态,暂不进行配置,故两模块工作状态跳转如图所示:

   剩下的工作就是把两个状态机实现出来,非常简单。有需要的朋友可以参考一下,关于芯片的具体参数详见:Realtek RTL8211E(G)-VB(VL)-CG Datasheet 1.8.上代码!

四、代码编写

MDIO控制模块:

MDIO时序接口模块:

顶层封装:

五、功能仿真

之后编写testbench进行行为仿真:

1 `timescale 1 ns/1 ps 2 3 `define BIT_CNT uut.mdio_interface.bit_cnt 4 5 module phy_manage_tb(); 6 7 //时钟和复位 8 reg clk ; 9 reg rst_n; 10 11 //uut的输入信号 12 reg mdio_en; 13 14 //uut的输出信号 15 wire link_up; 16 wire chk_done; 17 wire mdc; 18 wire mdio; 19 wire [16-1:0] back_data1,back_data2; 20 21 //时钟周期,单位为ns,可在此修改时钟周期。 22 parameter CYCLE = 10; 23 24 //复位时间,此时表示复位3个时钟周期的时间。 25 parameter RST_TIME = 2 ; 26 27 defparam uut.mdio_ctrl.MS_CYC = 100; 28 29 //待测试的模块例化 30 phy_manage uut( 31 .clk (clk) , 32 .rst_n (rst_n) , 33 34 .mdio_en (mdio_en) , 35 .link_up (link_up) , 36 .chk_done (chk_done) , 37 38 .mdc (mdc) , 39 .mdio (mdio) 40 ); 41 42 43 //生成本地时钟50M 44 initial begin 45 clk = 1; 46 forever 47 #(CYCLE/2) 48 clk=~clk; 49 end 50 51 //产生复位信号 52 initial begin 53 rst_n = 1; 54 #1; 55 rst_n = 0; 56 #(CYCLE*RST_TIME); 57 rst_n = 1; 58 end 59 60 //输入信号din0赋值方式 61 initial begin 62 #1; 63 //赋初值 64 mdio_en = 0; 65 #(10*CYCLE); 66 mdio_en = 1; 67 #(1*CYCLE); 68 mdio_en = 0; 69 //开始赋值 70 #100_000; 71 $stop; 72 end 73 74 //模拟PHY响应 75 76 //data 77 assign back_data1 = {16b0000_0000_0010_0000}; 78 assign back_data2 = {16b1010_0000_0000_0000}; 79 80 integer i = 0,j = 0; 81 initial begin 82 forever begin 83 wait(uut.mdio_interface.state_c == 1 && `BIT_CNT == 47 ); 84 @(posedge mdc); 85 force mdio = 0; 86 @(posedge mdc); 87 j = j+1; 88 if(j == 1) 89 force mdio = back_data1[16-1-i+1]; 90 else 91 force mdio = back_data2[16-1-i+1]; 92 93 wait(uut.mdio_interface.state_c == 0); 94 @(posedge mdc); 95 release mdio; 96 end 97 end 98 99 initial begin100 forever begin101 @(posedge mdc);102 if(uut.mdio_interface.state_c == 2)begin103 #10;104 i = i+1;105 end106 else 107 i = 0;108 end109 end110 111 112 endmodulephy_manage_tb

  testbench中利用force强迫更新mdio双向端口方式模拟PHY芯片响应。仿真波形上半部分为MDIO控制模块信号,下半部分则是MDIO时序接口模块信号。可见当读取寄存器数值满足PHY工作需求时,link_up信号拉高,证明此时MAC可以传输数据给PHY。

六、板级调试

  完整的设计,板级调试是必不可少的。真正地将接口调通,PHY芯片正确响应才能说明达到设计目的。顶层封装测试工程,内部例化:差分时钟缓冲原语、PLL、PHY管理顶层封装以及VIO ILA调试IP。我们来看下原理图顶层:

测试工程顶层:

 mdio_test

时钟引脚约束文件:

 clk_pin

  有一点相信调试过以太网的人大多都跳过一个坑:没有驱动PHY的复位输入信号。本人也在此处栽过跟头,这里直接连续赋值拉高PHY芯片复位信号。关于板级调试还有个小技巧,根据高亚军老师的书籍得知,将set up debug生成的ILA探针相关约束命令单独放入一个约束文件便于调试IP的管理和修改,debug约束文件就不贴出来了。

  查看debug波形,MDIO时序接口模块在释放MDIO串行总线时,由于存在上拉电阻为高电平,下一个MDC时钟上升沿时刻,PHY拉低MDIO信号响应并得到总线控制权,开始输出数据。

   得到读取的两个寄存器数据,根据数值分析满足:PHY自动协商完成,且工作在全双工1000Mbps速率下。

  最终RJ45接口绿色指示灯常亮,表明自动协商完成,网络连接正确。到此简易的PHY芯片检测管理模块设计完成。

‧  END  推荐阅读:ZYNQ | 开发板推荐ZYNQ | 学习路线ZYNQ | 资料推荐ZYNQ | 开发工具关注微信公众号『ZYNQ』,回复“加群”加入fpga/zynq技术交流群。后台回复“m”,查看更多精彩内容。

 你的每个在看,都是对作者最大的支持~


注明:本内容来源网络,不用于商业使用,禁止转载,如有侵权,请来信到邮箱:429562386ⓐqq.com 或联系本站客服处理,感谢配合!

用户登陆

    未注册用户登录后会自动为您创建账号

提交留言