千兆以太网PHY芯片调试-88E1111(RGMII接口-数据收发ECHO测试) Verilog实现python测试

千兆以太网PHY芯片调试-基于RGMII接口的88E1111(数据收发ECHO测试)

先放结果:
数据返回正确
wireshark监控
Py测试代码:

import  socket  #网络通信 TCP,UDP
DST_IP = '192.168.0.4'
DST_PORT = 8888
DST_ADDR = (DST_IP, DST_PORT)
SRC_IP = '192.168.0.35'
SRC_PORT = 8888
SRC_ADDR = (SRC_IP, SRC_PORT)
udp = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
udp.bind(SRC_ADDR)
times = 1000
right_pack_time = 0
err_pack_time = 0
while True:
    # data=input("输入消息")
    for n in range(times):
        data = b'\x10\x02\x03\x04\x05\x06\x07\x08\x09\x0A\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xBB' \
               b'\x20\x02\x03\x04\x05\x06\x07\x08\x09\x0A\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xCC' \
               b'\x30\x02\x03\x04\x05\x06\x07\x08\x09\x0A\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xDD' \
               b'\x40\x02\x03\x04\x05\x06\x07\x08\x09\x0A\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xEE' \
               b'\x50\x02\x03\x04\x05\x06\x07\x08\x09\x0A\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xFF'
        udp.sendto(data, DST_ADDR)  # 发消息
        data2 = udp.recvfrom(1024)
        if data == data2 :
            right_pack_time += 1
            print(f'数据返回正确 pakage times:{right_pack_time}')
        else:
            err_pack_time += 1
            print(f'数据返回正确 pakage times:{err_pack_time}')
    break
udp.close()

测试平台:
测试平台

数据收发参考:Verilog 实现千兆网UDP协议 基于88E1111–数据发送
Verilog 实现千兆网UDP协议 基于88E1111–数据接收
Verilog 实现千兆网UDP协议 基于88E1111–板级验证–增加ARP
**代码架构:**实现通信代码为ETH_Control下的几个模块,也就是send 发送 receive 接收 Eth_reg 为MDIO读取phy寄存器状态。两个FIFO,ping_data_buf专为ping指令reply使用,ETH_send_buf 为数据发送缓冲,本代码体系需提前数据发送数据长度,当数据发送缓冲fifo内数据足够时,代码执行开始发送指定量数量的数据。整体构架如下图:
代码架构
应用时只需关注ETH_control下子模块,cmd_process用于对数据包进行解析,实际使用时会对数据区增加编帧用于传输指令或数据等区分。完整ETH_control代码如下:

`timescale 1ns / 1ps

// _____   _____   _____   _____        _   _       ___   _____    _____  
///  ___| /  _  \ |  _  \ | ____|      | | | |     /   | |  _  \  |  _  \ 
//| |     | | | | | | | | | |__        | |_| |    / /| | | |_| |  | | | | 
//| |     | | | | | | | | |  __|       |  _  |   / / | | |  _  /  | | | | 
//| |___  | |_| | | |_| | | |___       | | | |  / /  | | | | \ \  | |_| | 
//\_____| \_____/ |_____/ |_____|      |_| |_| /_/   |_| |_|  \_\ |_____/ 
// _____       ___  __    __   _____       ___  __    __   _   _   _____  
//|  _  \     /   | \ \  / /  |  _  \     /   | \ \  / /  | | | | |  _  \ 
//| | | |    / /| |  \ \/ /   | | | |    / /| |  \ \/ /   | | | | | |_| | 
//| | | |   / / | |   \  /    | | | |   / / | |   \  /    | | | | |  ___/ 
//| |_| |  / /  | |   / /     | |_| |  / /  | |   / /     | |_| | | |     
//|_____/ /_/   |_|  /_/      |_____/ /_/   |_|  /_/      \_____/ |_|     
//
// Company: Nler Studio
// Engineer: Yueze Liu
//
// Create Date: 14:30:16 7/15/2021 
// Design Name: ETH_Control
// Module Name: ETH_Control
// Description: ETH_Control documents
// Revision:    <Code_revision_information>
//
// When I wrote this, only God and I understood what I was doing
// Now, God only konws
// So don't ask me
//



module ETH_Control(
	input						clk_50m,
	input						locked,			
	output reg 	[ 3:0] 			Eth_Command_o ,

	output  	[ 7:0] 			Txd_o ,
	output  					Txen_o,                    
	output  					Txer_o,  
	input						Tx_Clk_i,
	output						Tx_Gclk_o,
	input						Rx_Clk_i,
	input		[ 7:0] 			Rxd_i, 
	input						Rxdv_i,
	input						Rxer_i,
	output	reg					ETH_RESET_n,
	output						ETH_INT_n,
	input						ETH_COL_i,
	input						ETH_CRS_i,
	/*control interface*/
	input 						Open_Eth_Sent,
	input 		[15:0]			Data_length_i,
	input						Eth_Fifo_Clk_i,
	output		[ 7:0]			Eth_Fifo_Data_i,
	output						Eth_Fifo_Wr_en,
	input		[ 7:0]			Eth_Fifo_en_o,
	input		[ 7:0]			Eth_Fifo_Data_o,
	output						ETH_fifo_Afull_o,
	output		[10:0]			Eth_Send_wr_count,
	output		[15:0]			Rec_data_length,
	
	input						clk_5m,	
	input						rst_n,	
	output						MDC_o,	
	inout						MDIO_io
    );

/**/
reg 	[ 3:0] 					Eth_Command;    //[3]receive_DATA [2]send_ARP [1]send_ICMP [0]send_data
wire 							ARP_addr_en;
reg								ARP_addr_Get;
wire 	[79:0]					ARP_addr_data;
reg		[31:0]					Destination_IP;
reg		[47:0]					Destination_MAC;
wire	[ 7:0]					E2L_Fifo_Data_o;	
wire							E2L_Fifo_Rd_en;		
reg 	[31:0] 					eth_rst_reg;
wire 	[ 7:0]					Ping_Fifo_Data_i;
wire    						Ping_Fifo_Wr_en;
wire	[ 7:0]					Ping_Fifo_Data_o;
wire							Ping_Fifo_Rd_en;
wire							Ping_Fifo_Rd_Valid;
wire							Ping_Reply_Over;
wire    						Ping_active;		
wire    [15:0]					Ping_data_length;	
wire    [15:0]					Ping_Check_Sum;
reg     [15:0]					Ping_Check_Sum_i;
reg 							Ping_active_r;		
wire							clk_50m;
wire    [10:0]					Eth_Send_rd_count;

wire	[ 4:0]					Phy_addr;
wire	[ 4:0]					Reg_addr;
wire	[15:0]					Reg_data_i;
wire	[15:0]					Reg_data_o;
wire	[ 0:0]					Op_sw;
wire	[ 0:0]					Op_enable;
/*debug*/
/*	*/
assign 							ETH_INT_n  	= 1'b1;
assign							Tx_Gclk_o 	= Rx_Clk_i;
/* Ethernet Power-Up Reset Process */
always @(posedge clk_50m )
begin
	if(!locked) begin
		eth_rst_reg <= 32'h0000_0000;
		ETH_RESET_n    <= 1'b0;
	end
	else begin
		if(eth_rst_reg == 32'h02ff_ffff) begin
			eth_rst_reg 	<= eth_rst_reg;
			ETH_RESET_n   	<= 1'b1;
		end
		else begin
			eth_rst_reg 	<= eth_rst_reg + 1'b1;
			ETH_RESET_n   	<= 1'b0;	
		end
	end
end
/*Process Control */
always @(posedge Rx_Clk_i or negedge locked)
begin
	if(!locked)begin
		Eth_Command[3]  <= 1'b0;	//receive_open
		Eth_Command[2] 	<= 1'b0;    //send_ARP
		Eth_Command[1] 	<= 1'b0;    //send_ICMP
		Eth_Command[0] 	<= 1'b0;    //send_data
	end
	else begin
		Eth_Command_o	<= Eth_Command;
		/* ele_add receive start */
		if(ETH_RESET_n)		begin
			Eth_Command[3]   <= 1'b1;
		end
		else begin
			Eth_Command[3]   <= 1'b0;
		end
		/* receive ARP trigger reply // binding PC MAC IP */
		if (ARP_addr_en)	begin
			ARP_addr_Get 	<= 1'b1;
			Destination_MAC <= ARP_addr_data[79:32];
			Destination_IP  <= ARP_addr_data[31: 0];
			Eth_Command[2]  <= 1'b1;
		end
		else begin
			ARP_addr_Get 	<= 1'b0;
			Eth_Command[2]  <= 1'b0;
		end	
		/* receive ICMP trigger reply ping package */
		if (Ping_active || Ping_active_r)	begin			
			Eth_Command[1]  <= 1'b1;						
			if(Ping_Reply_Over) begin
				Ping_active_r	<= 1'b0;
			end
			else begin
				Ping_active_r	<= 1'b1;
			end
		end
		else begin
			Eth_Command[1]  <= 1'b0;
		end	
		/*lock Ping_Check_Sum*/
		if (Ping_active) Ping_Check_Sum_i  <= Ping_Check_Sum;
		else Ping_Check_Sum_i<= Ping_Check_Sum_i;
		/*START send_data*/
		if(Open_Eth_Sent)	begin
			if(Eth_Send_rd_count > Data_length_i - 4'd10)begin
				Eth_Command[0]  <= 1'b1;
			end
			else begin
				Eth_Command[0]  <= 1'b0;
			end
		end
		else begin
			Eth_Command[0]  <= 1'b0;
		end
	end
end

ETH_Send ETH_Send_u(
	.clk_i							(Rx_Clk_i			),
	.rst_n							(ETH_RESET_n		),
	.Txen_o							(Txen_o				),                     
	.Txer_o							(Txer_o				),                     
	.Txd_o							(Txd_o				),     
	.Eth_Command					(Eth_Command		),
	.Data_length_i					(Data_length_i		),
	.Eth_Fifo_Data_o				(E2L_Fifo_Data_o	),
	.Eth_Fifo_Rd_en					(E2L_Fifo_Rd_en		),
	.Destination_IP					(Destination_IP		),
	.Destination_MAC				(Destination_MAC	),
	.Ping_data_length				(Ping_data_length	),
	.Ping_Check_Sum					(Ping_Check_Sum_i	),
	.Ping_Reply_Over				(Ping_Reply_Over	),
	.Ping_Fifo_Data_o				(Ping_Fifo_Data_o	), 
	.Ping_Fifo_Rd_en				(Ping_Fifo_Rd_en	)
	);
	
ETH_Receive ETH_Receive_u(
	.clk_i							(Rx_Clk_i			),
	.rst_n							(ETH_RESET_n		),
	.Rxer_i							(Rxer_i				),                     
	.Rxdv_i							(Rxdv_i				),                     
	.Rxd_o							(Rxd_i				),     
	.Eth_Command					(Eth_Command		), 
	.Destination_IP					(Destination_IP		),
	.Destination_MAC				(Destination_MAC	),
	.Eth_Fifo_Data_i				(Eth_Fifo_Data_i	),
	.Eth_Fifo_Wr_en					(Eth_Fifo_Wr_en		),
	.Ping_Fifo_Data_i				(Ping_Fifo_Data_i	),
	.Ping_Fifo_Wr_en				(Ping_Fifo_Wr_en	),
	.ARP_addr_en					(ARP_addr_en		),
	.ARP_addr_Get					(ARP_addr_Get		),
	.ARP_addr_data	        		(ARP_addr_data		),
	.Ping_active					(Ping_active		),
	.Ping_data_length				(Ping_data_length	),
	.Ping_Check_Sum					(Ping_Check_Sum		),
	.Rec_data_length				(Rec_data_length	)	
	);	
Ping_data_buf Ping_data_buf_u (
	.rst							(!locked			),           
	.wr_clk							(Rx_Clk_i			),           
	.rd_clk							(Rx_Clk_i			),           
	.din							(Ping_Fifo_Data_i	),           
	.wr_en							(Ping_Fifo_Wr_en	),           
	.rd_en							(Ping_Fifo_Rd_en	),           
	.dout							(Ping_Fifo_Data_o	),           
	.full							(					),           
	.empty							(					),           
	.valid							(Ping_Fifo_Rd_Valid	)
);
Eth_Send_buf Eth_Send_buf_u (
	.rst							(!locked			),                      // input wire rst
	.wr_clk							(Eth_Fifo_Clk_i		),                // input wire wr_clk
	.rd_clk							(Rx_Clk_i			),                // input wire rd_clk
	.din							(Eth_Fifo_Data_o	),                      // input wire [7 : 0] din
	.wr_en							(Eth_Fifo_en_o		),                  // input wire wr_en
	.rd_en							(E2L_Fifo_Rd_en		),                  // input wire rd_en
	.dout							(E2L_Fifo_Data_o	),                    // output wire [7 : 0] dout
	.full							(					),                    // output wire full
	.almost_full					(ETH_fifo_Afull_o	),      // output wire almost_full
	.empty							(					),                  // output wire empty
	.rd_data_count					(Eth_Send_rd_count	),  // output wire [10 : 0] rd_data_count
	.wr_data_count					(Eth_Send_wr_count	)  // output wire [10 : 0] wr_data_count
);	
assign MDIO_io = (Op_sw_r) ? MDIO_o:1'bz;  
Eth_Reg_Wr Eth_Reg_Wr_u(
	.clk_i							(clk_5m				),
	.rst_n							(locked				),
	.MDC_o							(MDC_o				),
	.MDIO_i							(MDIO_io			),
	.MDIO_o							(MDIO_o				),
	.Phy_addr						(Phy_addr			),
	.Reg_addr						(Reg_addr			),
	.Reg_data_i						(Reg_data_i			),
	.Reg_data_o						(Reg_data_o			),
	.Op_sw							(Op_sw				),		
	.Op_enable						(Op_enable			),
	.Op_sw_r						(Op_sw_r			)
);
vio_0 vio_u (
	.clk							(clk_5m				),            
	.probe_in0						(Reg_data_o			),  
	.probe_out0						(Reg_data_i			), 
	.probe_out1						(Phy_addr			), 
	.probe_out2						(Reg_addr			), 
	.probe_out3						(Op_sw				), 
	.probe_out4						(Op_enable			)  
);
endmodule

对外控制接口:
Open_Eth_Sent,开启发送
Data_length_i,发送数据长度
接收数据直接写入fifo,这次测试实现CALLBACK所以外部没有连接fifo
Eth_Fifo_Clk_i,
Eth_Fifo_Data_i,
Eth_Fifo_Wr_en,
发送数据缓冲fifo
Eth_Fifo_en_o,
Eth_Fifo_Data_o,
ETH_fifo_Afull_o,
Eth_Send_wr_count,
接收数据package长度,从首部中提取出来计算出实际数据长度
Rec_data_length,

Process Control 内实现模式切换,包含UDP通讯,ARP响应,ICMP内PING reply

实现callback只需顶层将接收与发送信号相连

assign	Open_Eth_Sent 	= 1'b1;
assign  Eth_Fifo_Data_o	= Eth_Fifo_Data_i;
assign  Eth_Fifo_en_o	= Eth_Fifo_Wr_en;
assign  Data_length_i	= Rec_data_length ;
assign  Eth_Wr_Fifo_Clk = Rx_Clk_i;
  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 88e1111是一款流行的千兆以太网交换机芯片,支持多种接口类型,包括RGMII和SGMII。RGMII作为传统的以太网PHY接口,使用8位数据和时钟线,速率可以达到1Gbps,但需要大量的板级布线。而SGMII是一种串行接口,仅需4条信号线,可以采用同轴电缆或光纤进行连接,可减少布线难度。 因此,如何将88e1111RGMII转为SGMII接口呢?这需要注意以下几点: 1.引脚定义:RGMII和SGMII的接口引脚定义不同,需要先了解两种接口的引脚分配。 2.模式设置:88e1111支持多种模式设置,包括RGMII模式和SGMII模式,在配置寄存器中进行相应的设置即可。有些芯片还需要根据不同的模式设置电压、电流等参数。 3.时钟控制:RGMII需要两个时钟信号,而SGMII只需要一个。在将88e1111RGMII转为SGMII时,需要关闭相应的时钟输出,并修改时钟配置。 4.电路布线:SGMII通常采用不对称布线,需要根据板子布线进行相应的匹配,调整信号线长度,优化信号传输质量。 综上所述,将88e1111RGMII转为SGMII需要依次考虑引脚定义、模式设置、时钟控制和电路布线等方面,确保芯片能够正常工作。 ### 回答2: 88e1111是Marvell推出的一款集成了Switch、PHY、CPU等功能的网络芯片,支持多种接口,包括RGMII和SGMII。RGMII是Reduced Gigabit Media Independent Interface的缩写,是一种用于将网络物理层接口和MAC层接口进行连接的技术,其带宽可达到1Gbps,主要用于连接网络交换机和网卡等设备。SGMII是Serial Gigabit Media Independent Interface的缩写,与RGMII相比,其更加简洁,只需要两个差分对来传输信号,带宽也是1Gbps,用于连接高速的光电转换器或PHY等设备。 如果需要将88e1111RGMII接口转换成SGMII接口,可以使用Marvell提供的转换解决方案。该方案需要使用到88X3310和88E1118等IC芯片。其中,88X3310为RGMII-to-SGMII转换器,而88E1118是一款1G Ethernet PHY。通过将88X3310和88E1118与88e1111连接,可以实现RGMII接口与SGMII接口的无缝切换,使系统更加灵活和可扩展。 具体实现过程如下: 1.将88X3310的S0和S1引脚分别连接到高电平和低电平,设置其为RGMII接口模式。 2.将88X3310的RGMII Tx和Rx引脚连接到88e1111RGMII Tx和Rx引脚。 3.将88X3310的SGMII Tx和Rx引脚连接到88E1118的SGMII Tx和Rx引脚。 4.将88e1111的MDC和MDIO引脚连接到88E1118的MDC和MDIO引脚。 5.通过编程,控制88e1111输出SGMII接口信号。 通过以上步骤,就可以将88e1111RGMII接口转换成SGMII接口实现网络系统的扩展和优化。 ### 回答3: 88e1111是一种常用的网络交换机芯片,在数据传输过程中,需要将RGMII接口转换为SGMII接口RGMII即Reduced Gigabit Media Independent Interface,是一种高速接口标准,支持传输千兆位速率数据。而SGMII则是Serial Gigabit Media Independent Interface,是一种序列化的千兆位速率接口标准,它使千兆位速率的数据通过一个差分线对传输。 88e1111芯片支持将RGMII接口转换为SGMII接口,这种转换可以通过在芯片内部配置来实现。具体来说,需要在芯片的寄存器中设置相关的参数,使其支持SGMII接口。在配置时,需要注意以下几个方面: 1. 选择正确的速率:SGMII接口支持10、100、1000三种速率,需要根据实际情况选择正确的速率。 2. 配置PHY寄存器:芯片需要向PHY芯片发送一些配置参数,以使其能够正确地工作。这些参数可通过芯片的寄存器进行配置,例如PHY地址、PHY类型等参数。 3. 配置芯片寄存器:芯片内部也有一些寄存器需要配置,使芯片支持SGMII接口。这些寄存器包括MAC控制寄存器、PHY控制寄存器等。 总的来说,将88e1111芯片RGMII接口转换为SGMII接口需要进行多个方面的配置,包括芯片寄存器、PHY寄存器等。配置时需要仔细分析实际情况,选择正确的速率和参数,以确保转换后的接口能够正确地工作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值