如上图,共有三组寄存器,每组寄存器可存储三个数据,第一个时钟周期,Buffer1读入第一行的前三个数据,Buffer2读入第二行的前三个数据,Buffer3读入第三行的前三个数据,之后,各个寄存器组左移K-1次,这里K=3,之后,寄存器组1从寄存器组2的FIFO中读取一行数据(0,11,12),寄存器组2从寄存器组3的FIFO中读取一行数据(0,21,22),而最右边的寄存器组从Buffer3读取下一行数据,然后各寄存器组左移2次。这样一直进行K次,可以发现,经过KxK个周期后,寄存器组的第一列的数据按时间顺序恰好是第一个待卷积窗口的数值,第二列是第二个待卷积窗口的数值,而寄存器组2的第一列是第二行第一个待卷积窗口…,因而这个K^2个周期一共计算了3*3个输出像素。
下面进行一般性的总结,若卷积核大小为KxK,滑动步长为S,待卷积的特征图为Pix
×
\times
×Piy,则输出特征图为Pox
×
\times
×Poy,且满足 Pox=(Pix-K)/S+1 Poy=(Piy-K)/S+1 为了一起计算这Pox
×
\times
×Poy个输出,我们采用Poy个寄存器组,每个寄存器组可存储Pix-K+1个数据,我们进行如下K次操作: Buffer1输入第1行的前Pix-K+1个数据,Buffer2输入第1+S行的前Pix-K+1个数据,
B
u
f
f
e
r
i
Buffer_i
Bufferi输入1+S
×
\times
×(i-1)行的前Pix-K+1个数据,下个周期,Buffer1输入相较于之前那行的下一行,其余Buffer同理,这样一共输入S行,而剩下的K-S行,左边的Poy-1个寄存器组从右边相邻的FIFO中读取下一行,而最右边的寄存器组继续从Buffer读取下一行。如此,每组一共读取了K行,每次读取一行后左移K-1次,这样一共经过K^2个时钟周期,产生了Pox
×
\times
×Poy个输出像素,并行度为Pox
×
\times
×Poy.
一种基于FPGA的卷积算法
使用FIFO实现二维卷积
关注
打赏