How to use Fxpmath for axi_dma IP

Hello there!

I’m trying to test my IP with stream interfaces generated by HLS on pynq. I’m planning to transfer fixed-point inputs to the IP and receive the calculated output. However I don’t know how to deal with input data with Fxpmath. I already read all posts about fixed-point on the forum, but I am still confused about the Fxpmath. Here’s my code:

from future import print_function

from fxpmath import Fxp

import sys, os
import numpy as np
from time import time
import matplotlib.pyplot as plt

sys.path.append(‘/home/xilinx’)
os.environ[‘XILINX_XRT’] = ‘/usr’
from pynq import Overlay
from pynq import allocate

if name == “main”:
print(“Entry:”, sys.argv[0])
print(“System argument(s):”, len(sys.argv))

print("Start of \"" + sys.argv[0] + "\"")

load overlay & IPs

ol = Overlay("/home/xilinx/jupyter_notebooks/MPC/normalized_cf/mpc_normal_cf.bit")
ipMPC = ol.mpc_normal_cf_0
ipDMAIn_i = ol.axi_dma_in_0
ipDMAIn_v = ol.axi_dma_in_1
ipDMAOut = ol.axi_dma_out_0

fixed_type_i = Fxp(True,32,26)
fixed_type_v = Fxp(False,39,32)

load input data

#fiSamples_i = open("current.txt", "r+")
#fiSamples_v = open("voltage.txt", "r+")

numSamples = 8
i = np.array([1.931702575,1.92561515,2.166126345,2.205250491,2.165309505,1.927880424,1.69045187,1.807438998])
fixed_i = fixed_type_i(i)
v= np.array([102.2509034,102.2500827,102.2504605,102.2510664,102.252,102.2517362,102.2506075,102.2491174])
fixed_v = fixed_type_v(v)

u = 1;
outBuffer0 = 0;

for i in range(numSamples):
    timeKernelStart = time()
    
    ipMPC.write(0x10,u)
    ipMPC.write(0x00, 0x01)
    ipDMAIn_i.sendchannel.transfer(fixed_i[i])
    ipDMAIn_v.sendchannel.transfer(fixed_v[i])
    ipDMAOut.recvchannel.transfer(outBuffer0)
    ipDMAIn.sendchannel.wait()
    ipDMAOut.recvchannel.wait()
    
    timeKernelEnd = time()
    print("Kernel execution time: " + str(timeKernelEnd - timeKernelStart) + " s")
    print(outBuffer0)

But i got the error message:
—> 72 ipDMAIn_i.sendchannel.transfer(fixed_i[i])
73 ipDMAIn_v.sendchannel.transfer(fixed_v[i])
74 ipDMAOut.recvchannel.transfer(outBuffer0)

File /usr/local/share/pynq-venv/lib/python3.10/site-packages/pynq/lib/dma.py:140, in _SDMAChannel.transfer(self, array, start, nbytes)
138 raise RuntimeError(“DMA channel not idle”)
139 if nbytes == 0:
→ 140 nbytes = array.nbytes - start
141 if nbytes > self._max_size:
142 raise ValueError(
143 "Transfer size is {} bytes, which exceeds "
144 “the maximum DMA buffer size {}.”.format(nbytes, self._max_size)
145 )

AttributeError: ‘Fxp’ object has no attribute ‘nbytes’

It seems that “Fxp-datatype” cannot be used directly for dma ip. How should I use Fxpmath correctly?

Thanks in advance

1 Like

I have used Fxpmath before. to get the value you have to either use variable.get_val() or .bin() or .hex() or .astype(int) something like that. I didn’t go through your code completely but with a quick look, i have not seen something like that.

1 Like

Thanks for replying mizan!
You’re right to use variable.get_val(). Using fxpmath for dealing with fixed-point type in python is similar as the usual way but much clearer.
I found a very good example on github. If anyone has similar problem, please look through this example.

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.