Ejemplo n.º 1
0
int main (int argc, char *argv[])
{
	int PCnew = 0, IRnew, MDRnew, Anew, Bnew, ALUOUTnew;
					// Registradores auxiliares usados para a escrita dentro de um ciclo.
					// Guardam temporariamente o resultado durante um ciclo. Os resultados aqui armazenados estarao
					// disponiveis para leitura no final do ciclo atual (para que o mesmo esteja disponivel apenas no
					// incio do ciclo seguinte).
					// Em um ciclo sempre e lido o conteudo de um registrador atualizado no ciclo anterior.

	int PC = 0, IR=-1, MDR, A, B, ALUOUT;
					// Registradores especiais usados para a leitura em um ciclo.
					// Guardam os resultados que poderao ser utilizados ja neste ciclo, pois foram atualizados no final
					// do ciclo anterior.
					// Ex.: em um ciclo, o resultado da ULA e inserido inicialmente em ALUOUTnew.  Apenas no final
					// do ciclo esse conteudo podera ser atribuido para ALUOUT, para que o mesmo possa ser
					// usado no ciclo seguinte.
					// Em um ciclo sempre e lido o conteudo de um registrador atualizado no ciclo anterior.

	int sc = 0;	   			// Sinais de Controle
					//                    cada bit determina um dos sinais de controle que saem da UC.
					// A posicao de cada sinal dentro do int esta especificada no enunciado
	char ula_op = 0;   			// Sinais de Controle de entrada para a ULA
					//                    sao usados apenas os 4 bits menos significativos dos 8 disponiveis.

	int nr_ciclos = 0; 			// contador do numero de ciclos executados

/*
As variaveis zero e overflow nao precisam definidas na main.
Serao argumentos de retorno da ula e devem ser definidas localmente nas
rotinas adequadas.
char  zero, overflow;  			// Sinais de Controle de saida da UL: bit zero e bit para indicar overflow
*/

	memoria[0] = 0x8c480000;  // 1000 1100 01007 1000 0000 0000 0000 0000  lw $t0, 0($v0)								5
	memoria[1] = 0x010c182a;  // 0000 0001 0000 1100 0001 1000 0010 1010   slt $v1, $t0, $t4								4
	memoria[2] = 0x106d0004;  // 0001 0000 0110 1101 0000 0000 0000 0100  beq $v1, $t5, fim(4 palavras abaixo de PC+4)	3
	memoria[3] = 0x01084020;  // 0000 0001 0000 1000 0100 0000 0010 0000  add $t0, $t0, $t0								4
	memoria[4] = 0xac480000;  // 1010 1100 0100 1000 0000 0000 0000 0000  sw $t0, 0($v0)								4
	memoria[5] = 0x004b1020;  // 0000 0000 0100 1011 0001 0000 0010 0000  add $v0, $t3, $v0								4
	memoria[6] = 0x08000000;  // 0000 1000 0000 0000 0000 0000 0000 0000  j inicio (palavra 0)								3
	memoria[7] = 0;           // fim (criterio de parada do programa)    (27*6)+(5+4+3)+1
	memoria[8] = 0;
	memoria[9] = 0;

	// Dados
	memoria[20] = 10;
	memoria[21] = 12;
	memoria[22] = 14;
	memoria[23] = 16;
	memoria[24] = 18;
	memoria[25] = 20;
	memoria[26] = -1;

	reg[2]  = 80;  // $v0

	reg[11] = 4;  // $t3
	reg[12] = 0;  // $t4
	reg[13] = 1;  // $t5

	while(loop){
		// aqui comeca um novo ciclo

		// abaixo estao as unidades funcionais que executarao em todos os ciclos
		// os sinais de controle em sc impedirao/permitirao que a execucao seja, de fato, efetivada

		UnidadeControle(IR, &sc);
		Busca_Instrucao(sc, PC, ALUOUT, IR, A, B, &PCnew, &IRnew, &MDRnew);
		Decodifica_BuscaRegistrador(sc, IR, PC, A, B, &Anew, &Bnew, &ALUOUTnew);
		Execucao_CalcEnd_Desvio(sc, A, B, IR, PC, ALUOUT, &ALUOUTnew, &PCnew);
		EscreveTipoR_AcessaMemoria(sc, B, IR, ALUOUT, PC, &MDRnew, &IRnew);
		EscreveRefMem(sc, IR, MDR, ALUOUT);

		// contador que determina quantos ciclos foram executados
		nr_ciclos++;

		// atualizando os registradores temporarios necessarios ao proximo ciclo.
		PC	 	= PCnew;
		IR		= IRnew;
		MDR		= MDRnew;
		A		= Anew;
		B		= Bnew;
		ALUOUT 	= ALUOUTnew;

		// aqui termina um ciclo
	} // fim do while(loop)

	// impressao da memoria para verificar se a implementacao esta correta
	{
		int ii;
		for (ii = 20; ii < 27; ii++) {
			printf("memoria[%d]=%d \n", ii, memoria[ii]);
		}
		printf("Nr de ciclos executados =%d \n", nr_ciclos);
	}
	exit(0);
} 
int main (int argc, char *argv[])
{
    int PCnew = 0, IRnew, MDRnew, Anew, Bnew, ALUOUTnew;
    int PC = 0, IR=-1, MDR, A, B, ALUOUT;   
    short int sc = 0;
    int nr_ciclos = 0;
                             //                                             ## fat(n) iterativo
    memoria[0] = 0x8db00000; // 1000 1101 1011 0000 0000 0000 0000 0000         lw $s0, 0($t5)       # carrega n da memoria
    memoria[1] = 0x11300005; // 0001 0001 0011 0000 0000 0000 0000 0101   loop: beq $t1, $s0, fim    # se der a cond. sai do loop
    memoria[2] = 0x01025020; // 0000 0001 0000 0010 0101 0000 0010 0000         add $t2, $t0, $v0    # t2 = t0 + v0)
    memoria[3] = 0x00404025; // 0000 0000 0100 0000 0100 0000 0010 0101         or $t0, $v0, $zero   # t0 = v0
    memoria[4] = 0x01431024; // 0000 0001 0100 0011 0001 0000 0010 0100         and $v0, $t2, $v1    # v0 = t2
    memoria[5] = 0x012b4820; // 0000 0001 0010 1011 0100 1000 0010 0000         add $t1, $t1, $t3    # t1 = t1 + 1
    memoria[6] = 0x08000001; // 0000 1000 0000 0000 0000 0000 0000 0001         j loop (palavra 1)   # volta pro loop
    memoria[7] = 0xad820000; // 1010 1101 1000 0010 0000 0000 0000 0000   fim:  sw $v0, 0($t4)       # salva o resultado na memoria
    memoria[8] = 0;          // criterio de parada do programa   ciclos: 1+5+(22*(n-1))+3+4+1
    memoria[9] = 0;
    
    // Dados
    memoria[20] = 10;         // Fibonacci que se deseja calcular
                              // memoria[21] ira receber o resultado
    
    reg[0] = 0;   // $zero
    
    reg[2] = 0;   // $v0
    reg[3] = -1;  // $v1
    
    reg[8] = 1;   // $t0
    reg[9] = 1;   // $t1
    reg[11] = 1;  // $t3
    reg[12] = 84; // $t4
    reg[13] = 80; // $t5
    
    while(loop)
    {
        // aqui comeca um novo ciclo
        
        // abaixo estao as unidades funcionais que executarao em todos os ciclos
        // os sinais de controle em sc impedirao/permitirao que a execucao seja, de fato, efetivada
        UnidadeControle(IR, &sc);
        Busca_Instrucao(sc, PC, ALUOUT, IR, &PCnew, &IRnew, &MDRnew);
        Decodifica_BuscaRegistrador(sc, IR, PC, A, B, &Anew, &Bnew, &ALUOUTnew);
        Execucao_CalcEnd_Desvio(sc, A, B, IR, PC, ALUOUT, &ALUOUTnew, &PCnew);
        EscreveTipoR_AcessaMemoria(sc, B, IR, ALUOUT, PC, &MDRnew, &IRnew);
        EscreveRefMem(sc, IR, MDR, ALUOUT);
        
        // contador que determina quantos ciclos foram executados
        nr_ciclos++;
           
        // atualizando os registradores temporarios necessarios ao proximo ciclo.
        PC = PCnew;
        IR = IRnew;
        MDR = MDRnew;
        A = Anew;
        B = Bnew;
        ALUOUT = ALUOUTnew;
        // aqui termina um ciclo
    } // fim do while(loop)
    
    // impressao da memoria para verificar se a implementacao esta correta
    {
       int ii;
       for (ii = 20; ii < 22; ii++) {
           printf("memoria[%d]=%ld \n", ii, memoria[ii]);
       }
       printf("Nr de ciclos executados =%d \n", nr_ciclos);
    }
    
    exit(0);
} // fim de main