实验项目5.1 深度学习算法与硬件加速器

实验对CPU的修改不多,如果完全按照RISC-V的要求设计CPU,将mul归类为R-Type的话,改动较多。但是我们可以单独设计一跟op_mul电线,然后单独设计乘法指令。
在这里插入图片描述

乘法指令的实现,直接使用其提供的乘法部件即可:

wire [31: 0] Result_MUL = RF_rdata1*RF_rdata2; 
随后在选数里增加一项MUL的指令:
    assign RF_wdata = {32{op_shift}}&shift_result|
                      {32{op_J_Type}}&PC_4|
                      {32{op_lui}}&extend|
                      {32{op_auipc}}&(PC_temp+extend)|
                      {32{(op_I_Type|op_R_Type)&~op_shift}}&ALU_result|
                      {32{op_lw}}&load_word|
                      {32{op_lb }}& {{24{load_byte[7]}},load_byte}|
                      {32{op_lbu}}& {{24{1'b0}},load_byte}|
                      {32{op_lh}}& {{16{load_half[15]}},load_half}|
                      {32{op_lhu}}& {{16{1'b0}},load_half}|
                      {32{op_mul}}& Result_MUL
                      ;

并按照R-Type的指令设计,设计自动机的转移:

            `state_EX : begin
                if(op_B_Type)
                    next_state = `state_IF;
                else 
                    if(op_R_Type|op_I_Type|op_U_Type|op_J_Type|op_mul)
                        next_state = `state_WB;
                    else 
                        if(op_S_Type)
                            next_state = `state_ST;
                        else 
                            if(op_L_Type)
                                next_state = `state_LD;
                            else 
                                next_state= `state_EX; 
            end 

其次是DNN相关的代码:
按照定义,需要设计几种中间变量:

    short bias;
    short num_out;//output
    short num_in;//input
    short y,x,ky,kx;
    short k_square=1+mul(weight_size.d2,weight_size.d3);
    short in_square=mul(input_fm_h,input_fm_w);

bias指的是偏移量,存在 F i l t e r [ i ] [ 0 ] [ 0 ] Filter\left[i\right]\left[0\right]\left[0\right] Filter[i][0][0]位置。
其次num_in和num_out分别是吗枚举读入的图片通道数和输出的特征图片通道数。
x、y枚举的是当前图像处理的像素点位置,kx、ky指的是每一次卷积操作的时候卷积核的相对位置。
k_square和in_square是计算下标的中间变量。
在设计out的赋值时我发现,其赋值规律是顺序的,所以可以设计一个outoffset来计算位置。

    int out_offset=0;
    short bias_offset=mul(rd_size.d1,k_square); 

在这里插入图片描述

在第一重循环,枚举的是当前输出的通道数,在这一层可以计算bias的值。在第二层,枚举输入的通道数,随后枚举当前通道这张图片的像素点位置。在这种过程中,更据定义,需要增加当前图片间的步长Stride_X、Stride_Y。对于每个卷积核,其每个方块的由kx、ky两个块进行枚举。
在这里由于存在边界填充,所以存在一个pad的偏移,于是在这里需要作差的得到iw和ih。随后求出当前的像素值和卷积的权重,随后便可以计算卷积后的结果,在这里中间变量需要用32位整数存储。
在这里,值得注意的是16位定点数的符号位需要由32位定点数的符号位求出。最后,由于发现输出特征图的像素顺序是良序的,所以可以直接不断加1得到结果。
另外一个比较重要的步骤是池化操作,池化操作本质是取最大值,所以实现起来比较简单。

在这里插入图片描述

池化操作的计算也就是找到对应像素点位置,然后比个大小就可以了。注意到这里最大值max的初始值是0x8000,这在16位定点数里表示最小值,因此一定会被更大的数所替换。
硬件加速器就很简单了:

#ifdef USE_HW_ACCEL
void launch_hw_accel()
{
    volatile int* gpio_start = (void*)(GPIO_START_ADDR);
    volatile int* gpio_done = (void*)(GPIO_DONE_ADDR);
    * gpio_start =(* gpio_start )|0x01;
    while(1){
        if((*(volatile char*)gpio_done)&0x01)break;
    }
    return;
}
#endif

按照流程图,如果开始将对应位置低位赋值1,如果检测到结束位置低位赋值1就结束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值