**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
- :
- Xilinx HLS fixed point division vs Matlab fixed po...

- 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

rcst201427420m

Visitor

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

12-19-2018 11:09 PM

1,030 Views

Registered:
11-11-2015

Dear all,

I am trying to implement a moving average filter in HLS. I have already

developed the Matlab model in fixed point and the Fixed point model is

developed with the help of fi & fimath functions present in matlab in the

following manner.

fi(data, signedness(T/F),DataWidth,FractionWidth,'fimath',F); where

F = fimath('OverflowAction','Saturate','RoundingMethod','Nearest');

Similarly I have coded the algorithm in cpp for the correspoding HLS design

with the following fixed point format

ap_fixed<DataWidth,IntegerWidth, AP_RND, AP_SAT>

using AP_RND for rounding and AP_SAT for saturation ( which I believe

corresponds to the Rounding and Overflow method I used in Matlab).

When I compare the results of Matlab and HLS cpp , I find that in case of

addition , substraction and multiplication the results matches bittrue but

when I perform division (/) which is not a power of 2, the results are very

similar but not bittrue.

I would like to know if the mismatch in fixed point division of HLS and Matlab

is a known issue or else something is wrong in the way I am doing the

computation..

Thanks in advance

Regards

1 Solution

Accepted Solutions

nmoeller

Xilinx Employee

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

01-02-2019 02:10 PM

801 Views

Registered:
09-05-2018

Couple of ideas for workarounds - the obvious one, if you're okay with switching the rounding mode: just make Matlab truncate the result.

If you require rounding to positive infinity, do the division with one extra bit, then cast to the proper type in a separate step. I've tested it with the example numbers you provided, and it seems to work, but I only have the one data point. You should double check it with your testbench.

typedef ap_fixed<30,11,AP_RND,AP_SAT> ACC_T_PLUS_ONE_BIT; ... ACC_T_PLUS_ONE_BIT acc_new = acc; ACC_T mov_avg_val = acc_new/15; ... ap_int<30> test = acc_new.range(29,0); cout << "acc = " << acc_new.to_double() << " or 0x" << hex << test << endl;

Nicholas Moellers

Xilinx Worldwide Technical Support

Xilinx Worldwide Technical Support

10 Replies

nmoeller

Xilinx Employee

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

12-20-2018 02:35 PM

978 Views

Registered:
09-05-2018

Re: Xilinx HLS fixed point division vs Matlab fixed point division

Hey @rcst201427420m,

I'm curious if you could tell us more about the nature of the mismatch.

It's not necessarily an issue that the two results are different if they're still correct. But I am having trouble wrapping my mind around how we could have a difference when - at least on the HLS side - It can be thought of as integer division and keeping track of the decimal. Actually, that is a possible reason for the discrepancy: If Matlab uses floating point division under the hood, that would make sense.

Just double checking - you are properly casting your literals to the fixed point type? I.e., ap_fixed<W,I> a = (ap_fixed<W,I>) 0.25;

Nicholas Moellers

Xilinx Worldwide Technical Support

Xilinx Worldwide Technical Support

u4223374

Scholar

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

12-20-2018 06:01 PM

964 Views

Registered:
04-26-2015

Re: Xilinx HLS fixed point division vs Matlab fixed point division

It's possible that Xilinx and Mathworks are using slightly different definitions - in particular, should "round to nearest" with -0.5 give you -1.0 or 0.0? Depends whether you round by magnitude or not.

As @nmoeller has said, if you can provide an example where they differ and provide the full binary/hex string for each, it should be easy to check - even doing binary division by hand is not all that difficult unless you're working with hundreds of bits.

rcst201427420m

Visitor

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

12-20-2018 07:01 PM - edited 12-20-2018 10:15 PM

957 Views

Registered:
11-11-2015

Re: Xilinx HLS fixed point division vs Matlab fixed point division

Hi Nicholas & @u4223374,

Thanks for your reply. Please find the code snipped in the attachment section. One image shows what is happening on the HLS side while the other shows what happens in Matlab side. The values of HLS variable mov_avg_val should be same as Matlab variable stdFilter_Scale_fi but the results differ slightly.The images will provide more information about the mismatch.

I must add that not all the values are different . While I am performing this division operation some values match bittrue with the matlab results and some values does not match , like the one shown in the example.

Looking forward to your response.

Regards

Bhaskar

nmoeller

Xilinx Employee

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

12-21-2018 08:46 AM - edited 12-21-2018 08:46 AM

920 Views

Registered:
09-05-2018

Re: Xilinx HLS fixed point division vs Matlab fixed point division

