千兆以太网(二)——MDIO接口协议

这篇具有很好参考价值的文章主要介绍了千兆以太网(二)——MDIO接口协议。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.MDIO协议简介

  MAC和PHY芯片有一个配置接口,即MDIO接口。可以配置PHY芯片的工作模式以及获取PHY芯片的状态信息。PHY芯片内部有一系列寄存器。用户通过配置寄存器来配置PHY芯片的工作模式。
  FPGA通过MDIO接口对PHY芯片的内部寄存器进行配置。通常情况下芯片在默认情况下也可以工作,即配置芯片不是必须的。也可通过外接特殊引脚的方式来配置PHY芯片的工作模式。
mdio接口协议,# 千兆以太网协议,fpga开发

2. MDIO协议时序

  MDIO接口也被称为SMI接口(Serial Management Interface,串行管理接口),包括ETH_MDC(数据管理时钟,最大不超过12.5MHZ)和ETH_MDIO(数据管理输入输出,双向数据线)两条信号线。
  MDIO接口的读写通信协议如下图:
mdio接口协议,# 千兆以太网协议,fpga开发

名称1 作用
Preamble 32位引导码,由MAC端发送32位逻辑1,用于同步PHY芯片
ST(Start of Frame) 两位帧开始信号,用01表示
OP(Operation Code) 两位操作码,读:10 , 写:01
PHYAD 五位PHY地址,用于表示和那个PHY芯片通讯
REGAD(Register Address) 五位寄存器地址,可以表示32位寄存器
TA(Turnaround) 两位转向。在读命令中MDIO由MAC驱动改为PHY驱动。写命令中MAC固定输入01
data 读取PHYAD寄存器中对应的数据或者写入数据。高位在前低位在后
IDLE 空闲状态均为高阻态

转向就是MAC由发送数据变成接收数据
mdio接口协议,# 千兆以太网协议,fpga开发
mdio接口协议,# 千兆以太网协议,fpga开发
mdio接口协议,# 千兆以太网协议,fpga开发文章来源地址https://www.toymoban.com/news/detail-807630.html

3.MDIO程序

