pynq的介绍:https://blog.csdn.net/xiaoqu001/article/details/79479208
pynq官方文档:http://pynq.readthedocs.io/en/latest/python_environment.html
pynq github开源项目:https://github.com/xilinx/pynq
pynq sobel github 代码:https://github.com/clancylea/pynq-sobel
文中参考pynq 相关资料 ,使用python编写sobel的驱动部分,如有错误之处还请不吝赐教!
1.Load overlay and Load sobel IP
from pynq import Overlay
overlay = Overlay("/home/xilinx/jupyter_notebooks/sobel/sobel.bit")
sobel_ip=overlay.sobel_filter_0
2.使用PIL读取RGB 并转化为矩阵
from PIL import Image as PIL_Image
import numpy as np
orig_img_path = "/home/xilinx/jupyter_notebooks/sobel/test_1080p.bmp"
try:
img = PIL_Image.open(orig_img_path)
print("Open pictrue success!")
except IOError:
print('fail to load image!')
#显示图片及图片信息
print("pictrue format:",img.format)
print("pictrue size:",img.size) #注意,省略了通道 (w,h)
print("pictrue mode:",img.mode) #L为灰度图,RGB为真彩色,RGBA为加了透明通道
#RGB 通道分离
img_r,img_g,img_b = img.split()
#img = PIL_Image.merge("RGB",(r,g,b))
#R,G,B转矩阵
image_array_r = np.array(img_r,dtype='uint8')
image_array_g = np.array(img_g,dtype='uint8')
image_array_b = np.array(img_b,dtype= 'uint8')
3.allocated memory 使用pynq 框架中Xlnk申请内存,存储输入输出图片
from pynq import Xlnk
import numpy as np
nrows = 1080
ncols = 1920
xlnk = Xlnk()
#allocated the memory inbuff
RGB_IN = xlnk.cma_array(shape=(nrows*ncols,), dtype=np.uint32)
in_buffer_address=RGB_IN.physical_address
#allocated the memory outbuff
RGB_OUT = xlnk.cma_array(shape=(nrows*ncols,), dtype=np.uint32)
out_buffer_address=RGB_OUT.physical_address
#write the image to memory
RGB_3D = image_array_r*65536+image_array_g*256+image_array_b
np.copyto(RGB_IN,RGB_3D.flatten())
4.sobel驱动部分
from pynq import MMIO
mmio = MMIO(in_buffer_address,nrows*ncols)
#write data
byte_framein_offset = 1920
nrows = 1080
ncol = 1920
#address
IP_BASE_ADDRESS = 0x43C00000
ADDRESS_RANGE = 1000
#address offset
ADDR_AP_CRTL = 0x00
ADDR_GIE = 0x04
ADDR_IER = 0x08
ADDR_ISR = 0x0c
ADDR_ROWS = 0x24
ADDR_COLS = 0x2c
ADDR_RDOFFSET = 0x14
ADDR_WROFFSET = 0x1c
ADDR_FRAMEIN_OFFSET = 0x34
# sobel mapping memory
def XSOBEL_Init_EX():
# mapping memory
mmio = MMIO(IP_BASE_ADDRESS,ADDRESS_RANGE)
mmio.write(ADDR_ROWS,nrows)
mmio.write(ADDR_COLS,ncol)
mmio.write(ADDR_RDOFFSET,in_buffer_address)
mmio.write(ADDR_WROFFSET,out_buffer_address)
mmio.write(ADDR_FRAMEIN_OFFSET,byte_framein_offset)
print("inbuff_address:",mmio.read(ADDR_RDOFFSET))
print("out_buffer_address:",mmio.read(ADDR_WROFFSET))
print("nrows:",mmio.read(ADDR_ROWS))
print("ncol:",mmio.read(ADDR_COLS))
print("byte_framein_offse:",mmio.read(ADDR_FRAMEIN_OFFSET))
#Start Or Stop the FPGA IP Core start = 1; stop = 0;
def XSOBEL_StartStop_Ex(state):
# mapping memory
mmio = MMIO(IP_BASE_ADDRESS,ADDRESS_RANGE )
if(state):
#enable the interrupt
mmio.write(ADDR_GIE,1)
mmio.write(ADDR_IER,1)
mmio.write(ADDR_AP_CRTL,0x1)
else:
while True:
ap_done = (mmio.read(ADDR_AP_CRTL)>>1)&0x01
if(ap_done):
break
mmio.write(ADDR_GIE,0x0)
mmio.write(ADDR_IER,0x0)
5.run sobel hardware
import numpy
import time
#Set Control Registers State Or Value
XSOBEL_Init_EX()
time.sleep(3)
#Start The FPGA IP Core
start = time.time()
XSOBEL_StartStop_Ex(1)
#Stop The FPGA IP Core check Whether The IP Core is End
XSOBEL_StartStop_Ex(0)
stop = time.time()
time_sobel_fpga = stop - start
print("Sobel FPGA time:",time_sobel_fpga)
time.sleep(3)
6.read image from memory
RGB_temp = np.zeros(1080*1920,dtype = np.uint32)
RGB_temp = RGB_OUT.copy()
RGB_temp = numpy.array(RGB_temp).reshape(1080,1920)
image_array_r = RGB_temp//65536
image_array_g = RGB_temp//256
image_array_b = RGB_temp
#img = PIL_Image.merge("RGB",(r,g,b))
image_r = PIL_Image.fromarray(image_array_r.astype('uint8')).convert('RGB')
image_g = PIL_Image.fromarray(image_array_g.astype('uint8')).convert('RGB')
image_b = PIL_Image.fromarray(image_array_b.astype('uint8')).convert('RGB')
print("The image via sobel filter!! ",image_b)
image_r