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!

## High-Level Synthesis (HLS)

Showing results for
Do you mean

## Enforcing a interface to be output

Solved
Highlighted
Observer
Posts: 18
Registered: ‎08-07-2014

# Enforcing a interface to be output

Hello!

I'm starting playing with HLS by writing a small code. I'm using Vivado_HLS 2016.2.

The problem I'm facing is that a interface called 'output_p' is being inferred as input.

The core should simply calc the average of floats. So my approach was to send many floats (in hardware will be one per clock cycle) that get accumulated, when the number reaches a threshold (size), it asserts a flag 'done' and should place  the average in 'output_p'. But 'output_p' is inferred as input.

BTW, 'size' is also inferred as input.

Here goes the code:

file: avg.h

```#include <ap_cint.h>

#define MAX_VECTOR_SIZE 1024
#define RESET 0x1
#define CALC 0x2

typedef float data_t;

void avg(uint2 cmd, data_t *input_p, uint10 size, data_t *output_p, uint1 *done);
```

file: avg.c

```#include "avg.h"

void avg(uint2 cmd, data_t *input_p, uint10 size, data_t *output_p, uint1 *done) {
#pragma HLS INTERFACE axis port=input_p
#pragma HLS INTERFACE ap_none port=output_p
uint10 i;
static data_t acc;

switch(cmd) {
case RESET:
acc = 0.0;
i = 0;
break;
case CALC:
acc += *input_p;
i++;
if (i == size) {
*done = 1;
*output_p = acc/i;
}
break;
}
}
```

Testbench:

```#include "avg.h"

int main() {
int i;
data_t in[4] = {1.0,2.0,3.0,4.0};
data_t out;
uint1 done = 0;

avg(RESET, NULL, 4, NULL, &done);
for (i = 0; i < 4; i++) {
avg(CALC,&in[i], 4, &out, &done);
if (done) {
printf("output = %f\n",out);
return 0;
}
}
return (int)out;
}```

The testbench prints out:

```INFO: [APCC 202-1] APCC is done.
Generating csim.exe
output = 0.000000
INFO: [SIM 211-1] CSim done with 0 errors.
Finished C simulation.```

Interesting is that when I execute the testbench in debug mode, stepping instruction by instruction, the output average is right (out = 2.5000).

RTL Ports Dir Bits Protocol Source Object C Type
ap_clk in 1 ap_ctrl_hs inlocus_avg return value
ap_rst_n in 1 ap_ctrl_hs inlocus_avg return value
ap_start in 1 ap_ctrl_hs inlocus_avg return value
ap_done out 1 ap_ctrl_hs inlocus_avg return value
ap_idle out 1 ap_ctrl_hs inlocus_avg return value
ap_ready out 1 ap_ctrl_hs inlocus_avg return value
cmd in 2 ap_none cmd scalar
input_p_TDATA in 32 axis input_p pointer
input_p_TVALID in 1 axis input_p pointer
input_p_TREADY out 1 axis input_p pointer
size in 10 ap_none size scalar
output_p in 32 ap_none output_p pointer
done out 1 ap_vld done pointer
done_ap_vld out 1 ap_vld done pointer

Any insight? Is there a better approach ?

thanks!

Accepted Solutions
Voyager
Posts: 1,634
Registered: ‎06-24-2013

## Re: Enforcing a interface to be output

Hey @brasilino,

This is an excellent example how optimization combined with missing warnings can go terribly wrong ...

The problem here is that because your counter variable 'i' is not global, it will not be initialized and thus will have an unknown value. As a result Vivado HLS decides that the size comparison is not relevant and removes it together with the division and output_p assignment. A warning is issued ...

```WARNING: [RTGEN 206-101] Port 'avg/size' has no fanin or fanout and is left dangling.
Please use C simulation to confirm this function argument can be read from or written to.
WARNING: [RTGEN 206-101] Port 'avg/output_p' has no fanin or fanout and is left dangling.
Please use C simulation to confirm this function argument can be read from or written to.
```

... and because output_p is never written to, it becomes an input.

So the solution here is to make 'i' static and initialize it to '0'.

Hope this clarifies,

Herbert

-------------- Yes, I do this for fun!

All Replies
Voyager
Posts: 1,634
Registered: ‎06-24-2013

## Re: Enforcing a interface to be output

Hey @brasilino,

This is an excellent example how optimization combined with missing warnings can go terribly wrong ...

The problem here is that because your counter variable 'i' is not global, it will not be initialized and thus will have an unknown value. As a result Vivado HLS decides that the size comparison is not relevant and removes it together with the division and output_p assignment. A warning is issued ...

```WARNING: [RTGEN 206-101] Port 'avg/size' has no fanin or fanout and is left dangling.
Please use C simulation to confirm this function argument can be read from or written to.
WARNING: [RTGEN 206-101] Port 'avg/output_p' has no fanin or fanout and is left dangling.
Please use C simulation to confirm this function argument can be read from or written to.
```

... and because output_p is never written to, it becomes an input.

So the solution here is to make 'i' static and initialize it to '0'.

Hope this clarifies,

Herbert

-------------- Yes, I do this for fun!
Observer
Posts: 18
Registered: ‎08-07-2014

## Re: Enforcing a interface to be output

great explanation @hpoetzl, thanks!

It really makes sense. I've seen those 'no fanin/fanout' warnings and I was puzzled about them. It would be very useful if  Vivado HLS also warns about removing the variables when they are not initially driven at optimization phase....

regards.

Voyager
Posts: 1,634
Registered: ‎06-24-2013

## Re: Enforcing a interface to be output

Hey @brasilino,

great explanation @hpoetzl, thanks!

You're welcome!

It would be very useful if  Vivado HLS also warns about removing the variables when they are not initially driven at optimization phase....

Indeed, there are a number of situations where I miss the verbosity I'm used from GCC, but I think that will improve in the future, Vivado HLS is still quite young ...

All the best,

Herbert

-------------- Yes, I do this for fun!