**基于FPGA实现的加速人工智能算法**
## 1.项目由来
  毕业设计,为了蹭热点,选了几个和人工智能相关的课题,本意是希望通过毕业设计让自己了解一下机器学习,比如CNN一类的。很不幸,被体系结构实验室的老师抢走了。于是就面临了这个偏硬件的课题,用FPGA加速人工智能算法。</Br>
  毕竟只是本科毕业设计,这个课题在我手里就变成了用FPGA加速CNN,本来的目的还是要完成,在大致了解了CNN之后,还是在极不情愿中做完了这个项目。</Br>
  项目本质很简单,使用Verilog实现了一些CNN的模块。~~几乎没有多少实用价值。~~ 另外,和大多数FPGA加速CNN的项目一样,本项目只能运行推断,不能学习,所以没有后向传播~~这不怪我,Xilinx自己都已经放弃治疗了。~~
## 2.使用
  模块设计上参照了tensorflow。因为使用了全并行的设计,所以没有引入时序,也没有做流水线~~我不信哪块FPGA板子的部件延迟会大过总线周期~~,所以在资源占用上很不合理,可能需要在规模很大的FPGA板子上才能实现一个较大的网络吧~~也就是说本项目毫无卵用~~</Br></Br>
有以下几个模块:
### 2.1Conv2d
**说明:**
  卷积模块,可以进行二维卷积。支持多个卷积核,不同步长,是否启用边缘0填充等
**可配置参数:**
| 名称 | 说明 | 默认值 |
| ------------- | ----------------------------------- | ------ |
| BITWIDTH | 数据位宽 | 8 |
| DATAWIDTH | 图像的宽度 | 28 |
| DATAHEIGHT | 图像的高度 | 28 |
| DATACHANNEL | 图像通道数 | 3 |
| FILTERHEIGHT | 卷积核的高度 | 5 |
| FILTERWIDTH | 卷积核的宽度 | 5 |
| FILTERBATCH | 卷积核的数量 | 1 |
| STRIDEHEIGHT | 纵向步长 | 1 |
| STRIDEWIDTH | 横向步长 | 1 |
| PADDINGENABLE | 边缘是否使用0填充,1代表是,0代表否 | 0 |
**输入输出:**
| 名称 | 类型 | 说明 | 长度 |
| ------------ | ------ | ---------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| data | input | 输入的图像,数据从第一个通道左上至最后一个通道右下排列,每一个像素值为有符号定点数 | BITWIDTH × DATAWIDTH × DATAHEIGHT × DATACHANNEL |
| filterWeight | input | 卷积核权值,从第一个卷积核左上开始,到最后一个卷积核右下,每一个值为有符号定点数 | BITWIDTH × FILTERHEIGHT × FILTERWIDTH × DATACHANNEL × FILTERBATCH |
| filterBias | input | 卷积核偏置,按卷积核顺序排列,每一个值为有符号定点数 | BITWIDTH × FILTERBATCH |
| result | output | 输出的特征图,从第一张左上开始,到最后一张右下,每一个值为有符号定点数 | BITWIDTH × FILTERBATCH × (PADDINGENABLE == 0 ? (DATAWIDTH - FILTERWIDTH + 1) ÷ STRIDEWIDTH : (DATAWIDTH ÷ STRIDEWIDTH)) × (PADDINGENABLE == 0 ? (DATAHEIGHT - FILTERHEIGHT + 1) ÷ STRIDEHEIGHT : (DATAHEIGHT ÷ STRIDEHEIGHT)) |
### 2.2Max_pool
**说明:**
  最大池化模块,可以对输入进行最大池化运算。
**可配置参数:**
| 名称 | 说明 | 默认值 |
| ----------- | ------------ | ------ |
| BITWIDTH | 数据位宽 | 8 |
| DATAWIDTH | 特征图的宽度 | 28 |
| DATAHEIGHT | 特征图的高度 | 28 |
| DATACHANNEL | 特征图通道数 | 3 |
| KWIDTH | 池化窗口宽度 | 2 |
| KHEIGHT | 池化窗口高度 | 2 |
**输入输出:**
| 名称 | 类型 | 说明 | 长度 |
| ------ | ------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------ |
| data | input | 输入的特征图,像素数据从左上至右下排列,每一个值为有符号定点数 | BITWIDTH × DATAWIDTH × DATAHEIGHT × DATACHANNEL |
| result | output | 输出的特征图,从第一个通道左上到最后一个通道右下,每一个值为有符号定点数 | BITWIDTH × DATAWIDTH ÷ KWIDTH × DATAHEIGHT ÷ KHEIGHT × DATACHANNEL |
### 2.3Avg_pool
**说明:**
  平均池化模块,可以对输入进行平均池化运算。
**可配置参数:**
| 名称 | 说明 | 默认值 |
| ----------- | ------------ | ------ |
| BITWIDTH | 数据位宽 | 8 |
| DATAWIDTH | 特征图的宽度 | 28 |
| DATAHEIGHT | 特征图的高度 | 28 |
| DATACHANNEL | 特征图通道数 | 3 |
| KWIDTH | 池化窗口宽度 | 2 |
| KHEIGHT | 池化窗口高度 | 2 |
**输入输出:**
| 名称 | 类型 | 说明 | 长度 |
| ------ | ------ | -------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| data | input | 输入的特征图,数据从第一个通道左上至最后一个通道右下排列,每一个值为有符号定点数 | BITWIDTH × DATAWIDTH × DATAHEIGHT × DATACHANNEL |
| result | output | 输出的特征图,从第一个通道左上到最后一个通道右下,每一个值为有符号定点数 | BITWIDTH × DATAWIDTH ÷ KWIDTH × DATAHEIGHT ÷ KHEIGHT × DATACHANNEL |
### 2.4Relu_activation
**说明:**
  ReLU激活函数模块。可以根据情况决定卷积之后的特征图要不要连接激活函数。
**可配置参数:**
| 名称 | 说明 | 默认值 |
| ----------- | ------------ | ------ |
| BITWIDTH | 数据位宽 | 8 |
| DATAWIDTH | 特征图的宽度 | 28 |
| DATAHEIGHT | 特征图的高度 | 28 |
| DATACHANNEL | 特征图通道数 | 3 |
**输入输出:**
| 名称 | 类型 | 说明 | 长度 |
| ------ | ------ | -------------------------------------------------------------------------------- | ----------------------------------------------- |
| data | input | 输入的特征图,数据从第一个通道左上至最后一个通道右下排列,每一个值为有符