读懂相关程序
//top.h
#ifndef __TOP_H
#define __TOP_H
template<int D,int U,int TI,int TD>
struct ap_axif{
float data;
ap_uint<(D+7)/8> keep;
ap_uint<(D+7)/8> strb;
ap_uint<U> user;
ap_uint<1> last;
ap_uint<TI> id;
ap_uint<TD> dest;
};
typedef ap_axiu<32,1,1,1> AXI_VALUE;
typedef hls::stream<AXI_VALUE> AXI_STREAM;
void axi_stream_top(AXI_STREAM &inStream, AXI_STREAM &outStream);
#endif
1. template模板
模板(Template)指C++程序设计设计语言中采用类型作为参数的程序设计,支持通用程序设计。C++ 的标准库提供许多有用的函数大多结合了模板的观念,如STL以及IO Stream。
- 函数模板
Template <class或者也可以用typename T>
返回类型 函数名(形参表)
{//函数定义体 }
template是一个声明模板的关键字,表示声明一个模板关键字class不能省略,如果类型形参多余一个 ,每个形参前都要加class <类型 形参表>可以包含基本数据类型可以包含类类型.
template <class T>
T min(T x,T y)
{ return(x<y)?x:y;}
void main( )
{
int n1=2,n2=10;
double d1=1.5,d2=5.6;
cout<< "较小整数:"<<min(n1,n2)<<endl;
cout<< "较小实数:"<<min(d1,d2)<<endl;
system("PAUSE");
}
程序分析:main()函数中定义了两个整型变量n1 , n2 两个双精度类型变量d1 , d2然后调用min( n1, n2); 即实例化函数模板T min(T x, T y)其中T为int型,求出n1,n2中的最小值.同理调用min(d1,d2)时,,T为double型,求出d1,d2中的最小值.- 类模板
Template < class或者也可以用typename T >
class类名{
//类定义......
};
- 参数模板
- 模板专门化
未完
2.#ifndef,防止重复编译
2.1 #ifndef x //先测试x是否被宏定义过
2.2 #define x ... //如果没有宏定义下面就宏定义x并编译下面的语句
2.3 #endif //如果已经定义了则编译#endif后面的语句
条件指示符#ifndef检查预编译常量在前面是否已经被宏定义。如果在前面没有被宏定义,则条件指示符的值为真,于是从#ifndef到#endif之间的所有语句都被包含进来进行编译处理。相反,如果#ifndef指示符的值为假,则它与#endif指示符之间的行将被忽略。条件指示符#ifndef 的最主要目的是防止头文件的重复包含和编译。
主程序解析
//cnn.cpp
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "parameters.h"
#include "necstream.hpp"
#define REAL float
#define BIT_WIDTH 32
/* DMA constants */
float weights[16*27] = {}
void cnn(FloatStream streamIn, FloatStream streamOut)
{
FloatAxis tmp;
int i, j, k;
int sof = 1;
//DMA buffer and pointers
REAL buf_in[27*600];
REAL buf_out[16*600];
//REAL weights[16*27];
REAL temp, result;
//Load input image data
for (i = 0; i < 27 * 600; i++) {
#pragma HLS PIPELINE II=1
buf_in[i] = streamPop < float, FloatAxis, FloatStream > (streamIn);
}
for (i = 0; i < 16; i++) {
for (j = 0; j < 600; j++) {
result = 0;
for (k = 0; k < 27; k++) {
temp = weights[i*27+k] * buf_in[k*600+j];
result += temp;
}
buf_out[i*600+j] = result;
}
}
for (i = 0; i < 16 * 600; i++) {
//#pragma HLS PIPELINE II=1
FloatAxis d;
d.data = buf_out[i];
if (sof) {
d.user = 1;
sof = 0;
} else {
d.user = 0;
}
if (i == 16*600 - 1)
d.last = 1;
else
d.last = 0;
d.keep = -1;
streamOut << d;
}
}
1.全局变量与局部变量
int a,b; /*外部变量*/
void f1() /*函数f1*/
{
……
}
float x,y; /*外部变量*/
int f2() /*函数f2*/
{
……
}
main() /*主函数*/
{
int maomi();
……
}/*全局变量x,y作用域 全局变量a,b作用域*/
- 从上例可以看出a、b、x、y 都是在函数外部定义的外部变量,都是全局变量。但x,y 定义在函数f1之后,而在f1内又无对x,y的说明,所以它们在f1内无效。 a,b定义在源程序最前面,因此在f1,f2及main内不加说明也可使用。
- 全局变量是使用相同的内存块在整个类中存储一个值.
- 全局变量extern与static:extern在其他源程序中也可以使用;static只能在本程序中使用。
- 所以程序中的weights算是全局变量,(存储在DMA constants中?)主函数中可以调用。