Sei sulla pagina 1di 5

Lista 03 – Pipeline MIPS

1.
a) Os valores escolhidos foram t1 = 2 e t2 = 3. Algumas modificações de valor que não tem relação
com a instrução e não afetam o resultado foram omitidas para simplificar.

• 1º Estágio – IF
Através do somador, o PC é somado ao valor 4 e a saída disponibilizada tanto para o
registrador IF/ID, quanto para o primeiro MUX no canto superior esquerdo. O valor de PC é
entregue para ser lido na Instruction Memory, e a instrução lida é disponibilizada para o
registrador IF/ID.
• 2º Estágio – ID
Com a instrução obtida, ela é então dividida para as entradas do IR e sign-extend, 09 = t1 e
0a = t2. O IR entrega os valores 2 e 3 nas suas saídas, como era de se esperar. Esses
valores são salvos no registrador ID/EX.
• 3º Estágio – EX
O valor imediato estendido é somado a PC + 4, para uso em branches, o que não ocorre
nesse caso. Os valores 2 e 3 são definidos como entradas da ALU, de onde sai o resultado
5 em ALU result, sendo salvo no registrador EX/MEM.
• 4º Estágio – MEM
O valor salvo em EX/MEM correspondente ao ALU result é salvo no registrador MEM/WB. A
saída do EX/MEM correspondente ao endereço calculado do branch é ignorada, afinal o mux
está configurado para receber o valor de PC + 4. MemRead e MemWrite estão configurados
para 0, pois não há operação com a Data Memory.
• 5º Estágio – WB
O Mux é configurado para redirecionar o resultado da ALU do MEM/WB para o Write Data, e
o Write register é configurado como 8, o t0.

b) 5 ciclos.

2.
a) Escolhi o endereço 8001fffc, e o conteúdo lá é o número 1

• IF
Efetuado PC + 4 e lida a instrução da Instruction Memory, ambos são salvos em IF/ID.
• ID
Com a instrução obtida, ela é então dividida para as entradas do IR e sign-extend, com rs =
t1 e rt = t0. rs e o valor imediato estendido são salvos no registrador ID/EX.
• EX
O valor imediato estendido é somado a PC + 4, para uso em branches, o que não ocorre
nesse caso. Os valores de rs e o offset (imediato) são definidos como entradas da ALU, de
onde sai o resultado da soma de rs e offset, resultando no endereço a ser consultado na
memória. Os valores são salvos no registrador EX/MEM.
• MEM
O valor resultante do endereço salvo em EX/MEM é usado para ler a Data Memory naquele
endereço, MemRead é configurado para 1 para poder ler da memória, o valor lido (1) é salvo
em MEM/WB. A saída do EX/MEM correspondente ao endereço calculado do branch é
ignorada, afinal o mux está configurado para receber o valor de PC + 4.
• WB
O MUX é configurado para ter como fonte o resultado da leitura da memória, esse valor é
encaminhado para o Write Data. Com RegWrite = 1 e Write Register 08 = t0, salvamos o
valor lido da memória (1) em t0.

b) É feita a operação de soma do endereço base com o offset, que nesse caso era zero.

c) 5 ciclos.

d) Sim.

e)

a)

• IF
Efetuado PC + 4 e lida a instrução da Instruction Memory, ambos são salvos em IF/ID.
• ID
Com a instrução obtida, ela é então dividida para as entradas do IR e sign-extend, com rs =
t1 e rt = t0. rs e o valor imediato estendido (0004) são salvos no registrador ID/EX.
• EX
O valor imediato estendido é somado a PC + 4, para uso em branches, o que não ocorre
nesse caso. Os valores de rs e o offset (imediato) são definidos como entradas da ALU, de
onde sai o resultado da soma de rs e offset, resultando no endereço a ser sobrescrito na
memória. Além disso, temos o dado a ser salvo, que estava em rt. Os valores são salvos no
registrador EX/MEM.

2
• MEM
O valor resultante do endereço salvo em EX/MEM é usado para escrever na Data Memory
naquele endereço, e o valor salvo em EX/MEM vindo de rt com os dados é colocado em
Write Data. MemWrite é configurado para 1 para poder escrever na memória. A saída do
EX/MEM correspondente ao endereço calculado do branch é ignorada, afinal o mux está
configurado para receber o valor de PC + 4.
• WB
Como RegWrite = 0, nada de relevante acontece.

