Forum Discussion

2258432's avatar
2258432
Icon for Occasional Contributor rankOccasional Contributor
2 years ago
Solved

How to correctly read data from FIFO on HPS and send it out through HPS Ethernet

I am a novice. I have two clone V soc boards, and I generated some video data on the FPGA side of one of them and sent it to the HPS side through the H2F AXI bus. I want to send it to the second board through Ethernet. Before doing so, I used signalTap simulation to observe whether the HPS side can correctly read the data in the FIFO, but it seems to differ significantly from the written data. Can someone help me? Any help will be greatly appreciated.

Thank you in advance.qsyssignalTap

/* Code for reading data on the HPS side   */
#include <stdio.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdint.h>
#include <unistd.h>


#define HW_REGS_BASE (0xC0000000)
#define HW_REGS_SPAN (0x04000000)
#define ALT_H2F_OFST  (0xFF500000)
#define HW_REGS_MASK (HW_REGS_SPAN - 1)
#define LED_PIO_OFFSET (0x00000408)

int main()
{
    int fd;
    void *h2f_axi_base;
    void *led_pio_addr;


    fd = open("/dev/mem", O_RDWR | O_SYNC);
    if (fd == -1) {
        perror("could not open /dev/mem\n");
        return 1;
    }


    h2f_axi_base = mmap(NULL, HW_REGS_SPAN, PROT_READ | PROT_WRITE, MAP_SHARED, fd, HW_REGS_BASE);
    if (h2f_axi_base == MAP_FAILED) {
        perror("could not mirror the H2F AXI address\n");
        close(fd);
        return 1;
    }


    led_pio_addr = h2f_axi_base + ( ( unsigned long ) (ALT_H2F_OFST + LED_PIO_OFFSET) & (unsigned long ) (HW_REGS_MASK) );

    while (1) {
        // read data
        uint32_t data = *((volatile uint32_t *)led_pio_addr);

    }

    munmap(h2f_axi_base, HW_REGS_SPAN);
    close(fd);

    return 0;
}

12 Replies

    • 2258432's avatar
      2258432
      Icon for Occasional Contributor rankOccasional Contributor

      Hi,

      Thanks again for your help.

      Best regard.

    • 2258432's avatar
      2258432
      Icon for Occasional Contributor rankOccasional Contributor

      Hello EBERLAZARE,


      After the FIFO of the sending board, I used mSGDMA to first send the data into the HPS DDR, and then used the sendto function on the HPS side to send this data. After receiving the data on the HPS side of the receiving board, the data is sent to the HPS DDR through the mmap function. Next, I will study how to use PL330 DMA to write data from the HPS side to the HPS DDR.

      Thank you again for your help. Please close this thread.

      Best regard.

  • 2258432's avatar
    2258432
    Icon for Occasional Contributor rankOccasional Contributor

    I changed the FIFO to a dual port FIFO, and then used the same code to read the data in the FIFO. Everything looked normal. But when I added the function to send data, the reading of the data seemed to run counter to the correct result.

    FIFO has a depth of 2048 and a width of 32. qsys2reading datasending data

    /*   code for sending data    */
    #include <stdio.h>
    #include <fcntl.h>
    #include <sys/mman.h>
    #include <stdint.h>
    #include <unistd.h>
    #include <string.h>
    #include <arpa/inet.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    
    #define HW_REGS_BASE (0xC0000000)
    #define HW_REGS_SPAN (0x04000000)
    #define ALT_H2F_OFST  (0xFF500000)
    #define HW_REGS_MASK (HW_REGS_SPAN - 1)
    #define LED_PIO_OFFSET (0x00000408)
    #define DEST_IP_ADDR "192.168.0.11"
    #define DEST_PORT 1234
    
    int main()
    {
        int fd;
        void *h2f_axi_base;
        void *led_pio_addr;
        int sock;
        struct sockaddr_in dest_addr;
    
        fd = open("/dev/mem", O_RDWR | O_SYNC);
        if (fd == -1) {
            perror("could not open /dev/mem\n");
            return 1;
        }
    
        h2f_axi_base = mmap(NULL, HW_REGS_SPAN, PROT_READ | PROT_WRITE, MAP_SHARED, fd, HW_REGS_BASE);
        if (h2f_axi_base == MAP_FAILED) {
            perror("could not mirror the H2F AXI address\n");
            close(fd);
            return 1;
        }
    
        led_pio_addr = h2f_axi_base + ((unsigned long)(ALT_H2F_OFST + LED_PIO_OFFSET) & (unsigned long)(HW_REGS_MASK));
    
        sock = socket(AF_INET, SOCK_DGRAM, 0);
        if (sock == -1) {
            perror("socket creation failed\n");
            munmap(h2f_axi_base, HW_REGS_SPAN);
            close(fd);
            return 1;
        }
    
        memset(&dest_addr, 0, sizeof(dest_addr));
        dest_addr.sin_family = AF_INET;
        dest_addr.sin_port = htons(DEST_PORT);
        if (inet_pton(AF_INET, DEST_IP_ADDR, &(dest_addr.sin_addr)) <= 0) {
            perror("inet_pton failed\n");
            munmap(h2f_axi_base, HW_REGS_SPAN);
            close(sock);
            close(fd);
            return 1;
        }
    
        while (1) {
    
            uint32_t data = *((volatile uint32_t *)led_pio_addr);
    
            if (sendto(sock, &data, sizeof(data), 0, (struct sockaddr *)&dest_addr, sizeof(dest_addr)) == -1) {
                perror("sendto failed\n");
                break;
            }
    
        }
    
        close(sock);
    
        munmap(h2f_axi_base, HW_REGS_SPAN);
        close(fd);
    
        return 0;
    }
  • Hi,


    I’m glad that your question has been addressed, I now transition this thread to community support. If you have a new question, Please login to ‘https://supporttickets.intel.com’, view details of the desire request, and post a feed/response within the next 15 days to allow me to continue to support you. After 15 days, this thread will be transitioned to community support. The community users will be able to help you on your follow-up questions.



    p/s: If any answer from the community or Intel Support are helpful, please feel free to give best answer or rate 4/5 survey.