• 0
hdx

MII to RMII ARTY 35-t

Question

Hi,

I am trying to add the rmii ip component into my design and am having problems getting it to work. When I try to map the IO:s I get a lot of problems such as :

Quote

[Place 30-58] IO placement is infeasible. Number of unplaced terminals (7) is greater than number of available sites (0).
The following are banks with available pins: 
 IO Group: 0 with : SioStd: LVCMOS18   VCCO = 1.8 Termination: 0  TermDir:  Out  RangeId: 1 Drv: 12  has only 0 sites available on device, but needs 7 sites.
    Term: eth_txd[0]
    Term:  eth_txd[1]
    Term:  rmii_rtl_txd[0]
    Term:  rmii_rtl_txd[1]
    Term:  eth_ref_clk
    Term:  eth_tx_en
    Term:  and rmii_rtl_tx_en

I have tried the following, but neither worked

Tried connecting the two IPs together like this by just connecting them:

clean.thumb.png.ec57a8a43d015f440d091ac0742758fb.png

AND also tried to manually set the values inside .xdc file and create ports to each ports:

custom.thumb.png.14a784cf9f5f251c1b9ba246488a5866.png

Edited by hdx

Share this post


Link to post
Share on other sites

18 answers to this question

Recommended Posts

  • 1
20 minutes ago, hdx said:

The arty a7 35-t board I am using, is utilizing a TI Ethernet PHY (DP83848),  not DP84838 as in your case unfortunately-

 

 

I'm sorry it was typo, I mean DP83848.

I used external board with PHY like this one

https://www.waveshare.com/dp83848-ethernet-board.htm

This board has external 50MHz clocking required for RMII.

Here is my BD, settings and XDC.

RMII_page1.PNG

RMII_page2.PNG

design_1.pdf xdc.xdc

Share this post


Link to post
Share on other sites
  • 0

I have now managed to build and generate the bit file, however when I run my echo server application I can't seem to get any connection the board. Before when I only had the the mii ip block I managed easily to connect to the server and send messages, however, now I am not getting any connection with the echo server. Is there something I'll have to do in order to establish any connection and send messages?

 

Share this post


Link to post
Share on other sites
  • 0

Hi @hdx,

What version of Vivado do you have? I noticed that the Mii to RMii block you have is labeled as discontinued, which is true of later versions of Vivado. I did go through an older tutorial that we have for the Arty board, https://reference.digilentinc.com/learn/programmable-logic/tutorials/arty-getting-started-with-microblaze-servers/start, in Vivado 2018.3 (Vivado 2018.2 has an error) which does not use the Mii to RMii (it instead uses the material from the Vivado Board files), but does create a serial terminal.

Thanks,
JColvin

Share this post


Link to post
Share on other sites
  • 0

Hi @JColvin

Thanks for the reply!

I am currently using vivado 2019.1 and indeed the block is discontinued. Does this effect anything when I am trying to use reduced mii?

The application was working without any problems when using only ethernetlite, but when I integrated the mii2rmii I am not able to get any connection with the application server or able to send anything to the device. I am successfully able to generate the bit file and am not getting any errors when generating it.

I have the following constraints that I extracted from the master file for arty 35-t:

