from pynq import Overlay
overlay = Overlay(“/home/xilinx/pynq/overlays/sobelfilter/Sobelfilter2.bit”)
Load sobelfilter IP
sobel_ip = overlay.sobel_accel_0.s_axi_control
sobel_ip_r = overlay.sobel_accel_0.s_axi_control_r
from cffi import FFI
ffi = FFI()
from pynq import Xlnk
import numpy as np
from PIL import Image
IMAGE_PATH = ‘/home/xilinx/test_1080p.bmp’
prepare input/output image
COLS = 1920#640
ROWS = 1080#480
CHANNELS = 1
load original image + grayscale conversion
original_image = Image.open(IMAGE_PATH).convert(‘L’)
original_image = original_image.resize((COLS,ROWS), Image.ANTIALIAS)
original_image.load()
display origina image
display(original_image, ‘input image’)
to numpy array
gray_input_array = np.array(original_image)
newgraynp = gray_input_array.reshape(gray_input_array.shape[0],gray_input_array.shape[1], CHANNELS)
allocate memory buffer
xlnk = Xlnk()
image_buffer = xlnk.cma_array(shape=(ROWS,COLS,CHANNELS), dtype=np.uint8, cacheable=1)
return_buffer1 = xlnk.cma_array(shape=(ROWS,COLS,CHANNELS), dtype=np.uint8, cacheable=1)
return_buffer2 = xlnk.cma_array(shape=(ROWS,COLS,CHANNELS), dtype=np.uint8, cacheable=1)
copy input image to memory buffer
image_buffer[0:ROWS * COLS * CHANNELS] = newgraynp
return_buffer1[0:ROWS * COLS * CHANNELS] = 0
return_buffer2[0:ROWS * COLS * CHANNELS] = 0
input/output pointers
image_pointer = ffi.cast(“uint8_t *”, ffi.from_buffer(image_buffer)) # image_buffer.ctypes.data
return_pointer1 = ffi.cast(“uint8_t *”, ffi.from_buffer(return_buffer1)) # return_buffer1.ctypes.data
return_pointer2 = ffi.cast(“uint8_t *”, ffi.from_buffer(return_buffer2)) # return_buffer2.ctypes.data
print(‘Pointer size’, ffi.sizeof(image_pointer), ‘bytes’)
utilities functions
import pynq
CONTROL_ADDR = 0x00
def start(ip):
data = ip.read(CONTROL_ADDR) & 0x80
ip.write(CONTROL_ADDR, data | 0x01)
def enable_auto_restart(ip):
ip.write(CONTROL_ADDR, 0x80)
def disable_auto_restart(ip):
ip.write(CONTROL_ADDR, 0x0)
def is_done(ip):
data = ip.read(CONTROL_ADDR)
return (data >> 1) & 0x1
def is_idle(ip):
data = ip.read(CONTROL_ADDR)
return (data >> 2) & 0x1;
def is_ready(ip):
data = ip.read(CONTROL_ADDR)
return (data >> 2) & 0x1;
def set_img1(ip, image_buffer, input_image: bool):
addr = 0x10 if input_image else 0x1c
print(‘Image addr’, hex(addr))
print(‘writing’, hex(image_buffer.physical_address))
ip.write(addr, image_buffer.physical_address)
ip.write(addr + 4, 0x0)
def set_img2(ip, image_buffer, input_image: bool):
addr = 0x10 if input_image else 0x28
print(‘Image addr’, hex(addr))
print(‘writing’, hex(image_buffer.physical_address))
ip.write(addr, image_buffer.physical_address)
ip.write(addr + 4, 0x0)
def get_img(ip, input_image: bool):
# input/output image reg addr
addr = 0x10 if input_image else 0x1c
print(‘Image addr’, addr)
data_0 = ip.read(addr)
#data_1 = ip.read(addr + 4) << 32
data_1 = 0
data = int(‘{:32b}’.format(data_0 + data_1), 2)
print('read ', hex(data))
return data
rows, cols, threshold
def set_params(ip, rows, cols):
ip.write(0x10, rows)
ip.write(0x18, cols)
lettura registri
def read_reg(ip):
reg_0 = ip.read(0x0)
print(‘reg0’ , reg_0)
def read_reg_r(ip):
reg_1c = ip.read(0x1c)
print(‘reg1c’ , reg_1c)
reg_10 = ip.read(0x10)
print(‘reg10’ , reg_10)
reg_28 = ip.read(0x28)
print(‘reg28’ , reg_28)
#enable_auto_restart(fast_ip)
write values in ip registers
set_params(sobel_ip, ROWS, COLS)
set_img1(sobel_ip_r, image_buffer, input_image=True)
set_img1(sobel_ip_r, return_buffer1, input_image=False)
set_img2(sobel_ip_r, return_buffer2, input_image=False)
read_reg(sobel_ip)
read_reg_r(sobel_ip_r)
display original image and result
#display(original_image, ‘input image’)
#print(np.unique(return_buffer2))
display(Image.fromarray(np.array(return_buffer1).squeeze()), ‘output image’)
display(Image.fromarray(np.array(return_buffer2).squeeze()), ‘output image’)