How to read/write from my IP using MMIO

Hello,
I am trying to test an SVM IP on a ZCU104 board using PYNQ ( PYNQ2.7). I was able to reproduce this work for the hardware implementation of the SVM IP on ZCU104. My design is shown below


For the test of my SVM IP I tried the following

from pynq import Overlay
from pynq import MMIO
import numpy as np
import struct
from datetime import datetime

overlay= Overlay(“SVM_orig.bit”)
overlay.is_loaded()

overlay.download()
overlay.ip_dict

ol= overlay.svm_classifier_0

mmio = MMIO(0xA0000000,0xA000FFFF)

X=[-0.535835,0.291519,-1.055207,0.276026,-0.231975,-1.927177,-0.645042,0.133114,1.603685,-1.322951,-0.935624,2.438317,-1.307130,-0.219807,0.896202,0.740312]
mmio.write(0x100 ,X)
y= mmio.read(0x200)
print(y)

However, I got this error:

ValueError Traceback (most recent call last)
in
2
3 X=[-0.535835,0.291519,-1.055207,0.276026,-0.231975,-1.927177,-0.645042,0.133114,1.603685,-1.322951,-0.935624,2.438317,-1.307130,-0.219807,0.896202,0.740312]
----> 4 mmio.write(0x100 ,X)
5 y= mmio.read(0x200)
6 print(y)

/usr/local/share/pynq-venv/lib/python3.8/site-packages/pynq/mmio.py in write_mm(self, offset, data)
189 self.array[idx + i] = buf[i]
190 else:
→ 191 raise ValueError(“Data type must be int or bytes.”)
192
193 def write_reg(self, offset, data):

ValueError: Data type must be int or bytes

So, I found this

mmio = MMIO(0xA0000000,0xA000FFFF)

X=[-0.535835,0.291519,-1.055207,0.276026,-0.231975,-1.927177,-0.645042,0.133114,1.603685,-1.322951,-0.935624,2.438317,-1.307130,-0.219807,0.896202,0.740312]
mmio.write(0x100,struct.unpack(‘I’, struct.pack(‘f’, X))[0])
c=struct.unpack(‘f’, struct.pack(‘I’, mmio.read(0x200)))[0]
print(c)

But I got this error : error: required argument is not a float
I think mmio.write should take one value of X. However, the HLS code indicates that each entry should be a vector of a dimension of 16, and the output should be 1 or 0.

Any ideas please how to deal with this?

Regards

1 Like

Hi @alka,

Welcome to the PYNQ community.

You need to write element by element with MMIO.
Writing floating point values is not supported in the method. You can use a function like this one PYNQ_Composable_Pipeline/libs.py at main · Xilinx/PYNQ_Composable_Pipeline · GitHub to convert from float to int and then write.

Suggestion: the object ol= overlay.svm_classifier_0 already has an MMIO object associated to it, so you do not need to create the mmio object manually.

For instance, you can do this

svm = overlay.svm_classifier_0
svm.write(0x100, ...)

svm.read(0x100)

Mario

Is it ok to write element by element even if the input of the IP should be a vector of a dimension of 16, to predict its output which should be 1 or 0.

Actually I tried to convert each element from float to int and write it element by element like this

for i in range (16):
xab=struct.unpack(‘I’, struct.pack(‘f’, X[i]))[0]
z.append( xab)

z=[3205049468, 1049969146, 3213299974, 1049449288, 3194850011, 3220614588, 3206881657, 1040731913, 1070417293, 3215545973, 3211756814, 1075580259, 3215413257, 3194033430, 1063611775, 1060996374]
y =
for i in range(len(z)):
mmio.write(0x100 ,z[i])
y.append(struct.unpack(‘f’, struct.pack(‘I’, mmio.read(0x200)))[0])
print(y)
[5.605193857299268e-45, 1.8497139729087585e-43, 5.605193857299268e-45, 5.605193857299268e-45, 1.8357009882655104e-43, 1.8357009882655104e-43, 8.407790785948902e-45, 8.407790785948902e-45, 1.8357009882655104e-43, 8.407790785948902e-45, 5.605193857299268e-45, 8.407790785948902e-45, 8.407790785948902e-45, 5.605193857299268e-45, 8.407790785948902e-45, 5.605193857299268e-45]

The problem is the output y should be either 1 or 0 for a given entry

HLS registers are write-only typically.

So, I am not sure how are you getting this output.