set_property -dict { PACKAGE_PIN G14   IOSTANDARD LVCMOS33 } [get_ports { eth_crs }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=eth_crs
set_property -dict { PACKAGE_PIN G18   IOSTANDARD LVCMOS33 } [get_ports { eth_ref_clk }];
set_property -dict { PACKAGE_PIN D18   IOSTANDARD LVCMOS33 } [get_ports { eth_rxd }]; #IO_L21N_T3_DQS_A18_15 Sch=eth_rxd[0]
set_property -dict { PACKAGE_PIN C17   IOSTANDARD LVCMOS33 } [get_ports { eth_rxerr }]; #IO_L20N_T3_A19_15 Sch=eth_rxerr
set_property -dict { PACKAGE_PIN H15   IOSTANDARD LVCMOS33 } [get_ports { eth_tx_en }]; #IO_L19N_T3_A21_VREF_15 Sch=eth_tx_en
set_property -dict { PACKAGE_PIN H14   IOSTANDARD LVCMOS33 } [get_ports { eth_txd[0] }]; #IO_L15P_T2_DQS_15 Sch=eth_txd[0]
set_property -dict { PACKAGE_PIN J14   IOSTANDARD LVCMOS33 } [get_ports { eth_txd[1] }]; #IO_L19P_T3_A22_15 Sch=eth_txd[1]

These different ports are then created in the diagram as seen above in the picture

 

Besides from this I have also tried to add the following lines inside the constraints file according to the following guide https://www.xilinx.com/support/documentation/ip_documentation/mii_to_rmii/v2_0/pg146-mii-to-rmii.pdf

create_clock -name Ref_Clk -period 20 -waveform {0 6} [get_ports Ref_Clk]
create_clock -name Rmii2Mac_tx_clk -period 20 -waveform {0 6} [get_ports Rmii2Mac_tx_clk]
create_clock -name Rmii2Mac_rx_clk -period 20 -waveform {0 6} [get_ports Rmii2Mac_rx_clk]
set_property IOB TRUE [get_ports phy2rmii_rxd]
set_property IOB TRUE [get_ports phy2rmii_crs_dv]
set_property IOB TRUE [get_ports phy2rmii_rx_er]
set_property IOB TRUE [get_ports rmii2phy_txd]
set_property IOB TRUE [get_ports rmii2phy_tx_en]

 

Edited by hdx

Share this post


Link to post
Share on other sites
  • 0

Hi!

Which PHY IC you are using ?

There are several versions of RMII.

MII-to-RMII core is designed according v1.0 specification.

DP83848 PHY has RMII v1.2 by default (register 0x17, default value 0x21).

So there can be mismatch, and at least Zynq processor is sensitive for that.

In such cases you should change it (register 0x17, set value to 0x31), apply this for SDK:

 

FOR PS GEM CORE
add
 XEmacPs_PhyRead(xemacpsp, phy_addr, 0x17, &status);
 xil_printf("RMII = %x\r\n",status);
 XEmacPs_PhyWrite(xemacpsp, phy_addr, 0x17, 0x31);
 XEmacPs_PhyRead(xemacpsp, phy_addr, 0x17, &status);
 xil_printf("RMII = %x\r\n",status);
 
after
 if (conv_present) {
  XEmacPs_PhyWrite(xemacpsp, convphyaddr,
  XEMACPS_GMII2RGMII_REG_NUM, convspeeddupsetting);
 }
 
in file xemacpsif_physpeed.c (*\*_prj.sdk\*_bsp\ps7_cortexa9_0\libsrc\lwip141_v1_9\src\contrib\ports\xilinx\netif)
in function u32_t phy_setup (XEmacPs *xemacpsp, u32_t phy_addr) (used when speed is fixed), when speed is auto get_IEEE_phy_speed(XEmacPs *xemacpsp, u32_t phy_addr) function is used (it seems like that)


FOR LITE CORE
add
 XEmacLite_PhyRead(xemaclitep, phy_addr, 0x17, &control);
 xil_printf("RMII = %x\r\n",control);
 XEmacLite_PhyWrite(xemaclitep, phy_addr, 0x17, 0x31);
 XEmacLite_PhyRead(xemaclitep, phy_addr, 0x17, &control);
 xil_printf("RMII = %x\r\n",control);
 
after
 u32 phy_addr = detect_phy_emaclite(xemaclitep);

in file xemacliteif.c (*\*_prj.sdk\*_bsp\ps7_cortexa9_0\libsrc\lwip141_v1_9\src\contrib\ports\xilinx\netif)
in function unsigned get_IEEE_phy_speed_emaclite(XEmacLite *xemaclitep) (when speed is auto), when fixed configure_IEEE_phy_speed_emaclite function is used.

 

p.s. It was tested on Vivado v2017.3 , Zybo board and external DP83848 PHY.

Edited by toshas

Share this post


Link to post
Share on other sites
  • 0

Check info above, if it will not help you, I can share working RMII project for Arty board with you (2017.3).

Share this post


Link to post
Share on other sites
  • 0

Hi @toshas,

Thank you for the help!

I have tried to modify xemacliteif.c source file with suggested changes you proposed, but still have the same problem. I am using the ethernetlite core connected to a mii->rmii core as can be seen in the image in the first post. Also, I am running xilinx vivado 2019.1, sdk is also the same version

The arty a7 35-t board I am using, is utilizing an TI Ethernet PHY (DP83848),  not DP84838 as in your case unfortunately-

Quote

The Arty A7 includes a Texas Instruments 10/100 Ethernet PHY (TI part number DP83848J) paired with an RJ-45 Ethernet jack with integrated magnetics and indicator LEDs. The TI PHY uses the MII interface and supports 10/100 Mb/s. 

My configure_IEEE_phy_speed_emaclite function in xemacliteif.c file looks like this without any changes:

(I am using a fixed speed (100), as suggested by the digilent tutorial I originally followed)

unsigned configure_IEEE_phy_speed_emaclite(XEmacLite *xemaclitep, unsigned speed)
{
	u16 control;
	u32 phy_addr = detect_phy_emaclite(xemaclitep);

	XEmacLite_PhyRead(xemaclitep, phy_addr,
				IEEE_CONTROL_REG_OFFSET,
				&control);
	control &= ~IEEE_CTRL_LINKSPEED_100M;
	control &= ~IEEE_CTRL_LINKSPEED_10M;
	if (speed == 100) {
		control |= IEEE_CTRL_LINKSPEED_100M;
		/* Dont advertise PHY speed of 1000 Mbps */
		XEmacLite_PhyWrite(xemaclitep, phy_addr,
					IEEE_1000_ADVERTISE_REG_OFFSET,
					0);
		/* Dont advertise PHY speed of 10 Mbps */
		XEmacLite_PhyWrite(xemaclitep, phy_addr,
				IEEE_AUTONEGO_ADVERTISE_REG,
				ADVERTISE_100);

	}
	else if (speed == 10) {
		control |= IEEE_CTRL_LINKSPEED_10M;
		/* Dont advertise PHY speed of 1000 Mbps */
		XEmacLite_PhyWrite(xemaclitep, phy_addr,
				IEEE_1000_ADVERTISE_REG_OFFSET,
					0);
		/* Dont advertise PHY speed of 100 Mbps */
		XEmacLite_PhyWrite(xemaclitep, phy_addr,
				IEEE_AUTONEGO_ADVERTISE_REG,
				ADVERTISE_10);
	}

	XEmacLite_PhyWrite(xemaclitep, phy_addr,
				IEEE_CONTROL_REG_OFFSET,
				control | IEEE_CTRL_RESET_MASK);
	{
		volatile int wait;
		for (wait=0; wait < 100000; wait++);
		for (wait=0; wait < 100000; wait++);
	}
	return 0;
}

 

Edited by hdx

Share this post


Link to post
Share on other sites
  • 0
2 hours ago, hdx said:

 

set_property -dict { PACKAGE_PIN G14   IOSTANDARD LVCMOS33 } [get_ports { eth_crs }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=eth_crs
set_property -dict { PACKAGE_PIN G18   IOSTANDARD LVCMOS33 } [get_ports { eth_ref_clk }];
set_property -dict { PACKAGE_PIN D18   IOSTANDARD LVCMOS33 } [get_ports { eth_rxd }]; #IO_L21N_T3_DQS_A18_15 Sch=eth_rxd[0]
set_property -dict { PACKAGE_PIN C17   IOSTANDARD LVCMOS33 } [get_ports { eth_rxerr }]; #IO_L20N_T3_A19_15 Sch=eth_rxerr
set_property -dict { PACKAGE_PIN H15   IOSTANDARD LVCMOS33 } [get_ports { eth_tx_en }]; #IO_L19N_T3_A21_VREF_15 Sch=eth_tx_en
set_property -dict { PACKAGE_PIN H14   IOSTANDARD LVCMOS33 } [get_ports { eth_txd[0] }]; #IO_L15P_T2_DQS_15 Sch=eth_txd[0]
set_property -dict { PACKAGE_PIN J14   IOSTANDARD LVCMOS33 } [get_ports { eth_txd[1] }]; #IO_L19P_T3_A22_15 Sch=eth_txd[1]

These different ports are then created in the diagram as seen above in the picture

 

 

I rechecked your diagram, looks like rxd[1] is missing, isn't it ?

 

custom.png.127c54dc00a7509506411ccfeca91524.png

Share this post


Link to post
Share on other sites
  • 0

Yes, that's correct. I had excluded both rx[1] and tx[1] from the constraints and the ports, however, when I connected the ports to the ip core block it marked them as [1:0] so added just tx[1:0] but not rx. I have now tried to add it in the constraints file, both rx and tx -> [0] & [1], and also changed the ports to range from 0->1, but, still I'm not able to connect to the device. I Have also tried to change the configure_IEEE_phy_speed_emaclite function, to the register as per suggestion(0x17), but still can't connect. The configurations inside the constraints file seem to be correct, I have used the master file that I've found on digilent's github and also i'm using the onboard ethernet that is soldered on the arty a7 35-t. 

I the eth_ref_clk is set to 25MHz, is it right or should I be doubling the frq?

create_clock -add -name phy_clk -period 20.00 -waveform {0 10} [get_ports ref_clk]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets ref_clk_IBUF]

## SMSC Ethernet PHY
set_property -dict { PACKAGE_PIN G14   IOSTANDARD LVCMOS33 } [get_ports { phy2rmii_crs_dv }]; #IO_L15N_T2_DQS_ADV_B_15 Sch=eth_crs
set_property -dict {PACKAGE_PIN G18    IOSTANDARD LVCMOS33} [get_ports { eth_ref_clk }];
set_property -dict { PACKAGE_PIN D18   IOSTANDARD LVCMOS33 } [get_ports { phy2rmii_rxd[0] }]; #IO_L21N_T3_DQS_A18_15 Sch=eth_rxd[0]
set_property -dict { PACKAGE_PIN E17   IOSTANDARD LVCMOS33 } [get_ports { phy2rmii_rxd[1] }]; #IO_L16P_T2_A28_15 Sch=eth_rxd[1]
set_property -dict { PACKAGE_PIN C17   IOSTANDARD LVCMOS33 } [get_ports { phy2rmii_rx_er }]; #IO_L20N_T3_A19_15 Sch=eth_rxerr
set_property -dict { PACKAGE_PIN H15   IOSTANDARD LVCMOS33 } [get_ports { rmii2phy_tx_en }]; #IO_L19N_T3_A21_VREF_15 Sch=eth_tx_en
set_property -dict { PACKAGE_PIN H14   IOSTANDARD LVCMOS33 } [get_ports { rmii2phy_txd[0] }]; #IO_L15P_T2_DQS_15 Sch=eth_txd[0]
set_property -dict { PACKAGE_PIN J14   IOSTANDARD LVCMOS33 } [get_ports { rmii2phy_txd[1] }]; #IO_L19P_T3_A22_15 Sch=eth_txd[1]

new.thumb.jpg.b11d081663929678c4b16951c6c47a83.jpg

 

Edited by hdx
added files

Share this post


Link to post
Share on other sites
  • 0

Hi,

Thank you for all the help, I really appreciate it :)