`timescale 1ns / 1ps

module mdio_dri(
	input	wire 			clk 		,
	input	wire 			rst_n 		,
	input	wire			op_exec 	, 	//触发开始信号
	input	wire 			op_rh_wl	,	//低电平写,高电平读
	input	wire 	[4:0] 	op_phy_addr , 	//芯片地址
	input	wire 	[4:0] 	op_reg_addr , 	//寄存器地址
	input 	wire 	[15:0] 	op_wr_data 	, 	//写数据
	output	reg 	 		op_done 	, 	//操作完成
	output	reg 	[15:0] 	op_rd_data 	,	//读出的数据
	output 	reg  			op_rd_ack 	, 	//读应答

	output	reg   			eth_mdc 	,
	inout 	wire  			eth_mdio 	
);



localparam 		SYS_CLK 		= 	'd50_000_000 					;
localparam 		DRI_CLK 		= 	'd12_500_000 		 			;
localparam 		DIV_CNT_MAX 	=	(SYS_CLK/DRI_CLK  >> 1)  -  1 	;

localparam 		IDLE 			= 	6'b000_001; 	//初始状态
localparam 		PRE 			= 	6'b000_010; 	//前导码  32位1
localparam 		START 			= 	6'b000_100; 	//发送帧开始加操作码
localparam 		ADDR 			= 	6'b001_000; 	//发送PHY地址加寄存器地址
localparam 		WR 				= 	6'b010_000; 	//发送TA加写入数据
localparam 		RD 				= 	6'b100_000; 	//发送TA加接收数据

localparam		Pre 			= 	32'b1111_1111_1111_1111 ;	//前导码
localparam		ST 				= 	2'b01 					;	//帧开始

wire 			mdio_in 	 ; 	//mdio数据输入
reg 			st_done 	 ; 	//操作完成

reg 	[5:0] 	state 		 ; 	//状态机
reg 			op_rh_wl_r 	 ;
reg 	[5:0]	op_phy_addr_r;
reg 	[5:0]	op_reg_addr_r;
reg 	[15:0]	op_wr_data_r ;
reg 			mdio_out 	 ; 	//mdio数据输出
reg 	[9:0] 	clk_cnt 	 ; 	//时钟计数器
reg 			mdio_dir 	 ; 	//mdio数据方向指示  0输入 1输出
reg 	[1:0] 	op_code 	 ;

/********************ila模块*****************************/
wire 	[255:0] 	probe0;
assign probe0 = {	eth_mdc,
					mdio_out,
					mdio_in,
					mdio_dir,
					state,
					clk_cnt,
					op_code,
					op_rd_data,
					op_rh_wl,
					op_phy_addr,
					op_wr_data,
					st_done,
					op_reg_addr,
					op_rd_ack
				};
ila_0 ila_0_inst (
	.clk(clk), // input wire clk
	.probe0(probe0) // input wire [255:0] probe0
);
/********************************************************/
//双向IO
assign eth_mdio = mdio_dir ? mdio_out : 1'bz;
assign mdio_in  = eth_mdio;


//eth_mdc 	12.5MHZ    1   3时钟变化
always @(posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		eth_mdc 	<=  	'd1;
	end
	else if (state != IDLE && clk_cnt[0] == 1'b0) begin
		eth_mdc 	<= 	~eth_mdc;
	end
end

//寄存器  当传输开始时将数据锁存起来
always @(posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		op_code 		<= 'd0;
		op_phy_addr_r 	<= 'd0;
		op_reg_addr_r 	<= 'd0;
		op_wr_data_r	<= 'd0;
	end
	else if (op_exec == 1'b1) begin
		op_code 		<= {op_rh_wl,~op_rh_wl};//OP_CODE: 2'b01(写)  2'b10(读) 
		op_phy_addr_r 	<= op_phy_addr 	;
		op_reg_addr_r 	<= op_reg_addr;
		op_wr_data_r	<= op_wr_data ;
	end
end

//状态转移
always @(posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		state <= IDLE ;
	end
	else  begin
		case(state)
			IDLE 	: 	begin
				if (op_exec == 1'b1) begin
					state <= PRE ;
				end
			end
			PRE 	: 	begin
				if (st_done == 1'b1) begin
					state <= START ;
				end
			end
			START 	: 	begin
				if (st_done == 1'b1) begin
					state <= ADDR ;
				end
			end
			ADDR 	: 	begin
				if (st_done == 1'b1 && op_code[1] == 1'b0) begin
					state <= WR ;
				end
				else if (st_done == 1'b1 && op_code[1] == 1'b1) begin
					state <= RD ;
				end
			end
			WR 		: 	begin
				if (st_done == 1'b1) begin
					state <= IDLE ;
				end
			end
			RD 		: 	begin
				if (st_done == 1'b1) begin
					state <= IDLE ;
				end
			end
		endcase
	end
end


//状态输出
always @(posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		clk_cnt 	<= 'd0;
		mdio_out 	<= 1'b0;
		mdio_dir 	<= 1'b0;
		op_done 	<= 1'b0;
		st_done 	<= 1'b0;
		op_rd_data 	<= 16'b0;
	end
	else  begin
	clk_cnt  <= clk_cnt + 1'b1;
	op_done  <= 1'b0;
		case(state)
			IDLE 	: 	begin
				clk_cnt 	<= 'd0;
				mdio_dir 	<= 'd0;
				mdio_out 	<= 'd1;
				op_rd_ack 	<= 1'b1;
				op_done 	<= 1'b0;
			end
			PRE 	: 	begin 	//前导码  发送32位1
				mdio_dir <= 1'b1;
				mdio_out <= 1'b1;
				if (clk_cnt == 4 * 32 - 2) begin
					st_done <= 1'b1;
				end
				else if (clk_cnt == 4 * 32 - 1) begin
					st_done <= 1'b0;
					clk_cnt <= 'd0;
				end
			end
			START 	: 	begin 	//帧开始加操作码
				mdio_dir <= 1'b1;
				case(clk_cnt)
					0 	: 	mdio_out 	<= 	1'b0 		;
					4 	: 	mdio_out 	<=  1'b1 		; 	//两位帧开始
					8 	: 	mdio_out 	<= 	op_code[1] 	;
					12 	: 	mdio_out 	<= 	op_code[0] 	;
					14  : 	st_done 	<= 	1'b1 		;
					15 	: 	begin
						st_done 	<= 	1'b0 	;
						clk_cnt 	<= 	'd0 	;
					end
				endcase
			end
			ADDR 	: 	begin
				mdio_dir <= 1'b1;
				case(clk_cnt)
					0 	: 	mdio_out 	<= 	op_phy_addr_r[4] 	;
					4 	: 	mdio_out 	<= 	op_phy_addr_r[3] 	;
					8 	: 	mdio_out 	<= 	op_phy_addr_r[2] 	;
					12 	: 	mdio_out 	<= 	op_phy_addr_r[1] 	;
					16 	: 	mdio_out 	<= 	op_phy_addr_r[0] 	; 	//PHY地址
					20 	: 	mdio_out 	<= 	op_reg_addr_r[4] 	;
					24 	: 	mdio_out 	<= 	op_reg_addr_r[3] 	;
					28 	: 	mdio_out 	<= 	op_reg_addr_r[2] 	;
					32 	: 	mdio_out 	<= 	op_reg_addr_r[1] 	;
					36 	: 	mdio_out 	<= 	op_reg_addr_r[0] 	; 	//寄存器地址
					38 	: 	st_done 	<= 	1'b1 				;
					39  : 	begin
						st_done 	<= 	1'b0;
						clk_cnt 	<= 	 'b0;
					end
				endcase
			end
			WR 		: 	begin
				mdio_dir <= 1'b1;
				case(clk_cnt)
				 	0 	: 	mdio_out 	<= 	1'b1 			 ;
				 	4 	: 	mdio_out 	<= 	1'b0 			 ; 	//写操作 不转向 10
				 	8 	: 	mdio_out 	<= 	op_wr_data_r[15] ;
				 	12 	: 	mdio_out 	<= 	op_wr_data_r[14] ;
				 	16 	: 	mdio_out 	<= 	op_wr_data_r[13] ;
				 	20 	: 	mdio_out 	<= 	op_wr_data_r[12] ;
				 	24 	: 	mdio_out 	<= 	op_wr_data_r[11] ;
				 	28 	: 	mdio_out 	<= 	op_wr_data_r[10] ;
				 	32 	: 	mdio_out 	<= 	op_wr_data_r[9]  ;
				 	36 	: 	mdio_out 	<= 	op_wr_data_r[8]  ;
				 	40 	: 	mdio_out 	<= 	op_wr_data_r[7]  ;
				 	44 	: 	mdio_out 	<= 	op_wr_data_r[6]  ;
				 	48 	: 	mdio_out 	<= 	op_wr_data_r[5]  ;
				 	52 	: 	mdio_out 	<= 	op_wr_data_r[4]  ;
				 	56 	: 	mdio_out 	<= 	op_wr_data_r[3]  ;
				 	60 	: 	mdio_out 	<= 	op_wr_data_r[2]  ;
				 	64 	: 	mdio_out 	<= 	op_wr_data_r[1]  ;
				 	68 	: 	mdio_out 	<= 	op_wr_data_r[0]  ;
				 	70 	: 	st_done 	<= 	1'b1 			;
				 	71 	: 	begin
				 		st_done 	<= 1'b0 ;
				 		clk_cnt 	<= 'd0  ;
				 		mdio_dir 	<= 1'b0 ;
				 		op_done 	<= 1'b1 ;
				 		mdio_out 	<= 1'b1 ;
				 	end
				 endcase
			end
			RD 		: 	begin
				mdio_dir <= 1'b0;
				case(clk_cnt)
					2 	: 	 								; 	//等待转向
					6 	: 	op_rd_ack 		<= 	mdio_in  	; 	//转向完成  应答信号拉低代表应答成功  
					10 	: 	op_rd_data[15] 	<= 	mdio_in 	; 	
					14 	: 	op_rd_data[14] 	<= 	mdio_in 	;
					18 	: 	op_rd_data[13] 	<= 	mdio_in 	;
					22 	: 	op_rd_data[12] 	<= 	mdio_in 	;
					26 	: 	op_rd_data[11] 	<= 	mdio_in 	;
					30 	: 	op_rd_data[10] 	<= 	mdio_in 	;
					34 	: 	op_rd_data[9] 	<= 	mdio_in 	;
					38 	: 	op_rd_data[8] 	<= 	mdio_in 	;
					42 	: 	op_rd_data[7] 	<= 	mdio_in 	;
					46 	: 	op_rd_data[6] 	<= 	mdio_in 	;
					50 	: 	op_rd_data[5] 	<= 	mdio_in 	;
					54 	: 	op_rd_data[4] 	<= 	mdio_in 	;
					58 	: 	op_rd_data[3] 	<= 	mdio_in 	;
					62 	: 	op_rd_data[2] 	<= 	mdio_in 	;
					66 	: 	op_rd_data[1] 	<= 	mdio_in 	;
					70 	: 	op_rd_data[0] 	<= 	mdio_in 	;
					72 	: 	st_done 		<= 	1'b1 		;
					73 	: 	begin
						st_done 	<= 	1'b0 				;
						clk_cnt 	<= 	'd0   				;
						mdio_dir 	<= 	'd0 				; 	//高阻
						mdio_out 	<=  'd1 				;
						op_done 	<= 	1'b1 				;
					end
				endcase 
			end
		endcase
	end
end
endmodule



到了这里,关于千兆以太网(二)——MDIO接口协议的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 基于UDP协议的千兆以太网传输(FPGA)

    基于UDP协议的千兆以太网传输(FPGA)

    @[TOC]基于UDP协议的千兆以太网传输(FPGA) UDP协议是一种基于无连接协议,即发送端发送数据无需确认接收端是否存在;接收端收到数据后也无需给发送端反馈是否收到,所以UDP在数据发送过程中允许丢失一两包数据。用于对丢包不严格的场合,比如视频流,偶有一两帧的丢

    2024年02月12日
    浏览(11)
  • 千兆以太网传输层 UDP 协议原理与 FPGA 实现(UDP接收)

    千兆以太网传输层 UDP 协议原理与 FPGA 实现(UDP接收)

    相关文章: (1)千兆以太网网络层 ARP 协议的原理与 FPGA 实现 (2)千兆以太网硬件设计及链路层 MAC 协议格式 (3)CRC校验原理及实现 (4)RGMII 与 GMII 转换电路设计 (5)千兆以太网网络层 IP 协议介绍与 IP 校 验和算法实现 (6)千兆以太网传输层 UDP 协议原理与 FPGA 实现(

    2024年02月04日
    浏览(12)
  • FPGA千兆网口数据传输MDIO接口——FPGA学习笔记3

    FPGA千兆网口数据传输MDIO接口——FPGA学习笔记3

            是当今现有局域网采用的最通用的通信协议标准,它规定了包括物理层的连线、电子信号和介质访问层协议的内容。成本低,通信速率高,抗干扰能力强。 标准以太网:10Mbit/s 快速以太网:100Mbit/s 千兆以太网:1000Mbit/s ......... 以太网和千兆网口其实不完全相同。

    2024年03月24日
    浏览(12)
  • FPGA 20个例程篇:12.千兆网口实现MDIO接口读写

    FPGA 20个例程篇:12.千兆网口实现MDIO接口读写

           千兆网口是我们日常生活中经常见到的外设接口,在后面三个例程中,我们将会一起去动手实现千兆网口实现MDIO接口读写、ARP通信协议、ICMP和UDP通信协议等,这三个例程有一定的难度,通过实际分析、动手编码、模块划分、上板调试大家可以学到很多内容,涵盖了

    2024年02月01日
    浏览(34)
  • FPGA实现千兆/百兆自适应以太网UDP传输

    FPGA实现千兆/百兆自适应以太网UDP传输

    笔者最近在项目中需要使用到ZYNQ中PL端做以太网UDP传输并且需要支持100M/1000M自适应切换。使用的PHY型号为RTL8211。以下分享的主要为利用已有的1000M协议栈修改为100M并且实现二者自适应切换,IP核主要实现以下功能 1、实现100M/1000M自适应 2、回环测试 PS:完整的IP核文件下载地

    2024年01月21日
    浏览(30)
  • FPGA优质开源项目 - UDP RGMII千兆以太网

    FPGA优质开源项目 - UDP RGMII千兆以太网

    本文介绍一个FPGA开源项目:UDP RGMII千兆以太网通信。该项目在我之前的工作中主要是用于FPGA和电脑端之间进行图像数据传输。本文简要介绍一下该项目的千兆以太网通信方案、以太网IP核的使用以及Vivado工程源代码结构。 Vivado 的 Tri Mode Ethernet MAC IP核需要付费才能使用,因

    2024年02月14日
    浏览(33)
  • FPGA驱动千兆以太网PHY但电脑只显示百兆

    FPGA驱动千兆以太网PHY但电脑只显示百兆

    前两天公司做了个新板子,ZYNQ7035 + RTL8211E,拿给我测,于是写逻辑代码测试一下数据回环,没想到电脑端网络适配器一直显示是百兆网。查了多方原因,差点想手动配置寄存器了,但是想想又觉得不对,FPGA逻辑驱动以太网PHY芯片是不用配置寄存器的,只要PHY芯片外部引脚上

    2024年02月16日
    浏览(9)
  • FPGA-以太网基础知识-MII接口-RMII接口-GMII接口-RGMII接口-MAC协议-UDP协议

    FPGA-以太网基础知识-MII接口-RMII接口-GMII接口-RGMII接口-MAC协议-UDP协议

    记录学习FPGA以太网基础知识、包括MII接口-RMII接口-GMII接口-RGMII接口-MAC协议、UDP协议 由上图可得,以太网传输流程 : 1、一块fpga的pcb板子以太网部分,包括FPGA芯片、PHY以太网芯片、网口接口。 2、FPGA芯片包括UDP层、IP层、MAC层,即FPGA封装好了这些硬件模块也叫IP核(这里的

    2024年02月08日
    浏览(11)
  • 千兆以太网芯片88E1111 RGMII模式的FPGA驱动实现

    千兆以太网芯片88E1111 RGMII模式的FPGA驱动实现 在网络应用领域,千兆以太网已经成为主流,而88E1111作为一款先进的千兆以太网芯片,其驱动实现对于网络设备的性能和稳定性有着至关重要的影响。本文将介绍在RGMII模式下,如何实现88E1111芯片在FPGA上的驱动。 一、准备工作

    2024年01月22日
    浏览(8)
  • 千兆/百兆车载以太网转换器 罗森伯格H-MTD 泰科MATEnet接口

    千兆/百兆车载以太网转换器 罗森伯格H-MTD 泰科MATEnet接口

    重庆汇迪能电子设备有限公司 www.hdn-vdo.com #车载以太网转换器 车载以太网转换器是将车载以太网转换为标准以太网的一种协议转换器。将方便的支持用户将两线的车载以太网转换为RJ45接口的网线接入到电脑。 为千兆和百兆可切换双速车载以太网转换器。采用车载以太网普遍

    2024年02月07日
    浏览(10)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包