最近想要实现CNN的FPGA加速处理,首先明确在CNN计算的过程中,因为卷积运算是最耗时间的,因此只要将卷积运算在FPGA上并行实现,即可完成部分运算的加速

那么对于卷积的FPGA实现首先要考虑的是卷积子模板具体如何实现,我们在matlab或者c实现比如3X3的子模板的时候,只要用一个数组即可将模板的数据存储起来,而在FPGA的话有以下三种方法:

  1. 用2个或3个RAM存储3X3像素阵列
  2. 用2个或3个FIFO存储3X3像素阵列
  3. 用shift_RAM移位存储3X3像素阵列

而shift_RAM好像就是为了阵列的实现量身定做的一般。

shift_RAM的配置参数主要有以下几个:

手册中可以参考理解的一个非常形象的图如下:

进一步的进行单独一个IP核的仿真后得到:

其中上述参数设置分别为8,2,3,上述仿真图中,相当于把一个矩阵A通过移位寄存的方法通过row3_data送入到RAM,然后分三行输出,在游标所示处就可以开始输出3X3矩阵

0,56,-122

92,50,-57

-58,-13,-61

以下部分是加入了对视频信号处理控制后的代码实现过程:

/*-----------------------------------------------------------------------

CONFIDENTIAL IN CONFIDENCE
This confidential and proprietary software may be only used as authorized
by a licensing agreement from CrazyBingo (Thereturnofbingo).
In the event of publication, the following notice is applicable:
Copyright (C) 2011-20xx CrazyBingo Corporation
The entire notice above must be reproduced on all authorized copies.
Author : CrazyBingo
Technology blogs : http://blog.chinaaet.com/crazybingo
Email Address : thereturnofbingo@gmail.com
Filename : VIP_Matrix_Generate_3X3_8Bit.v
Data : 2014-03-19
Description : Generate 8Bit 3X3 Matrix for Video Image Processor.
Give up the 1th and 2th row edge data caculate for simple process
Give up the 1th and 2th point of 1 line for simple process
Modification History :
Data By Version Change Description
=========================================================================
13/05/26 CrazyBingo 1.0 Original
14/03/16 CrazyBingo 2.0 Modification
-*/ `timescale 1ns/1ns
module VIP_Matrix_Generate_3X3_8Bit
#(
parameter [:] IMG_HDISP = 'd640, //640*480
parameter [:] IMG_VDISP = 'd480
)
(
//global clock
input clk, //cmos video pixel clock
input rst_n, //global reset //Image data prepred to be processd
input per_frame_vsync, //Prepared Image data vsync valid signal
input per_frame_href, //Prepared Image data href vaild signal
input per_frame_clken, //Prepared Image data output/capture enable clock
input [:] per_img_Y, //Prepared Image brightness input //Image data has been processd
output matrix_frame_vsync, //Prepared Image data vsync valid signal
output matrix_frame_href, //Prepared Image data href vaild signal
output matrix_frame_clken, //Prepared Image data output/capture enable clock
output reg [:] matrix_p11, matrix_p12, matrix_p13, //3X3 Matrix output
output reg [:] matrix_p21, matrix_p22, matrix_p23,
output reg [:] matrix_p31, matrix_p32, matrix_p33
); //Generate 3*3 matrix
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//sync row3_data with per_frame_clken & row1_data & raw2_data
wire [:] row1_data; //frame data of the 1th row
wire [:] row2_data; //frame data of the 2th row
reg [:] row3_data; //frame data of the 3th row
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
row3_data <= ;
else
begin
if(per_frame_clken)
row3_data <= per_img_Y;
else
row3_data <= row3_data;
end
end //---------------------------------------
//module of shift ram for raw data
wire shift_clk_en = per_frame_clken;
Line_Shift_RAM_8Bit
#(
.RAM_Length (IMG_HDISP)
)
u_Line_Shift_RAM_8Bit
(
.clock (clk),
.clken (shift_clk_en), //pixel enable clock
// .aclr (1'b0), .shiftin (row3_data), //Current data input
.taps0x (row2_data), //Last row data
.taps1x (row1_data), //Up a row data
.shiftout ()
); //------------------------------------------
//lag 2 clocks signal sync 因为数据存储耗费了一个时钟,因此3*3阵列读取使能和时钟要偏移一个时钟
reg [:] per_frame_vsync_r;
reg [:] per_frame_href_r;
reg [:] per_frame_clken_r;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
per_frame_vsync_r <= ;
per_frame_href_r <= ;
per_frame_clken_r <= ;
end
else
begin
per_frame_vsync_r <= {per_frame_vsync_r[], per_frame_vsync};
per_frame_href_r <= {per_frame_href_r[], per_frame_href};
per_frame_clken_r <= {per_frame_clken_r[], per_frame_clken};
end
end
//Give up the 1th and 2th row edge data caculate for simple process
//Give up the 1th and 2th point of 1 line for simple process
wire read_frame_href = per_frame_href_r[]; //RAM read href sync signal
wire read_frame_clken = per_frame_clken_r[]; //RAM read enable
//将存储RAM以及阵列生成两个步骤需要的时钟都去掉
assign matrix_frame_vsync = per_frame_vsync_r[];
assign matrix_frame_href = per_frame_href_r[];
assign matrix_frame_clken = per_frame_clken_r[]; //----------------------------------------------------------------------------
//----------------------------------------------------------------------------
/******************************************************************************
---------- Convert Matrix ----------
[ P31 -> P32 -> P33 -> ] ---> [ P11 P12 P13 ]
[ P21 -> P22 -> P23 -> ] ---> [ P21 P22 P23 ]
[ P11 -> P12 -> P11 -> ] ---> [ P31 P32 P33 ]
******************************************************************************/
//---------------------------------------------------------------------------
//---------------------------------------------------
/***********************************************
(1) Read data from Shift_RAM
(2) Caculate the Sobel
(3) Steady data after Sobel generate
************************************************/
//wire [23:0] matrix_row1 = {matrix_p11, matrix_p12, matrix_p13}; //Just for test
//wire [23:0] matrix_row2 = {matrix_p21, matrix_p22, matrix_p23};
//wire [23:0] matrix_row3 = {matrix_p31, matrix_p32, matrix_p33};
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
{matrix_p11, matrix_p12, matrix_p13} <= 'h0;
{matrix_p21, matrix_p22, matrix_p23} <= 'h0;
{matrix_p31, matrix_p32, matrix_p33} <= 'h0;
end
else if(read_frame_href)
begin
if(read_frame_clken) //Shift_RAM data read clock enable
begin
{matrix_p11, matrix_p12, matrix_p13} <= {matrix_p12, matrix_p13, row1_data}; //1th shift input
{matrix_p21, matrix_p22, matrix_p23} <= {matrix_p22, matrix_p23, row2_data}; //2th shift input
{matrix_p31, matrix_p32, matrix_p33} <= {matrix_p32, matrix_p33, row3_data}; //3th shift input
end
else
begin
{matrix_p11, matrix_p12, matrix_p13} <= {matrix_p11, matrix_p12, matrix_p13};
{matrix_p21, matrix_p22, matrix_p23} <= {matrix_p21, matrix_p22, matrix_p23};
{matrix_p31, matrix_p32, matrix_p33} <= {matrix_p31, matrix_p32, matrix_p33};
end
end
else
begin
{matrix_p11, matrix_p12, matrix_p13} <= 'h0;
{matrix_p21, matrix_p22, matrix_p23} <= 'h0;
{matrix_p31, matrix_p32, matrix_p33} <= 'h0;
end
end endmodule
//注意这里得到的每一行得第一第二的像素都没有用到,而且最后一行的像素没有被运算。

RAM-Based Shift Register (ALTSHIFT_TAPS) IP Core-实现3X3像素阵列存储的更多相关文章

  1. 阅读 RAM-Based Shift Register(ALTSHIFT_TAPS) IP Core User Guide

    阅读 RAM-Based Shift Register(ALTSHIFT_TAPS) IP Core User Guide 说明:本文档自带测试工程: DE_ALTSHIFT_TAPS.zip 1.支 ...

  2. Modelsim独立仿真Vivado Clocking Wizard IP Core

    工欲善其事,必先利其器.在使用Vivado自带的仿真软件仿真的时候,相对于更优秀的仿真工具Modelsim,效率低了很多,为了更高效的开发,我尝试着用Vivado级联Modelsim仿真,但是级联后还 ...

  3. 在EDK里面添加ISE IP core的方法

    (1)在ISE下,使用core generator,可以得到xilinx的IP的*.v和*.ngc 文件,将这两个文件拷贝出来: (2)在EDK下使用“Create or Import Periphe ...

  4. 使用xilinx ip core FIFO First- World First-Through (FWFT)模式的注意事项

    也许很多人知道xilinx ip core 中的fifo可以配成standard 模式和FWFT模式,并知道两者的区别是:standard模式下,当rd为高时,fifo会延时一个时钟输出数据(时序逻辑 ...

  5. IP Core 分类

    IP(Intelligent Property)核是具有知识产权核的集成电路芯核总称,是经过反复验证过的.具有特定功能的宏模块,与芯片制造工艺无关,可以移植到不同的半导体工艺中.到了SOC阶段,IP核 ...

  6. H.265 Video Encoder IP Core

    复制: 开源H.265硬件视频编码器H.265 Video Encoder IP Core是开源的H.265硬件视频编码器,实现了H.265(或叫HEVC)的大部分功能. 它由复旦大学专用集成电路与系 ...

  7. Vivado 2017封装自定义IP Core

    使用Vivado2017.3自定义IP Core.通常情况下,我们做设计采用模块化设计,对于已经设计好的一部分模块功能,就可以直接拿来调用,IP Core就是这样来的,一般来说我们看不到IP Core ...

  8. Xilinx 7系列例化MIG IP core DDR3读写

    昨晚找了一下,发现DDR3读写在工程上多是通过例化MIG,调用生成IPcore的HDL Functional Model.我说嘛,自己哪能写出那么繁琐的,不过DDR读写数据可以用到状态机,后期再添砖加 ...

  9. Shift Register(Using Submodule)

    /*************************************************** /  Shift Register module by Submodule /  Progra ...

随机推荐

  1. APP分享视频H5页面

    男左女右中国APP需要做一个APP分享视频H5页面,效果图见下面的图. 出现的问题: (1)URL参数为中文的时候乱码: (2)vedio点击默认是QQ,微信的播放器: (3)给视频添加一个默认的封面 ...

  2. faster rcnn报错:TypeError: slice indices must be integers or None or have an __index__ method

    https://blog.csdn.net/qq_27637315/article/details/78849756 https://blog.csdn.net/qq_21089969/article ...

  3. redis常用命令--基础

    redis默认有个数据库,下标从开始,不支持自定义数据库名字. 使用select  index 切换数据库  : select 7 (切换到第八个数据库) dbsize:求当前数据库中键值对的数量. ...

  4. 关于 sublime 使用技巧

    实行多位置编写  按住 alt 键 用鼠标点击想要编写的位置 实行正方形任意拉选操作  按住 alt 键  用鼠标拖动来进行勾选 继续转发别人的帖子 模块与包的导入 https://blog.csdn ...

  5. iOS精美过度动画、视频会议、朋友圈、联系人检索、自定义聊天界面等源码

    iOS精选源码 iOS 精美过度动画源码 iOS简易聊天页面以及容联云IM自定义聊天页面的实现思路 自定义cell的列表视图实现:置顶.拖拽.多选.删除 SSSearcher仿微信搜索联系人,高亮搜索 ...

  6. iOS 修改默认 UserAgent

    User-Agent(用户代理)字符串是Web浏览器用于声明自身型号版本并随HTTP请求发送给Web服务器的字符串,在Web服务器上可以获取到该字符串. UIWebView修改UserAgent UI ...

  7. 实验吧web--易--后台登陆

    题目地址:http://www.shiyanbar.com/ctf/2036 这道题确实有点考研脑洞了. 1.首先,查看网页源代码(Ctrl+U),会发现一段PHP代码: $sql = "S ...

  8. SQL基础教程(第2版)第6章 函数、谓词、CASE表达式:6-3 CASE表达式

    ● 虽然CASE表达式中的ELSE子句可以省略,但为了让SQL语句更加容易理解,还是希望大家不要省略. ● CASE表达式中的END不能省略. ● 使用CASE表达式能够将SELECT语句的结果进行组 ...

  9. 201771010123汪慧和《面向对象程序设计Java》第十一周实验总结

    一.理论部分 1.栈 (1)栈是一种特殊的线性表,是一种后进先出的结构.(2)栈是限定仅在表尾进行插入和删除运算的线性表,表尾称为栈顶,表头称为栈底.(3)栈的物理存储可以用顺序存储结构,也可以用链式 ...

  10. while read line do done < file

    zzx@zzx120:~/test1$ cat file.txt    1122zzx@zzx120:~/test1$ cat ./read.sh #!/bin/bashwhile read line ...