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

📄 dlxdoc.cpp

📁 计算机体系结构中,关于DLXS的模拟程序.在vc6.0下编译通过.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// DlxDoc.cpp : implementation of the CDlxDoc class
//

#include "stdafx.h"
#include "Architecture.h"

#include "Globals.h"
#include "PeriodDlg.h"
#include "RegDlg.h"
#include "MemDlg.h"
#include "CodeMemDlg.h"
#include "DlxDoc.h"
#include "mybar.h"
#include "MemBar.h"
#include "RegBar.h"
#include "codemem.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

extern CDlxApp theApp;

extern CMyBar * MyBar;
extern CMemBar * MemBar;
extern CRegBar * RegBar;
extern CCodeMemBar * CodeMemBar;

CDlxDoc* MyDoc;
Operation OpCode[MAXOPERATION] = 
{{"LW",LW},{"SW",SW},{"ADD",ADD},{"SUB",SUB},{"MUT",MUT},
{"DIV",DIV},{"AND",AND},{"OR",OR},{"XOR",XOR},{"ADDI",ADDI},
{"SUBI",SUBI},{"MUTI",MUTI},{"DIVI",DIVI},{"ANDI",ANDI},{"ORI",ORI},
{"XORI",XORI},{"BEQZ",BEQZ},{"BNEZ",BNEZ},{"J",J},{"JR",JR},
{"TRAP",TRAP}};

const CString OpMachineCode[MAXOPERATION] = 
{
"010001","010010","100001","100010","100011",
"100100","100101","100110","101111","010011",
"010100","010101","010110","010111","011000",
"011001","011010","011011","110001","011100",
"111111"
} ;

Tokentype Lookout(const char * mcode)
{
	for(int i=0;i<MAXOPERATION;i++)
		if(!strcmp(OpMachineCode[i],mcode))
			return OpCode[i].tok;
		return UNKNOWN;
}
Tokentype Lookup(const char * name)
{
	for(int i=0; i < MAXOPERATION; i++)
		if(!strcmp(OpCode[i].name,name))
			return OpCode[i].tok;
	return UNKNOWN;
}


/////////////////////////////////////////////////////////////////////////////
// CDlxDoc

IMPLEMENT_DYNCREATE(CDlxDoc, CDocument)

BEGIN_MESSAGE_MAP(CDlxDoc, CDocument)
	//{{AFX_MSG_MAP(CDlxDoc)
	ON_COMMAND(ID_SET_PERIOD, OnSetPeriod)
	ON_COMMAND(ID_EXE_RUN, OnExeRunStep)
	ON_COMMAND_RANGE(ID_SET_FWD,ID_SET_NFWD,OnSetFwd)
	ON_COMMAND_RANGE(ID_SET_FLUSH,ID_SET_DELAY,OnSetBranch)
	ON_UPDATE_COMMAND_UI_RANGE(ID_SET_FWD, ID_SET_NFWD, OnUpdateFwd)
	ON_UPDATE_COMMAND_UI_RANGE(ID_SET_FLUSH, ID_SET_DELAY, OnUpdateBranch)
	ON_COMMAND(ID_EXE_RESET, OnExeReset)
	ON_COMMAND(ID_SET_MEM, OnSetMem)
	ON_COMMAND(ID_SET_REG, OnSetReg)
	ON_COMMAND(ID_SAVE, OnSave)
	ON_COMMAND(MY_ID_RESET, OnIdReset)
	ON_COMMAND(MY_ID_COMPLE, OnIdComple)
	ON_COMMAND(MY_ID_RUN, OnIdRun)
	ON_COMMAND(ID_SET_CODEMEM, OnSetCodemem)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDlxDoc construction/destruction

