📄 simulator.cpp
字号:
// Simulator.cpp: implementation of the CSimulator class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ScoreBoard.h"
#include "Simulator.h"
#include <string.h>
#include <stdio.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CSimulator::CSimulator(CListCtrl *m_cProList, CListCtrl *m_cInsStaList, CListCtrl * m_cFunList, CListCtrl *m_cRegList)
{
this->pProList=m_cProList;
this->pInsList=m_cInsStaList;
this->pFunList=m_cFunList;
this->pRegList=m_cRegList;
}
CSimulator::~CSimulator()
{
}
void CSimulator::initial(CString filePath)
{
//读入程序,并初始化指令
int i;
FILE *file;
file=fopen(filePath, "r");
if(file==NULL)
{
AfxMessageBox("open file failed!");
return;
}
fscanf(file,"%d", &insNum);
curPro=new Instruction[insNum];
for(i=0; i<insNum; i++)
{
fscanf(file,"%s %s %s %s",curPro[i].op, curPro[i].destReg, curPro[i].srcOperand1, curPro[i].srcOperand2);
curPro[i].ExcuteTime=GetPeriods(curPro[i]);
curPro[i].waitSta=WAIT_ISSUE;
curPro[i].unitUsed=NULL;
}
for(i=0; i<insNum; i++)
{
int nitem=pProList->InsertItem(i, curPro[i].op);
pProList->SetItemText(nitem, 1, curPro[i].destReg);
pProList->SetItemText(nitem, 2, curPro[i].srcOperand1);
pProList->SetItemText(nitem, 3, curPro[i].srcOperand2);
}
//初始化功能部件单元
funUnit=new FunUnit[5];
funUnit[0].Name="Integer";
funUnit[1].Name="Mult1";
funUnit[2].Name="Mult2";
funUnit[3].Name="Add";
funUnit[4].Name="Divide";
for(i=0; i<5; i++)
{
funUnit[i].Busy=false;
funUnit[i].Op="";
funUnit[i].Fi="";
funUnit[i].Fj="";
funUnit[i].Fk="";
funUnit[i].Qj=NULL;
funUnit[i].Qk=NULL;
funUnit[i].Rj=false;
funUnit[i].Rk=false;
}
//初始化寄存器部件
for(i=0;i<31;i++)
Register[i]=NULL;
numItem=new int[insNum];
for(i=0; i<insNum; i++)
{
numItem[i]=pInsList->InsertItem(i, "clock:");
}
}
FunUnit * CSimulator::GetFunUnit(Instruction *ins)
{
if(strcmp(ins->op, "LD")==0)
{
if(!funUnit[INTEGER].Busy)
{
return &funUnit[INTEGER];
}
else
return NULL;
}
if(strcmp(ins->op, "MULTD")==0)
{
if(!funUnit[MULT1].Busy)
{
return &funUnit[MULT1];
}
else if(!funUnit[MULT2].Busy)
{
return &funUnit[MULT2];
}
else
return NULL;
}
if(strcmp(ins->op, "SUBD")==0||strcmp(ins->op, "ADDD")==0)
{
if(!funUnit[ADD].Busy)
{
return &funUnit[ADD];
}
else
return NULL;
}
if(strcmp(ins->op, "DIVD")==0)
{
if(!funUnit[DIVIDE].Busy)
{
return &funUnit[DIVIDE];
}
else
return NULL;
}
return NULL;
}
int CSimulator::GetPeriods(Instruction ins)
{
if(strcmp(ins.op, "LD")==0)
{
return 1;
}
if(strcmp(ins.op, "MULTD")==0)
{
return 10;
}
if(strcmp(ins.op, "SUBD")==0)
{
return 2;
}
if(strcmp(ins.op, "ADDD")==0)
{
return 2;
}
if(strcmp(ins.op, "DIVD")==0)
{
return 40;
}
return 0;
}
bool CSimulator::Issue(Instruction *ins)
{
int index;
ins->unitUsed->Busy=true;
ins->unitUsed->Op=ins->op;
ins->unitUsed->Fi=ins->destReg;
ins->unitUsed->Fj=ins->srcOperand1;
ins->unitUsed->Fk=ins->srcOperand2;
index=GetIndex(ins->destReg);
Register[index]=ins->unitUsed;
index=GetIndex(ins->srcOperand1);
if(index==-1||index==-2)
{
ins->unitUsed->Qj=NULL;
}
else
{
ins->unitUsed->Qj=Register[index];
}
index=GetIndex(ins->srcOperand2);
if(index==-1||index==-2)
{
ins->unitUsed->Qk=NULL;
}
else
{
ins->unitUsed->Qk=Register[index];
}
if(ins->unitUsed->Qj==NULL)
ins->unitUsed->Rj=true;
else
ins->unitUsed->Rj=false;
if(ins->unitUsed->Qk==NULL)
ins->unitUsed->Rk=true;
else
ins->unitUsed->Rk=false;
ins->waitSta=WAIT_READ;
return true;
}
bool CSimulator::ReadOperand(Instruction *ins)
{
ins->waitSta=WAIT_EXCUTE;
return true;
}
bool CSimulator::ExcuteInstruction(Instruction *ins)
{
ins->ExcuteTime--;
if(ins->ExcuteTime==0)
{
ins->waitSta=WAIT_WRITE;
return true;
}
return false;
}
bool CSimulator::WriteResult(Instruction *ins)
{
int i;
for(i=INTEGER; i<=DIVIDE; i++)
{
if(funUnit[i].Qj==ins->unitUsed)
{
funUnit[i].Qj=NULL;
funUnit[i].Rj=true;
}
if(funUnit[i].Qk==ins->unitUsed)
{
funUnit[i].Qk=NULL;
funUnit[i].Rk=true;
}
}
int index=GetIndex(ins->destReg);
Register[index]=NULL;
ins->unitUsed->Busy=false;
ins->unitUsed->Op="";
ins->unitUsed->Fi="";
ins->unitUsed->Fj="";
ins->unitUsed->Fk="";
ins->unitUsed->Qj=NULL;
ins->unitUsed->Qk=NULL;
ins->unitUsed->Rj=false;
ins->unitUsed->Rk=false;
ins->waitSta=FINISHED;
return true;
}
//前进一个时钟周期
bool CSimulator::RunStep(int curStep)
{
int i;
bool finished=true;
RunType *temp=new RunType[insNum];
CString str;
for(i=0; i<insNum; i++)
{
if(curPro[i].waitSta!=FINISHED)
finished=false;
}
if(finished)
return true;
for(i=0; i<insNum; i++)
{
temp[i]=GetRunType(&curPro[i], i);
}
//逐条指令进行处理
for(i=0; i<insNum; i++)
{
switch(temp[i])
{
case ISSUE:
if(Issue(&curPro[i]))
{
str.Format("%d", curStep);
pInsList->SetItemText(numItem[i], 1, str);
}
break;
case READ:
if(ReadOperand(&curPro[i]))
{
str.Format("%d", curStep);
pInsList->SetItemText(numItem[i], 2, str);
}
break;
case EXCUTE:
if(ExcuteInstruction(&curPro[i]))
{
str.Format("%d", curStep);
pInsList->SetItemText(numItem[i], 3, str);
}
break;
case WRITE:
if(WriteResult(&curPro[i]))
{
str.Format("%d", curStep);
pInsList->SetItemText(numItem[i], 4, str);
}
break;
case NOTHING:
break;
default:
;
}
}
UpdateList();
return false;
}
//更新状态表
void CSimulator::UpdateList()
{
int i, nitem;
pFunList->DeleteAllItems();
pRegList->DeleteAllItems();
for(i=INTEGER; i<=DIVIDE; i++)
{
nitem=pFunList->InsertItem(i, funUnit[i].Name);
if(funUnit[i].Busy)
{
pFunList->SetItemText(nitem, 1, "Yes");
}
else
pFunList->SetItemText(nitem, 1, "No");
if(funUnit[i].Op!="")
{
pFunList->SetItemText(nitem, 2, funUnit[i].Op);
}
if(funUnit[i].Fi!="")
{
pFunList->SetItemText(nitem, 3, funUnit[i].Fi);
}
if(funUnit[i].Fj!="")
{
pFunList->SetItemText(nitem, 4, funUnit[i].Fj);
}
if(funUnit[i].Fk!="")
{
pFunList->SetItemText(nitem, 5, funUnit[i].Fk);
}
if(funUnit[i].Qj!=NULL)
{
pFunList->SetItemText(nitem, 6, funUnit[i].Qj->Name);
}
if(funUnit[i].Qk!=NULL)
{
pFunList->SetItemText(nitem, 7, funUnit[i].Qk->Name);
}
if(funUnit[i].Rj)
pFunList->SetItemText(nitem, 8, "Yes");
else
pFunList->SetItemText(nitem, 8, "No");
if(funUnit[i].Rk)
pFunList->SetItemText(nitem, 9, "Yes");
else
pFunList->SetItemText(nitem, 9, "No");
}
nitem=pRegList->InsertItem(0, "status");
for(i=0; i<31; i++)
{
if(Register[i]!=NULL)
pRegList->SetItemText(nitem, i+1, Register[i]->Name);
}
}
//
int CSimulator::GetIndex(char *RegName)
{
char* str;
if(RegName[0]!='F'&&RegName[0]!='R')
return -2;
else if (RegName[0]=='R')
{
return -1;
}
else
{
str=&RegName[1];
return atoi(str);
}
}
RunType CSimulator::GetRunType(Instruction *ins, int num)
{
int i;
FunUnit *temp;
bool WARConfilct=false, OrderConflict=false;
int index=GetIndex(ins->destReg);
switch(ins->waitSta)
{
case WAIT_ISSUE:
if(num!=0&&curPro[num-1].waitSta==WAIT_ISSUE)
OrderConflict=true;
temp=GetFunUnit(ins);
if(temp!=NULL&&Register[index]==NULL&&!OrderConflict)
{
ins->unitUsed=temp;
return ISSUE;
}
break;
case WAIT_READ:
if(ins->unitUsed->Rj&&ins->unitUsed->Rk)
return READ;
break;
case WAIT_EXCUTE:
return EXCUTE;
break;
case WAIT_WRITE:
for(i=0; i<num; i++)
{
if(curPro[i].waitSta==WAIT_READ&&(strcmp(funUnit[i].Fj, ins->destReg)==0||strcmp(funUnit[i].Fk, ins->destReg)==0))
WARConfilct=true;
}
if(!WARConfilct)
return WRITE;
break;
default:
return NOTHING;
}
return NOTHING;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -