zoukankan      html  css  js  c++  java
  • 17调试经验之串口读写flash协议

    一是设计功能

    我的理解协议就是一个命令包,通过给出不同的控制命令,来调动不同的功能模块,实现不同的功能,如读数据,写数据,擦除等。

    二设计过程

         先看了尤老师的视频,主要讲了大致设计原理和总体框架,当然咯还有时序图,然后就从核心的控制模块做起,控制模块又分成三个部分,一是读数据,二是页写数据,三是擦除时序。我是先写一个部分,再仿真验证一个部分,每写好一个都把另外一个屏蔽了仿真验证,然后接着写下一个部分,直到把整个控制模块写好,再把所有功能模块在顶层连接好,然后我直接就建立了工程,然后下板验证,自然遇到了很多问题,我先将问题总结如下:

          三调试经验

    问题一:发送数据后,串口显示接收数据为零。

    尤老师的建议,看看顶层的sck, cs_n, sdi , sdo.

    我以前的经验是,若是rx_data有问题,那就查看关于它的所有相关代码,分析它的执行逻辑,即它的驱动源有没有赋值,逻辑对不对。

    (6.5日)我仔细想了下,rx_data一直为零,可能是tx_data发送后,没有接收到数据,那我先看看读数据模块,有没有问题,通过建立单独工程和仿真验证实现。通过仿真发现,单独的读数据模块仿真结果正确,那么就可能是state_ctrl模块的逻辑不对。

    6.6日,直接在state_ctrl模块里,对读数据模块仿真(其他页写模块和擦除模块都屏蔽了),第一个逻辑错误:发现就是在开始接收到数据,rx_data = 8'hdd和rx_flag=1;时,read_byte_cnt<=0;应该为零(而我是没有设置,那么会为1,这样仿真时数据长度为0,不能走完整个读状态过程)

    //修改逻辑如下

    else if((read_byte_cnt=='d4 &rx_d_flag)|(state!=READ) |(rx_data==8'hdd &rx_d_flag))

           read_byte_cnt<=0;

    仿真程序如下:

           task gene_flag;

    begin

           repeat(5)begin

                  rx_flag = 0;

                  #40; rx_flag=1;

                  #20;

           end

           rx_flag = 0;

    end

           endtask

    initial begin

           rst = 0;rx_data = 0;

           #60;rst = 1;rx_data = 8'hdd;rx_flag=1;#20 rx_flag=0;

           #60;gene_flag;

    end

           initial begin

           #140;rx_data = 8'h00;

           #100;rx_data = 8'h00;

           #120;rx_data = 8'h01;

           #60;rx_data = 8'h00;

    end

    //data mem

    reg [7:0] mem[255:0];

    initial begin

           $readmemb("./data.txt",mem);

    end

    task data_gene;

           integer i;

           integer j;

           begin

                  for(j=0;j<256;j=j+1)begin

                         for(i=0;i<256;i=i+1)begin

                 rrd_data=mem[i];

                 #200;

                 end

                 end

                         end

           endtask

    initial begin

           rrd_ready = 0;

           #500;rrd_ready = 1;

           data_gene;

           #20 rrd_ready = 0;

    end

    state_ctrl #(

                  .baud_rate(10)

                  )

           inst_state_ctrl(//端口省略);

    //仿真波形如下:

     

    可以看出波形基本正确,如能够从读状态跳转到初始状态,也有读的数据和FIFO的写使能

    我想了哈,还得继续分析一下,其他信号的时许逻辑有没有错。

    找到这个关键点错误二:串口发送和接收模块的波特率错误。

    过程是:在上述仿真没问题后,我就重新编译整个过程,下载到开发板,然后我再串口助手调试时,发现还是没有接收到数据,之后再用尤老师的源码发现,也是没有接收到数据,再问尤老师原因是啥,然后他回答是波特率不对,妈耶一下子我就豁然开朗,知道错误在哪里了,然后再修改串口发送和接收模块的波特率为9600,然后再发送,果然可以接收到数据了,开心哈。

    问题二:发送读数据命令包后,串口显示接收和发送的数据,个数远大于预期。

    预期应该是写命令包+256个数据,总共是260个字节。即在串口调试助手发送读命令包时,应该是接收到256个字节,且与写入的数据一样。

    这是新的问题,就是接收了1312个字节,发送了290个字节,我后面要仔细看看到底是那个模块出现了问题。

     

    总结,遇到问题时,可以先只对其中很小的模块仿真,待仿真功能正确后,再整个工程验证,若是觉得仿真没问题却功能不实现,可以看看源码在开发板是否实现预期功能,若是没有可能是操作不正确。

    6.7日对于问题二的解决:我看了读状态仿真波形,发现rd_data 和tx_data在rd_ready为零时,还在发送数据,所以我就简单修改逻辑为assign tx_data =(rd_ready)?rd_data :0;

    然后下板验证效果如下:

    写数据256字节:

     

    读数据如下:读数据和写数据个数正确了。

     

    问题三:读和写的内容不一样,通过上面的读数据和写数据截图

    我的想法,可以先下载源码到开发板验证,看看是不是其他问题。

    由于我页写数据模块,自己在源码的基础上修改了逻辑,所以可能有问题。

    解决办法:修改写数据模块的如下逻辑

    // //read_fifo_en

           always@(posedge Sclk or negedge Rst )

           if(Rst==0)

           read_fifo_en<=0;

           else if(state==PP & bit_cnt>='d31 & bit_cnt<'d2079& div_cnt==2'd2& bit_cnt[2:0]==3'b111)

           read_fifo_en<=1;

           else

           read_fifo_en<=0;

    //pp_shift_flag

           always@(posedge Sclk or negedge Rst )

           if(Rst==0)

           pp_shift_flag<=0;

           else if(state==PP & bit_cnt>='d31 & bit_cnt<'d2079& div_cnt==2'd2& bit_cnt[2:0]!=3'b111)

           pp_shift_flag<=1;

           else

           pp_shift_flag<=0;

    问题四:烧写程序到开发板时,未成功

    解决办法:这个是JTAG线没连好,所以不能识别芯片。

    问题五:擦除模块没有起作用

    解决办法:先是对擦除模块进行仿真,查看波形,发现基本上是正确的,再看看控制模块的对擦除模块的逻辑控制是否正确,最后是查看了顶层,发现原来是这个擦除模块的两个标志信号没有连到控制模块。

    //erro is .se_flag (s_se_flag),

           //            .se_addr (s_se_addr),

    //I don't connect correct

    即检查的顺序:功能模块,控制模块,顶层模块。

    成功解决问题的效果:

    总结调试经验:

                        先是明确问题:如通过观察实验现象,就是没有接收到数据,

                   再是分析问题的源头:一是软件的操作或编写的工程的程序不对,要是操作那就下载源码验证下,看看怎么设置串口调试的参数。对于第二个问题,分析程序的逻辑,可以先从功能模块通过testbench仿真,再对控制模块的逻辑仿真(如对读数据模块,在仿真过程对其他模块屏蔽掉如擦除模块和页写模块),顶层就看信号的连接有没有错,如是否从顶层到控制模块,最后到各个功能模块。当这三个模块,功能,控制,顶层都验证好嘞,再下载到板子上验证,看看实验现象,若是还有问题(一是通过逻辑分析仪。二是返回进行仿真)

    关键是: 调试一定得靠实验现象,仿真波形和逻辑分析仪,来找到问题,而不是靠猜想。

  • 相关阅读:
    cf 785#
    hdu 4920 Matrix multiplication
    poj 2443 Set Operation
    bzoj 3687: 简单题
    洛谷 三月月赛 C
    洛谷 三月月赛 B
    洛谷 三月月赛 A
    bzoj 3156: 防御准备
    bzoj 3437: 小P的牧场
    bzoj 3675: [Apio2014]序列分割
  • 原文地址:https://www.cnblogs.com/Xwangzi66/p/13062410.html
Copyright © 2011-2022 走看看