【仿真】基于仿真的 32 位虚拟计算机设计与实现 Mips32指令系统
实现内容:
- 完成Mips32指令的取指、译码、计算、访存和写回五个步骤的软件模拟
- 能够像系统输入机器语言源程序
- 能够对内部寄存器进行初始化
- 能够运行程序
- 能够查看运行结果,能够反映指令的执行过程
- 模拟五段流水线的执行过程
- 解决了数据相关问题
- 反映了流水线的执行过程
- 完成了图形界面的开发
运行截图如下:
【注】本系统着重于功能的实现,因此在一些细节方面与硬件不符。
(一 )类说明
Mips32指令类的声明
class Mips32_instruction
{
public:
void init();
int IF();//取指阶段
void ID();//译码阶段
void EX();//计算阶段
void MEM();//访存阶段
void WB();//写回阶段
char instruction[33];
string op;//6:代表位数
string rs;//5
string rt;//5
string rd;//5
string shamt;//5
string func;//6
string immediate;//16
string address;//26
char type;
int result;//存放数据计算结果
int add_result;//存放地址计算结果
int rs_num = 0;//rs编号
int rt_num = 0;//rt编号
int rd_num = 0;//rd编号
int shamt_num = 0;//shamt数值
int immediate_num = 0;//立即数数值
int address_num = 0;//转移后指令地址
int memory_address = 0;//数据访存地址
string order;
int rs_data, rt_data;//取数
};
指令类初始化的对象为一条Misp32指令。
(1)一条指令具有5个阶段:取指,译码,计算,访存,写回,用类函数进行实现。
(2)Mips32指令分为几种类型(可以参考其他文章的Mips32指令大全),利用变量type进行区分,方便译码函数的实现
五段流水线类的声明
class Pipeline
{
public:
Mips32_instruction Task[5];
int Task_Pro[5];
int IF_Used = 0, ID_Used = 0, EX_Used = 0, MEM_Used = 0, WB_Used = 0;
//
void System_Run();//取指阶段
};
(1)同一时间只能同时运行5条Mips32指令
(2)利用变量判断指令运行的状态(e.g:IF_Used=0代表该指令下一步执行取指阶段)
(二)全局变量的声明
extern HDC g_hdc, g_mdc; //全局设备环境句柄
extern HBITMAP g_hBackGround; //定义位图句柄
extern wchar_t sz[100];
extern HWND edit_ip;
extern HWND Start_Button;//定义主页开始按钮
extern HWND Help_Button;//定义主页帮助按钮
extern HWND End_Button;//定义主页结束按钮
extern vector<char> Instruction_Memory;//指令段内存
extern int Data_Memory[256];//数据段内存
//指令数据分开存放 解决资源相关问题
extern string Register_name[32];//寄存器名
extern int reg_result[32];//解决数据相关问题,定向传送,结果缓冲寄存器
extern int clock_cycle;//时钟周期
extern int PC;//程序计数器
extern int PC_Next;//若为零则无控制相关问题,否则存放预测地址
extern int PC_Len;//存放指令条数
extern int regis_init;//程序运行前是否初始化寄存器和内存
//译码结果存储,显示在图形界面
extern string instruction_out;
extern string rt;
extern string rs;
extern char outtype;
extern int outimmediate;
extern int special;
(三)五段流水线的实现
int start = 0;
void Pipeline::System_Run()
{
instruction_out = "";
int i, sign = 0;
IF_Used = 0, ID_Used = 0, EX_Used = 0, MEM_Used = 0, WB_Used = 0;
if (clock_cycle == 0)
Task_Pro[0] = 0;
if (clock_cycle == 1)
Task_Pro[1] = 0;
if (clock_cycle == 2)
Task_Pro[2] = 0;
if (clock_cycle == 3)
Task_Pro[3] = 0;
if (clock_cycle == 4)
Task_Pro[4] = 0;
for (int k = 0; k < 5; k++)
{
i = (start + k) % 5;
switch (Task_Pro[i])
{
case 0://取指
if (IF_Used == 0)
{
if (Task[i].IF())
{
IF_Used = i + 1;
Task_Pro[i] = (Task_Pro[i] + 1) % 5;
}
}
break;
case 1://译码
if (ID_Used == 0)
{
Task[i].ID();
ID_Used = i + 1;
Task_Pro[i] = (Task_Pro[i] + 1) % 5;
}
break;
case 2://计算
if (EX_Used == 0)
{
Task[i].EX();
EX_Used = i + 1;
Task_Pro[i] = (Task_Pro[i] + 1) % 5;
}
break;
case 3://访存
if (MEM_Used == 0)
{
Task[i].MEM();
MEM_Used = i + 1;
Task_Pro[i] = (Task_Pro[i] + 1) % 5;
}
break;
case 4://写回
if (WB_Used == 0)
{
sign = 1;
Task[i].WB();
WB_Used = i + 1;
Task_Pro[i] = (Task_Pro[i] + 1) % 5;
}
break;
}
}
clock_cycle++;
if (sign)
start = (start + 1) % 5;
}
源码地址:https://github.com/850552586/Mips32
请大家多多star~
谢谢啦
有问题可以留言。