Hi, I’m trying to get my hands on image processing so I decided to start making an overlay with this example of the library xfOpenCV, I should also mention that I’m working with the Ultra96v1 board and PYNQ v2.5, although I also tried with the previous version of PYNQ (v2.4).
Well, the fact is that I’m having problems getting this working, and as I have no previous experience with PYNQ, HLS or Vivado IP Integrator, I’ll be adding all the information that I consider may be helpful to diagnose what is it that I’m doing wrong.
First of all, I modified a little bit the “xf_ip_accel_app.cpp” file to make it have a proper interface to be handled from the address space of the Zynq platform. This is how my actual file is:
#include "xf_dilation_config.h" void dilation_accel(xf::Mat<TYPE, HEIGHT, WIDTH, NPC1> &_src,xf::Mat<TYPE, HEIGHT, WIDTH, NPC1> &_dst, unsigned char kernel[FILTER_SIZE*FILTER_SIZE]); void ip_accel_app(hls::stream< ap_axiu<8,1,1,1> >& input_stream,hls::stream< ap_axiu<8,1,1,1> >& output_stream,int height,int width, unsigned char kernel[FILTER_SIZE*FILTER_SIZE]) { #pragma HLS INTERFACE s_axilite port=kernel bundle=CNTRL_BUS #pragma HLS INTERFACE s_axilite port=width bundle=CNTRL_BUS #pragma HLS INTERFACE s_axilite port=height bundle=CNTRL_BUS #pragma HLS INTERFACE axis port=output_stream #pragma HLS INTERFACE axis port=input_stream #pragma HLS INTERFACE s_axilite port=return bundle=CNTRL_BUS xf::Mat<TYPE, HEIGHT, WIDTH, NPC1> imgInput1(height,width); xf::Mat<TYPE, HEIGHT, WIDTH, NPC1> imgOutput1(height,width); #pragma HLS stream variable=imgInput1.data dim=1 depth=1 #pragma HLS stream variable=imgOutput1.data dim=1 depth=1 #pragma HLS dataflow xf::AXIvideo2xfMat(input_stream, imgInput1); dilation_accel(imgInput1,imgOutput1, kernel); xf::xfMat2AXIvideo(imgOutput1, output_stream); }
It simulates, synthesizes, and cosimulates without errors, below is the waveform of the input and output streams. As it seems, at least under my inexperienced eyes, all is working as it should be expected.
Then, I export the design as IP and create a block design with it around the Zynq UltraScale+ in order to get the bistream and .tcl .hwh files for the overlay. Here are both my block design:
The design is validated without any critical warnings, and the same goes to synthesis and implementation. I have 56 critical warnings in the implementation step, though. They refer to the constraints file that I added for the Ultra96, so I don’t think it to be the problem because I’ve tried simpler designs (from here to be precise) with the same constraints files (and the same block design) and they worked without problems.
Once I have all the files required for the overlay, It’s time to go the Ultra96, first of all, when I try to access the “foo.register_map” property of my ip, I get the following error message:
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-4-affb02eb4e83> in <module>() ----> 1 dilate_ip.register_map /usr/local/lib/python3.6/dist-packages/pynq/overlay.py in register_map(self) 623 self._register_map = RegisterMap.create_subclass( 624 self._register_name, --> 625 self._registers)(self.mmio.array) 626 else: 627 raise AttributeError( /usr/local/lib/python3.6/dist-packages/pynq/registers.py in __init__(self, buffer) 424 continue 425 self._instances[k] = v[0]( --> 426 address=v[1], width=align_width, buffer=array) 427 428 def _set_value(self, value, name): /usr/local/lib/python3.6/dist-packages/pynq/registers.py in __init__(self, address, width, debug, buffer) 101 102 self.address = address --> 103 self.width = width 104 self.debug = debug 105 /usr/local/lib/python3.6/dist-packages/pynq/registers.py in _reordered_setitem(self, value, index) 232 233 """ --> 234 return self.__setitem__(index, value) 235 236 def __str__(self): /usr/local/lib/python3.6/dist-packages/pynq/registers.py in __setitem__(self, index, value) 186 """ 187 --> 188 curr_val = self._buffer[0] 189 if isinstance(index, int): 190 if value != 0 and value != 1: AttributeError: 'Registerwidth' object has no attribute '_buffer'
Then, after setting the parameters of the block (width, height, and kernel), and starting de block with the value 0x81 (I also tried 0x1). The DMA stops when I wait for the receive channel to finish the job. This is the exact snippet where it freezes:
input_buffer[:] = frameF[:]
print(“Input buffer shape: \n”+str(input_buffer.shape)+“\n”)io_stream.recvchannel.stop()
io_stream.sendchannel.stop()io_stream.sendchannel.start()
io_stream.recvchannel.start()print("Send channel idle: "+str(io_stream.sendchannel.idle))
print("Receive channel idle: "+str(io_stream.recvchannel.idle))io_stream.sendchannel.transfer(input_buffer)
io_stream.recvchannel.transfer(output_buffer)
io_stream.sendchannel.wait()
io_stream.recvchannel.wait()print("Send channel running: "+str(io_stream.sendchannel.running))
print("Receive channel running: "+str(io_stream.recvchannel.running))
print("Send channel idle: "+str(io_stream.sendchannel.idle))
print("Receive channel idle: "+str(io_stream.recvchannel.idle))
print("Send channel first transfer: "+str(io_stream.sendchannel._first_transfer))
print(“Receive channel first transfer: “+str(io_stream.recvchannel._first_transfer))
print(”\n”)print(“Output buffer shape: \n”+str(output_buffer.shape)+“\n”)
And that’s my problem. Thank you so much for your attention, I’d be really glad if someone could help me, I’ve been trying for several days now and It’s starting to seem just an impossible task. I wanted to add more images to the post, unfortunately I can’t to that with a new account, so if you need any other detail or file in order to figure out the problem, I’ll be willing to give it to you.