[读书日志]8051软核处理器设计实战(基于FPGA)第七篇:8051软核处理器的测试(verilog+C)

6. 8051软核处理器的验证和使用

为了充分测试8051的性能,我们需要测试每一条指令。在HELLO文件夹中存放了整个测试的C语言工程文件。主函数存放在指令被分为五大类,和上面一样。

在这里插入图片描述

在这里插入图片描述

打开后是这样的文件结构。HELLO.c是主文件,这是里面的代码:

/*------------------------------------------------------------------------------
HELLO.CCopyright 1995-2005 Keil Software, Inc.
------------------------------------------------------------------------------*/#include <REG52.H>                /* special function register declarations   *//* for the intended 8051 derivative         */#include <stdio.h>                /* prototype declarations for I/O functions */#include "instruction.h"/*------------------------------------------------
The main C function.  Program execution starts
here after stack initialization.
------------------------------------------------*/
void main (void) {test_status = 1;instruction_test_all();if (test_status) {printf("Test success!\n");}else{printf("Test failed!\n");}printf("Test finished!\n");kill_self = 1;while (1);
}

这里引用了头文件instruction.h,它的实现在Instruction文件夹中,先看一下instruction.c的内容:

#include <REG52.H>
#include <stdio.h> 
#include "instruction.h"void error(void){if (test_status==0) {printf("ERROR HERE...\n");while(1);}
}	void instruction_test_all(void){
#ifdef ARITHMETICarithmetic();  
#endif
#ifdef LOGICALlogical();
#endif
#ifdef TRANSFERtransfer();
#endif
#ifdef BOOLEANboolean();
#endif
#ifdef PROGRAMprogram();
#endif
}void arithmetic(void){
#ifdef ADD_A_RNadd_a_rn();
#endif
#ifdef ADD_A_DIadd_a_di();
#endif	
#ifdef ADD_A_RIadd_a_ri();
#endif		
#ifdef ADD_A_DAadd_a_da();
#endif
#ifdef ADDC_A_RNaddc_a_rn();
#endif	
#ifdef ADDC_A_DIaddc_a_di();
#endif		
#ifdef ADDC_A_RIaddc_a_ri();
#endif
#ifdef ADDC_A_DAaddc_a_da();
#endif
#ifdef SUBB_A_RNsubb_a_rn();
#endif
#ifdef SUBB_A_DIsubb_a_di();
#endif
#ifdef SUBB_A_RIsubb_a_ri();
#endif
#ifdef SUBB_A_DAsubb_a_da();
#endif
#ifdef INC_Ainc_a();
#endif
#ifdef INC_RNinc_rn();
#endif
#ifdef INC_DIinc_di();
#endif
#ifdef INC_RIinc_ri();
#endif
#ifdef INC_DPinc_dp();
#endif
#ifdef DEC_Adec_a();
#endif
#ifdef DEC_RNdec_rn();
#endif
#ifdef DEC_DIdec_di();
#endif
#ifdef DEC_RIdec_ri();
#endif
#ifdef MULTmult();
#endif
#ifdef DIVIDEdivide();
#endif
#ifdef DA_Ada_a();
#endif
}

这里只列出了一部分。可以看出通过预编译指令定义了五类指令及每一类的指令。而每一类中具体的指令通过汇编语言使用预编译指令进行编译。它们分布在剩余的几个c文件中。比如算术运算指令如下:

#include <REG52.H>
#include <stdio.h> 
#include "instruction.h"void add_a_rn(void) {printf("ADD_A_RN\n");#pragma ASM  push pswpush accmov  psw,#0H	setb rs0     setb rs1	#pragma ENDASM #pragma ASMmov acc,#01Hmov R0,#0fHadd A,R0#pragma ENDASM	if (ACC!=0x10) test_status = 0;if (AC!=1) test_status = 0;if (OV!=0) test_status = 0;if (CY!=0) test_status = 0;AC = 0;#pragma ASMmov acc,#40Hmov R1,#40Hadd A,R1#pragma ENDASMif (ACC!=0x80) test_status = 0;if (AC!=0) test_status = 0;if (OV!=1) test_status = 0;if (CY!=0) test_status = 0;OV = 0;#pragma ASMmov acc,#80Hmov R2,#81Hadd A,R2#pragma ENDASMif (ACC!=0x01) test_status = 0;if (AC!=0) test_status = 0;if (OV!=1) test_status = 0;if (CY!=1) test_status = 0;OV = 0;CY = 0;#pragma ASMmov acc,#0C0Hmov R3,#0C2Hadd A,R3#pragma ENDASMif (ACC!=0x82) test_status = 0;if (AC!=0) test_status = 0;if (OV!=0) test_status = 0;if (CY!=1) test_status = 0;CY = 0;	#pragma ASM pop accpop psw	#pragma ENDASM 	error();
}

