cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Anonymous
Not applicable
4,063 Views

Transfer float numbers through AXI4 stream: unsupported pointer reinterpretation

Jump to solution

Hi,
I've got a problem with vivado HLS (for zynq):

I want to write a float number into the ap_axiu<32,...> data field (AXI4-Stream).
When I do
    typedef ap_axiu<32,4,5,5> AXI_VAL;

    ...
    AXI_VAL temp;
    float result[];

    myfunction(result, some input);
    for(i ...){
        temp.data = *(uint32_t*)(result + i);
        ...
        outstream.write(temp);
    }
    ...
I get the following error during C synthesis:
    CRITICAL WARNING: [SYNCHK 200-41]
    unsupported pointer reinterpretation from type 'float*' to type 'ap_axiu<32, 4, 5, 5>' on variable 'result'.
    CRITICAL WARNING: [HLS 200-70] Synthesizability check failed.
Before that, I tried memcpy, but this is also not supported:
    memcpy(&temp.data, &result[i], sizeof(float));

    CRITICAL WARNING: [SYNCHK 200-22]memory copy is not supported unless used on bus interface possible cause(s):
    non-static/non-constant local array with initialization).
    CRITICAL WARNING: [HLS 200-70] Synthesizability check failed.

What I want to achieve, is simply to put a float numbered result into the 32bit data field  of the stream data structure
(which seems to be handled as uint32).

Best regards,
phoppen

0 Kudos
1 Solution

Accepted Solutions
jprice
Scholar
Scholar
5,839 Views
Registered: ‎01-28-2014

If I'm reading your solution correctly, I'm not really sure what HLS is doings since it doesn't support pointer reinterpretation. To do what you want you typically have to use a union. My guess is your RTL won't behave the way you expect. 

View solution in original post

6 Replies
hbucher
Scholar
Scholar
4,046 Views
Registered: ‎03-22-2016
Can you add line number information? It does not look this error comes from the line you think it comes.
vitorian.com --- We do this for fun. Always give kudos. Accept as solution if your question was answered.
I will not answer to personal messages - use the forums instead.
0 Kudos
Anonymous
Not applicable
4,008 Views

The full warning looks like this:

    CRITICAL WARNING: [SYNCHK 200-41] axi_stream_neuron/axi_stream_neuron.cpp:79:

    unsupported pointer reinterpretation from type 'float*' to type 'ap_axiu<32, 4, 5, 5>' on variable 'result'.

 

The template function in which the error occurs:

 

49   template <typename T, int D, int NH, int HL, int NO>
50   void nn_wrapper(hls::stream<AXI_VAL> &in_stream, hls::stream<AXI_VAL> &out_stream)
51   {
52   	T dendrites[D];
53	T weights[(D + 1)*NO];
54	T result[NO];
55	AXI_VAL temp;
56
57	for(int i = 0; i < D; i++)
58	{
59		#pragma HLS PIPELINE II=1
60		temp = in_stream.read();
61		//memcpy(&dendrites[i], &temp.data, sizeof(T));
62		dendrites[i] = *(T*)&temp.data;
63
64		out_stream.write(temp);
65	}
66	for(int i = 0; i < (D+1)*NO; i++)
67	{
68		#pragma HLS PIPELINE II=1
69		temp = in_stream.read();
70		//memcpy(&weights[i], &temp.data, sizeof(T));
71		weights[i] = *(T*)&temp.data;
72
73		out_stream.write(temp);
74	}
75
76	layer_fwd<T, D, NO>(dendrites, weights, result);
77	for(int i = 0; i < NO; i++){
78		//memcpy(&temp.data, &result[i], sizeof(T));
79		temp.data = *(uint32_t*)(result + i);
80		out_stream.write(temp);
81	}
82   }

This function is called in this manner:

   nn_wrapper<float,2,4,1,2>(in_stream, out_stream);

 

Best regards,

phoppen

0 Kudos
Anonymous
Not applicable
4,000 Views

Okay, my problem is more or less solved.

However, I don't understand why:

 

Now I do the following (T is float type):

    T rt = result[i];
    temp.data = *(uint32_t*)&rt;
    out_stream.write(temp);

 

The float number is stored in a temporary float variable, and then I cast the address of this variable, instead of the previous way:

    temp.data = *(uint32_t*)(result + i);      OR       temp.data = *(uint32_t*)&result[i];

 

Has anybody an idea, what the difference is?

I will leave this thread open for one day, and then I will mark it as solved :)

 

Best regards,

phoppen

0 Kudos
jprice
Scholar
Scholar
5,840 Views
Registered: ‎01-28-2014

If I'm reading your solution correctly, I'm not really sure what HLS is doings since it doesn't support pointer reinterpretation. To do what you want you typically have to use a union. My guess is your RTL won't behave the way you expect. 

View solution in original post

hbucher
Scholar
Scholar
3,980 Views
Registered: ‎03-22-2016

I would at least add another parenthesis

 

temp.data = *((uint32_t*)&rt);

or perhaps do more directly

memcpy( &temp.data, &rt, sizeof(uint32_t) );

 

 

 

 

vitorian.com --- We do this for fun. Always give kudos. Accept as solution if your question was answered.
I will not answer to personal messages - use the forums instead.
Anonymous
Not applicable
3,963 Views

memcpy(&temp.data, &rt, sizeof(T)); gives me again that error:
    CRITICAL WARNING: [SYNCHK 200-22] axi_stream_neuron/axi_stream_neuron.cpp:50:
    memory copy is not supported unless used on bus interface possible cause(s):
    non-static/non-constant local array with initialization).

As pointer reinterpretation is possibly not supported,
I changed the pointer reinterpretation stuff to reading/writing from/to a temorary union variable.
It gives me no errors, it works with the C simulation,  and the utilization estimates are identical to the previous.

    typedef union
    {
          float f;
          uint32_t i;
    } t_rip;

    ...
    t_rip valtemp;
    valtemp.f = result[i];
    temp.data = valtemp.i;
    ...

Thank you for your responses :)

0 Kudos