当前位置:   article > 正文

PYNQ-Z2调试笔记:使用PL的硬件IP定制overlay实现加速(How to accelerate a function with PYNQ)_pynq如何调试

pynq如何调试

本篇主要介绍,使用PYNQ板上可编程逻辑部分的IP核定制overlay,并与python自带的函数进行比较,以突出可编程逻辑部分的加速优势。


目录

前言

正文

(1)使用python的scipy模块函数对信号源信号滤波

(2)使用Vivado的滤波器核生成overlay

(3)使用overlay对相同信号源信号滤波,比较时间开销

结尾


​​​​​​​

前言

在前面的帖子中:https://blog.csdn.net/CSD_N_csdn/article/details/105669069,介绍了使用Vivado HLS制作了一个具有加法器功能的IP核,然后使用此IP核定制overlay,并在PYNQ上使用python调用验证功能。

本篇以前面的帖子为基础,省去了制作IP核的部分。一方面,直接调用Vivado的滤波器IP核,生成overlay,然后在jupyter-notebook上调用此overlay,实现对信号源信号的滤波,这用到了可编程逻辑部分,属于硬件加速,计算时间1。另一方面,调用python的scipy模块,scipy模块是具有滤波功能的函数,使用此函数对相同的信号源信号滤波,这属于纯软件实现滤波,计算时间2。将时间1与时间2比较,以突出硬件加速(即overlay方法)的优势。

正文

(1)使用python的scipy模块函数对信号源信号滤波

首先,在浏览器打开jupyter,新建python3文件,输入如下代码,这段代码的大致意思是定义了一个函数,将使用它来绘制数据,n_samples参数可以限制绘制的样本数量。其作用就是绘制一会儿要显示的信号。

  1. %matplotlib notebook
  2. import matplotlib.pyplot as plt
  3. def plot_to_notebook(time_sec,in_signal,n_samples,out_signal=None):
  4. plt.figure()
  5. plt.subplot(1, 1, 1)
  6. plt.xlabel('Time (usec)')
  7. plt.grid()
  8. plt.plot(time_sec[:n_samples]*1e6,in_signal[:n_samples],'y-',label='Input signal')
  9. if out_signal is not None:
  10. plt.plot(time_sec[:n_samples]*1e6,out_signal[:n_samples],'g-',linewidth=2,label='FIR output')
  11. plt.legend()

再输入如下代码,用于模拟信号源生成信号,这里生成的信号是低频正弦信号,并混有高频噪声。

  1. #模拟信号源生成输入信号
  2. import numpy as np
  3. T = 0.002
  4. fs = 100e6 #采样频率
  5. n = int(T * fs) #采样点数
  6. t = np.linspace(0, T, n, endpoint=False)
  7. samples = 10000*np.sin(0.2e6*2*np.pi*t) + 1500*np.cos(46e6*2*np.pi*t) + 2000*np.sin(12e6*2*np.pi*t)
  8. #信号源为200kHz的正弦信号,46MHz和12MHz的低幅度信号作为输入的模拟噪声。
  9. samples = samples.astype(np.int32) #将样本转换为32位整数
  10. print('Number of samples: ',len(samples))
  11. #输出采样点数
  12. plot_to_notebook(t,samples,1000)
  13. #画图

运行效果如图,即滤波前的信号:

下面调用scipy函数对上述信号进行滤波,代码如下:

代码中的coeffs为滤波器的系数向量,获取网站https://www.youtube.com/watch?v=LoLCtSzj9BU(需要翻墙),该网站是一个免费的滤波器设计网站。配置通频带、阻带和采样率,点击DESIGN FILTER,即可获取右边的系数向量。

  1. #采用SciPy函数调用的软件FIR滤波器
  2. from scipy.signal import lfilter
  3. coeffs = [-255,-260,-312,-288,-144,153,616,1233,1963,2739,3474,4081,4481,4620,4481,4081,3474,2739,1963,1233,616,153,-144,-288,-312,-260,-255]
  4. #滤波器系数,生成0-5MHz频带的低通滤波器。
  5. import time
  6. start_time = time.time()
  7. sw_fir_output = lfilter(coeffs,70e3,samples)
  8. stop_time = time.time()
  9. sw_exec_time = stop_time - start_time
  10. print('Software FIR execution time: ',sw_exec_time) #输出软件滤波器的滤波耗时。
  11. # 画图
  12. plot_to_notebook(t,samples,1000,out_signal=sw_fir_output)

运行效果如图,即使用scipy函数滤波后的信号对比:

时间开销打印为0.08311s

(2)使用Vivado的滤波器核生成overlay

