FPGA, SoC, And CPLD Boards And Kits
FPGA Evaluation and Development Kits
Announcements
All support for Intel NUC 7 - 13 systems has transitioned to ASUS. Read latest update.
5843 Discussions

How to improve Ethernet transmission speed?

2258432
New Contributor I
927 Views

I generated some image data on the Cyclone V FPGA side, sent it to DDR3 through SGDMA, and finally sent it out from the HPS side using Ethernet.

 

However, the sending speed is not sufficient for the design needs. The current transmission rate is approximately 350Mbps, while the design requires approximately 880Mbps. How can I modify my design or Linux application to improve the transmission rate?

 

Can someone help me? Any help will be immensely appreciated.

 

Thank you in advance.

0 Kudos
11 Replies
2258432
New Contributor I
920 Views

I use the functions defined below to send data.

sendData(data, 0x189C000 "192.168.137.1", 12345);

#ifndef ETHERNET_SENDER_H
#define ETHERNET_SENDER_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <unistd.h>

void sendData(const uint8_t* data, int size, const char* destIP, int destPort) {
    struct sockaddr_in serverAddr;
    int sockfd;

    
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("socket");
        return;
    }

    
    int flags = fcntl(sockfd, F_GETFL, 0);
    if (flags < 0) {
        perror("fcntl");
        close(sockfd);
        return;
    }
    if (fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0) {
        perror("fcntl");
        close(sockfd);
        return;
    }

    // set   server  address
    memset(&serverAddr, 0, sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(destPort);
    serverAddr.sin_addr.s_addr = inet_addr(destIP);

     // Send the data in groups
    int blockSize = 1450; 
    int numBlocks = (size + blockSize - 1) / blockSize;
    int totalSent = 0;

for (int i = 0; i < numBlocks; i++) {
        int offset = i * blockSize;
        int blockBytes = (i == numBlocks - 1) ? (size - offset) : blockSize;

        ssize_t sentBytes = sendto(sockfd, data+offset, blockBytes, 0, (struct sockaddr*)&serverAddr, sizeof(serverAddr));

        totalSent += sentBytes;

}


    
    close(sockfd);
}


#endif // ETHERNET_SENDER_H
0 Kudos
ZiYing_Intel
Employee
894 Views

Hi,


May I know the image resolution that you use?


Best regards,

zying


0 Kudos
2258432
New Contributor I
863 Views

Hello,

 

Thanks for your help.

 

Sorry, I sent video data instead of image data. And my video resolution is 1280x720@60fps.

 

Best regards.

0 Kudos
ZiYing_Intel
Employee
799 Views

Hi,


May I know you are using which IP in your design?


Best regards,

zying


0 Kudos
2258432
New Contributor I
784 Views

Hello Zying,

 

I use the Cyclone V board to send data to the PC, and the IP address of the board is 192.168.137.245, while the IP address of the PC is 192.168.137.1.

 

Thanks.

0 Kudos
ZiYing_Intel
Employee
755 Views

Hi,


Thanks for your reply. What I means is Intellectual property (IP).

For example Ethernet IP, embedded IP or other etc....


Also , are you using provided example design ? or this is your custom design ?


Regards,

ZiYing_Intel


2258432
New Contributor I
745 Views

Hello,

 

Sorry for misunderstanding your meaning. I downloaded the GHRD project for Cyclone V from Rocketboards and made modifications based on GHRD. On the FPGA side, I used FIFO and SGDMA IPs, but on the HPS side, I did not use IP. I did not use Ethernet IP, just wrote code on the HPS side to read the data in DDR3 and send it through the sendData function.

 

Thanks.

2258432_0-1701739286387.png

 

 

 

 

//main code
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "sgdma_dispatcher.h"
#include "sgdma_dispatcher_regs.h"
#include "ethernet_sender.h"

#define DISPATCHER_CSR_BASEADDR_W 0xC0001000
#define DISPATCHER_DESC_BASEADDR_W 0xC0002000
#define DISPATCHER_CSR_BASEADDR_R 0xC0003000
#define DISPATCHER_DESC_BASEADDR_R 0xC0004000

#define HPS_MEM_STORE_STARTADDR 0x10000000

#define FRAME_WIDTH 1280
#define FRAME_HEIGHT 720
#define PIXEL_FRAME 14
#define PIXEL_SIZE 2
#define FRAME_SIZE (FRAME_WIDTH * FRAME_HEIGHT * PIXEL_FRAME * PIXEL_SIZE)

int main(int argc, char* argv[]) {
    int mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
    if (mem_fd == -1) {
        perror("Error opening /dev/mem");
        return -1;
    }

    // Map the HPS DDR3 memory region to user space
    uint8_t* data = (uint8_t*)mmap(NULL, 0x2FFFFFFF, PROT_READ, MAP_SHARED, mem_fd, HPS_MEM_STORE_STARTADDR);
    if (data == MAP_FAILED) {
        perror("Error mapping DDR3 memory");
        close(mem_fd);
        return -1;
    }

    // Create dispatcher control
    tcSGDMADispatcher write_dispatcher(DISPATCHER_CSR_BASEADDR_W, DISPATCHER_DESC_BASEADDR_W, 0);

    // Create descriptors
    tsSGDMADescriptor write_descriptor = {0};

   
 while (1) {

        
        write_descriptor.write_addr = HPS_MEM_STORE_STARTADDR;
        write_descriptor.length = FRAME_SIZE;
        write_descriptor.control.msBits.end_on_eop = 1;
        write_descriptor.control.msBits.go = 1;

        write_dispatcher.WriteDescriptor(write_descriptor);   

        sendData(data, FRAME_SIZE, "192.168.137.1", 12345); 
      

     }

    // Unmap the DDR3 memory region and close /dev/mem
    munmap(data, 0x2FFFFFFF);
    close(mem_fd);

    return 0;
}

 

 

 

 

 

0 Kudos
ZiYing_Intel
Employee
666 Views

Hi,

 

Can you elaborate more about this?

 

How much is the bandwidth of from DDR3 to HPS through SGDMA ?

How much of bandwidth degradation is in HPS ?

How much of transferring bandwdth is through Ethernet ?

Where is the bottle neck in data path from/to ?

Is ethernet link 1G link ?

 

Best regards,

Zying


2258432
New Contributor I
628 Views

Hello,

 

Sorry, I'm not sure how to measure the bandwidth of SGDMA. I will describe the complete process of data movement to you.

 

The data is output by video sensors with a resolution of 1280x720@56fps and the format is RGB565. Afterwards, the data is sent to FIFO, then to DDR3 through SGDMA, and finally to PC using the sendData function on the HPS side. The receiving rate measured on the PC side is about 350Mbps, and I have tried using Wireshark to capture packets, but there was no data loss. I am sure the Ethernet connection speed is 1Gbps.

 

I have also tried sending data directly from HPS to PC, and the fastest speed can reach 750Mbps. However, when sending video data from FPGA, the speed drops to 350Mbps. By the way, I use a CAT5E network cable.

 

The video sensor is driven by an internal clock, with a frequency of 145.6 MHz and a data width of 8 bits.

 

Thanks for your patient help.

 

Regards.

0 Kudos
ZiYing_Intel
Employee
518 Views

Hi,

 

I am not sure where the bottle neck is and below is my suggestion:

  1. You can try to count in the video blanking area(vertical and horizontal) and do the testing again to see whether the ethernet speed issue still exist anot.
  2. Adjust the resolution and refresh rate

 

Besides that, you can refer the design in link below:

  1. https://www.intel.com/content/www/us/en/support/programmable/support-resources/design-examples/design-store.html?q=niosV&s=Relevancy
  2. https://www.rocketboards.org/foswiki/Main/WebHome

 

Best regards,

zying


0 Kudos
ZiYing_Intel
Employee
478 Views

Hi,


I now transition this thread to community support. If you have a new question, feel free to open a new thread to get the support from Intel experts. Otherwise, the community users will continue to help you on this thread.


Best regards,

zying


0 Kudos
Reply