Xilinx/xup_vitis_network_example

Does host_xrt supports U50?

sergey-gra opened this issue · 15 comments

Hello. I have point to point connected two U50 FPGA. Is it possible to run host_xrt example on U50?
I tried to run that example on my u50 devices, but couldn't receive anything. Sender prints that packet was sent, but receiver part shows nothing.
@fpgafais

Thank you for your reply @fpgafais. I have already did changes that you mentioned. As host_xrt example based on basic example, I suppose maybe the problem can be connected with having 100 GbE capable NIC as mentioned in basic example assumptions. Note that I haven't setup that. What do you think?

Did you try to check the link status? You can do so by reading the AlveoVnxCmac register "stat_rx_status" from within the AlveoVnxLink. We'll facilitate access to this register and make proper status checks in send/receive functions in the future.

I checked "stat_rx_status" and it returned 192 at the first calling, after that returned always 3, which I suppose mean that link status is false. As I understand from readRegister function link status is true if returned value is 0.
Note that with Jupiter Notebook pynq examples link status returns true.

Right, the registers require a double read, also from the Python package. However, the value 3 in rx_status should mean link up and aligned so everything seems to be all right. The return value from the readRegister function is the actual register value, the comment is indeed misleading and will be fixed.
Are you able to transfer data between the U50s using Jupyter?

Yes, I used vnx-basic-image-transfer.ipynb Notebook for image transferring between two U50 devices in the same host and it worked.

Hi @sergey-gra,

I would be good if you can post the code snippet of the rx and tx code here. and how you execute the code.

Hi @mariodruiz. Below I provide rx and tx code.

TX part

// Copyright (C) FPGA-FAIS at Jagiellonian University Cracow
//
// SPDX-License-Identifier: BSD-3-Clause

#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <unistd.h>

#include "fpga_device.h"
#include "alveo_vnx_link.h"


int main(int argc, char *argv[]) {

    std::string xclbin;
    std::string file_to_transfer;
    int alveo_id;

    if (argc != 4) {
        std::cout << "Usage: ./tx <xclbin_file> <alveo_id> <file_to_transfer>" << std::endl;
        return EXIT_FAILURE;
    }
    else {
        std::ifstream f(argv[1]);
        if (f.good() == false) {
            std::cout << "Make sure the path to the bitfile <xclbin_file> is correct" << std::endl;
            return EXIT_FAILURE;
        }
        f.close();
        xclbin = std::string(argv[1]);

        alveo_id = atoi(argv[2]);
        if ( alveo_id < 0 || alveo_id > 15 ) {
            std::cout << "Make sure Alveo ID is a correct number" << std::endl;
            return EXIT_FAILURE;
        }

        f = std::ifstream(argv[3]);
        if (f.good() == false) {
            std::cout << "Make sure the path to the file <file_to_transfer> is correct" << std::endl;
            return EXIT_FAILURE;
        }
        f.close();
        file_to_transfer = std::string(argv[3]);
    }

    auto u50 = FpgaDevice(alveo_id);

    // fetch the string with the card name and compare to the target
    std::string name = u50.getName();
    if ( name.compare(ALVEO_DEVICE) != 0) {
        std::cout << ALVEO_DEVICE << std::endl;
        std::cout << name << std::endl;
        std::cerr << "ERR: FpgaDevice: could not connect to the target accelerator card" << std::endl;
        return EINVAL;
    }
    std::cout << "Device created: " << u50.getName()<<std::endl;

    auto uuid = u50.loadBitfile(xclbin);
    std::cout << "Bitfile loaded: " << uuid << std::endl;


    auto l0 = AlveoVnxLink(u50, 0);
    l0.setMyAddresses("192.168.0.5", "00:0a:35:02:9d:0a", 60512);

    std::ifstream infile(file_to_transfer, std::ios::binary | std::ios::ate);
    size_t infile_size = infile.tellg();
    infile.seekg(0, std::ios::beg);

    char *tx_buf = new char[infile_size];
    infile.read(tx_buf, infile_size);
    infile.close();

    std::cout<< "Transfering file " << file_to_transfer << ", " << infile_size << " bytes" << std::endl;

    l0.sendTo("192.168.0.10", 61277, tx_buf, infile_size);

    std::cout << "Packet sent" << std::endl;

    return 0;
}

RX part

