• 基于FPGA的DW8051移植(二)


      基于上一篇博文继续,本来想换到oc8051,但是还是不甘心,弄了这么久还是没有弄出来,真是打击屎了。

      上一篇说3f进入了operation code所以判断是代码错误,后来发现不可以这么判断。 因为地址00开始进入 operation code 的数据也是02 00  26.可是程序成功的转跳到了26 这个地址,所以不可以简单的说3f当operation code处理了所以core就错了。

      最后采用的方法是屏蔽掉STARTUP.51A里面的初始化loop,就是将idatalength 改为0 ,这一改我就更懵了。

      在keile C 中调试窗口看到的程序执行顺序是00 01 02    26 27 28      29 2a 2b       19 1a     1b 1c    1d 1e     1f 20 21     03 04 05 06 07 0a 0b 0c 0d 0e      0f 10 11  12 13 14  15 16 17      0f 10 11  12 13 14  15 16 17       03  04 05 06 07 08 0a 0b 0c 0d 0e 0f 10 一直到16     。。。。。。。。。。。。循环了。在modelsim中看到的是相同的,

    为了进一步探求程序,所以又写了测试4

      1 `timescale 1us/100ns 
      2 
      3 module dw8051_tb ; 
      4 
      5 reg         clk ,            reset ;
      6 reg         int0_n,        int1_n ; 
      7 reg      rxd0_in ,   rxd1_in ; 
      8 reg      t0 ,        t1     ;
      9 
     10 wire         rst_out_n ;
     11 wire         stop_mode_n,   idle_mode_n ; 
     12 wire     rxd0_out ,     txd0    ;
     13 wire     rxd1_out ,     txd1    ;
     14 wire     t0_out  ,      t1_out  ;
     15 
     16 integer i ; 
     17 
     18 DW8051_top  cpu_core(
     19 
     20              .clk (clk)         , 
     21              .reset (reset)       ,
     22              .rst_out_n (rst_out_n)    ,           
     23              .stop_mode_n (stop_mode_n) , 
     24              .idle_mode_n (idle_mode_n) ,         
     25                          
     26            //int
     27              .int0_n (int0_n)      , 
     28              .int1_n (int1_n)      , 
     29            
     30            //serial port
     31              .rxd0_in (rxd0_in)     , 
     32              .rxd0_out (rxd0_out)    , 
     33              .txd0 (txd0)        , 
     34                          
     35              .rxd1_in (rxd1_in)      , 
     36              .rxd1_out (rxd1_out)    , 
     37              .txd1 (txd1)        , 
     38            
     39            //timer/counter input/output
     40              .t0 (t0)          , 
     41              .t1 (t1)          , 
     42              .t0_out (t0_out)       , 
     43              .t1_out (t1_out)      , 
     44                          
     45 
     46        //sfr interface
     47                .sfr_data_in () , 
     48              .sfr_addr ()    , 
     49              .sfr_data_out () , 
     50              .sfr_wr ()      , 
     51              .sfr_rd ()      ,
     52            
     53            //external ram interface or user-defined peripheral reg
     54                .mem_data_in () , 
     55              .mem_addr ()    , 
     56              .mem_data_out (), 
     57              .mem_wr_n ()     , 
     58              .mem_rd_n ()
     59             );    
     60 
     61 always #10 clk = ~clk ; 
     62                             
     63 initial   begin 
     64     i = 0  ;
     65     clk = 0 ;     reset =0 ; 
     66     int0_n=0 ;    int1_n=0 ;
     67     rxd0_in=0 ;   rxd1_in=0 ;
     68     t0 =  0  ;    t1  = 0   ;
     69     #180 reset =1 ; 
     70     
     71     
     72     
     73 //**********测试1 : 发现无论如何修改idata初始化空间大小,程序都会进入29-2a-2b-2c 这个循环,无法跳出
     74       // while (i<'h1ff) begin 
     75               // @(cpu_core.irom_addr == 16'h0029)   i = i+1 ; 
     76               // if (i>'h100) begin 
     77                       // $display ("rom loop at 0029 is over 01 00h time ");
     78                       // $display ("  i = %d 
    ", i );
     79                       // end 
     80               // end 
     81 //---------------------------------------------------------------------------------------            
     82 
     83 /**********测试2: 依据测试1追查27这个地址上的循环次数数值去了哪里
     84     1,@(cpu_core.core.irom_addr == 16'h0027) 测试发现跑到最后一个displays里面去了 ,屏蔽掉所有的if
     85 打印具体数据信息结果显示 cpu_core.core.i_cpu.biu_instr == 8'h78
     86 而cpu_core.core.i_cpu.biu_data_in == 8'h00
     87     2,@(cpu_core.core.irom_addr == 16'h0028) 测试发现cpu_core.core.i_cpu.biu_instr == 8'h3f而
     88 cpu_core.core.i_cpu.biu_data_in == 8'h00。由1和2对比可知数据有一个周期的停滞期
     89 */
     90 //@(cpu_core.core.irom_addr == 16'h0028) begin 
     91 //        //if (cpu_core.core.int_rom_data_out == 8'h3f) begin 
     92 //                //if (cpu_core.core.i_cpu.biu_instr == 8'h3f)
     93 //                        $display ("the rom data 3f have get to biu_instr = %h  
     ",cpu_core.core.i_cpu.biu_instr );
     94 //                //if (cpu_core.core.i_cpu.biu_data_in == 8'h3f)
     95 //                        $display ("the rom data 3f have get to biu_data_in  = %h
    ", cpu_core.core.i_cpu.biu_data_in);
     96 //                end 
     97 //        else  begin 
     98 //                $display ("operation error ! rom data 3f at address 27 have not load in ");
     99 //                end 
    100 //                end 
    101 //-----------------------------------------------------------------------------------------------------------
    102 
    103 
    104 /********测试3 依据测试2追查内核执行情况 ,发现7f进入了operation——操作码,于是断定是核错误,可是后来追溯到最开始
    105 的程序那一段 02 00 26 可以成功转跳到26这个地址,而26也进入了operation 操作码里面,这么一说,不可以简单的说由于3f
    106 进入了operation 操作码段而断定核错误。
    107 最后修改了STARTUP.51A 里面的idata length 为0 ,即不执行ram初始化,通过观测ram地址发现程序进入了用户程序段。
    108 */
    109  
    110  // $display ("display  data  :  
    ");
    111  // $monitor ("%h",cpu_core.core.i_cpu.i_opdec.op);
    112  // #8000 $stop ; 
    113 //-------------------------------------------------------------------------------------------------------------
    114 
    115 
    116 /********测试4 既然测试3已经进入了用户程序,依据keilC里面显示,main函数入口地址19,子函数入口地址03,子函数
    117 出口地址18,LED翻转地址22, 再一起进入子函数main的保存地址为 1B,所以有了下面的测试程序,结果发现只有前面五个
    118 出来了,后面两个都不见了程序就进入了stop,加大了时长还是不行哦
    119 */
    120     @(cpu_core.irom_addr == 16'h0019)
    121     $display ("enter customer code of main ");
    122     
    123     @(cpu_core.irom_addr == 16'h001b)
    124     $display ("at the door of  delay loop at first ");
    125     
    126     @(cpu_core.irom_addr == 16'h0003)
    127     $display ("enter  delay loop at first  ");
    128     
    129     @(cpu_core.irom_addr == 16'h000d)
    130     $display ("enter delay loop of 'for' ");
    131     
    132     @(cpu_core.irom_addr == 16'h0018)
    133     $display ("over the loop at first  ");
    134     
    135     @(cpu_core.irom_addr == 16'h0022)
    136     $display ("return to main at first   ");
    137     
    138     @(cpu_core.irom_addr == 16'h0024)
    139     $display ("over the main at first ");
    140 end 
    141 
    142 
    143 initial  begin 
    144         #80000 ; 
    145         #80000 ;
    146         #80000 ;
    147         #80000 ;
    148         #80000 ;
    149         #80000 ;
    150         $stop ; 
    151 
    152 end 
    153 
    154 endmodule 


    都没有人给我指点一二,还要不要人活了啊。

    追查第五个display输出 后这个地址是怎么变的

    你丫这是想干啥 ,怎么跑到for里面去了啊

    补充:

      追查这个转跳地址是谁给的,最终找到了罪魁祸首

    i_cpu里面的result这条bus上,这条暴死一头连接着DW8051_updn_ctr 模块的data作为了输入口,当然我们要找的是输出口,输出口就是DW8051_control,面对几十个input output  和 两千多行代码    石化了

    result转跳地址给错了,怎么改啊怎么改啊

  • 相关阅读:
    printf函数实现的深入剖析
    rhel/centos播放mp3文件
    GRUB(GRand Unified Boot loader)引导加载程序
    NAT DHCP WWW rc.local
    论文 毕业设计 相关 用语 评语
    Linux禁止单用户模式(single)来增强系统安全
    Kernel command using Linux system calls
    GNU-ld链接脚本浅析
    AT&T汇编心得之间接寻址和LEA指令
    Linux 汇编语言开发指南
  • 原文地址:https://www.cnblogs.com/sepeng/p/4141072.html
Copyright © 2020-2023  润新知