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