ap_fixed data types should be casted to double using their to_double() member function. Shouldn't be an issue, but we should eliminate the possibility:

cout << ... << mov_avg_val.to_double() << endl; cout << ... << acc.to_double() << endl;

But also, to check if your values are "bittrue", you should be checking the bit representation of the ap_fixed data types, not the floating point representation of the ap_fixed number. Something like the following, stolen from this forum post should be what you want on the HLS side:

ap_uint<29> Result=0; Result = mov_avg_val.range(28,0); cout << hex << Result << " ";

I would recommend you print mov_avg_val, acc, and also save the value WINDOW_LEN-1 as a fixed type, so we can see all the binary numbers involved in the division. Otherwise, I'd be inclined to blame integer to floating point conversion.

@u4223374 - It looks like both Matlab and HLS are set to round to positive infinity.

Nicholas Moellers

Xilinx Worldwide Technical Support

Xilinx Worldwide Technical Support

rcst201427420m

Visitor

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

01-01-2019 10:21 PM

835 Views

Registered:
11-11-2015

Re: Xilinx HLS fixed point division vs Matlab fixed point division

Hi Nicholas,

Thanks for your support. I have made the changes that you recommended. Please find the code snipped and the result in the attachment section. It seems the hex value of the result in HLS side still differs from matlab. Is there a way , I can get both the HLS and matlab output to be the same for this division??

And finally, Wish you a very Happy New Year.

Regards

Bhaskar

nmoeller

Xilinx Employee

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

01-02-2019 01:33 PM - edited 01-02-2019 01:34 PM

808 Views

Registered:
09-05-2018

Re: Xilinx HLS fixed point division vs Matlab fixed point division

Hey @rcst201427420m,

Happy New Year!

I've got good news and bad news. The good news is that we can now divide out 0x14df38 by 0xf by hand and see what the answer should be. Answer: 0x16436 with a remainder of 0xe or 0b1110. Hardware would only calculate the MSB of this which is 1. The definition of the AP_RND quantization mode is "round to positive infinity", or more specifically, add the MSB of the remainder to the number. Which should give us 0x16437, which is the answer that Matlab gave. Which brings us to the bad news, which is it looks to me like you've found a rounding bug in HLS fixed point division. But maybe that now gets us some more good news, which is now this can be reported to the engineering team.

Thanks for finding and reporting this issue.

Nicholas Moellers

Xilinx Worldwide Technical Support

Xilinx Worldwide Technical Support

nmoeller

Xilinx Employee

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

01-02-2019 02:10 PM

802 Views

Registered:
09-05-2018

Couple of ideas for workarounds - the obvious one, if you're okay with switching the rounding mode: just make Matlab truncate the result.

If you require rounding to positive infinity, do the division with one extra bit, then cast to the proper type in a separate step. I've tested it with the example numbers you provided, and it seems to work, but I only have the one data point. You should double check it with your testbench.

typedef ap_fixed<30,11,AP_RND,AP_SAT> ACC_T_PLUS_ONE_BIT; ... ACC_T_PLUS_ONE_BIT acc_new = acc; ACC_T mov_avg_val = acc_new/15; ... ap_int<30> test = acc_new.range(29,0); cout << "acc = " << acc_new.to_double() << " or 0x" << hex << test << endl;

Nicholas Moellers

Xilinx Worldwide Technical Support

Xilinx Worldwide Technical Support

rcst201427420m

Visitor

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

01-04-2019 12:02 AM

773 Views

Registered:
11-11-2015

Re: Xilinx HLS fixed point division vs Matlab fixed point division

Hi Nicholas,

Thanks for your reply. I tried your second solution. It worked for all the values in my test vector.

Thanks !!

Regards

Bhaskar

nmoeller

Xilinx Employee

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

01-04-2019 10:23 AM

758 Views

Registered:
09-05-2018

Re: Xilinx HLS fixed point division vs Matlab fixed point division

Hey @rcst201427420m,

That's awesome, glad to hear it!

Nicholas Moellers

Xilinx Worldwide Technical Support

Xilinx Worldwide Technical Support

nmoeller

Xilinx Employee

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

01-07-2019 08:53 AM

705 Views

Registered:
09-05-2018

Re: Xilinx HLS fixed point division vs Matlab fixed point division

Hey @rcst201427420m,

For what it's worth, I've been informed that the tool is behaving per spec when it truncates the result of the division.

So really that just means that my "workaround" is actually just the recommended way to do division with rounding, i.e., use one extra bit and then cast.

Nicholas Moellers

Xilinx Worldwide Technical Support

Xilinx Worldwide Technical Support