基于PYNQ-Z2开发板实现矩阵乘法加速详细流程
基于PYNQ-Z2开发板实现矩阵乘法加速
主要内容
1、在Vivado HLS中生成矩阵乘法加速的IP核。
2、在Vivado中完成Block Design。
3、在Jupyter Notebook上完成IP的调用。
完整项目工程文件下载链接见文末
所需硬件
PYNQ-Z2开发板、USB数据线、网线
SD卡、读卡器
开发板配置参考链接
1、Vivado HLS生成矩阵乘法加速IP
- HLS硬件配置信息
- mul.h关键代码
#define MAT_A_ROWS 32
#define MAT_A_COLS 32
#define MAT_B_ROWS 32
#define MAT_B_COLS 32typedef int mat_a_t;
typedef int mat_b_t;
typedef int result_t;void matrixmul(mat_a_t a[MAT_A_ROWS][MAT_A_COLS],mat_b_t b[MAT_B_ROWS][MAT_B_COLS],result_t res[MAT_A_ROWS][MAT_B_COLS]);
定义输入的a,b矩阵维度和输出矩阵的维度
- mul.cpp关键代码
#include "mul.h"void matrixmul(mat_a_t a[MAT_A_ROWS][MAT_A_COLS],mat_b_t b[MAT_B_ROWS][MAT_B_COLS],result_t res[MAT_A_ROWS][MAT_B_COLS])
{int tempA[MAT_A_ROWS][MAT_A_COLS];int tempB[MAT_B_ROWS][MAT_B_COLS];int tempAB[MAT_A_ROWS][MAT_B_COLS];for (int ia = 0; ia<MAT_A_ROWS ;ia++){for(int ja = 0; ja< MAT_A_COLS; ja++){tempA[ia][ja] = a[ia][ja];}}for (int ib = 0; ib<MAT_B_ROWS ;ib++){for(int jb = 0; jb< MAT_B_COLS; jb++){tempB[ib][jb] = b[ib][jb];}}/* for each row and column of AB */row: for(int i = 0; i < MAT_A_ROWS; ++i) {col: for(int j = 0; j < MAT_B_COLS; ++j) {/* compute (AB)i,j */int ABij = 0;product: for(int k = 0; k < MAT_A_COLS; ++k) {ABij += tempA[i][k] * tempB[k][j];}tempAB[i][j] = ABij;}}for (int iab = 0; iab<MAT_A_ROWS ;iab++){for(int jab = 0; jab< MAT_B_COLS; jab++){res[iab][jab] = tempAB[iab][jab];}}}
- 在约束文件中添加接口约束和循环流水,实现矩阵乘法的硬件加速
此处IP核使用ap_ctrl_none接口协议,输入的a,b矩阵和输出的res矩阵均使用axis流数据,注意流数据传输中Block Design中需添加DMAip核进行数据格式转换。 - 编写相关的C仿真代码,此处不表,详见项目文件。
进行C仿真
- C仿真结果
- 进行C综合
- 进行IP导出
- 生成的IP在./solution1/impl/ip路径下,为一压缩包,如下图所示。
2、Vivado进行Block Design
Vivado硬件配置信息
添加Vivado HLS生成的IP,PROJECT MANAGER->Settings
Project Settings->IP->Repository
- 点击+号,选择IP所在路径进行IP的添加
- 然后进行Block Design
- 首先添加ZYNQ的IP
- 双击生成的ZYNQip核,进行配置参数的修改,首先使能HP接口
- 取消勾选USB接口,然后点击OK
- 添加HLS编写的IP
- 添加两个DMA的IP
- 结果如下
- 因为我们有两个AXI流数据的入口,一个AXI流数据的输出,所以要对DMA的读写端口数量进行修改,配置两个DMA的读端口,1个DMA的写端口。下面对DMA的IP参数进行设置。
- DMA0:
- DMA1:
- 之后进行手动连线,下图中标黄的部分
- 然后继续自动完成连线
- 最终的Block如下图所示
- 进行验证
- 此处出现警告信息,可以不管,主要是流数据的Last信号缺失。
- 之后生成顶层调用文件,右击顶层模块,点击Create HDL Wrapper…
- 之后生成BIT文件 PROGRAM AND DEBUG->Generate Bitstream
- Bitstream生成后弹出弹窗,点击cancel。然后点击File->Export->Export Hardware
- 然后点击File->Export->Export Bitstream File,输出路径选择项目根目录。
- 在下图所示的路径中,找到.hwh文件,拷贝到文件的根目录。
- 将bit文件、tcl文件和hwh文件重命名成一个名字,如下所示。
至此完成了Vivado相关的工作。
3、Jupyter Notebook进行矩阵乘法加速IP的调用
PYNQ-Z2板的详细配置过程见文章顶的相关链接,此处默认大家能正常启动板子。
- 在Jupyter Notebook上新建文件夹,进行文件的上传。点击Upload上传之前生成的bit文件、tcl文件和hwh文件。
- 进行新建python文件操作
- python调用IP相关代码
import pynq.lib.dma
import numpy as npmmol = pynq.Overlay("./mul.bit")dma0 = mmol.axi_dma_0
dma1 = mmol.axi_dma_1from pynq import Xlnk
xlnk = Xlnk()
a = xlnk.cma_array(shape=(32,32), dtype=np.int)
b = xlnk.cma_array(shape=(32,32), dtype=np.int)
res = xlnk.cma_array(shape=(32,32), dtype=np.int)for i in range(32):for j in range(32):a[i][j] = 8;b[i][j] = 8;dma0.sendchannel.transfer(a)
dma1.sendchannel.transfer(b)
dma0.recvchannel.transfer(res)
print(res)
- 点击run查看结果
传入的a,b矩阵为32*32的矩阵,元素均为8。结果显示乘法IP核调用正常。
项目工程下载链接
[2020.6.18更新,解决Block Design中TLAST管脚警告的问题]
改变数据类型
mul.c:
#include "mul.h"void matrixmul(mat_a_t a[SIZE],mat_b_t b[SIZE],result_t res[SIZE])
{int tempA[MAT_A_ROWS][MAT_A_COLS];int tempB[MAT_B_ROWS][MAT_B_COLS];int tempAB[MAT_A_ROWS][MAT_B_COLS];for (int ia = 0; ia<MAT_A_ROWS ;ia++){for(int ja = 0; ja< MAT_A_COLS; ja++){tempA[ia][ja] = a[ia*MAT_A_ROWS+ja].data;}}for (int ib = 0; ib<MAT_B_ROWS ;ib++){for(int jb = 0; jb< MAT_B_COLS; jb++){tempB[ib][jb] = b[ib*MAT_A_ROWS+jb].data;}}/* for each row and column of AB */row: for(int i = 0; i < MAT_A_ROWS; ++i) {col: for(int j = 0; j < MAT_B_COLS; ++j) {/* compute (AB)i,j */int ABij = 0;product: for(int k = 0; k < MAT_A_COLS; ++k) {ABij += tempA[i][k] * tempB[k][j];}tempAB[i][j] = ABij;}}for (int iab = 0; iab<MAT_A_ROWS ;iab++){for(int jab = 0; jab< MAT_B_COLS; jab++){res[iab*MAT_A_ROWS+jab]=push_stream<int>(tempAB[iab][jab],iab==(MAT_A_ROWS-1)&&jab==(MAT_B_COLS-1));}}}
mul.h:
#ifndef __MATRIXMUL_H__
#define __MATRIXMUL_H__#include <cmath>
#include <ap_axi_sdata.h>// Uncomment this line to compare TB vs HW C-model and/or RTL
//#define HW_COSIM#define MAT_A_ROWS 32
#define MAT_A_COLS 32
#define MAT_B_ROWS 32
#define MAT_B_COLS 32
#define SIZE 1024typedef ap_axis<32,0,0,0> mat_a_t;
typedef ap_axis<32,0,0,0> mat_b_t;
typedef ap_axis<32,0,0,0> result_t;// Prototype of top level function for C-synthesis
void matrixmul(mat_a_t a[SIZE],mat_b_t b[SIZE],result_t res[SIZE]);template <typename T>
ap_axis<32,0,0,0> push_stream(T const &v, bool last = false)
{#pragma HLS INLINEap_axis<32,0,0,0> e;//assert(sizeof(T) == sizeof(int));union{int oval;T ival;} converter;converter.ival = v;e.data = converter.oval;e.strb=-1;e.keep=15;e.last = last ? 1 : 0;return e;
}#endif // __MATRIXMUL_H__ not defined
使用ap_axis数据类型,其中含有last信号,需对最后一次输出的信号的last信号赋1。或者自己定义数据类型的结构体,含last信号即可。这时进行Block Design的验证时不会再报TLAST信号丢失的Warning。
基于PYNQ-Z2开发板实现矩阵乘法加速详细流程相关推荐
- 基于Linux+6818开发板实现普通电子相册翻页功能
更多资料请点击:我的目录 本篇仅用于记录自己所学知识及应用,代码仍可优化,仅供参考,如果发现有错误的地方,尽管留言于我,谢谢. 首先是外部进程传参,传进的是某目录文件的路径(绝对路径/相对路径).接着 ...
- 【Verilog】基于Nexys4DDR开发板实现数字钟
功能: 基于Nexys4DDR开发板实现的数字钟,六位数码管显示时分秒,可切换24时制/12时制,有整点报时功能(led灯闪烁). Verilog代码: `timescale 1ns / 1ps//数 ...
- Mixly(米思齐)的安装以及基于Arduino开发板实现电容触摸控制灯
Mixly(米思齐)的安装以及基于Arduino开发板实现电容触摸控制灯 1.Mixly下载 http://mixly.org/bnu-maker/mixly-arduino-win Mixly软件安 ...
- 基于STM32开发板实现传感数据采集-DHT11温湿度采集
基于STM32开发板实现传感数据采集-DHT11温湿度采集 一.项目简介 本次项目是基于STM32开发板实现传感数据采集-DHT11温湿度采集.采用ARM结构中最为代表的Cortex-M4系列的芯片, ...
- STM32实例——基于STM32开发板实现传感数据采集-DHT11温湿度采集
STM32开发板实现传感数据采集-DHT11温湿度采集 一.前言 本项目是基于STM32开发板的温湿度采集,传感器采用DHT11温湿度传感器,软件采用keil5等.本项目采用ARM结构中最为代表的Co ...
- 基于RK3588开发板实现多屏拼接
基于RK3588开发板实现多屏拼接 多屏拼接功能说明 将一组完整的画面分割为若干子画面分别送给不同的屏幕显示,可以支持下图的多种模式 硬件环境 基于RK3588 EVB开发板实现4屏拼接,RK3588 ...
- 【微信小程序控制硬件16 】 安信可 ESP32-S 开发板实现移植腾讯物联开发平台蓝牙 llsync 协议,实现一键蓝牙快速配网+远程控制。(附带源码)
文章目录 一.前言 二.源码目录说明 三.编译指导 四.常见问题 五.开源微信物联网控制一览表 另外,不要把我的博客作为学习标准,我的只是笔记,难有疏忽之处,如果有,请指出来,也欢迎留言哈! 微信物联 ...
- RT3070无线网卡AP模式——开发板实现路由功能
RT3070无线网卡有两种工作模式STA模式和softAP模式,分别由STA驱动和softAP驱动来实现,STA驱动支持无线网卡工作在STA模式下,可以连接到网络实现上网功能.而SoftAP的驱动支持 ...
- 利用粤嵌LinuxGEC6818开发板实现电子相册
实验目的 利用粤嵌LinuxGEC6818开发板实现电子相册,要求如下: 实验操作必须在Linux操作系统下完成 源代码模块化设计 实现水平或者垂直滑动切换图片 实验步骤 因为操作需要在Linux下运 ...
最新文章
- springboot配置Druid数据源
- 初读设计模式-----《design pattern explained》读后感
- Java中读取属性文件以及做资源国际化
- JavaScript里的...(三个点)操作符
- Nexys4DDR+OV7670实现图像灰度显示系统
- matlab指令vpa(j10),matlab中vpa函数
- oracle视图可以带日期变量么,创建视图时日期字段如何只都天
- 五个实用又有趣的网站
- Insus NET Utility
- vscode c语言插件_推荐学习C语言或CPP使用的代码编辑器
- 关于sourcetree这是一个无效源路径的解决办法
- Unity小游戏教程系列 | 创建小型太空射击游戏(三)
- 基于jenkins进行定制化开发
- linux分段内存管理中的GDT,LDT,GDTR,LDTR
- win7计算机右键菜单多,win7系统清理右键菜单多余的选项|win7删除右键菜单多余选项的方法...
- 标准正态分布alpha分位点
- 【已解决】Spring容器中找不到ServletWebServerFactory类出现的异常
- Linux下dirname命令
- 店群怎么玩?2020最新玩法介绍 胖哥给大家分享干货
- 一种基于区块链的身份认证方法
热门文章
- WebClient UI create a hidden form and submit
- 使用nodejs创建Marketing Cloud的contact数据
- Marketing Cloud里如何创建新的query视图并设置为默认显示界面
- SAP CRM WebClient UI界面防止XSS攻击的保护措施
- 在Corporate Network里配置SAP Cloud Connector连接SAP云平台,需要设置代理
- territory pop up window是否显示的逻辑,和transaction type差不多
- 采访问题 What is your role at XX and what are your responsibilities
- SAP Connect对inbound邮件接收问题的处理和调试环境搭建
- freetextbox java_FreeTextBox3.2.2下载及使用详解(图)
- java掩码校验_Java 检查Ip掩码