CDlxDoc::CDlxDoc() :m_Forwarding(ID_SET_NFWD),m_Branch(ID_SET_FLUSH),
	m_MulPeriod(4),m_DivPeriod(4),m_InstructionNum(4),
	m_CurInstr(0),m_Clock(0),m_Pc(0)
{
	for(int i=0; i<MAXREGS; i++)
		this->m_Register[i] = 0;		//对所有寄存器置初值
	for(i=0; i<MAXMEM; i++){
		this->m_Memory[i] = 0;			//对所有DATA内存置初值
		this->m_CodeMemory[i] = "00000000000000000000000000000000";
	}
	for(i=0; i<MAXPC; i++)
	{
		this->m_Instruction[i].cmdString = "TRAP";
		this->m_Instruction[i].outstate = _S_STALL;
		this->m_Instruction[i].period = 1;
		this->m_Instruction[i].state = _S_STALL;
		for(int j = 0; j < 5; j++)
			this->m_Instruction[j].forward[j][0] =
			this->m_Instruction[j].forward[j][1] = 
			CSize(0,0);
	}
	
}

CDlxDoc::~CDlxDoc()
{
}

BOOL CDlxDoc::OnNewDocument()
{
	MyDoc = this;
	if (!CDocument::OnNewDocument())
		return FALSE;


	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
//函数名:Serialize()	功能:从外部文件读入程序指令 存放到m_CmdString
//参数:文件流			返回值: 无			
/////////////////////////////////////////////////////////////////////////////
void CDlxDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
	}
	else
	{
		int i=0;		
		do
		{			
			ar.ReadString(this->m_CmdString[i]);
			this->m_CmdString[i].MakeUpper();
		} while(this->m_CmdString[i++] != "TRAP");
		i--;
		this->SetInstructionNum(i);
		this->OnExeReset();
		this->UpdateAllViews(NULL);
	}
}

/////////////////////////////////////////////////////////////////////////////
// CDlxDoc diagnostics

#ifdef _DEBUG
void CDlxDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CDlxDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CDlxDoc commands

