MATLAB generated IP core. Data type error

I am working on the PYNQ Z2 board. I am able to generate ip-core from MATLAB and overlay it to PYNQ, i am hoping that i can use the FPGA portion to accelerate some calculations in the future. this is the block diagram that i am testing with, it is essentially c = (a+b) * b

However I faced this problem where the data type is not detected in my notebook. Example if i set data type to be 32b fixed point (1 sign + 16 int + 15 fraction). i will obtain this result
image and as (1+1)*1 should be 2.
Then with the help of this community i discovered that if i put 32769(1000000000000000(15 zeros), then it will work fine as shown below. where 32769 ==1 and 32770 ==2.

This error can be fixed if i use 32b uint. as seen below. However, if this is the case then i wont be able to use decimals and negative numbers, which would not be ideal.

Does anyone know how to configure data types so that it will be able to use fixed point format? other than creating a seperate python function for conversion as it would not be time efficient. Thank you in advance

The PYNQ MMIO read() and write() are writing 32 bit registers in your IP.
Your issues is with how those values are interpreted in your IP and PYNQ.

You need to pack the data on the PYNQ side into the format you want, then write it to your IP.

E.g. If your IP expects 1 sign (S) + 16 int (I) + 15 fraction (F) you need to set the following bits properly: SIIIIIIIIIIIIIIIIFFFFFFFFFFFFFFF
so for decimal 1 (assuming sign is 0):
0 0000000000000001 000000000000000

This would be:

The issue isn’t fixed by using 32b uint. If you write decimal 1, your IP will see this as
F= 1
which I assume is decimal: 0.000030517578125 (1/2^15)

Your IP might add the following numbers:
to give:

This may be deciaml 0.00006103515625 (1/2^14) in your fixed point format, but if you read it back in PYNQ and interpret it as an integer, it is 2.
You will also need to “convert” the result from your IP.

There may be a Python package to help with fixed point, or you could do the conversion yourself.


I had a similar issue with floats. What about pacing it like this:
But you will need to create custom function like this

def ap_to_uint(int, fraction):
     <some packing ops>
return ap

and vice versa
def uint_to_ap(int, fraction)...

On the other hand, if you were using axi M + axi Lite to pass array physical address with variables, IP should work out of box. If you are calculating more data than 2 ap_ints this should be a better option unless you just want to learn how to use different interfaces.

1 Like

Hi, thank you, I have tried this method and it works for the conversion. I guess for now i will stick to this method until i require more time critical tasks.