**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!

Turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

- Community Forums
- :
- Forums
- :
- Design Tools
- :
- HLS
- :
- float operation gives 0

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

Highlighted

joseer

Explorer

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

09-15-2016 07:07 AM

5,124 Views

Registered:
07-06-2016

Hi,

I'm trying to do a simple division between two integers and I'm having a zero as a result instead a float (Iuf and Ivf variables):

void VTransform(short Iu, short Iv, short *Ialpha, short *Ibeta) { int iuOverRoot3, ivOverRoot3, tempIBeta; float Iuf,Ivf; short Iunormalized,Ivnormalized; Iuf=(Iu/4095); Ivf=(Iv/4095); *Ialpha =(short) (Iuf * 32768); *Ibeta=(short) (Ivf * 32768); }

I added the library "hls_math.h" hoping that it will solve the problem but I'm having the next error:

"#error C++ is required to include this header file"

Anyone knows why?

Thanks.

1 Solution

Accepted Solutions

u4223374

Scholar

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

09-15-2016 07:12 AM

9,788 Views

Registered:
04-26-2015

That's 100% correct C behaviour. If you divide an integer by an integer, you get an integer. Integer division rounds towards zero, so if your expected value is less than 1, you'll just get zero.

Try this:

Iuf=(Iu/4095.0f); Ivf=(Iv/4095.0f);

Having one variable as a float will force C to do a floating-point divide.

For the HLS math library you need to be using C++, not C. This should be as simple as renaming all the files from "*.c" to "*.cpp", and changing any instances of "uintX" to "ap_uint<X>".

5 Replies

u4223374

Scholar

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

09-15-2016 07:12 AM

9,789 Views

Registered:
04-26-2015

That's 100% correct C behaviour. If you divide an integer by an integer, you get an integer. Integer division rounds towards zero, so if your expected value is less than 1, you'll just get zero.

Try this:

Iuf=(Iu/4095.0f); Ivf=(Iv/4095.0f);

Having one variable as a float will force C to do a floating-point divide.

For the HLS math library you need to be using C++, not C. This should be as simple as renaming all the files from "*.c" to "*.cpp", and changing any instances of "uintX" to "ap_uint<X>".

joseer

Explorer

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

09-15-2016 07:40 AM

5,109 Views

Registered:
07-06-2016

Re: float operation gives 0

Many thanks, it worked.

Best regards.

herver

Xilinx Employee

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

09-15-2016 01:38 PM

5,094 Views

Registered:
08-17-2011

Re: float operation gives 0

...short Iu, short *Ialpha, float Iuf, Iuf=(Iu/4095); *Ialpha =(short) (Iuf * 32768);

as @u4223374 rightfully pointed to you the issue and the floating point computation will give you the correct result.

However for this testcase, isn't "*Ialpha=Iu/4095*32768" mostly equivalent to *Ialpha=Iu*8 for most small values and you don't really need to use floating points but just a shift by 3?

if you care about really 8.001953601953602 (which makes a difference for large numbers over 1000) then what about 32766/4096 simplified as 4097/512- once again the usual programming tricks "multiply and shift" is easier than full divide. Moreover, multiply by 4097 is not even a difficult multiplication, that's just shift and add too.

i hope this makes some sense ;-)

- Hervé

SIGNATURE:

* New Dedicated Vivado HLS forums* http://forums.xilinx.com/t5/High-Level-Synthesis-HLS/bd-p/hls

* Readme/Guidance* http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

* Please mark the Answer as "Accept as solution" if information provided is helpful.

* Give Kudos to a post which you think is helpful and reply oriented.

SIGNATURE:

* New Dedicated Vivado HLS forums* http://forums.xilinx.com/t5/High-Level-Synthesis-HLS/bd-p/hls

* Readme/Guidance* http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369

* Please mark the Answer as "Accept as solution" if information provided is helpful.

* Give Kudos to a post which you think is helpful and reply oriented.

u4223374

Scholar

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

09-19-2016 01:30 AM

5,035 Views

Registered:
04-26-2015

Re: float operation gives 0

Regarding @herver's point:

In certain cases, HLS will even do it automatically:

#include "ap_int.h" ap_uint<5> runDivision(ap_uint<8> x) { ap_uint<5> result = x/5; return result; }

Produced HDL code:

module runDivision (

ap_start,

ap_done,

ap_idle,

ap_ready,

x_V,

ap_return

);

parameter ap_const_lv18_19A = 18'b110011010;

parameter ap_const_lv32_B = 32'b1011;

parameter ap_const_lv32_F = 32'b1111;

input ap_start;

output ap_done;

output ap_idle;

output ap_ready;

input [7:0] x_V;

output [4:0] ap_return;

wire [7:0] mul_fu_30_p0;

wire [17:0] mul_fu_30_p2;

wire [17:0] mul_fu_30_p00;

assign ap_done = ap_start;

assign ap_idle = 1'b1;

assign ap_ready = ap_start;

assign ap_return = {{mul_fu_30_p2[ap_const_lv32_F : ap_const_lv32_B]}};

assign mul_fu_30_p0 = mul_fu_30_p00;

assign mul_fu_30_p00 = x_V;

assign mul_fu_30_p2 = (mul_fu_30_p0 * $signed('h19A));

endmodule //runDivision

(using a total of zero LUTs, zero FFs, one DSP48).

And, simplified:

module runDivision ( x, ap_return ); input [7:0] x; output [4:0] ap_return; wire [17:0] mulOut; assign mulOut = (x * $signed('h19A)); assign ap_return = mulOut[15 : 11]; endmodule //runDivision

Presumably HLS has calculated that this will guarantee correct outputs for every valid input - which is a pretty nifty thing for the software to do all by itself. Some Xilinx engineer must have been pretty pleased with himself/herself after getting that working.

Unfortunately, for a much more basic situation (converting a multiply by 4097 into a shift and add) HLS does not seem to be quite so smart. It'll default to using a DSP slice for any multiplication unless it's multiplying by a constant power of two - even, as I've found, when both inputs are only 2-bit wide. The RESOURCE directive provides a suitable workaround (with core Mul_LUT) and presumably this does actually get optimised as appropriate.

joseer

Explorer

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

09-19-2016 04:59 AM

5,023 Views

Registered:
07-06-2016

Re: float operation gives 0

Thanks u4223374 and herver, yes it really makes sense, you are right about the conversion, but in this case being Iu an ADC input, I did this conversion just to check the right voltage values given by the external hardware, as a debug purposes.

Indeed on the final code that will be optimized.

Thanks again for the help.

Best regards.