/// <summary> /// Metodo que procesa una instruccion. /// Se encarga de hacer la decodificacion de la instruccion y llamar al metodo de procesamiento correcto. /// </summary> /// <param name="palabra">Instruccion cuyo codigo se decodifica</param> private void procesarInstruccion(Instruccion inst) { mapa[inst.GetCodigo()](inst); programCounter += 4; // Se modifica el pc para que la proxima instruccion arranque donde debe Debug.WriteLine("Procesador " + id + ": Esperando 1 tick luego de ejecutar una instruccion"); controlador.Esperar(1); }
/// <summary> /// Metodo que ejecuta la instruccion de Fin /// </summary> /// <param name="palabra">Instruccion de la cual se extraen los parametros necesarios</param> private void Fin(Instruccion i) { // A pesar de que se asigna true a finalizado cada vez que llega a un final de programa // El controlador revisa entre ciclos de reloj si hay un siguiente programa // Si lo hay entonces modifica Finalizado a false para que el procesador no deje de hacer su procesamiento Finalizado = true; Debug.WriteLine("Procesador " + id + ": Un programa ha finalizado"); }
/// <summary> /// Metodo que ejecuta la instruccion de Sw /// </summary> /// <param name="palabra">Instruccion de la cual se extraen los parametros necesarios</param> private void Sw(Instruccion i) { int y = i.GetParametro(1), x = i.GetParametro(2), n = i.GetParametro(3); controlador.CachesDatos[id].Escribir(n + registros[y], registros[x]); Debug.WriteLine("Procesador " + id + ": SW MEM(" + n + " + R" + y + ") = R" + x); Debug.WriteLine("Procesador " + id + ": SW MEM(" + (n + registros[y]) + ") = " + registros[x]); }
/// <summary> /// Metodo que ejecuta la instruccion de Lw /// </summary> /// <param name="palabra">Instruccion de la cual se extraen los parametros necesarios</param private void Lw(Instruccion i) { int y = i.GetParametro(1), x = i.GetParametro(2), n = i.GetParametro(3); registros[x] = controlador.CachesDatos[id].Leer(n + registros[y]); this.Modificado = true; // Indica que hubo un cambio en un registro Debug.WriteLine("Procesador " + id + ": LW R" + x + " = MEM(" + n + " + R" + y + ")"); Debug.WriteLine("Procesador " + id + ": LW R" + x + " = MEM(" + (n + registros[y]) + ")"); Debug.WriteLine("Procesador " + id + ": LW R" + x + " = " + registros[x]); }
/// <summary> /// Metodo que ejecuta la instruccion de Dsub /// </summary> /// <param name="palabra">Instruccion de la cual se extraen los parametros necesarios</param> private void Dsub(Instruccion i) { int y = i.GetParametro(1), z = i.GetParametro(2), x = i.GetParametro(3); Debug.WriteLine("Procesador " + id + ": DSUB R" + x + " = R" + y + " - R" + z); Debug.WriteLine("Procesador " + id + ": DSUB R" + x + " = " + registros[y] + " - " + registros[z]); registros[x] = registros[y] - registros[z]; this.Modificado = true; // Indica que hubo un cambio en un registro Debug.WriteLine("Procesador " + id + ": DSUB R" + x + " = " + registros[x]); }
/// <summary> /// Metodo que ejecuta la instruccion de Daddi /// </summary> /// <param name="palabra">Instruccion de la cual se extraen los parametros necesarios</param> private void Daddi(Instruccion i) { int y = i.GetParametro(1), x = i.GetParametro(2), n = i.GetParametro(3); Debug.WriteLine("Procesador " + id + ": DADDI R" + x + " = R" + y + " + " + n); Debug.WriteLine("Procesador " + id + ": DADDI R" + x + " = " + registros[y] + " + " + n); registros[x] = registros[y] + n; this.Modificado = true; // Indica que hubo un cambio en un registro Debug.WriteLine("Procesador " + id + ": DADDI R" + x + " = " + registros[x]); }
/// <summary> /// Metodo que ejecuta la instruccion de Bnez /// </summary> /// <param name="palabra">Instruccion de la cual se extraen los parametros necesarios</param> private void Bnez(Instruccion i) { int x = i.GetParametro(1), n = i.GetParametro(3); if (registros[x] != 0) { programCounter = (programCounter + 4) + n * 4; Debug.WriteLine("Procesador " + id + ": BNEZ Salto a " + programCounter); programCounter -= 4; } else { Debug.WriteLine("Procesador " + id + ": BNEZ No salto"); } // Despues el metodo que llama a este aumenta en 4 el pc }
/// <summary> /// Este es el metodo principal del procesador. /// /// Cuando el procesador se envuelva en un hilo, este es el metodo que se ejecuta /// /// Basicamente mientras hayan instrucciones que ejecutar el hilo continua ejecutandose /// </summary> public void Procesar() { try { while (!Finalizado) { Debug.WriteLine("Procesador " + id + ": PC = " + programCounter); Instruccion i = controlador.CacheInstrucciones.ObtenerInstruccion(programCounter); procesarInstruccion(i); Debug.Flush(); } controlador.OnProcesadorTerminado(); } catch (Exception) { #if !DEBUG MessageBox.Show("Ocurrió un error :/\nAsí quedó la simulación."); #endif } }
/// <summary> /// Crea una cacheDatos de instrucciones /// </summary> /// <param name="instruccionesRecibidas"></param> /// <param name="iniciosProgramas"></param> /// <param name="cantidadProgramasRecibida"></param> public CacheInstrucciones(int numeroProcesadores, int[] instruccionesRecibidas, int[] iniciosProgramas, int cantidadProgramasRecibida, String[] nombresProgramasRecibidos) { cantidadProgramas = cantidadProgramasRecibida; nombresProgramas = nombresProgramasRecibidos; programasAsignados = new String[numeroProcesadores]; Debug.WriteLine("CacheInstrucciones: Hay " + cantidadProgramas + " programas"); instrucciones = new Instruccion[instruccionesRecibidas.Length / 4]; for (short inst = 0; inst < instruccionesRecibidas.Length; inst += 4) { instrucciones[inst / 4] = new Instruccion(instruccionesRecibidas[inst], instruccionesRecibidas[inst + 1], instruccionesRecibidas[inst + 2], instruccionesRecibidas[inst + 3]); } Debug.WriteLine("CacheInstrucciones: Hay " + instrucciones.Length + " instrucciones en todos los programas"); instruccionesIniciales = new int[iniciosProgramas.Length]; for (short i = 0; i < iniciosProgramas.Length; ++i) { instruccionesIniciales[i] = iniciosProgramas[i]; } indiceSiguientePrograma = 0; }