打开Vivado,新建一个工程,这里我命名为project_demo,点击Next,选择Boards为PYNQ-Z2,然后Next,最后Finish。

点击左侧Create Block Design,弹框点击OK。

添加ZYNQ7的IP核,然后点击自动连线(Run Connection Automation),勾选左侧,点击OK。

然后添加滤波器IP核,双击此IP核进行设置,首先修改系数向量(Coefficient Vector),

系数向量(Coefficient Vector)获取网站https://www.youtube.com/watch?v=LoLCtSzj9BU(需要翻墙),该网站是一个免费的滤波器设计网站。配置通频带、阻带和采样率,点击DESIGN FILTER,即可获取右边的系数向量,复制粘贴到IP核的配置框里。如图

然后修改输入采样频率为100,修改时钟频率为100。

修改输入数据位宽为32,修改Output Rounding Mode为Non Symmetric Rounding Up模式,修改输出宽度为32。

最后修改TLAST为Packet Framing,勾选Output TREADY,其他不做修改,点击OK。

添加DMA的IP核,双击此IP核设置,取消勾选Enable Scatter Gather Engine,Width of Buffer Length Register修改为23,点击OK。

将axi_dma_0与fir_compiler_0进行手动连线,连完如图

对processing_system7_0进行配置,勾选如图所示接口,点击OK。

点击自动连线(Run Connection Automation),全部勾选,点击OK。

再次点击自动连线(Run Connection Automation),全部勾选,点击OK。

改名,将axi_dma_0改为fir_dma,将fir_compiler_0改为fir。对fir_dma点击Create Hieracty,如图,改名为filter,点击OK。

点击保存,点击生成硬件封装(Create HDL Wrapper)。

然后是生成bit文件,这个时间比较久。

上面完成后,点击Export Block Design生成Tcl文件。

下面就是熟悉的操作了,在此工程文件夹中找到bit文件,tcl文件和hwh文件,修改名字统一为fir_accel,在PYNQ中新建文件夹fir_accel,将三个文件粘贴到文件夹中。

至此,overlay生成完成。

(3)使用overlay对相同信号源信号滤波,比较时间开销

我们继续(1)中的python3文件进行编程,下面调用overlay实现滤波,代码如下:

  1. #硬件滤波器实现
  2. from pynq import Overlay
  3. import pynq.lib.dma
  4. overlay = Overlay('/home/xilinx/pynq/overlays/fir_accel/fir_accel.bit') #加载overlay文件
  5. dma = overlay.filter.fir_dma #加载滤波器的DMA
  6. from pynq import Xlnk
  7. import numpy as np
  8. # 为输入和输出信号分配缓冲区
  9. xlnk = Xlnk()
  10. in_buffer = xlnk.cma_array(shape=(n,), dtype=np.int32)
  11. out_buffer = xlnk.cma_array(shape=(n,), dtype=np.int32)
  12. np.copyto(in_buffer,samples)
  13. import time
  14. start_time = time.time() #读取开始的时间点
  15. dma.sendchannel.transfer(in_buffer)
  16. dma.recvchannel.transfer(out_buffer)
  17. dma.sendchannel.wait()
  18. dma.recvchannel.wait()
  19. stop_time = time.time() #读取jieshushijia
  20. hw_exec_time = stop_time-start_time
  21. print('Hardware FIR execution time: ',hw_exec_time) #输出硬件滤波器的滤波耗时
  22. print('Hardware acceleration factor: ',sw_exec_time / hw_exec_time) #输出加速比
  23. # 画图
  24. plot_to_notebook(t,samples,1000,out_signal=out_buffer)
  25. # 释放缓冲区
  26. in_buffer.close()
  27. out_buffer.close()

运行结果如下:

打印的第一个结果是调用overlay滤波的时间开销,第二个结果是与(1)中软件滤波所用时间的比值,即加速比,达到了20倍以上!

结尾

帖子到这里就结束了,反观PYNQ开发板硬件加速的流程及方法,发现它要求使用者具有ZYNQ方面的硬件开发知识,并且对python的调用方法熟练掌握,所以下一步的学习依然任重而道远!


参考英文视频教程:https://www.bilibili.com/video/BV1ax411Z7B4

overlay文件以及jupyter的ipynb文件链接:https://pan.baidu.com/s/1slDxWPTdoBKCw0x4w-PKow 
提取码:9b9h


本篇博客到此就结束了,文中有不严谨之处欢迎批评指正,下方评论交流,韭菜会尽快回复的!

但行努力,莫问前程,如果您觉着文章有用,请点赞鼓励,谢谢!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/468496?site
推荐阅读
相关标签
  

闽ICP备14008679号