【仿真】基于仿真的 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~
謝謝啦
有問題可以留言。