Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

UDP packets via TSE

Altera_Forum
Honored Contributor II
3,173 Views

Hi, I am working on a project that requires me to send data packets from DE2-115 to a PC. since I need a transfer rate in access of 500 Mbps, i decided to do it using Ethernet using Triple Speed Ethernet IP from altera. But I am facing some problem with the packet fabrication.  

 

what i did 

The hardware side of it is very similar to the "using triple-speed ethernet on de2-115 boards" (ftp://ftp.altera.com/up/pub/altera_material/12.0/tutorials/de2-115/using_triple_speed_ethernet.pdf) tutorial. I used TSE and DMA to send data from ethernet. it works fine. I think...  

On the software side, I used the tse_tutorial.v provided with the tutorial but changed it arround to make the following changes: 

 

Firstly, I made the following struct to help make ethernet, ip and udp headers 

 

struct etheader { unsigned char preamble; unsigned char MACdestination; unsigned char MACsource; unsigned char proto; }; struct ipheader { unsigned char iph_type; unsigned char iph_dscp; unsigned short int iph_len; unsigned short int iph_ident; unsigned char iph_flag; unsigned char iph_offset; unsigned char iph_ttl; unsigned char iph_protocol; unsigned short int iph_chksum; unsigned char iph_sourceip; unsigned char iph_destip; }; // UDP header's structure struct udpheader { unsigned short int port; unsigned short int udph_len; unsigned short int udph_chksum; }; struct crc32body { unsigned int crc_chksum; unsigned char end; };  

 

Then I made the following function to compute the ipchecksum and crc32: 

unsigned int crc32c(unsigned char *message, unsigned int last) { int i, j; unsigned int byte, crc, mask; static unsigned int table; /* Set up the table, if necessary. */ if (table == 0) { for (byte = 0; byte <= 255; byte++) { crc = byte; for (j = 7; j >= 0; j--) { // Do eight times. mask = -(crc & 1); crc = (crc >> 1) ^ (0xEDB88320 & mask); } table = crc; } } /* Through with table setup, now calculate the CRC. */ i = 0; crc = 0xFFFFFFFF; while ((byte = message) != 0) { crc = (crc >> 8) ^ table; i = i + 1; } return ~crc; } unsigned short csum(unsigned short *buf, int nwords, int mwords) { // unsigned short *sht_buf = (buf + mwords ); unsigned long sum; for(sum=0; nwords>0; nwords--) sum += *sht_buf++; sum = (sum >> 16) + (sum &0xffff); sum += (sum >> 16); return (unsigned short)(~sum); } unsigned short int htons(unsigned short int x) {# if BYTE_ORDER == LITTLE_ENDIAN u_char *s = (u_char *) &x; return (unsigned short int)(s << 8 | s);# else return x;# endif }  

the codes are correct to my understanding. 

 

after initializing the TSE core, I started with the making to the transmission frame: 

// frame buffer unsigned char rx_frame // size of frame unsigned frame Tx_UDPpayloadlength = 180 unsigned int total_size = sizeof(struct etheader)+Tx_UDPpayloadlength+ sizeof(struct ipheader)+sizeof(struct udpheader) + 0x0004; // structure the frame unsigned char MAC_des = {0x78,0x84,0x3c,0xcf,0xf4,0x25};// laptop unsigned char MAC_src = {0x01,0x60,0x6E,0x11,0x02,0x0F}; unsigned char IP_des = {192,168,0,2}; unsigned char IP_src = {192,168,0,44}; struct etheader *eth = (struct etheader * ) tx_frame; struct ipheader *ip = (struct ipheader *) (tx_frame + sizeof(struct etheader) ); struct udpheader *udp = (struct udpheader *) (tx_frame + sizeof(struct etheader)+ sizeof(struct ipheader)); struct crc32body *crc_32b = (struct crc32body *) (tx_frame + sizeof(struct etheader)+ sizeof(struct ipheader)+sizeof(struct udpheader) + Tx_UDPpayloadlength); // Fabricate the ethernet header or we can use the int lp=0; for (lp=0; lp < 2; lp++) // Ethernet preamble eth->preamble = 0x00; for (lp=0; lp < 6; lp++) // Ethernet preamble { eth->MACsource = MAC_src; eth->MACdestination = MAC_des; if (lp < 4) { ip->iph_sourceip = IP_src; ip->iph_destip = IP_des; } } eth->proto=0x08; eth->proto=0x00; // Fabricate the IP and UDP header ip->iph_type = 0x45; ip->iph_dscp = 0x00; ip->iph_len = Tx_UDPpayloadlength + sizeof(struct ipheader) + sizeof(struct udpheader); ip->iph_ident = 0x0000; ip->iph_offset = 0x00; ip->iph_flag = 0x00; ip->iph_ttl = 0x80; // time to live ip->iph_protocol = 0x11; // UDP = 17 udp->port=htons(1024);//0x04; udp->port=0x00; udp->port=htons(1024);//=0x04; udp->port=0x00; //udp->port=htons(1024); udp->udph_len=htons(sizeof(struct udpheader)+Tx_UDPpayloadlength); udp->udph_chksum=0x0000; ip->iph_chksum=csum((unsigned short *)tx_frame, sizeof(struct ipheader) + sizeof(struct udpheader), sizeof(struct etheader) ); crc_32b->crc_chksum =crc32c(tx_frame, total_size-0x0005); crc_32b->end = '\0';  

 

this in should make a frame that send date from 192.168.0.44:1024 to 129.168.0.2:1024. I used tcpdump to validate my packets. This is what I get:  

<time> IP truncated-ip - 53035 bytes missing! 192.168.0.44.1024 > 192.168.0.2.1024: UDP, length 180 

 

commands for sending packet: 

alt_avalon_sgdma_construct_mem_to_stream_desc( &tx_descriptor, &tx_descriptor_end, tx_frame, total_size, 0, 1, 1, 0 ); // Set up non-blocking transfer of sgdma transmit descriptor alt_avalon_sgdma_do_async_transfer( sgdma_tx_dev, &tx_descriptor );  

 

TSE settings: 

 

--- Quote Start ---  

Select the following options: Enable MAC 10/100 half duplex support, Include statistics counters,Align packet headers to 32-bit boundary, and Include MDIO module (MDC/MDIO),  

 

--- Quote End ---  

 

 

Maybe someone has experience with this to know where I am going wrong!
0 Kudos
8 Replies
Altera_Forum
Honored Contributor II
757 Views

found the problem. had to change the line: 

 

ip->iph_len = Tx_UDPpayloadlength + sizeof(struct ipheader) + sizeof(struct udpheader);  

to  

 

ip->iph_len = htons(Tx_UDPpayloadlength + sizeof(struct ipheader) + sizeof(struct udpheader)); 

 

silly me, wasted the entire 2 days solving this !! 

 

hopefully this code will help others to make a upd TX :) 

 

also, i just realized, if you are not plugging in the device to a hub but sending directly to PC via cross over cable, you donot need to add the ip and udp header. just sending the data with its MAC header will allow you to capture the packet using a network sniffing code that binds to the network device.
0 Kudos
Altera_Forum
Honored Contributor II
757 Views

The bandwidth of the network analyzer packet capture interface is much lower than the native OS bandwidth. I doubt you will be able to get 500 mbps out of it. Remember also that UDP doesn't guarantee delivery of all data. If it is critical to get all data use TCP, or build your self a retransmit mechanism.

0 Kudos
Altera_Forum
Honored Contributor II
757 Views

 

--- Quote Start ---  

The bandwidth of the network analyzer packet capture interface is much lower than the native OS bandwidth. I doubt you will be able to get 500 mbps out of it. Remember also that UDP doesn't guarantee delivery of all data. If it is critical to get all data use TCP, or build your self a retransmit mechanism. 

--- Quote End ---  

 

 

500 Mbps will probably not be possible for the DE2-115 to TX at. right now i am maxing out at 348 Mbps with payload as 1300. I will try increasing the clock to see if it helps, but i doubt it will help. If not than I am planning do some additional data processing in the fpga to "compress" the data. If all else fails, i could use usb and the second ethernet as well.  

 

right now i am designing the system in such a way that packet loss will not be an issue, but there are too many packet drops, than i have will do a write a retransmit protocol.  

 

but just out of curiosity, what other mode of data transfer can be faster than Ethernet on this board. I would imagine usb will not be able to use full 480 Mbps either.
0 Kudos
Altera_Forum
Honored Contributor II
757 Views

USB devices only transmit when requested by the host. This is determined by the OS on the PC. You can get a rough idea by timing how long it takes to copy a large file from a USB drive to your computer.  

 

You could only use a 2nd Ethernet if it is going to a different Ethernet port on your PC. Most hubs just drop packets from other ports while they are receiving from one.
0 Kudos
Altera_Forum
Honored Contributor II
757 Views

Hello Dear  

sarwar_r87 

Can you give me example file of send udp using tse ? 

Thank's alot 

ahmadm@chmail.ir
0 Kudos
Altera_Forum
Honored Contributor II
757 Views

Hi, All codes and steps are listed in the first post. I am unsure what you want

0 Kudos
Altera_Forum
Honored Contributor II
757 Views

Hi all 

How can i receive udp packet on de2-115 using tse with nios ii? 

Thanks.
0 Kudos
Altera_Forum
Honored Contributor II
757 Views

hello&#65292;i am now working with de2i 150 development Kit which is significiantly similar with de2 115 ,my project is similar with yuors ,sending data from FPGA directly to the PC which needs a speed at least 200Mbps, I am confused now, so i wonder if you could generously send your design files to me or give me some helpful advice.Thank you 

my email address :sys@mail.ustc.edu.cn
0 Kudos
Reply