zoukankan      html  css  js  c++  java
  • lab3:LeNet上板

    0.模型训练:暂时跳过

      CNN有监督,可以用BP训练:http://www.mamicode.com/info-detail-2288678.html

    1.参数:

    1.1一开始混乱的点

      (1)每个核有一个bias,每个核出一个通道的结果(一个特征)。

      (2)fcweight1:500行;fcweight1:10行;

      (3)一组核:所求特征(输出)由多个子特征(输入)组成,每个子特征有一个核

    1.2过程  

      (1)卷积一:输入28*28,20个核(5*5)20个bias(1*20),输出20通道24*24,算步长:28=5+(24-1)*步长,所以步长=1;

      (2)卷积一池化:每2*2选一个最大值,无重合,规模横纵减半;

      (3)卷积二:输入20通道12*12,20*50个核(50组核,一组核对应一个bias,得一个通道结果)(每个通道输入*对应组对应通道的核),50个bias,输出50通道8*8,12=5+7*1,步长=1;

      (4)卷积二池化:减半

      (5)全连接层一:输入50通道4*4,展开1*800,映射到1*500(全连接->每个输入都要乘weightN+biasN=iN,所以有500*800个参数,500个bias,:(500*800)* (800*1)=(500*1)+bias(500*1)

      (6)全连接层一过滤:输入1*500,负数取正,输出1*500

      (7)全连接层二:输入1*500,输出1*10:(10*500)*(500*1)=10*1+bias(10*1)

      (8)输出:找到1*10向量中最大值,输出下标为识别结果

     weight=20*25+20*50*25+500*800+10*500=500+25000+400000+5000=430500 开440000空间

    bias=20+50+500+10=580 开600

    2.设计:看指导书

    数据通路不要和控制写一起,控制单独写状态机!

    (1)定点数问题:

      参数和数据处理:转为8位二进制数(有符号,参数有负数)。运算后要移位?

      教程:https://jingyan.baidu.com/article/f71d6037b3b43f1ab641d10d.html

      处理成1符号+2整数+5小数,相当于一个数放大了2^5倍

      原始数据*32=输入数据,还要看数据会不会溢出(大于3)

    错误和经验:

    1.clock design生成.v文件后,再把里面的模块设成top,单独写仿真或综合时是找不到这个模块的,要把block design生成的.v文件删了之后才能找到。。。但是重启vivado后又可以直接改top了?妙

    2.lia:https://blog.csdn.net/qq_34322603/article/details/72854621:

    然后常规方法进入软件调试界面,设置断点。(这里提醒一下,联合调试一定要在SDK下将比特流下载到FPGA中,而不要在vivado中下载比特流。Xilinx官方给出的解释是:由于使用PS端的时钟来接入ILA,所以要现在SDK中将比特流进行下载) 

    3.verliog:一个信号只能有一个驱动,多个改变位置要加选择器。

    4.加完debug后布线报错:

    [Chipscope 16-213] The debug port 'dbg_hub/clk' has 1 unconnected channels (bits). This will cause errors during implementation.

    原因:综合之后没有选debug的设置,有的线还没有连时钟。给clk加debug好像有个buff报错解决不了,就把clk的debug删了

    5.lia的wave出不来:要用sdk烧一遍才行。先用vivado 的hardware烧板子作为启动,然后用sdk烧,就能弹出来了。

    6.#include "xil_io.h"报错:clean一遍编译

    7.ila的wave图点运行就走一点点:一次只能抓1000个,要选好时间。令人做藕

    8.初始化的使能是必须加的,因为pl初始化好了之后ps可能还没开始传东西。。。要用axi-lite告诉初始化模块我要开始传有效数据了。

    9.可以直接在netlist里面mark debug,要是写(**)没加进去的话

    选上线右键mark debug就行。

    10.ila弹不出来:用sdk导完之后再用vivado烧一次就有了。

     11.我放弃了,我还是写仿真测吧。上板子弄单元测试太麻烦了。而且我发现wrapper会自动生成一个仿真文件。。。可以先不加系统,把输入输出都引出来然后写仿真,最后再把输入输出都换成axi。我爱中间输出。

    12.用自带的wrapper的test,改block的代码的话,要重新生成一边wrapper。但是生成完之后自己加的测试代码也没有了。所以还是手动搭一个吧,可以把自动的那个文件顶层粘过去

    13.我爱子状态机。for循环拆成状态机:每个条件判断一个状态,执行内容一个状态,跟编译插标签似的

    每层:判断本层边界,符合则初始化下一层计数,跳出则上层计数加一

    14.系统命令错误:参数不存在等,准确错误报不出来,形如下图就是$display后面参数不存在的报错

     15.XXX右移还是XXX

    16.综合时不自动保存,综合前一定要把文件都保存了。

    状态机套路 以cov为例

    将for循环改写,每个循环变量拆分成以下子状态:

    父状态:循环变量初始化

    判条件,转移

    在叶节点自加(不能在当前状态自加,因为后面可能还要用i的当前值)

    always@(posedge clk)begin
            case(s1)
            0:
            begin
                if(state==1||state==3)begin
                    s1<=1;
                    s1_cha_count<=0;
                    cov_en<=0;
                    //若复用,需要初始化计数
                end
            end
            1://读1个通道bias,开始计数
            begin
                //计数:如果>1,finish
                //读入bias
                if(s1_cha_count>=s1_cha_num) s1<=7;
                else begin
                    read_bias<=1;
                    read_bias_finish<=0;
                    s1<=10;
                    s1_wei_count<=0;
                end
            end
            10://等待读bias
            begin
                if(read_bias_finish==1)begin
                    s1<=2;
                end
            end
            2://每个通道,读20个weight矩阵
            begin
                //计数,若为21转到1
                if(s1_wei_count>=s1_wei_num)begin
                    s1<=1;
                    s1_cha_count<=s1_cha_count+1;
                end
                else begin
                    read_weight<=1;
                    read_weight_finish<=0;
                    s1<=8;
                    s1_i<=0;
                end
            end
            8://等待读weight
            begin
                if(read_weight_finish==1)begin
                    s1<=3;
                end
            end
            3://读从data读i行
            begin
                //计数,如果行数>24,跳到2,否则到4
                if(s1_i>=s1_result_num)begin
                    s1<=2;
                    s1_wei_count<=s1_wei_count+1;
                end
                else begin
                    s1<=4;
                    s1_j<=0;
                end
            end
            4://列计数
            begin
                ans_wen<=0;
                //列计数,如果列数>24,跳到3,否则到5
                if(s1_j>=s1_result_num) begin
                    s1<=3;
                    s1_i<=s1_i+1;
                end
                else begin
                    s1<=5;
                end
            end
            5://执行体
            begin
                read_data<=1;//子模块读完后置0
                read_data_finish<=0;
                s1<=9;
            end
            9://等读data
            begin
                if(read_data_finish==1)begin
                    s1<=6;
                    cov_en<=1;
                end
            end
            6://等待计算结果写回
            begin
                //写回,跳到4
                if(COVFINISH==1)begin//测试,待改正COVFINISH==1
                    //写回,待
                    s1<=4;
                    s1_j<=s1_j+1;
                    ans_addr<=s1_cha_count*s1_wei_num*s1_result_num*s1_result_num
                                    +s1_wei_count*s1_result_num*s1_result_num
                                    +s1_result_num*s1_i
                                    +s1_j;
                    ans_in<=COVRESULT;
                    ans_wen<=1;
                    $display("cov%d channel=%d weight=%d i=%d j=%d result=%d addr=%d",state,s1_cha_count,s1_wei_count,s1_i,s1_j,COVRESULT,s1_cha_count*s1_wei_num*s1_result_num*s1_result_num
                                    +s1_wei_count*s1_result_num*s1_result_num
                                    +s1_result_num*s1_i
                                    +s1_j);
                end
                
            end
            7://结束状态,置finish为1
            begin
                finish<=1;
                s1<=0;
            end
            default:;
            endcase
        end
  • 相关阅读:
    【存货管理】存货的计价方法
    【NHibernate】列“ReservedWord”不属于表 ReservedWords
    【MySQL】MySQL中where条件的执行分析
    brew卸载&重新安装
    mac nvm安装&使用&一些问题解决方案
    python初始环境配置
    股票数据api整理
    输入一个url到页面渲染完毕过程
    自己简单封装一个promise
    节流&防抖
  • 原文地址:https://www.cnblogs.com/iwanna/p/10119221.html
Copyright © 2011-2022 走看看