您当前的位置: 首页 > 

FPGA硅农

暂无认证

  • 2浏览

    0关注

    282博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

fpga基于shift ram的卷积实现

FPGA硅农 发布时间:2020-02-18 13:46:20 ,浏览量:2

verilog实现卷积运算

设输入矩阵为NixNi,卷积核大小为KxK,卷积步长为S,则可以选用长度为Ni,高度为K的shift_ram实现,具体如下。 记输入shift_ram的时间为clk0,则易知经过NixK个周期后shift_ram被充满,也即产生第一列有效输出 X 0 , 0 , X 1 , 0 , X 2 , 0 X_{0,0},X_{1,0},X_{2,0} X0,0​,X1,0​,X2,0​,再经过Nix(Ni-K+1)-1个周期,产生最后一列有效输出 X N i − 1 , N i − 1 , X N i − 2 , N i − 1 , X N i − 3 , N i − 1 X_{Ni-1,Ni-1},X_{Ni-2,Ni-1},X_{Ni-3,Ni-1} XNi−1,Ni−1​,XNi−2,Ni−1​,XNi−3,Ni−1​,设数据读出延时为2+1个clk,计算卷积需要乘法1个周期,加法需要2个周期(每列相加,再把每列的和相加),则从输入第一个数据的读地址开始,需要经过NixK+(2+1)+(1+2)+K-1(需等待余下K-1列读出)个clk才会产生第一个卷积输出,经过NixK+(2+1)+(Ni-K+1)xNi-1+(1+2)个周期产生最后一个卷积输出,当然,这之间的输出并不都有效,应视步长S有选择的进行读取结果。 这种方式计算一个矩阵的大约需要 O ( N i 2 ) O(N_i^2) O(Ni2​)个clk周期。 代码如下,已通过仿真,卷积核大小为3,其他卷积核大小需要修改部分代码,但思路一样。 conv.v

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2020/02/13 20:54:56
// Design Name: 
// Module Name: top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module conv
# (
    parameter Ni=5,
    parameter K=3,
    parameter S=2,
    parameter No=(Ni-K)/S+1,
    parameter F=8)         //FΪС��λ��
(
input clk,
input rst,
input start,
input signed[15:0]weight,
output reg[7:0]weight_addr,
input signed [15:0]rd_data,
output signed [15:0]wr_data,
output reg[15:0]rd_addr,
output reg[15:0]wr_addr,
output wren,
output done
    );


wire [47:0]taps;
wire signed[15:0]dout,dout0,dout1,dout2;
reg read_weight;
reg read;
reg sum_valid;
reg sum_valid_d1;
reg wr_data_valid;
reg signed[15:0]din;
reg signed[15:0]dout0_d1,dout0_d2,dout1_d1,dout1_d2,dout2_d1,dout2_d2;
reg signed [31:0]mul1,mul2,mul0,mul1_d1,mul2_d1,mul0_d1,mul2_d2,mul1_d2,mul0_d2;
reg signed [31:0]sum0,sum1,sum2;
reg signed [15:0]sum;
reg [7:0]weight_addr_d1,weight_addr_d2;
reg [9:0]cnt1,cnt2;
reg [9:0]cnt_s1,cnt_s2;
reg busy;
wire signed [31:0]p11,p12,p13,p21,p22,p23,p31,p32,p33;
reg signed[15:0]k11,k12,k13,k21,k22,k23,k31,k32,k33;

assign        p13=dout0*k13;
assign        p23=dout1*k23;
assign        p33=dout2*k33;
assign        p12=dout0_d1*k12;
assign        p22=dout1_d1*k22;
assign        p32=dout2_d1*k32;
assign        p11=dout0_d2*k11;
assign        p21=dout1_d2*k21;
assign        p31=dout2_d2*k31;

assign {dout0,dout1,dout2}=taps;

always@(posedge clk,posedge rst)
if(rst)
    busy            
关注
打赏
1658642721
查看更多评论
0.0443s