Ok I'll try 50MHz clock reference instead. However, if I remember correctly I had some problems getting the ethernet port to work as it was giving me on the pc that the ethernet port was off, will give it a try again anyways. Might be something with the pull-up as you've mentioned, as it needs to be switched to rmii mode

Regarding the ethernet port, I am using the arty a7 35-t dev board which has a ethernet connector by default onboard, same as can be found in this link: https://reference.digilentinc.com/reference/programmable-logic/arty-a7/reference-manual

 

Edited by hdx

Share this post


Link to post
Share on other sites
  • 0

I have tried to set the pin as pull-up, but I'm unsure whether this is correct or not?

Quote

set_property -dict { PACKAGE_PIN G16   IOSTANDARD LVCMOS33 } [get_ports { eth_rx_dv }]; #IO_L13N_T2_MRCC_15 Sch=eth_rx_dv
set_property PULLUP {TRUE} [get_ports eth_rx_dv];

 

Share this post


Link to post
Share on other sites
  • 0

Hi,

Here are two points which should be taken into account :

1) Reset time - strap's are applied after power on. FPGA configuration time can be much more. In this case special reset sequence after boot up is needed.

2) Internal pull-ups are weak. They can be not sufficient for set correct logic level. As per TI datasheet 2.2k pullup is required.

https://forums.xilinx.com/t5/Processor-System-Design/Zynq-7000-Pull-up-down-Resistor-Value-Thread/td-p/939389
https://www.xilinx.com/support/answers/67577.html

Share this post


Link to post
Share on other sites
  • 0

Hi,

After several hours of trail and error, trying to debug and understand what the problem is, I finally managed to get it to work! 

The solution was as you've mentioned with the MII mode. I had to set the eth_rx_dv pin manually to high to set the PHY into RMII mode, this was solved finally by creating a gpio block with one output and setting the default value to 0xFFFFFFFF. Afterwards the rmii mode was activated!

final.thumb.jpg.914e72b64f8400639c866f9c4ff38f2b.jpg

Thank you for all the help @toshas!

Edited by hdx

Share this post


Link to post
Share on other sites
  • 0

I have not made any changes on the SDK code itself, I am using the "echo server" application that can be created and generated by anybody that are using the xilinx sdk application. 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now