⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simulator.cpp

📁 计算机系统结构中实现记分牌算法的一个模拟器
💻 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 + -