差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
students:xuhao [2019/08/17 19:25]
xuhao [池化ip的生成]
students:xuhao [2019/08/26 19:07] (当前版本)
xuhao
行 1: 行 1:
 +# 培训总结
 +
 +[培训内容](students:​peixun)
 +
 # KiCad pcb和原理图设计 # KiCad pcb和原理图设计
   * KiCad,是一款免费开源的PCB设计工具,提供了一个用于原理图输入和PCB布局布线的集成化开发环境,在这个工具中还有用于产生BOM、Gerber文件、对PCB及其上元器件进行3D查看的功能,支持Python脚本定制。  ​   * KiCad,是一款免费开源的PCB设计工具,提供了一个用于原理图输入和PCB布局布线的集成化开发环境,在这个工具中还有用于产生BOM、Gerber文件、对PCB及其上元器件进行3D查看的功能,支持Python脚本定制。  ​
行 5: 行 9:
     * [官方库](https://​kicad.github.io/​)     * [官方库](https://​kicad.github.io/​)
     * [Ultra Librarian](https://​www.ultralibrarian.com/​)     * [Ultra Librarian](https://​www.ultralibrarian.com/​)
-    * [SamacSys](www.samacsys.com)+    * [SamacSys](https://www.samacsys.com)
   * 几点心得   * 几点心得
     * 少用标签     * 少用标签
行 181: 行 185:
  
 # PYNQ和Vivado # PYNQ和Vivado
 +[一些学习笔记](https://​blog.csdn.net/​xh116996/​article/​details/​89218766)
  
 # MNIST数据集训练与加速 # MNIST数据集训练与加速
  
 ## 方案思路 ## 方案思路
-  * 利用tensorflow训练神经网络识别mnist数据集,保存训练参数;利用vivado hls定制卷积和池化ip核;在pynq上复现训练好的神经网络,导入网络参数,利用硬件加速手写数字识别。 +  ​* 搭建并训练神经网络 
-  * mnist神经网络的搭建和训练([深入MNIST](http://​www.tensorfly.cn/​tfdoc/​tutorials/​mnist_pros.html)) +    ​* 利用tensorflow训练神经网络识别mnist数据集,保存训练参数;利用vivado hls定制卷积和池化ip核;在pynq上复现训练好的神经网络,导入网络参数,利用硬件加速手写数字识别。 
-    * 开发工具 PyCharm, python 3.7, tensorflow 1.14.0 +    * mnist神经网络的搭建和训练([深入MNIST](http://​www.tensorfly.cn/​tfdoc/​tutorials/​mnist_pros.html)) 
-    * 搭建四层的神经网络: +      * 开发工具 PyCharm, python 3.7, tensorflow 1.14.0 
-        * (1, 5, 5, 32)卷积,relu激活,2X2池化; +      * 搭建四层的神经网络: 
-        * (32, 5, 5, 64)卷积,relu激活,2X2池化; +          * (1, 5, 5, 32)卷积,relu激活,2X2池化; 
-        * (7X7X64, 1024)全连接层,relu激活,dropout; +          * (32, 5, 5, 64)卷积,relu激活,2X2池化; 
-        * (1024, 10)全连接输出层,softmax分类; +          * (7X7X64, 1024)全连接层,relu激活,dropout; 
-  * 如何保存训练数据?训练好的网络参数是以浮点数(float)类型存储,而在硬件电路中,浮点数计算较慢,所以把网络参数转化为定点数类型导入网络。设计的硬件ip中,乘法运算采用int16型乘法,所以网络权重参数采用int16存储,但可以配置小数点位数(fraction_cnt)来存储小数(= int16 / pow(2, fraction_cnt))。将数据以字节的形式存放在bin中。+          * (1024, 10)全连接输出层,softmax分类; 
 +  ​* 保存神经网络数据 
 +    ​* 如何保存训练数据?训练好的网络参数是以浮点数(float)类型存储,而在硬件电路中,浮点数计算较慢,所以把网络参数转化为定点数类型导入网络。设计的硬件ip中,乘法运算采用int16型乘法,所以网络权重参数采用int16存储,但可以配置小数点位数(fraction_cnt)来存储小数(= int16 / pow(2, fraction_cnt))。将数据以字节的形式存放在bin中。 
 +  * 在pynq的pl中搭建神经网络 
 +    * fpga的配置采用ip设计,主要包括卷积运算ip和池化运算ip。 
 +    * 利用对卷积计算ip和池化运算ip的复用来实现多层卷积神经网络。 
 +{{ :​students:​硬件卷积神经网络.jpg?​200 |}}
  
 +  * 在pynq的ps中控制神经网络,能够实现对数字的识别
 +    * 在jupyter notebook的环境中开发。
 +    * 主要包括导入比特流文件配置pl部分,读取图片和利用网络识别数字。
  
-## vivado综合硬件模块:卷积和池化+## 搭建并训练神经网络,保存网络数据 
 +  * 参考[深入MNIST](http://​www.tensorfly.cn/​tfdoc/​tutorials/​mnist_pros.html)搭建网络,网络数据按照想要的格式保存下来。 
 + 
 +## vivado综合硬件ip:卷积和池化
  
 ### 开发工具 ​ ### 开发工具 ​
行 285: 行 302:
     * C综合是根据上述设定的优化选项和接口协议等将C++程序综合成RTL级HDL语言,并生成综合报告,描述综合后的硬件的时序、消耗的逻辑资源和对外接口类型。     * C综合是根据上述设定的优化选项和接口协议等将C++程序综合成RTL级HDL语言,并生成综合报告,描述综合后的硬件的时序、消耗的逻辑资源和对外接口类型。
     * C&​RTL联合仿真是对综合出来的硬件进行仿真,分析仿真波形来修改C++程序或优化选项等。     * C&​RTL联合仿真是对综合出来的硬件进行仿真,分析仿真波形来修改C++程序或优化选项等。
 +
 +{{ :​students:​池化ip的时序和逻辑消耗.png?​200 |}}
 +{{ :​students:​池化ip外部接口类型.png?​200 |}}
 +
   * 生成IP核   * 生成IP核
-    * 选择 Export RTL生成ip核,包括硬件描述、HDL程序和C驱动程序等。在Vivado中调用生成的ip核时,需要将生成的文件夹添加到Vivado的ip搜索目录下;配置ip时参考driver目录下的xxx_hw.h文件。+    * 选择 Export RTL生成ip核,包括硬件描述、HDL程序和C驱动程序等。在Vivado中调用生成的ip核时,需要将生成的文件夹添加到Vivado的ip搜索目录下;在jupyter notebook中配置ip时参考driver目录下的xxx_hw.h文件。 
 + 
 +{{ :​students:​ip核驱动程序.png?​200 |}}
  
  
行 292: 行 315:
   * 卷积算法   * 卷积算法
  
-## jupyter硬件加速识别数字+## jupyter配置硬件加速识别数字 
   * Vivado构建pynq的overlay——利用ip配置pynq中的PL部分   * Vivado构建pynq的overlay——利用ip配置pynq中的PL部分
-  ​+    ​搭建如图所示的结构,综合、实现、生成比特流。将生成的.srcs\sources_1\bd\design_1\hw_handoff\design_1.hwh文件和.runs\impl_1\design_1_wrapper.bit文件找出来并修改为同样的名字。 
 + 
 +{{ :​students:​捕获.jpg?​200 |}} 
 + 
 +  * 连上pynq开发板,将hwh文件和bit文件通过本地资源管理器连接pynq上传到板子的文件系统内,并在该目录下新建一个ipynb文件,在该文件中实现相应功能程序。 
 +  * 导入比特流文件,配置pynq上的pl部分。 
 + 
 +```python 
 +from pynq import Overlay 
 +from pynq import Xlnk 
 +ol = Overlay("​conv.bit"​) 
 +ol.download() 
 +print(ol.ip_dict.keys()) 
 +dma = ol.axi_dma_0 
 +pool = ol.pool_stream_0 
 +conv = ol.Conv_0 
 +xlnk = Xlnk() 
 +``` 
 +  * 导入网络参数 
 + 
 +```python 
 +import driver 
 +from MNIST_LARGE_cfg import * 
 +driver.Load_Weight_From_File(W_conv1,​ "​./​record/​W_conv1.bin"​) 
 +driver.Load_Weight_From_File(W_fc1,​ "​./​record/​W_fc1.bin"​) 
 +driver.Load_Weight_From_File(W_fc2,​ "​./​record/​W_fc2.bin"​) 
 +``` 
 +  * 导入数字图片,并使用搭建好的网络识别数字,同时利用内置计时器观察硬件执行时间 
 + 
 +```python 
 +start=time.time() 
 +driver.Run_Conv(conv,​ 1,32, 3,3,  1,1,  1,0,  src_buffer,​PTR_IMG,​W_conv1,​PTR_W_CONV1,​h_conv1,​PTR_H_CONV1) 
 +driver.Run_Pool(pool,​dma,​ 32,  4,4,  h_conv1,​h_pool1) 
 +driver.Run_Conv(conv,​ 32,​256, ​ 7,7,  1,1,  0,0,  h_pool1,​PTR_H_POOL1,​W_fc1,​PTR_W_FC1,​h_fc1,​PTR_H_FC1) 
 +driver.Run_Conv(conv,​ 256,​10, ​ 1,1,  1,1,  0,0,  h_fc1,​PTR_H_FC1,​W_fc2,​PTR_W_FC2,​h_fc2,​PTR_H_FC2) 
 +end=time.time() 
 +print("​Hardware run time=%s s"​%(end-start)) 
 +``` 
 +  * 观察最后识别出的数字 
 + 
 +```python 
 +max=-32768 
 +num=0 
 +for i in range(10):​ 
 +    if(h_fc2[i//​K][0][0][i%K]>​max):​ 
 +        max=h_fc2[i//​K][0][0][i%K] 
 +        num=i; 
 +print("​predict num is %d"​%num);​ 
 +```