赞
踩
Quartus prime 18.1
作为HLS实验环境搭建的必要软件之一,经验证Quartus Prime 17.1以及18.1版本可支持HLS开发。该软件可在Intel官网上注册后直接下载并按默认选项安装即可。
Modelsim Starter Edition 10.5b
ModelSim是Quartus Prime的附加软件之一。安装Quartus Prime的同时也会安装相应版本的ModelSim,所以无需专门安装该软件。
在此次HLS实验中,使用的版本是ModelSim Starter Edition 10.5b,此为HLS的默认调用版本并且不需要License。
Microsoft Visual Studio 2010 (Visual C++, 未使用license)
在整个HLS实验环境搭建中,建议安装使用Microsoft Visual Studio 2010因为经验证更新后的版本将不支持HLS开发。其中Profession、Ultimate、Standard三个版本均可从网上下载安装并未使用License,但是需要注意的是Standard版本仅支持HLS 18.1以及HLS 19.1,所以到时候需要手动匹配HLS版本方可运行。此外,在安装过程中需确保Visual C++被成功勾选。
在此次HLS实验中,使用的版本是Microsoft Visual Studio 2010 Ultimate。
(需要注意的是在全部软件安装完成后,环境变量都已自动被设置,故而无需再手动设置。)
C5MB_GHRD的黄金参考工程
重要说明:
Width 输入图像宽度
Height 输入图像高度
OutDir 如果是1的话,将卷积结果存放在LocalMap中;如果是0保存在Result中
Accmulate 如果是1表示需要累加
maps weight localmap result分别是4块独立的内存区域
一下代码的int main() 这个函数可以加可不加
如图下面四个C文件
文件名 | 描述 |
---|---|
conv.c | 卷积算子 |
biasrelu.c | 偏置算子 |
pooling.c | 池化算子 |
full_connecttion.c | 全连接算子 |
#include <HLS/stdio.h> #include "HLS/hls.h" component void AccConvolution(int Width, int Height, int OutDir, int Accmulate, ihc::mm_master<float> &maps, ihc::mm_master<float> &Weight, ihc::mm_master<float> &LocalMap, ihc::mm_master<float> &Result) { float temp; int _height = Height - 2; int _width = Width - 2; int index = 0; for(int h = 0;h < _height ;h++) { for(int w = 0;w < _width ;w++) { temp = maps[ (h ) * Width + w ] * Weight[0] + maps[ (h ) * Width + w + 1 ] * Weight[1] + maps[ (h ) * Width + w + 2 ] * Weight[2] + maps[ (h + 1) * Width + w ] * Weight[3] + maps[ (h + 1) * Width + w + 1 ] * Weight[4] + maps[ (h + 1) * Width + w + 2 ] * Weight[5] + maps[ (h + 2) * Width + w ] * Weight[6] + maps[ (h + 2) * Width + w + 1 ] * Weight[7] + maps[ (h + 2) * Width + w + 2 ] * Weight[8] ; index = h * (Width - 2) + w; if(Accmulate) temp += LocalMap[index]; if(OutDir) LocalMap[index] = temp; else Result[index] = temp; } } } int main() { int Width = 5; int Height = 5; int OutDir = 1; //输出特征图保存在LocalMap int Accmulate = 0; //不叠加LocalMap float maps[5*5] = { //保存输入特征图 1,1,1,0,0, 0,1,1,1,0, 0,0,1,1,1, 0,0,1,1,0, 0,1,1,0,0 }; float Weight[3*3] = { //卷积窗3*3 1,0,1, 0,1,0, 1,0,1 }; float LocalMap[3*3] = {0.0}; //输出特征图尺寸3*3 float Result[3*3] = {0.0} ;//输出特征图尺寸3*3 //打印输入的特征图 printf("input picture:\n"); for(int i=0;i<25;i++) { printf("%.1f ",maps[i]); if((i+1)%5==0) { printf("\n"); } } //打印输入的权重 printf("input Weight:\n"); for(int i=0;i<9;i++) { printf("%.1f ",Weight[i]); if((i+1)%3==0) { printf("\n"); } } ihc::mm_master<float> mm_maps(maps,sizeof(float)*25); ihc::mm_master<float> mm_Weight(Weight,sizeof(float)*9); ihc::mm_master<float> mm_LocalMap(LocalMap,sizeof(float)*9); ihc::mm_master<float> mm_Result(Result,sizeof(float)*9); //调用component AccConvolution(Width,Height,OutDir,Accmulate,mm_maps,mm_Weight,mm_LocalMap,mm_Result); //打印Result中的结果 printf("result in LocalMap:\n"); for(int i=0;i<9;i++) { printf("%.1f ",LocalMap[i]); if((i+1)%3==0) { printf("\n"); } } return 0; }
#include <HLS/stdio.h> #include "HLS/hls.h" component void AccBiasRelu(int Width, int Height, int InDir, int OutDir, ihc::mm_master<float> &LocalMap, ihc::mm_master<float> &maps, ihc::mm_master<float> &Result, ihc::mm_master<float> &Weight) { int Exit = Width * Height; float temp; float *temp1; float *inputbuffer; if(InDir) inputbuffer = LocalMap; else inputbuffer = maps; if(OutDir) temp1 = LocalMap; else temp1 = Result; #pragma ivdep for(int i = 0;i < Exit;i++) { temp = inputbuffer[i] + Weight[0]; temp1[i] = (temp > 0) ? temp : 0; } } int main() { int Width = 3; int Height = 3; int InDir = 1; //从LocalMap取数据(也就是卷积后的数据) int OutDir = 1; //从LocalMap取数据(加偏置后的数据) float LocalMap[3*3] = { //激活后的结果保存在LocalMap里面,激活的输入数据来自于私有存储器 4.0 ,3.0, 4.0, 2.0 ,4.0, 3.0, 2.0 ,3.0, 4.0 }; //打印输入的图片 printf("input picture:\n"); for(int i=0;i<9;i++) { printf("%.1f ",LocalMap[i]); if((i+1)%3==0) { printf("\n"); } } float maps[3*3] = {0.0}; float Result[3*3] = {0.0}; float Weight[3*3] = { //加载偏置数据到FPGA的Weight存储器中 1.0 ,0.0, 1.0, 0.0 ,1.0, 0.0, 1.0 ,0.0, 1.0 }; //打印输入的权重 printf("input Weight:\n"); for(int i=0;i<9;i++) { printf("%.1f ",Weight[i]); if((i+1)%3==0) { printf("\n"); } }; ihc::mm_master<float> mm_maps(maps,sizeof(float)*9); ihc::mm_master<float> mm_Weight(Weight,sizeof(float)*9); ihc::mm_master<float> mm_LocalMap(LocalMap,sizeof(float)*9); ihc::mm_master<float> mm_Result(Result,sizeof(float)*9); //调用component AccBiasRelu(Width,Height,InDir,OutDir,mm_LocalMap, mm_maps,mm_Result,mm_Weight); //打印LocalMap中的结果 printf("LocalMap data:\n"); for(int i=0;i<9;i++) { printf("%.1f ",LocalMap[i]); if((i+1)%3==0) { printf("\n"); } } return 0; }
#include <HLS/stdio.h> #include "HLS/hls.h" #include <HLS/stdio.h> #include "HLS/hls.h" component void AccPool( int Width, int Height, int InDir, int OutDir, ihc::mm_master<float>&LocalMap, ihc::mm_master<float>&maps, ihc::mm_master<float>&Result) { float PoolWindow[2][2]; float temp0; float temp1; float temp2; int _height = Height >> 1; int _width = Width >> 1; int index = 0; int _index = 0; int _index_1 = 0; float *input; float *output; if(InDir) input = LocalMap; else input = maps; if(OutDir) output = LocalMap; else output = Result; for(int h = 0;h < _height;h++) { #pragma ivdep for(int w = 0;w < _width;w++) { _index = h * 2 * Width + w * 2; _index_1 = (h * 2 + 1) * Width + w * 2; PoolWindow[0][0] = input[ _index ]; PoolWindow[0][1] = input[ _index + 1]; PoolWindow[1][0] = input[ _index_1 ]; PoolWindow[1][1] = input[ _index_1 + 1]; temp0 = (PoolWindow[0][0] > PoolWindow[0][1]) ? PoolWindow[0][0] : PoolWindow[0][1]; temp1 = (PoolWindow[1][0] > PoolWindow[1][1]) ? PoolWindow[1][0] : PoolWindow[1][1]; temp2 = (temp0 > temp1) ? temp0 : temp1; output[h*_width + w] = temp2; } } } int main() { int Width = 4; int Height = 4; int InDir = 1; //从 Localmap 读取图片数据 int OutDir = 0; //将输出结果放到 Result中 float LocalMap[4*4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 2, 2, 3, 4 }; //打印从LocalMap获取的数据 printf("input LocalMap:\n"); for(int i=0;i<16;i++) { printf("%.1f ",LocalMap[i]); if((i+1)%4==0) { printf("\n"); } } float maps[4*4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 2, 2, 3, 4 }; float Result[2*2] = {0.0}; ihc::mm_master<float> mm_maps(maps,sizeof(float)*16); ihc::mm_master<float> mm_LocalMap(LocalMap,sizeof(float)*16); ihc::mm_master<float> mm_Result(Result,sizeof(float)*4); //调用组件 AccPool(Width, Height,InDir, OutDir,mm_LocalMap,mm_maps,mm_Result); //打印 Result 内存中的结果 printf("pooling result:\n"); for(int i=0;i<4;i++) { printf("%.1f ",Result[i]); if((i+1)%2==0) { printf("\n"); } } return 0; }
#include <HLS/stdio.h> #include "HLS/hls.h" component void AccFullConnect(ihc::mm_master<float>&maps, ihc::mm_master<float>&Weight, ihc::mm_master<float>&Result) { float temp[16]; float tmp = 0.0; float *result; result = Result; #pragma unroll for(int i = 0;i < 16;i++) { temp[i] = maps[i] * Weight[i]; } #pragma unroll for(int i=0; i< 16;i++) { tmp += temp[i]; } result[0] = tmp; } int main() { float maps[16]={1,1,1,0,0,1,1,1,0,0,1,1,0,0,1,1}; //打印maps中的数据 printf("input maps:\n"); for(int i=0;i<16;i++) { printf("%.1f ",maps[i]); } printf("\n"); float Weight[16] = {1,0,1,1,0,1,0,0,1,0,1,1}; //打印Weight中的数据 printf("input Weight:\n"); for(int i=0;i<16;i++) { printf("%.1f ",Weight[i]); } printf("\n"); float Result[16] = {0.0f}; ihc::mm_master<float> mm_maps(maps,16*sizeof(float)); ihc::mm_master<float> mm_Weight(Weight,16*sizeof(float)); ihc::mm_master<float> mm_Result(Result,16*sizeof(float)); //调用组件 AccFullConnect(mm_maps,mm_Weight,mm_Result); //打印 Result 内存中的数据 printf("full_connection Result:\n"); printf("%.1f \n",Result[0]); return 0; }
①先初始化环境(命令根据自己的路径来定)
d:\FPGA\intelFPGA\18.1\hls\init_hls.bat
②编译
i++ -march=CycloneV conv.c -o conv -v
然后自动生成
③最终完整四个算子
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。