// Copyright (C) FPGA-FAIS at Jagiellonian University Cracow
//
// SPDX-License-Identifier: BSD-3-Clause

#include <iostream>
#include <fstream>
#include <string>
#include <unistd.h>

#include "fpga_device.h"
#include "alveo_vnx_link.h"


int main(int argc, char *argv[]) {

    std::string xclbin;
    int alveo_id;


    if (argc != 3) {
        std::cout << "Usage: ./rx <xclbin_file> <alveo_id>" << std::endl;
        return EXIT_FAILURE;
    }
    else {
        std::ifstream f(argv[1]);
        if (f.good() == false) {
            std::cout << "Make sure the path to the bitfile <xclbin_file> is correct" << std::endl;
            return EXIT_FAILURE;
        }
        f.close();
        xclbin = std::string(argv[1]);

        alveo_id = atoi(argv[2]);
        if ( alveo_id < 0 || alveo_id > 15 ) {
            std::cout << "Make sure Alveo ID is a correct number" << std::endl;
            return EXIT_FAILURE;
        }
    }

    auto u50 = FpgaDevice(alveo_id);

    // fetch the string with the card name and compare to the target
    std::string name = u50.getName();
    if ( name.compare(ALVEO_DEVICE) != 0) {
        std::cerr << "ERR: FpgaDevice: could not connect to the target accelerator card" << std::endl;
        return EINVAL;
    }

    std::cout << "Device created: " << u50.getName()<<std::endl;


    auto uuid = u50.loadBitfile(xclbin);
    std::cout << "Bitfile loaded " << uuid << std::endl;


    auto l1 = AlveoVnxLink(u50, 0);
    l1.setMyAddresses("192.168.0.10", "00:0a:35:02:9d:e5", 61277);

    char *rx_buf = new char[1000000];
    size_t size = l1.receive("192.168.0.5", 60512, rx_buf);

    std::cout << "Packet received " << size << " bytes" << std::endl;

    std::ofstream outfile("out.bin", std::ios::binary | std::ios::ate);
    outfile.write(rx_buf, size);
    outfile.close();


    return 0;
}

Steps for execution
./rx ../../../basic.intf0.xilinx_u50_gen3x4_xdma_2_202010_1/vnx_basic_if0.xclbin 0
Output:

Device created: xilinx_u50_gen3x4_xdma_base_2
Bitfile loaded d3b97163-a829-8c56-82f3-0b9421e1d551
Link status is: 192
l1 created

And it never ends.

./tx ../../../basic.intf0.xilinx_u50_gen3x4_xdma_2_202010_1/vnx_basic_if0.xclbin 2 ../../test.txt
Output:

Device created: xilinx_u50_gen3x4_xdma_base_2
Bitfile loaded: d3b97163-a829-8c56-82f3-0b9421e1d551
Link status is: 192
l0 created
Transfering file ../../test.txt, 64 bytes
l0 header 80000040
l0 data transfered 64 bytes
l0 size left: 0 total_transferred_size 64
l0 packet sent
Packet sent

Hi @sergey-gra, could you please try to have the Rx part done with jupyter and try to receive a packet from the C++ Tx? Then you should be able to easily access the link status and registers of the cmac and network layer cores.

Hi @fpgafais. Will try to reproduce it and let you know. Thank you.

Hi @sergey-gra

There is a new C++ driver here https://github.com/Xilinx/xup_vitis_network_example/tree/master/xrt_host_api, unrelated to the one you have tried.

Mario

Hi @mariodruiz

Thank you very much for provided information. I'll take a look.

Hi @mariodruiz

Do I need a NIC sheel/driver for running the ping example of xrt_host_api? I am encountering an issue where, after configuring a new IP address on the FPGA device and attempting to ping it, the ping operation fails.

Here are output logs:

Link interface cmac_0: true
RS-FEC enabled: false
setting up IP 10.1.212.100 to interface cmac_0
Pinging the Alveo card on interface cmac_0, this takes 4s...
PING 10.1.212.100 (10.1.212.100) 56(84) bytes of data.

--- 10.1.212.100 ping statistics ---
5 packets transmitted, 0 received, 100% packet loss, time 3209ms

Interface cmac_0 is unreachable.

Hi @sergey-gra,

You need a standard NIC in the same server within the same sub network that is connected to the FPGA via QSFP26 to be able to run the ping test.

Mario

Closing this issue as the C++ driver supports all the boards.