Created
April 14, 2015 19:40
-
-
Save ricardo-dlc/ea9013d6aa859c5641ac to your computer and use it in GitHub Desktop.
Arquitectura
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <fstream> | |
#include <string> | |
#include <cstring> | |
#include <cstdlib> | |
#include <time.h> | |
#include <stdlib.h> | |
using namespace std; | |
class Registro{ | |
private: | |
string value; | |
int valor; | |
public: | |
string Leer(string); | |
void Escribir(string); | |
void InValor(int); | |
int OutValor(); | |
}; | |
class Interrupcion{ | |
public: | |
string Interrumpir(); | |
}; | |
class ALU{ | |
private: | |
string operadorA; | |
string operadorB; | |
string resultado; | |
string opCode; | |
public: | |
void SET(string, const char); | |
void SET(string); | |
string OUT(const char); | |
string OUT(); | |
int ADD(int, int); | |
int SUB(int, int); | |
int DIV(int, int); | |
int MUL(int, int); | |
}; | |
class Memoria{ | |
private: | |
string Espacio[64]; | |
public: | |
void EscribirMemProg(string); | |
void EscribirMemProg(string, const char); | |
string DarDato(int); | |
void VaciarMem(); | |
}; | |
class ISA{ | |
private: | |
string Instruccion; | |
string dir; | |
string data; | |
public: | |
void SET(string, const char); | |
void SET(string); | |
string OUT(const char); | |
string OUT(); | |
string buscar(string); | |
bool validarOp(string); | |
void MOVE(string); | |
void LOAD(string, Memoria, const char); | |
void STORE(string); | |
}; | |
class Bus{ | |
private: | |
string Instruccion; | |
int Direccion; | |
public: | |
void setInst(string); | |
string askInst(); | |
void setDir(int); | |
int askDir(); | |
string LeerMemo(int, Memoria); | |
void EscMem(string, Memoria); | |
}; | |
class UnidadC{ | |
public: | |
string LeerMem(Bus, Memoria, int); | |
void Decodificar(string, Bus, Memoria&, ISA, ALU); | |
void Ejecutar(ALU, Memoria&); | |
void Ejecutar(ISA, Memoria&); | |
}; | |
int main(int argc, char** argv){ | |
int pc=0; | |
ALU UniALU; | |
srand(time(NULL)); | |
ISA SetInstrucciones; | |
Registro MAR,PC, A, B, C, MBR; | |
UnidadC UC; | |
Bus BDir,BDat,BDC; | |
Memoria Mem; | |
Mem.VaciarMem(); | |
string Instruccion; | |
ifstream fe("Instrucciones.txt"); | |
if(fe.fail()){ | |
cout << "Error al abrir el archivo" << endl; | |
} | |
else{ | |
// Leer la linea del archivo mediante getline() | |
// para leer toda la cadena completa | |
while (!fe.eof()){ | |
getline(fe, Instruccion); | |
Mem.EscribirMemProg(Instruccion); | |
} | |
} | |
for(int i = 0; i < 32; i++){ | |
int r = rand() % 10; | |
if(r<5){ | |
if(Mem.DarDato(pc) != ""){ | |
PC.InValor(pc); | |
MAR.InValor(PC.OutValor()); | |
BDir.setDir(MAR.OutValor()); | |
BDat.setInst(UC.LeerMem(BDC, Mem, MAR.OutValor())); | |
pc++; | |
cout << BDat.askInst() << endl; | |
if(SetInstrucciones.validarOp(Mem.DarDato(PC.OutValor()))){ | |
//cout << "OK" << endl; | |
UC.Decodificar(Mem.DarDato(PC.OutValor()),BDat, Mem, SetInstrucciones, UniALU); | |
} | |
else{ | |
cout << "Error en la instruccion [" << PC.OutValor() << "] \"" + \ | |
Mem.DarDato(PC.OutValor()) + "\" . No se reconoce la operacion." << endl; | |
return 0; | |
} | |
for(int i = 32; i < 35; i++){ | |
cout << "[" << i << "] " << Mem.DarDato(i) << endl; | |
} | |
} | |
} | |
else{ | |
Interrupcion Int; | |
MBR.InValor(pc); | |
for(int j = 0; j < 32; j++){ | |
if(Mem.DarDato(j) != ""){ | |
Mem.EscribirMemProg(Int.Interrumpir()); | |
PC.InValor(j); | |
break; | |
} | |
} | |
MAR.InValor(MBR.OutValor()); | |
MBR.InValor(PC.OutValor()); | |
PC.InValor(MAR.OutValor()); | |
} | |
} | |
return 0; | |
} | |
void Memoria::EscribirMemProg(string cad){ | |
for(int i = 0; i < 32; i++){ | |
if(Espacio[i] == ""){ | |
Espacio[i] = cad; | |
break; | |
} | |
} | |
} | |
void Memoria::EscribirMemProg(string cad, const char y){ | |
switch(y){ | |
case 'A': | |
Espacio[32] = cad; | |
break; | |
case 'B': | |
Espacio[33] = cad; | |
break; | |
case 'C': | |
Espacio[34] = cad; | |
break; | |
case 'D': | |
Espacio[35] = cad; | |
break; | |
case 'E': | |
Espacio[36] = cad; | |
break; | |
case 'F': | |
Espacio[37] = cad; | |
break; | |
default: | |
break; | |
} | |
} | |
void Registro::InValor(int i){ | |
valor = i; | |
} | |
int Registro::OutValor(){ | |
return valor; | |
} | |
void Bus::setDir(int i){ | |
Direccion = i; | |
} | |
int Bus::askDir(){ | |
return Direccion; | |
} | |
void Bus::setInst(string x){ | |
Instruccion = x; | |
} | |
string Bus::askInst(){ | |
return Instruccion; | |
} | |
string Memoria::DarDato(int i){ | |
return Espacio[i]; | |
} | |
void Memoria::VaciarMem(){ | |
for(int i = 0; i < 64; i++){ | |
Espacio[i] = ""; | |
} | |
} | |
string Bus::LeerMemo(int i, Memoria Mem){ | |
return Mem.DarDato(i); | |
} | |
string UnidadC::LeerMem(Bus BDC, Memoria Mem, int i){ | |
return BDC.LeerMemo(i, Mem); | |
} | |
void UnidadC::Decodificar(string instruccion, Bus Datos, Memoria &Mem, ISA SetIns, ALU UniALU){ | |
string opcode, a, b; | |
int pos = instruccion.find(" "); | |
opcode = instruccion.substr(0, pos); | |
pos = instruccion.find(","); | |
a = instruccion.substr(pos-1, 1); | |
b = instruccion.substr(pos+1, instruccion.length()); | |
cout << "OPCODE>> " << opcode << "\nA>> " << a << "\nB>> " << b << endl; | |
switch(SetIns.buscar(opcode)[0]){ | |
case 'A': | |
//cout << "ES ALU" << endl; | |
UniALU.SET(opcode); | |
UniALU.SET(a, 'A'); | |
UniALU.SET(b, 'B'); | |
Ejecutar(UniALU, Mem); | |
break; | |
case 'T': | |
//cout << "ES ISA" << endl; | |
SetIns.SET(opcode); | |
SetIns.SET(a, 'B'); | |
SetIns.SET(b, 'D'); | |
Ejecutar(SetIns, Mem); | |
break; | |
} | |
} | |
void UnidadC::Ejecutar(ISA SetIns, Memoria &Mem){ | |
cout << "DATA>> " << SetIns.OUT('D') << "\nDIR>> " << SetIns.OUT('B')[0] << endl; | |
if(SetIns.OUT() == "LOAD"){ | |
Mem.EscribirMemProg(SetIns.OUT('D'), SetIns.OUT('B')[0]); | |
} | |
} | |
void UnidadC::Ejecutar(ALU UniALU, Memoria &Mem){ | |
int A, B; | |
char buffer[20]; | |
string res; | |
string sets = "ABCDEF"; | |
switch(UniALU.OUT('A')[0]){ | |
case 'A': | |
A = atoi(Mem.DarDato(32).c_str()); | |
break; | |
case 'B': | |
A = atoi(Mem.DarDato(33).c_str()); | |
break; | |
case 'C': | |
A = atoi(Mem.DarDato(34).c_str()); | |
break; | |
case 'D': | |
A = atoi(Mem.DarDato(35).c_str()); | |
break; | |
case 'E': | |
A = atoi(Mem.DarDato(36).c_str()); | |
break; | |
case 'F': | |
A = atoi(Mem.DarDato(37).c_str()); | |
break; | |
default: | |
break; | |
} | |
size_t a = sets.find(UniALU.OUT('B')); | |
if(a != std::string::npos){ | |
switch(UniALU.OUT('B')[0]){ | |
case 'A': | |
B = atoi(Mem.DarDato(32).c_str()); | |
break; | |
case 'B': | |
B = atoi(Mem.DarDato(33).c_str()); | |
break; | |
case 'C': | |
B = atoi(Mem.DarDato(34).c_str()); | |
break; | |
case 'D': | |
B = atoi(Mem.DarDato(35).c_str()); | |
break; | |
case 'E': | |
B = atoi(Mem.DarDato(36).c_str()); | |
break; | |
case 'F': | |
B = atoi(Mem.DarDato(37).c_str()); | |
break; | |
default: | |
break; | |
} | |
} | |
else{ | |
B = atoi(UniALU.OUT('B').c_str()); | |
} | |
if(UniALU.OUT() == "ADD"){ | |
A = UniALU.ADD(A, B); | |
} | |
else if(UniALU.OUT() == "SUB"){ | |
A = UniALU.SUB(A, B); | |
} | |
res = itoa(A, buffer, 10); | |
Mem.EscribirMemProg(res, UniALU.OUT('A')[0]); | |
} | |
bool ISA::validarOp(string instruccion){ | |
string instrucciones = "ADDDIVLOADMOVEMULSTORESUB"; | |
int pos = instruccion.find(" "); | |
string opcode = instruccion.substr(0,pos); | |
size_t a = instrucciones.find(opcode); | |
//cout << pos << "<< POSICION " << opcode << "<< INSTRUCCION" << endl; | |
if(a != std::string::npos){ | |
return true; | |
} | |
return false; | |
} | |
string ISA::buscar(string instruccion){ | |
if(instruccion == "ADD" || instruccion == "DIV" || instruccion == "MUL" || \ | |
instruccion == "SUB"){ | |
return "A"; | |
} | |
else{ | |
return "T"; | |
} | |
} | |
string Interrupcion::Interrumpir(){ | |
return "LOAD A,40"; | |
} | |
void ISA::LOAD(string value, Memoria Mem, const char where){ | |
Mem.EscribirMemProg(value, where); | |
} | |
void ALU::SET(string value, const char where){ | |
if(where == 'A'){ | |
operadorA = value; | |
} | |
else if(where == 'B'){ | |
operadorB = value; | |
} | |
} | |
void ALU::SET(string value){ | |
opCode = value; | |
} | |
string ALU::OUT(){ | |
return opCode; | |
} | |
string ALU::OUT(const char where){ | |
if(where == 'A'){ | |
return operadorA; | |
} | |
else if(where == 'B'){ | |
return operadorB; | |
} | |
else if(where == 'R'){ | |
return resultado; | |
} | |
} | |
int ALU::ADD(int a, int b){ | |
return (a + b); | |
} | |
int ALU::SUB(int a, int b){ | |
return (a - b); | |
} | |
void Registro::Escribir(string valor){ | |
value = valor; | |
} | |
void ISA::SET(string value, const char where){ | |
if(where == 'B'){ | |
dir = value; | |
} | |
else if(where == 'D'){ | |
data = value; | |
} | |
} | |
void ISA::SET(string value){ | |
Instruccion = value; | |
} | |
string ISA::OUT(){ | |
return Instruccion; | |
} | |
string ISA::OUT(const char where){ | |
if(where == 'B'){ | |
return dir; | |
} | |
else if(where == 'D'){ | |
return data; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment