最近 半个月都在移植8051,看到DW8051内核资料比较齐全又是新思发布的,所以就开始玩弄

  可是这半个月的努力几近白费 —— 移植失败了,不知道从何着手这个内核。可能大家能找到不同的版本,我的是最初的版本,里面包含了datasheet 以及一些说明文档,看上去貌似是最原始的(可能已经修改过了),本想传上来,但是我一直到偶没有找到哪里可以上传文件。

  我没有添加片外memory,只有片内64k的rom 和256k的ram

  首先来看看我的tb

 `timescale 1us/100ns 

 module dw8051_tb ; 

 reg         clk ,            reset ;
reg int0_n, int1_n ;
reg rxd0_in , rxd1_in ;
reg t0 , t1 ; wire rst_out_n ;
wire stop_mode_n, idle_mode_n ;
wire rxd0_out , txd0 ;
wire rxd1_out , txd1 ;
wire t0_out , t1_out ; integer i ; DW8051_top cpu_core( .clk (clk) ,
.reset (reset) ,
.rst_out_n (rst_out_n) ,
.stop_mode_n (stop_mode_n) ,
.idle_mode_n (idle_mode_n) , //int
.int0_n (int0_n) ,
.int1_n (int1_n) , //serial port
.rxd0_in (rxd0_in) ,
.rxd0_out (rxd0_out) ,
.txd0 (txd0) , .rxd1_in (rxd1_in) ,
.rxd1_out (rxd1_out) ,
.txd1 (txd1) , //timer/counter input/output
.t0 (t0) ,
.t1 (t1) ,
.t0_out (t0_out) ,
.t1_out (t1_out) , //sfr interface
.sfr_data_in () ,
.sfr_addr () ,
.sfr_data_out () ,
.sfr_wr () ,
.sfr_rd () , //external ram interface or user-defined peripheral reg
.mem_data_in () ,
.mem_addr () ,
.mem_data_out (),
.mem_wr_n () ,
.mem_rd_n ()
); always # clk = ~clk ; initial begin
i = ;
clk = ; reset = ;
int0_n= ; int1_n= ;
rxd0_in= ; rxd1_in= ;
t0 = ; t1 = ;
# reset = ; //**********测试1 : 发现无论如何修改idata初始化空间大小,程序都会进入29-2a-2b-2c 这个循环,无法跳出
// while (i<8'hff) begin
// @(cpu_core.irom_addr == 16'h0029) i = i+1 ;
// if (i>8'h7f) begin
// $display ("rom loop at 0029 is over 7f time ");
// $display (" i = %d \n", i );
// end
// end
//--------------------------------------------------------------------------------------- /**********测试2: 依据测试1追查27这个地址上的循环次数数值去了哪里
1,@(cpu_core.core.irom_addr == 16'h0027) 测试发现跑到最后一个displays里面去了 ,屏蔽掉所有的if
打印具体数据信息结果显示 cpu_core.core.i_cpu.biu_instr == 8'h78
而cpu_core.core.i_cpu.biu_data_in == 8'h00
2,@(cpu_core.core.irom_addr == 16'h0028) 测试发现cpu_core.core.i_cpu.biu_instr == 8'h3f而
cpu_core.core.i_cpu.biu_data_in == 8'h00。由1和2对比可知数据有一个周期的停滞期
*/
//@(cpu_core.core.irom_addr == 16'h0028) begin
// //if (cpu_core.core.int_rom_data_out == 8'h3f) begin
// //if (cpu_core.core.i_cpu.biu_instr == 8'h3f)
// $display ("the rom data 3f have get to biu_instr = %h \n ",cpu_core.core.i_cpu.biu_instr );
// //if (cpu_core.core.i_cpu.biu_data_in == 8'h3f)
// $display ("the rom data 3f have get to biu_data_in = %h\n", cpu_core.core.i_cpu.biu_data_in);
// end
// else begin
// $display ("operation error ! rom data 3f at address 27 have not load in ");
// end
// end /********测试3 依据测试2追查内核执行情况 */
$display ("display data : \n");
$monitor ("%h",cpu_core.core.i_cpu.i_opdec.op);
# $stop ; @(cpu_core.irom_addr == 'h0019)
# $stop ; end endmodule

  最后的一个stop 是始终执行不到那里去,也就是说代码根本没有执行到程序存储地址19这里来。

  当然需要解释一下我为什么要这么测试,不懂为什么tb这么写,可以先忽略掉。我们一步步来追究,首先看看我的c程序

 #include <reg51.h>
#define uchar unsigned char
#define uint unsigned int sbit LED = P0^ ; void DelayMS (uint x )
{
uchar i ;
while (x--);
{
for (i=;i<;i++) ; }
} void main ()
{
LED = ;
while ()
{ DelayMS();
LED=~LED ;
}
}

调试窗口中显示我的程序起始地址是19,也就是说如果执行我的main函数要从19这个地址作为入口进行执行。在后面的step按钮下一步步调试发现,我的子函数起始地址是 03 。整个用户程序的起始地址是03,终止地址是25.

下面来看看keilC输出的hex

:03000000020026D5
:0C002600783FE4F6D8FD75810702001950
:10000300EF1FAA0670011E4A600BE4FDEDC39402C4
:0500130050EE0D80F726
:0100180022C5
:0D001900D2807F057E00120003B28080F5CA
:00000001FF

依据我查到的资料上说: 03000000020026D5

03 代码数据数目  0000 代表存储地址,00代表数据类型   020026代表数据  D5代表校验码

依据上述的意思去查QuartusII里面的信息

经过对比发现两者是一致的,说明QuartusII 对hex档的读取是没有问题的(当然我的C程序也是调试过没有问题的)

下面让我们看看modelsim仿真出来的结果

modelsim中仿真可以看到,程序执行地址 00- 01 - 02- 26 -27 - 28 - 29 - 2a - 2b - 2c - 29........然后就是这个循环一直都没有退出,也就是说根本没有执行用户程序。

  继续追踪这个程序段

reset之后一切明白了,程序从00地址开始执行 转跳到地址26——记住用户程序是从03到25,所以这个时候执行的是startup程序段,现在追踪startup,这个startup.a51是每个单片机上电的时候都需要进行执行的代码段,也就是初始化单片机的程序(具体的操作大家自己找资料看,网上很多人对这个文件有了中文的解析,比如这位大虾的http://www.cnblogs.com/heiyue/p/3262389.html

在调试中发现

立即数3f给了r0 ,也就是地址段27这个地方的数据,它表示的是我的ram的大小(startup.a51里面默认的是80编译出来是7f,改成40编译出来是3f),也就是我的初始化执行这个loop的次数。

好,现在可以解释一下为什么有了我的程序中的测试1

依据程序中规定的,这个loop应该是执行3f次—— 我也可以把这个loop直接停止掉,不用去初始化我的ram。因为我不管怎么修改这个loop都跳转不出来,所以我就开始追踪 3f去哪里了,所以才有了测试2

测试2发现这个3f居然进了decode模块的op端口(biu_instr和op相连),为了证实所以有了测试3

3f居然进了decode模块当操作码(op)处理了,它应该是一个立即数才对啊、再进入decode模块证实是否真的当操作码处理了,当我进入decode模块的时候发现真的悲剧了,没有使能信号控制,3f直接进入了操作码的case语句。

初步认定核有问题

在我写这个博客的时候觉得还有一丝希望的是,这个3f虽然当做操作码处理了,loop里面的所有数据都当操作码处理了,但是没有初始化完成,最后有一个使能把执行结果屏蔽了,—— 后待验证

基于FPGA的DW8051移植(一)的更多相关文章

  1. 基于FPGA的DW8051移植(三)

    总结一下问题: 1) http://www.cnblogs.com/sepeng/p/4137405.html  基于FPGA的DW8051移植(一)里面用modelsim观测波形发现程序进入了ida ...

  2. 基于FPGA的DW8051移植(二)

    基于上一篇博文继续,本来想换到oc8051,但是还是不甘心,弄了这么久还是没有弄出来,真是打击屎了. 上一篇说3f进入了operation code所以判断是代码错误,后来发现不可以这么判断. 因为地 ...

  3. 基于FPGA的RGB565_YCbCr_Gray算法实现

    前面我们讲了基于FPGA用VGA显示一副静态图片,那么接下来我们就接着前面的工程来实现我们图像处理的基础算法里最简单的一个那就是彩色图像转灰度的实现. 将彩色图像转化为灰度的方法有两种,一个是令RGB ...

  4. 基于FPGA的中值滤波算法实现

    在这一篇开篇之前,我需要解决一个问题,上一篇我们实现了基于FPGA的均值滤波算法的实现,最后的显示效果图上发现有一些黑白色的斑点,我以为是椒盐噪声,然后在做基于FPGA的中值滤波算法的实验时,我发现黑 ...

  5. 基于FPGA的肤色识别算法实现

    大家好,给大家介绍一下,这是基于FPGA的肤色识别算法实现. 我们今天这篇文章有两个内容一是实现基于FPGA的彩色图片转灰度实现,然后在这个基础上实现基于FPGA的肤色检测算法实现. 将彩色图像转化为 ...

  6. PCIE_DMA实例四:xapp1052在Xilinx 7系列(KC705/VC709)FPGA上的移植

    PCIE_DMA实例四:xapp1052在Xilinx 7系列(KC705/VC709)FPGA上的移植 一:前言 这段时间有个朋友加微信请求帮忙调试一块PCIe采集卡.该采集卡使用xilinx xc ...

  7. 基于FPGA的VGA可移植模块终极设计【转】

    本文转载自:http://www.cnblogs.com/lueguo/p/3373643.html 略过天涯   基于FPGA的VGA可移植模块终极设计 一.VGA的诱惑 首先,VGA的驱动,这事, ...

  8. 基于FPGA的图像开发平台 其他摄像头附件说明(OV5642 OV9655)

    基于FPGA的图像开发平台 其他摄像头附件说明 FPGA_VIP_V101 编者 奇迹再现 个人博客 http://www.cnblogs.com/ccjt/ 联系邮箱 Shenyae86@163.c ...

  9. FPGA经典:Verilog传奇与基于FPGA的数字图像处理原理及应用

    一 简述 最近恶补基础知识,借了<<Verilog传奇>>,<基于FPGA的嵌入式图像处理系统设计>和<<基千FPGA的数字图像处理原理及应用>& ...

随机推荐

  1. Vistual Studio 2010 调试无法进断点

    系统是2003出现的问题 win8就没事 打sp1 补丁就行

  2. 阿里云ECS每天一件事D1:配置SSH

    近期因为项目需求,采购了两台阿里云ECS,选择的系统为CentOS 6.3 X64 安全加固版,额外买了160G的硬盘,应该够应付此项目的需求了. ECS默认已经配置好了sshd服务,可以使用root ...

  3. 读书笔记:js设计模式

    面向过程编程,面向对象编程和函数式编程> 定义一个类方法1:function Anim(){ } Anim.prototype.start = function(){ .. };Anim.pro ...

  4. 挺有意思的Blog

    http://blog.csdn.net/dawanganban/article/details/19925449 http://www.syslog.org/ https://baoz.net/li ...

  5. QString类的使用(无所不包,极其方便)

    Qt的QString类提供了很方便的对字符串操作的接口. 使某个字符填满字符串,也就是说字符串里的所有字符都有等长度的ch来代替. QString::fill ( QChar ch, int size ...

  6. 基于Visual C++2013拆解世界五百强面试题--题7-链表的各种操作

    请用C实现一个链表,实现链表的查找,逆置,替换,删除,添加,清空,创建. 查找.替换和删除.添加里面都会用到遍历链表的操作,所以重点在于遍历, 链表的逆置和清空考虑到效率,我们可以用递归实现, 至于创 ...

  7. HDU 1286 找新朋友

    题解:分析题目,就是一个裸的欧拉函数,于是AC. #include <cstdio> int eular(int n){ int ret=1,i; for(i=2;i*i<=n;i+ ...

  8. hdoj 1166 敌兵布阵(树状数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 思路分析:该问题为动态连续和查询问题,使用数组数组可以解决:也可使用线段树解决该问题: 代码如下 ...

  9. IOS开发新手教程(一)-数据类型和运算符

    OC语法入门(一) 数据类型和运算符 1.1凝视 凝视和其它语言一样,同意单行 ,多行凝视,一份规范的代码里面须要有一些正式的凝视,例如以下凝视: /* 这是多行 凝视 */ //这是多行凝视 OC语 ...

  10. BI系统的应用组织思路与数据分析模式

    BI商业智能软件一般都会提供若干数据整合.数据查询.分析与评价.数据可视化及数据分享的手段,但是在BI项目的构建与实施过程中,如果不按照一定的应用组织思路.数据分析模式及分析流程使用这些工具或手段,呈 ...