如果每一条指令都通过,最后会打印测试成功字样,如果有任何一条指令执行有误则会导致抛出错误和暂停测试。

将HELLO工程编译后生成了HELLO.bin,这就是我们最后需要使用的文件,将其留存。之后编写一个tb文件,用于对接接口和设置存储空间:

`timescale 1 ns/1 ps
`define PERIOD 10
`define HALF_PERIOD (`PERIOD/2)
//`define TYPE8052
`define CODE_FILE "C:/Users/15661/Desktop/R8051_test/HELLO/HELLO.bin"
module tb;reg     clk = 1'b0;
always #`HALF_PERIOD clk = ~clk;reg     rst = 1'b1;
initial #`PERIOD rst = 1'b0;wire            rom_en;
wire [15:0]     rom_addr;
reg  [7:0]      rom_byte;
reg             rom_vld;wire            ram_rd_en_data;
wire            ram_rd_en_sfr;
wire            ram_rd_en_xdata;
wire [15:0]     ram_rd_addr;reg  [7:0]      ram_rd_byte;wire            ram_wr_en_data;
wire            ram_wr_en_sfr;
wire            ram_wr_en_xdata;
wire [15:0]     ram_wr_addr;
wire [7:0]      ram_wr_byte;r8051 u_cpu (.clk                  (    clk              ),.rst                  (    rst              ),.cpu_en               (    1'b1             ),.cpu_restart          (    1'b0             ),.rom_en               (    rom_en           ),.rom_addr             (    rom_addr         ),.rom_byte             (    rom_byte         ),.rom_vld              (    rom_vld          ),.ram_rd_en_data       (    ram_rd_en_data   ),.ram_rd_en_sfr        (    ram_rd_en_sfr    ),.ram_rd_en_xdata      (    ram_rd_en_xdata  ),.ram_rd_addr          (    ram_rd_addr      ),.ram_rd_byte          (    ram_rd_byte      ),.ram_rd_vld           (    1'b1             ),.ram_wr_en_data       (    ram_wr_en_data   ),.ram_wr_en_sfr        (    ram_wr_en_sfr    ),.ram_wr_en_xdata      (    ram_wr_en_xdata  ),.ram_wr_addr          (    ram_wr_addr      ),.ram_wr_byte          (    ram_wr_byte      ));reg [7:0] rom[(1'b1<<16)-1:0];integer fd,fx;
initial beginfd = $fopen(`CODE_FILE,"rb");fx = $fread(rom,fd);$fclose(fd);
endalways @ ( posedge clk )
if ( rom_en )rom_byte <=  rom[rom_addr];
else;always @ ( posedge clk )
rom_vld <=  rom_en;reg [7:0] data [127:0];
reg [7:0] data_rd_byte;
always @ ( posedge clk )
if ( ram_rd_en_data )data_rd_byte <=  data[ram_rd_addr[6:0]];
else;always @ ( posedge clk )
if ( ram_wr_en_data )data[ram_wr_addr[6:0]] <=  ram_wr_byte;
else;reg [7:0] xdata [127:0];
reg [7:0] xdata_rd_byte;
always @ ( posedge clk )
if ( ram_rd_en_xdata )xdata_rd_byte <=  xdata[ram_rd_addr[6:0]];
else;always @ ( posedge clk )
if ( ram_wr_en_xdata )if (( ram_wr_addr[6:0]==8'h7f ) & ram_wr_byte[0] ) beginrepeat(1000) @ (posedge clk);$display("Test over, simulation is OK!");$stop(1);endelsexdata[ram_wr_addr[6:0]] <=  ram_wr_byte;
else;reg [7:0] sfr_rd_byte;always @ ( posedge clk )
if ( ram_wr_en_sfr & ( ram_wr_addr[7:0]==8'h99 ) )$write("%s",ram_wr_byte);
else;always @ ( posedge clk )
if ( ram_rd_en_sfr ) if ( ram_rd_addr[7:0]==8'h98 )sfr_rd_byte <=  8'h3;else if ( ram_rd_addr[7:0]==8'h99 )sfr_rd_byte <=  0;elsebegin$display($time," ns : --- SFR READ: %2h---",ram_rd_addr[7:0]);//$stop;end
else;	always @ ( posedge clk )
if ( ram_wr_en_sfr )if(( ram_wr_addr[7:0]==8'h98 )|( ram_wr_addr[7:0]==8'h99 ))#0;else	begin$display($time," ns : --- SFR WRITE: %2h -> %2h---",ram_wr_addr[7:0],ram_wr_byte);//$stop;end
else;	reg [1:0] read_flag;
always @ ( posedge clk )
if ( ram_rd_en_sfr )read_flag <= 2'b10;
else if ( ram_rd_en_xdata )read_flag <= 2'b01;	
else if ( ram_rd_en_data )read_flag <= 2'b0;
else;always @*
if ( read_flag[1] )ram_rd_byte = sfr_rd_byte;
else if ( read_flag[0] )ram_rd_byte = xdata_rd_byte;
elseram_rd_byte = data_rd_byte;endmodule

将tb.v和R8051.v一起加入Modelsim工程(注意不要导入instruction.v,否则会报错,需要更改的有两处路径,分别是tb中引用HELLO.bin的路径,和R8051.v中对instruction.v引用的路径,更改后即可复现代码。)之后进行仿真,结果正确。

在这里插入图片描述

在这里插入图片描述

至此,我们的8051软核处理器开发基本完毕。之后可以自行修改一些功能,使用这套测试框架进行测试。现在这个软核处理器中没有添加中断,在书中并没有提供添加中断的说明。后续如果有机会将继续更新添加中断的内容。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/1828.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入浅出 Android AES 加密解密:从理论到实战

深入浅出 Android AES 加密解密&#xff1a;从理论到实战 在现代移动应用中&#xff0c;数据安全是不可忽视的一环。无论是用户隐私保护&#xff0c;还是敏感信息的存储与传输&#xff0c;加密技术都扮演着重要角色。本文将以 AES&#xff08;Advanced Encryption Standard&am…

IDEA编译器集成Maven环境以及项目的创建(2)

选择&#xff1a;“File” ---> "Othoer Setting" --> "Settings for New Projects..." --->搜索“Maven” 新建项目 利用maven命令去编译这个项目 利用maven去打包

Open FPV VTX开源之默认MAVLink设置

Open FPV VTX开源之默认MAVLink设置 1. 源由2. 准备3. 连接4. 安装5. 配置6. 测试6.1 启动wfb-ng服务6.2 启动wfb-ng监测6.3 启动QGroundControl6.4 观察测试结果 7. 总结8. 参考资料9. 补充9.1 telemetry_tx异常9.2 DEBUG串口部分乱码9.3 PixelPilot软件问题 1. 源由 飞控图传…

gesp(C++五级)(4)洛谷:B3872:[GESP202309 五级] 巧夺大奖

gesp(C五级)&#xff08;4&#xff09;洛谷&#xff1a;B3872&#xff1a;[GESP202309 五级] 巧夺大奖 题目描述 小明参加了一个巧夺大奖的游戏节目。主持人宣布了游戏规则&#xff1a; 游戏分为 n n n 个时间段&#xff0c;参加者每个时间段可以选择一个小游戏。 游戏中共有…

像JSONDecodeError: Extra data: line 2 column 1 (char 134)这样的问题怎么解决

问题介绍 今天处理返回的 JSON 的时候&#xff0c;出现了下面这样的问题&#xff1a; 处理这种问题的时候&#xff0c;首先你要看一下当前的字符串格式是啥样的&#xff0c;比如我查看后发现是下面这样的&#xff1a; 会发现这个字符串中间没有逗号&#xff0c;也就是此时的J…

道旅科技借助云消息队列 Kafka 版加速旅游大数据创新发展

作者&#xff1a;寒空、横槊、娜米、公仪 道旅科技&#xff1a;科技驱动&#xff0c;引领全球旅游分销服务 道旅科技 &#xff08;https://www.didatravel.com/home&#xff09; 成立于 2012 年&#xff0c;总部位于中国深圳&#xff0c;是一家以科技驱动的全球酒店资源批发商…

导出文件,能够导出但是文件打不开

背景&#xff1a; 在项目开发中&#xff0c;对于列表的查询&#xff0c;而后会有导出功能&#xff0c;这里导出的是一个excell表格。实现了两种&#xff0c;1.导出的文件&#xff0c;命名是前端传输过去的&#xff1b;2.导出的文件&#xff0c;命名是根据后端返回的文件名获取的…

ISP各模块功能介绍

--------声明&#xff0c;本文为转载整理------- ISP各个模块功能介绍&#xff1a; 各模块前后效果对比&#xff1a; 黑电平补偿&#xff08;BLC&#xff09; 在理想情况下&#xff0c;没有光照射的像素点其响应值应为0。但是&#xff0c;由于杂质、受热等其它原因的影响&…

dockerfile实现lnmp

dockerfile实现lnmp 自定义镜像实现整个架构 (基础镜像centos7) nginx cd /opt mkdir nginx mysql php vim Dockerfile docker network create --subnet172.111.0.0/16 mynetwork #创建自定义网段 docker run -itd --name nginx -p 80:80 --cpu-quota 20000 -m 512m -v /op…

DeepSeek-V3技术报告

摘要 https://arxiv.org/pdf/2412.19437v1 我们介绍DeepSeek-V3&#xff0c;这是一个强大的混合专家&#xff08;MoE&#xff09;语言模型&#xff0c;具有6710亿个总参数&#xff0c;每个token激活37亿个参数。为了实现高效推理和经济实惠的训练&#xff0c;DeepSeek-V3采用了…

【spring mvc】文件上传、下载

文件上传&#xff0c;存储至本地目录中 一、代码1、工具类&#xff08;敏感后缀过滤&#xff09;2、文件上传&#xff0c;存储至本地3、文件下载 二、效果演示1、上传1.1、postMan 请求1.2、上传效果 2、下载2.1、下载效果 一、代码 1、工具类&#xff08;敏感后缀过滤&#x…

CryptoMamba:利用状态空间模型实现精确的比特币价格预测

“CryptoMamba: Leveraging State Space Models for Accurate Bitcoin Price Prediction” 论文地址&#xff1a;https://arxiv.org/pdf/2501.01010 Github地址&#xff1a;https://github.com/MShahabSepehri/CryptoMamba 摘要 预测比特币价格由于市场的高波动性和复杂的非线…

dockerfile2.0

dockerfile实现lnmp nginx centos7 mysql centos7 php centos7 自定义镜像来实现整个架构 cd /opt mkdir nginx mysql php cd nginx 拖入nginx和wordpress vim Dockerfile vim nginx.conf ↓ worker_processes 1; events {worker_connections 1024; } http {include …

C#类型转换

C#是静态类型的语言&#xff0c;变量一旦声明就无法重新声明或者存储其他类型的数据&#xff0c;除非进行类型转换。本章的主要任务就是学习类型转换的知识。类型转换有显式的&#xff0c;也有隐式的。所谓显式&#xff0c;就是我们必须明确地告知编译器&#xff0c;我们要把变…

智能物流升级利器——SAIL-RK3576核心板AI边缘计算网关设计方案(一)

近年来&#xff0c;随着物流行业智能化和自动化水平不断提升&#xff0c;数据的实时处理与智能决策成为推动物流运输、仓储管理和配送优化的重要手段。传统的集中式云平台虽然具备强大计算能力&#xff0c;但高延迟和带宽限制往往制约了物流现场的即时响应。为此&#xff0c;我…

【算法篇】前缀和

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;算法笔记仓 前缀和是一种常用于处理数组区间求和问题的技巧。它可以用来减少重复计算&#xff0c;使得多次查询区间和的时间复杂度从 O(n) 降低到 O(1) 目录 1. 一维模版2. 二维模版3. 除自身以外数…

第R4周:LSTM-火灾温度预测

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 文章目录 一、代码流程1、导入包&#xff0c;设置GPU2、导入数据3、数据集可视化4、数据集预处理5、设置X&#xff0c;y6、划分数据集7、构建模型8、定义训练函…

机组存储系统

局部性 理论 程序执行&#xff0c;会不均匀访问主存&#xff0c;有些被频繁访问&#xff0c;有些很少被访问 时间局部性 被用到指令&#xff0c;不久可能又被用到 产生原因是大量循环操作 空间局部性 某个数据和指令被使用&#xff0c;附近数据也可能使用 主要原因是顺序存…

Windows图形界面(GUI)-QT-C/C++ - Qt图形绘制详解

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 Qt绘图基础 QPainter概述 基本工作流程 绘图事件系统 paintEvent事件 重绘机制 文字绘制技术 基本文字绘制 ​编辑 高级文字效果 基本图形绘制 线条绘制 ​编辑 形状绘制 …

mapbox进阶,添加绘图控件

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️MapboxDraw 绘图控件二、🍀添加绘图控…