void CDlxDoc::OnSetPeriod() 
{
	// TODO: Add your command handler code here
	CPeriodDlg dlg;
	dlg.m_Mul = this->GetMulPeriod();
	dlg.m_Div = this->GetDivPeriod();

	if(dlg.DoModal() ==	IDOK)
	{
		this->SetMulPeriod(dlg.m_Mul);
		this->SetDivPeriod(dlg.m_Div);
	}
}
//////////////////////////////////////////
//函数名: OnExeRunStep()	功能:执行当前指令
//参数: 无				返回参数:无
/////////////////////////////////////////
void CDlxDoc::OnExeRunStep() 
{
//	OnSave();
	UINT forward = GetForwarding();
	UINT branch = GetBranch();
	int instrNum = GetInstructionNum();

	if(m_Clock >= MAXCLOCK)
		return;
	
	//遍历当前正在流水线上执行的所有指令
	for(int i=0,j=0,stall=0; i < m_CurInstr; i++)
	{
		Tokentype t = ::Lookup(LPCSTR(m_Instruction[i].op));
		
		//如果上一条指令在此时钟周期上stall则该条指令也stall	
		if(i &&  m_Instruction[i-1].states[ m_Clock] == _S_STALL)
			m_Instruction[i].states[ m_Clock] = _S_STALL;				
		
		else
			switch( m_Instruction[i].state)
		{
			case _S_IF:
				//采用预测转移不成功策略
				if(i && branch == ID_SET_UNTAKEN && this->m_Pc != m_Instruction[i].pc+1)
				{
					m_Instruction[i].state = _S_IDLE;
					m_Instruction[i].states[ m_Clock] = _S_IDLE;
					this->m_Instruction[i].exetimes = 1;
					break;
				}
				
				//Forwarding
				if(m_Instruction[i].src1.GetLength())
					//从该指令开始往前遍历该指令前的所有指令
					for(j=i-1; j>=0; j--)
					{					
						Instruction * pInstr = & m_Instruction[j];
						if(pInstr->states[ m_Clock] < _S_HALT&&
							pInstr->dest ==  m_Instruction[i].src1&&
							pInstr->dest.GetAt(0) == 'R')
						{
							if(forward == ID_SET_FWD && pInstr->state == _S_WB)
								m_Instruction[i].forward[_S_IF][0] =
								CSize( m_Clock,j);
							else if(t == BEQZ || t == BNEZ || t == J || t == JR)
							{
								if(forward == ID_SET_FWD && pInstr->state > _S_EXE
									&& pInstr->state > pInstr->outstate)
									m_Instruction[i].forward[_S_IF][0] =
									CSize( m_Clock,j);
								else
									stall = 1;
							}
							break;
						}
					}
				
				//Forwarding
				if(!stall&&m_Instruction[i].src2.GetLength())
					//从该指令开始往前遍历该指令前的所有指令
					for(j=i-1; j>=0; j--)
					{					
						Instruction * pInstr = & m_Instruction[j];
						if(pInstr->states[ m_Clock] < _S_HALT&&
							pInstr->dest ==  m_Instruction[i].src2&&
							pInstr->dest.GetAt(0) == 'R')
						{
							if(forward == ID_SET_FWD && pInstr->state == _S_WB)
								m_Instruction[i].forward[_S_IF][1] =
								CSize( m_Clock,j);
							else if(t == BEQZ || t == BNEZ || t == J || t == JR)
							{
								if(forward == ID_SET_FWD && pInstr->state > _S_EXE
									&& pInstr->state > pInstr->outstate)
									m_Instruction[i].forward[_S_IF][1] =
									CSize( m_Clock,j);
								else
								{
									m_Instruction[i].forward[_S_IF][0] = CSize(0,0);
									stall = 1;
								}
							}
							break;
						}
					}
					
				if(!stall)
				{
					m_Instruction[i].state++;
					m_Instruction[i].states[ m_Clock] = _S_ID;
				}
				else
					m_Instruction[i].states[ m_Clock] = _S_STALL;
					
				break;

			case _S_ID:
				//ALU 唯一
				if (i &&  m_Instruction[i-1].states[ m_Clock] == _S_EXE)
				{
					m_Instruction[i].states[ m_Clock] = _S_STALL;	
					break;
				}
				if(m_Instruction[i].src1.GetLength()&&t != BEQZ&&t != BNEZ&&t != J&&t != JR)
					for(j=i-1; j>=0; j--)
					{					
						Instruction * pInstr = & m_Instruction[j];
						if(pInstr->states[ m_Clock] < _S_HALT&&
							pInstr->dest ==  m_Instruction[i].src1&&
							pInstr->dest.GetAt(0) == 'R')
						{
							if(forward == ID_SET_FWD && pInstr->state > _S_EXE
								&& pInstr->state > pInstr->outstate)
								m_Instruction[i].forward[_S_ID][0] =
								CSize( m_Clock,j);
							else
								stall = 1;
							break;
						}
					}
					if(!stall && m_Instruction[i].src2.GetLength()&&t != BEQZ&&t != BNEZ&&t != J&&t != JR)
						for(j=i-1; j>=0; j--)
						{					
							Instruction * pInstr = & m_Instruction[j];
							if(pInstr->states[ m_Clock] < _S_HALT&&
								pInstr->dest ==  m_Instruction[i].src2)
							{
								if(forward == ID_SET_FWD && pInstr->state > _S_EXE
									&& pInstr->state > pInstr->outstate)
									m_Instruction[i].forward[_S_ID][1] =
									CSize( m_Clock,j);
								else
								{
									m_Instruction[i].forward[_S_ID][0] =
										CSize(0,0);
									stall = 1;
								}
								break;
							}
						}
						if(!stall)
						{
							m_Instruction[i].state++;
							m_Instruction[i].states[ m_Clock] = _S_EXE;
							m_Instruction[i].exetimes++;
							CString temp;
							temp = this->m_Instruction[i].src1;
							if(temp.GetLength())
								if(temp.GetAt(0) == 'R')
								{
									temp.Delete(0);
									m_Instruction[i].val1 = ::atoi(LPCSTR(temp));
									m_Instruction[i].val1 = this->m_Register[m_Instruction[i].val1];
								}
								else
									m_Instruction[i].val1 = ::atoi(LPCSTR(temp));
								
								temp = this->m_Instruction[i].src2;
								if(temp.GetLength())
									if(temp.GetAt(0) == 'R')
									{
										temp.Delete(0);
										m_Instruction[i].val2 = ::atoi(LPCSTR(temp));
										m_Instruction[i].val2 = this->m_Register[m_Instruction[i].val2];
									}
									else
										m_Instruction[i].val2 = ::atoi(LPCSTR(temp));
									//Forwarding 
									CSize size;
									if((size=m_Instruction[i].forward[_S_ID-1][0]) != CSize(0,0))
									{
										m_Instruction[i].val1 = m_Instruction[size.cy].val0;
									}
									if((size=m_Instruction[i].forward[_S_ID-1][1]) != CSize(0,0))
									{
										m_Instruction[i].val2 = m_Instruction[size.cy].val0;
									}
									//Branch
									switch(t)
									{
									case BEQZ:
										if(m_Instruction[i].val1 == 0)
											this->m_Pc = this->m_Instruction[i].pc+::atoi(LPCSTR(this->m_Instruction[i].dest))/4;
										break;
									case BNEZ:
										if(m_Instruction[i].val1 != 0)
											this->m_Pc = this->m_Instruction[i].pc+::atoi(LPCSTR(this->m_Instruction[i].dest))/4;
										break;
									case J:
										this->m_Pc = ::atoi(LPCSTR(this->m_Instruction[i].dest))/4;
										break;
									case JR:
										temp = this->m_Instruction[i].src1;
										temp.Delete(0);
										this->m_Pc = this->m_Register[::atoi(LPCSTR(temp))]/4;
										break;
									default:
										break;
									}
									//Forwarding
									if((size=m_Instruction[i].forward[_S_ID][0]) != CSize(0,0))
									{
										m_Instruction[i].val1 = m_Instruction[size.cy].val0;
									}
									if((size=m_Instruction[i].forward[_S_ID][1]) != CSize(0,0))
									{
										m_Instruction[i].val2 = m_Instruction[size.cy].val0;
									}
						}
						else
						{
							m_Instruction[i].states[ m_Clock] = _S_STALL;
						}
						break;
			case _S_EXE:
				if( m_Instruction[i].exetimes <  m_Instruction[i].period)
				{
					m_Instruction[i].states[ m_Clock] = _S_EXE;
					m_Instruction[i].exetimes++;
				}
				else
				{
					if( m_Instruction[i].outstate == _S_EXE)
						this->InstructionExe(i,m_Instruction[i].val1,m_Instruction[i].val2,1);
					m_Instruction[i].state++;
					m_Instruction[i].states[ m_Clock] = _S_MEM;
				}
				break;
			case _S_MEM:
				if( m_Instruction[i].outstate == _S_MEM)
					this->InstructionExe(i,m_Instruction[i].val1,m_Instruction[i].val2,1);
				m_Instruction[i].state++;
				m_Instruction[i].states[ m_Clock] = _S_WB;
				break;
			case _S_WB:
				m_Instruction[i].state++;
				m_Instruction[i].states[ m_Clock] = _S_HALT;
				this->InstructionExe(i,m_Instruction[i].val1,m_Instruction[i].val2,0);
				break;
			case _S_HALT:
				m_Instruction[i].states[ m_Clock] = _S_HALT;
				break;
			case _S_IDLE:
				if( m_Instruction[i].exetimes < 4)
				{
					m_Instruction[i].states[ m_Clock] = _S_IDLE;
					m_Instruction[i].exetimes++;
				}
				else
				{
					m_Instruction[i].state = _S_HALT;
					m_Instruction[i].states[ m_Clock] = _S_HALT;
				}
				break;
			default:  
				::AfxMessageBox("Unexpected fatat error during OnExeRunStep!\n");
		}// switch end
	}// for end

	//取新指令执行,初始化指令(配置指令)
	if (this->m_Pc < instrNum)	//指令还没有全部执行
		
		if (i==0) 
		{
			this->m_Instruction[i].pc = this->m_Pc;
			m_CmdString[m_Pc] = DisCompileInstruction(m_Pc);
			this->m_Instruction[i].cmdString = this->m_CmdString[m_Pc++]; //取当前指令
			this->SetInstruction(i);									  //设置指令
			m_CurInstr++;
		}
		
		else if(m_Instruction[i-1].states[ m_Clock] != _S_STALL)
			switch(::Lookup(LPCSTR(m_Instruction[i-1].op)))
		{
			case BEQZ:
			case BNEZ:
			case J:
			case JR:
				if((branch != ID_SET_FLUSH && branch != ID_SET_TAKEN)
					|| m_Instruction[i-1].state != _S_ID)
				{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -