xilinx 以太网验证方案简介

说明:基于Microblaze+Lwip+perf建立测试工程验证以太网通信

以太网接口:MII/RMII/GMII/RGMII/SGMII(本次主要使用MII/RMII接口)

-------------------------------------------------------------------------------------------------------------------------------------------------

第一部分:建立vivado工程

1、我们可以通过vivado自带的官方example来生成一个microblaze的以太网参考设计:

这个设计时基于官方board的,我们可以选择一个相近的板卡作为参考,我们只需要网口部分,不需要的都不选,简化设计:

参照这个设计,新建一个工程对应到自己的板卡,以及自己的以太网PHY

2、对于mii/gmii/rgmii接口ethernet subsystem ip核是很好支持的,sgmii接口复杂点,目前还我没有找到正确的操作方法

注意microblaze默认高电平复位,但我们外部信号一般是低电平复位的(点到这个引脚,Ctrl+E在属性里面设置下):

以太网对内存有一定要求,我们尽可能把LBM设置大点:

LMB容量最大可以选择4MBytes,在Address Editor更新后,重新生成block里面会同步更新!

同时注意不要有悬空net没有连接:

3、当你有多个Microblaze以及对应的Ethernet Subsytem时:当你只有一个 ETH核时,选第一个,把共享逻辑放在核里;当你有多个ETH核时,保留一个选第一个(共享逻辑放在核里),其它都选第二个(在设计里共享),同时“把共享逻辑放在核里”作为时钟输出将信号给到其它核{此处的区别实际上主要是避免idelayctrl实例多个}

4、Ethernet ip需要license,可以在官网上自行申请:

https://www.xilinx.com/products/intellectual-property/ip-evaluation.html

copy license需要不同的名字否则会把原来的覆盖,同时工程需要重新生成!

5、适配管脚,生成bit,以太网接口需要放到同一Bank

同时要注意clk引脚不能放在bank的boundary位置:【此处为了实现大于1.25ns延时,将idelay和odelay做了级联,使用级联时不能将管脚适配到byte boundary,注意一个bank是4个byte,每个byte有2个nibble,每个nibble一个idelaycrtl(实际一个工程我们只用一个idelaycrtl,在布局布线时应该会自动拷贝)】

 参考:https://www.xilinx.com/support/answers/67641.html

关于引脚信息请参考:ug575-ultrascale-pkg-pinout.pdf

http://www.xilinx.com/support/packagefiles/usapackages/usaall.zip

--------------------------------------------------------------------------------------------------------------

第二步:成功生成bit后需要进入SDK中进行后面的软件生成及调试操作:

1、新建Tcp Appllication/选择tcp perf server

2、虽然LBM已经设置到了最大,但编译lwip还是会make error,我们需要配置下lwip的参数:

3、debug

备注:

-------------------------------------------------------------------------------------------------------------------------------------------------------

第三部分:适配自己的phy及网络调试

1、以太网调试首先是要适配自己的phy,xilinx提供的参考例程只是适配了自己的官方板卡的phy,其它型号的phy需要自己适配:

   以太网PHY的SMI接口属于总线接口,类似于I2C,每个PHY都是有地址的,lwip不关心这个地址时多少,它会扫描查找31-1(0地址没有查找)

SMI接口频率设置:



unsigned int get_phy_speed_88E1514(XAxiEthernet *xaxiemacp, u32 phy_addr)
{
	u16 phy_val;
	u16 control;
	u16 status;
	u16 partner_capabilities;
	u16 temp;
    //mode select:sgmii reg20_18
	XAxiEthernet_PhyWrite(xaxiemacp,phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 18);
	XAxiEthernet_PhyRead(xaxiemacp, phy_addr, 20, &temp);
	xil_printf("phy_addr:%d mode:%x 
",phy_addr,temp);
	temp |= 0x0001;
	temp &= 0xfff9;
	XAxiEthernet_PhyWrite(xaxiemacp,phy_addr, 20, temp);
	xil_printf("phy_addr:%d mode:%x 
",phy_addr,temp);
	//reset phy
	temp |= 0x8000;
	XAxiEthernet_PhyWrite(xaxiemacp,phy_addr, 20, temp);
	//will add:
	//reg:0_1  sgmii negotiation
	XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 1);
	XAxiEthernet_PhyRead(xaxiemacp, phy_addr, 0, &temp);
	xil_printf("phy_addr:%d auto negotiation:%x 
",phy_addr,temp);
	temp |= 1<<12;//auto negotiation
	temp |= 1<<9;//restart auto negotiation
	XAxiEthernet_PhyWrite(xaxiemacp,phy_addr, 0, temp);
	xil_printf("phy_addr:%d auto negotiation:%x 
",phy_addr,temp);
	//reg:26_1 sgmii negotiation
	XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 1);
	XAxiEthernet_PhyRead(xaxiemacp, phy_addr, 26, &temp);
	xil_printf("phy_addr:%d auto negotiation:%x 
",phy_addr,temp);
	temp &= (~(1<<6));//auto negotiation
	XAxiEthernet_PhyWrite(xaxiemacp,phy_addr, 26, temp);
	xil_printf("phy_addr:%d auto negotiation:%x 
",phy_addr,temp);



   //-----------------------------------------------------------------
	xil_printf("Start PHY autonegotiation 
");

	//reg:21_2(page)
	XAxiEthernet_PhyWrite(xaxiemacp,phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 2);
	XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_CONTROL_REG_MAC, &control);
	control |= IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK;
	XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, IEEE_CONTROL_REG_MAC, control);

	XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);

	//reg:4_0(page)
	XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);
	control |= IEEE_ASYMMETRIC_PAUSE_MASK;
	control |= IEEE_PAUSE_MASK;
	control |= ADVERTISE_100;
	control |= ADVERTISE_10;
	XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);

	////reg:9_0(page) 1000 BASE-T FUll-Duplex/Half-Duplex Advertise
	XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
				&control);
	control |= ADVERTISE_1000;
	XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
				control);
	//reg:16_0(page) Not for 88e1514
	//XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
	//XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_COPPER_SPECIFIC_CONTROL_REG,&control);
	//control |= (7 << 12);	/* max number of gigabit atphy_valts */
	//control |= (1 << 11);	/* enable downshift */
	//XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, IEEE_COPPER_SPECIFIC_CONTROL_REG,control);
	//reg:0_0(page)
	XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
	control |= IEEE_CTRL_AUTONEGOTIATE_ENABLE;
	control |= IEEE_STAT_AUTONEGOTIATE_RESTART;
	XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
    //reset the phy
	XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
	control |= IEEE_CTRL_RESET_MASK;
	XAxiEthernet_PhyWrite(xaxiemacp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
	while (1) {
		XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
		if (control & IEEE_CTRL_RESET_MASK)
			continue;
		else
			break;
	}
    //
	xil_printf("Waiting for PHY to complete autonegotiation.
");
	xil_printf("
----------------------------------------
");
	//reg:1_0(page)
	XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
	while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
		xil_printf("IEEE_STATUS_REG:%x
",status);
		AxiEthernetUtilPhyDelay(1);
		//reg:19_0(page)
		XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_COPPER_SPECIFIC_STATUS_REG_2,
							&phy_val);
		if (phy_val & IEEE_AUTONEG_ERROR_MASK) {
			xil_printf("Auto negotiation error 
");
		}
		XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_STATUS_REG_OFFSET,
					&status);
	}
	xil_printf("IEEE_STATUS_REG:%x
",status);
	xil_printf("autonegotiation complete 
");

	XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_SPECIFIC_STATUS_REG,
				&partner_capabilities);
	if ( ((partner_capabilities >> 14) & 3) == 2)/* 1000Mbps */
		return 1000;
	else if ( ((partner_capabilities >> 14) & 3) == 1)/* 100Mbps */
		return 100;
	else					/* 10Mbps */
		return 10;
}

2、网络报文

ila中抓取到的包:

同时我们也可以在代码里将报文通过串口打印出来分析:

在low_level_input/low_level_ouput函数中将buf数据打印数出来

3、PC端监控:单独将PC和板卡通过一根网线连接,通过抓包软件对PC端网卡进行抓包可以分析两边的通信数据,同时通过wifi连接网络,这时PC端的有线网卡数据比较干净主要是和子卡之间的数据便于调试。

4、perf测试

当dhcp成功给我们的板卡分配一个ip后,便可以进行perf测试,该软件有windows及linux两个版本,也可以通过命令行操作:

原文地址:https://www.cnblogs.com/time93/p/13246416.html