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核時,保留一個選第一個(共享邏輯放在覈裏),其它都選第二個(在設計裏共享),同時“把共享邏輯放在覈裏”作爲時鐘輸出將信號給到其它核

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

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

copy license需要不同的名字否則會把原來的覆蓋,同時工程需要重新生成!

5、適配管腳,生成bit,以太網接口需要放到同一Bank

同時要注意clk引腳不能放在bank的boundary位置:

 參考: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 \r\n",phy_addr,temp);
	temp |= 0x0001;
	temp &= 0xfff9;
	XAxiEthernet_PhyWrite(xaxiemacp,phy_addr, 20, temp);
	xil_printf("phy_addr:%d mode:%x \r\n",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 \r\n",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 \r\n",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 \r\n",phy_addr,temp);
	temp &= (~(1<<6));//auto negotiation
	XAxiEthernet_PhyWrite(xaxiemacp,phy_addr, 26, temp);
	xil_printf("phy_addr:%d auto negotiation:%x \r\n",phy_addr,temp);



   //-----------------------------------------------------------------
	xil_printf("Start PHY autonegotiation \r\n");

	//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.\r\n");
	xil_printf("\r\n----------------------------------------\r\n");
	//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\r\n",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 \r\n");
		}
		XAxiEthernet_PhyRead(xaxiemacp, phy_addr, IEEE_STATUS_REG_OFFSET,
					&status);
	}
	xil_printf("IEEE_STATUS_REG:%x\r\n",status);
	xil_printf("autonegotiation complete \r\n");

	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兩個版本,也可以通過命令行操作:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章