b) É feita a operação de soma do endereço base com o offset, que nesse caso era 0004.

c) 4 ciclos.

d) Não, pois o estágio Write Back to Register não é utilizado.

f)

a)

• IF
Efetuado PC + 4 e lida a instrução da Instruction Memory, ambos são salvos em IF/ID.
• ID
Com a instrução obtida, ela é então dividida para as entradas do IR e sign-extend, com rs =
t1 e rt = t0. rs e o valor imediato estendido (0004) são salvos no registrador ID/EX.
• EX
O valor imediato estendido multiplicado por 4 é somado a PC + 4, para uso no branch. Rt é
selecionado no MUX para ser a entrada da ALU para ser efetuada a comparação com rs. O
resultado está na flag zero. Os valores são salvos no registrador EX/MEM.
• MEM
Resultado do branch salvo no EX/MEM é efetivamente escrito em PC e a memória não é
mexida pois MemWrite e MemRead = 0.
• WB
Como RegWrite = 0, nada de relevante acontece.

b) É feita a operação de comparação de rs com rt, o resultado é colocado na flag 0.

c) 4 ciclos.

d) Não, pois o estágio Write Back to Register não é utilizado.

3
3.
a) 5 ciclos.

b) 3 ciclos.

c) A segunda instrução add necessita do resultado da primeira instrução add, acontece que esse
resultado só está disponível depois, o que acaba por entregar o resultado errado. Para resolver isso
podemos usar a técnica de forwarding.

d) OK.

e) Sim, porque o simulador sugerido conta com o recurso de forwarding, que adianta o valor
necessário antes mesmo de escrever no registrador de destino.

4.
a) 7 ciclos.

b) Executa normalmente através do pipeline, um estágio atrás do branch.

c) O problema é que a instrução de add vai ser executada mesmo que o branch não seja satisfeito.
Para solucionar, podemos usar soluções de hardware ou bolhas.

d) O programa mais uma vez executou incorretamente, executando o add quando não deveria, pois
o branch deveria levar para start.

5.
a) 6 ciclos.

b) Deveria estar disponível no 5º ciclo.

c) A instrução sub precisa de t1 antes do valor estar disponível, o que leva a efetuar o cálculo
incorreto. Para resolver isso, poderíamos usar, assim como sugerimos anteriormente, soluções de
hardware ou bolhas.

4
d) O resultado não foi o que deveria acontecer numa execução correta. Aparentemente o simulador
está com algum defeito, ele subtraiu t2 de t3 ao invés de usar t1. Vale notar que não é a primeira
vez que o simulador apresentou comportamento inesperado, na questão 4 também.

6.
a) O programa dado não compila no MipsIT, procurando na internet, achei uma versão do mesmo
código que compila, mesmo assim, os já observados defeitos do MipsPipeXL não executaram o
código corretamente. Sendo assim, para pelo menos descobrir o que o programa faz com mais
facilidade, executei com o simulador padrão, Mips.exe, sem pipeline.

O que observamos em primeira análise é que é um programa que ordena um vetor de palavras. Ao
final da execução, o vetor de palavras A está ordenado em ordem crescente. Executando passo a
passo para entender como o código funciona, observamos que se trata de um dos mais triviais
algoritmos de ordenação, o bubble sort. Ele foi facilmente identificado pelos dois loops aninhados
presentes no código e as condições para fazer o swap, as características mais marcantes do bubble
sort. Determinei um código equivalente em Python:
def swap(s1, s2):
return s2, s1

a = [5, 6, 2, 3, 1]

for i in range(len(a)):
for j in range(i, len(a)):
if a[i] > a[j]:
a[i], a[j] = swap(a[i], a[j])
print(*a)

De forma simples, para determinar a corretude, observei o número de vezes que cada loop, interno
e externo, foi executado. Em ambos programas, o loop interno foi executado 15 vezes e o externo
5 vezes, o que confirma a corretude.

b-d) Não é possível fazer pois o programa não compilou e mesmo a versão encontrada na internet
não funcionou corretamente no MipsPipeXL.

e) Embora não tenhamos conseguido executar o programa, eu acredito que a versão com resolução
de conflitos rodaria mais rápido, porque seriam muito menos bolhas. Mas, é só um chute mesmo.
Tem casos em que a execução serial é mais rápida que a execução concorrente com resolução de
conflitos. Para uma verdadeira análise, precisaríamos executar os códigos.

Potrebbero piacerti anche