Ethernet module

Technical questions regarding the XTC tools and programming with XMOS.
User avatar
kean
Member++
Posts: 19
Joined: Tue Sep 27, 2011 11:49 am

Ethernet module

Post by kean »

Hi everybody

I am writing an application for XC-3 development board which sends and receivs data from ethernet. I managed to use the ethernet module provided by XMOS, but in my specific case I need to strip it down, since I basically only need the part that reads and sends data (bytes, words, whatever) directly to the MII. So I tried to reuse the ethernet module code. I have strange annoying issues when trying to read data though. My thread can read data from the MII, but it partially drops it. I guess I can say that around 20/30% of the words are dropped. It looks like my thread doesn't keep up with the 100Mbps ethernet speed, which is strange.

Here is a copy of the code that I am dealing with:

Code: Select all

on stdcore[2]: mii_interface_t mii =
  {
    XS1_CLKBLK_1,
    XS1_CLKBLK_2,

    PORT_ETH_RXCLK_0,
    PORT_ETH_RXER_0,
    PORT_ETH_RXD_0,
    PORT_ETH_RXDV_0,

    PORT_ETH_TXCLK_0,
    PORT_ETH_TXEN_0,
    PORT_ETH_TXD_0,
  };

#pragma unsafe arrays
void eth_rx(in port p_mii_rxdv, in buffered port:32 p_mii_rxd)
{
	unsigned rx_data[500];
	int i, eof;

	p_mii_rxdv when pinseq(0) :> int lo;	//Wait end of current frame

	while(1)
	{
		p_mii_rxd when pinseq(0xD) :> int sof;	//Wait start of new frame

		for(i=0, eof=0; eof==0; i++)
		{
			select
			{
				case p_mii_rxd :> rx_data[i]:	//Read frame word
					break;
				case p_mii_rxdv when pinseq(0) :> int lo:	//End of frame
					eof=1;
					break;
			}
		}
		//After the loop I check rx_data contents...
	}
}

int main()
{
	par
	{
		on stdcore[2]:
		{
			phy_init(clk_smi, p_mii_resetn, smi, mii);	//Function declared in ethernet module
			eth_rx(mii.p_mii_rxdv, mii.p_mii_rxd);
		}
	}
	return 0;
}
As can be seen I just implemented a very small function (eth_rx) to read raw bytes of a frame. When I compare the content of rx_data with the actual frame's data (sniffed with wireshark) I can always find some difference.

I hope someone can tell me why...what am I missing?


User avatar
Berni
Respected Member
Posts: 363
Joined: Thu Dec 10, 2009 10:17 pm

Post by Berni »

It looks like you are initializing and using the PHY interface at the same time.

The par{} statement tells the processor to run there two functions in parallel as separate threads and keep the threads going until the function returns.
User avatar
Bianco
XCore Expert
Posts: 754
Joined: Thu Dec 10, 2009 6:56 pm

Post by Bianco »

Berni wrote:It looks like you are initializing and using the PHY interface at the same time.

The par{} statement tells the processor to run there two functions in parallel as separate threads and keep the threads going until the function returns.
The par statement will not execute the statements in the on stdcore block in parallel.

This would:

Code: Select all

int main()
{
   par
   {
      on stdcore[2]:
      {
         par
         {
             phy_init(clk_smi, p_mii_resetn, smi, mii);   //Function declared in ethernet module
             eth_rx(mii.p_mii_rxdv, mii.p_mii_rxd);
         }
      }
   }
   return 0;
}
User avatar
Andy
Respected Member
Posts: 279
Joined: Fri Dec 11, 2009 1:34 pm

Post by Andy »

Hi kean,

When p_mii_rxdv goes low it may still have data in the buffered p_mii_rxd port that has been sampled by the port but not yet input by the processor. Hence, you may need to do final inputs on the port to get the remaining nibbles of data.

An example MII receive that does this is described in the XC programming guide on page 66: https://www.xmos.com/download/public/Pr ... 1.0%29.pdf

It checks the number of bits left in the port by calling the function endin() in xs1.h.

You also need to make sure that your code that checks rx_data after receiving a packet is smaller than the Ethernet interframe gap of 960 ns if you wish to receive back to back frames without dropping data. If it's not, you can always transfer the words over a channel to another thread and do the processing there.
User avatar
kean
Member++
Posts: 19
Joined: Tue Sep 27, 2011 11:49 am

Post by kean »

Hi andy

Thank you for your reply. Unfortunately the problem is still there. I had already seen the code example in the XC programming guide. This was just a simple and stupid example to show that I am reading data from the ethernet port. My problem is that when I check the contents of rx_data I am not only missing some nibble at the end, but also several entire words in the middle of the frame.
User avatar
Andy
Respected Member
Posts: 279
Joined: Fri Dec 11, 2009 1:34 pm

Post by Andy »

kean wrote:Hi andy

Thank you for your reply. Unfortunately the problem is still there. I had already seen the code example in the XC programming guide. This was just a simple and stupid example to show that I am reading data from the ethernet port. My problem is that when I check the contents of rx_data I am not only missing some nibble at the end, but also several entire words in the middle of the frame.
That's unusual. Can you check that you're compiling with O2 or O3 optimisations?

How are you checking the contents? If you are printing out the entire packet I'd expect this to break the real time behaviour of the code. Do you always receive the first packet correctly?
User avatar
kean
Member++
Posts: 19
Joined: Tue Sep 27, 2011 11:49 am

Post by kean »

To check what has been read I stop the execution with a breakpoint after the RXDV signal goes down and I display the memory contents.

Maybe you are right about the optimization option (hope so), in fact my code is not being optimized for the moment. I'll try as soon as I can get my hands on the XC-3 and I'll let you know.

Anyway before I had already taken a look at the generated assembly code and it didn't scary me that much, since the number of instructions to be executed was less than 32... If I am not missing something when on the core are running up to 4 threads, each one of these should have time to execute 32 instructions (@100MHz) before that one word has been received from the mii.
User avatar
kean
Member++
Posts: 19
Joined: Tue Sep 27, 2011 11:49 am

Post by kean »

PROBLEM SOLVED! :P

You were right about the optimisation Andy. Thank you a lot!