UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Observer pupkin
Observer
3,200 Views
Registered: ‎09-10-2016

Numerous problems with generated HDL

Greetings,

 

Recently we've been experiencing numerous issues with HLS generating buggy verilog causing co-simulation to hang or to produce wrong results. Most of the time they appear to be caused by broken control state machines.

 

Here is one example I managed to isolate. The idea is func_a() picks up interesting bits from input stream and sends it to func_b() for the processing though a FIFO. The code as shown hands co-simulation. If I comment out PIPELINE pragma in func_b(), everything works, but func_b() takes unacceptably long time for each iteration.

 

I appreciate any suggestions.

 

#include <hls_stream.h>

struct Q
{
    int  x;
    bool eof;
};

void func_a(hls::stream<int>&   sin, hls::stream<Q>& queue)
{
    Q q;
    
    for (int i = 0; i < 100; i++)
    {
        int x = sin.read();
        if (i >= 10 && i < 15)
        {
            q.x = x;
            q.eof = false;
            queue.write(q);
        }
    }
    
    q.x = 0;
    q.eof = true;
    queue.write(q);
}


void func_b(hls::stream<Q>& queue, hls::stream<int>&   sout)
{
    for(;;)
    {
#pragma HLS PIPELINE II=1
        Q q  = queue.read();
        if (q.eof)
            break;
        int y = q.x/3;    // lengthy operation
        sout.write(y);
    }
}


void hls_top(hls::stream<int>& sin, hls::stream<int>& sout)
{
#pragma HLS DATAFLOW
    hls::stream<Q> queue;
#pragma HLS STREAM variable=queue depth=1000

    func_a(sin,  queue);
    func_b(queue, sout);
}

and a testbench

#include <stdio.h>
#include <hls_stream.h>

void hls_top(hls::stream<int>& sin, hls::stream<int>& sout);

int main()
{
    hls::stream<int> sin, sout;
    
    for (int i = 0; i < 100; i++)
        sin.write(i);
    
    hls_top(sin, sout);
    
    while (!sout.empty())
        printf("%d\n", sout.read());
}

 

0 Kudos
1 Reply
Observer pupkin
Observer
3,161 Views
Registered: ‎09-10-2016

Re: Numerous problems with generated HDL

OK as promised, here is another co-sim failure case:

#include <hls_stream.h>
#include <hls_fft.h>

typedef hls::ip_fft::config_t<hls::ip_fft::params_t> config_t;

int func_a
(
    config_t& config,
    int const table[1]
)
{
    return config.getDir() ? table[0] : -1;
}

void func_b
(
    int const           table[1],
    hls::stream<int>&   sout
)
{
#pragma HLS DATAFLOW
    config_t    config;
#pragma HLS data_pack   variable=config
#pragma HLS stream      variable=config
    config.setDir(1);

    sout.write(func_a(config, table));
}

void top
(
    int const           table[2][1],
    hls::stream<int>&   sout
)
{
    for (int i = 0; i < 2; i++)
        func_b(table[i],sout);
}

and a testbench:

#include <stdio.h>
#include <hls_stream.h>

void top(const int table[2][1], hls::stream<int>&   sout);

const int table[2][1] = { { 123 }, { 456 } };

int main()
{
    hls::stream<int>    sout;
    top(table,sout);
    for (int i = 0; i < 2; i++)
    {
        int val = sout.read();
        printf("%d\n", val);

        if (val != table[i][0])
        {
            printf("MISMATCH!\n");
            return -1;
        }
    }

    printf("All Good!\n");
    return 0;
}

It appears that table index gets passed into the function a couple of clock cycles too late and as a result the function uses old value. I tried passing index along as a separate variable, with the same result.

0 Kudos