Práctica 3


Esta práctica se compone de tres partes, en la primera de ellas, veremos como se codifican diferentes instrucciones de la forma que quedarían en memoria y sean procesables por el ordenador, esto será una secuencia en binario de las diferentes partes de cada instrucción. Continuaremos viendo las señales que son necesarias generar para efectuar dichas operaciones por la ALU y unidad de control, y por último, utilizando el programa Logisim, con una CPU real, donde recrearemos todas estas instrucciones para visualizar la secuencia de pasos.

Primera parte:


Para codificar las instrucciones, necesitaremos saber el tipo de instrucción que estamos tratando (tipo R, I o J), como está estructurada y numero de bits que corresponden a cada parte. Para ello haremos uso de el siguiente documento de referencia, Apendice Hennessy Patterson. En dicho documento, buscaremos la instrucción que nos interese y veremos algo como lo siguiente:

En la parte izquierda vemos como se emplea la instrucción add normalmente. Consta de tres registros, de los cuales, los llamados rs y rt se sumarán, guardando el resultado de la suma en el registro llamado rd.
En la pequeña tabla vemos como codificaríamos la instrucción en memoria y debajo el numero de bits de cada parte.
Debemos notar que aunque la instrucción tenga un determinado orden de los registros al escribirse, cuando la codificamos en memoria el orden de los mismo varía. Es decir, el registro rd pasa a tercer lugar, rs al primero y rt al segundo. Por otra parte, vemos que la primera celda consta 6 bits a cero (operación de tipo aritmética) y la última celda con el número hexadecimal es el código de la operación (en este caso una suma).

Con esto sabemos como está estructurada nuestra instrucción, pero aun necesitamos saber el numero que corresponde a cada registro. Pongamos un ejemplo, en la instrucción add $t0, $s1, $s3, necesitamos conocer el número de los registros $t0, $s1 y $s3 (no hay que confundir con el valor). Para ello, en la práctica se nos proporciona una tabla donde podemos consultarlo, aunque también podemos hacerlo en el mismo documento de referencia que hemos empleado para las instrucciones.



Por lo que vemos, el registro $t0 es el número 8, el registro $s1 es el número 17 y el registro $s3 es el número 19 (deberemos pasarlos a binario).

Ya tenemos todos los datos necesarios para formar nuestra instrucción:
  • 1) 6 bits: 000000
  • 2) 5 bits: rs = $s1 = 17 = 10001
  • 3) 5 bits: rt = $s3 = 19 = 10011
  • 4) 5 bits: rd = $t0 = 8 = 01000
  • 5) 5 bits: 00000
  • 6) 6 bits: 0x20 = 100000

Ordenada en memoria sería: 00000010001100110100000000100000
Y convertida a hexadecimal: 0x02334020

Emplearemos el mismo método para todas las instrucciones, teniendo en cuenta como están formadas las mismas según el tipo que sean.

Segunda parte:


En esta parte debemos indicar la secuencia de transferencia y acciones que se realizan para cada una de las instrucciones basándonos en la CPU que nos proporciona la práctica.



Debemos tener en cuenta para empezar, que el ciclo de captación de instrucción (FETCH) se realiza siempre, para todas las instrucciones que realiza la CPU. Por lo tanto la incluiremos en todas las instrucciones.
Primero se carga en MAR la dirección de la instrucción que se va a ejecutar, la cual está en el contador de programa, después se incrementa en contador de programa para dejar preparada la siguiente instrucción y se guarda en MBR la instrucción codificada que corresponde a la dirección que había en MAR, por ultimo se carga en el registro de instrucción la propia instrucción que teníamos en MBR. Después de esto se produce la decodificación de la instrucción. Podríamos decir que las transferencias serían:

S1: MAR ß PC
S2: PC ß PC + 4 | MBR ß MP
S3: RI ß MBR
S4: Decodificación

Todo esto en lenguaje de señales quedaría de la siguiente manera:

S1: T4, C1
S2: Td, L, C4, C2
S3: T3, C6
S4: -------------------

A partir de este punto veríamos en que consiste nuestra instrucción, que registros están involucrados y que datos están haciendo uso de un determinado bus en un determinado momento.
En nuestro ejemplo queremos utilizar la instrucción add $t0, $s1, $s3, es decir:

R8($t0) ß R17($s1) R19($s3)

¿Que señales necesitaríamos para realizar esta acción?
Debemos fijarnos en la CPU que nos han dado, lo primero es seleccionar con RA y RB los registros R17 y R19, después indicaremos en los multiplexores MA y MB un cero, para que tome el dato directamente y no el de los registros RT1 y RT2, continuaremos indicando la operación que vamos a realizar (una suma), tomaremos el resultado directamente sin pasar por el registro RT3 abriendo el triestado T5, seleccionaremos el registro en el que vamos a guardar el resultado con RC, en este caso el R8 y por ultimo activaremos la carga con SC:

RA = R17, RB = R19, MA = 0, MB = 0, OP = SUMA, T5, RC = R8, SC

Debemos tener en cuenta que no todas las operaciones pueden realizarse directamente como esta, en algunas tendremos que guardar los valores en registros intermedios para dejar libre el bus, en otras tomaremos datos del registro de instrucción y en otros modificaremos el contenido de PC, por lo tanto utilizaremos mas señales y más ciclos.

Resolución de la práctica:

a) ADD $t0, $t1, $t2

add rd, rs, rt

Instrucción tipo R
Mnemónico
ADD
rs=$t1
rt=$t2
rd=$t0
0
0x0020
Binario
.000000
.01001
.01010
01000
00000
100000

Hexadecimal
0x012A4020

En este ejercicio, las señales que tendremos que generar serán como en ejemplo que se ha dado anteriormente, únicamente varían los registros que utilizaremos. Recordemos que debemos incluir siempre la fase de captación en todas las instrucciones.

Lenguaje de transferenciasLenguaje de señales
S1:MAR ß PC
S2: PC ß PC+4, MBR ß MP
S3 :RI ß MBR
S4 : Decodificación
S5: R8 ß R9+R10
S1: T4, C1
S2: Td, L, C4, C2
S3: T3, C6
S4: ----------------
S5: RA=(R9), RB=(R10), MA=0, MB=0, OP=(SUMA), T5, RC=(R8), SC

b) ADDI $s0,$s1, 0x0011

addi rt, rs, imm

Instrucción tipo I
Mnemónico
ADDI
rs=$s1
rt=$s0
0x0011
Binario
.001000
10001
10000
0000000000001011

Hexadecimal
0x2230000B

En esta instrucción utilizaremos un valor inmediato. Este valor inmediato lo sacaremos de la propia instrucción, es decir, tendremos que sacar ese valor del registro de instrucción (RI) y llevarlo a los registros RT1 o RT2 para utilizarlos posteriormente en la suma.

Lenguaje de transferencias
Lenguaje de señales
S1:MAR ← PC
S2: PC ← PC+4, MBR ← MP
S3:RI ← MBR
S4: Decodificación
S5: RT2 ← RI
S6: R16 ← R17+RT2
S1: T4, C1
S2: Td, L, C4, C2
S3: T3, C6
S4: -----------------
S5: T8, C10
S6: RA=1(R17),OP=(SUMA), MA=0, MB=1, T5, RC=(R16), SC

c) ORI $t0, $t2, 0x00A1

ori rt, rs, imm

Instrucción tipo I
Mnemónico
ORI
rs=$t2
rt=$t0
0x00A1
Binario
001101
01010
01000
0000000010100001

Hexadecimal
0x354800A1

En este caso realizaremos una operación OR entre un valor de un registro y un valor inmediato, nuevamente tendremos que tomar la parte del valor inmediato del registro de instrucción y llevarlo a un registro intermedio (RT1 o RT2) para realizar la operación OR.

Falta terminar
Lenguaje de transferencias
Lenguaje de señales
S1:MAR ← PC
S2: PC ← PC+4, MBR ← MP
S3:RI ← MBR
S4: Decodificación 
S5: RT2 ← RI
S6: R8 ← R10 OR RT2
S1: T4, C1
S2: Td, L, C4, C2
S3: T3, C6
S4: -----------------
S5: T8, C10
S6: RA=R10, MA=0, MB=1, OP=OR, T5, RC=R8, SC

d) SLL $t0, $t0, 0x0002

sll rd, rt, shamt

Instrucción tipo R
Mnemónico
SLL
rs
rt=$t0
rd=$t0
shamt=0x0002
0
Binario
.000000
.00000
01000
01000
00010
000000
Hexadecimal
0x00084080

SLL es una operación de tipo desplazamiento, la cual desplazará un numero de bits a la izquierda. Primero debemos obtener el número de bits que van a desplazarse del registro de instrucción y guardarlo en un registro intermedio (por ejemplo RT1). Normalmente realizaríamos la operación directamente leyendo del registro que vamos a desplazar los bits y escribiendo en otro, pero en este caso, el registro del que leemos y en el que vamos a escribir es el mismo, por lo que tendremos que guardar el resultado de la operación en el registro RT3 para dejar libre el bus. Una vez aquí el dato ya podremos guardarlo en el registro destino en el siguiente ciclo de reloj.


Lenguaje de transferencias
Lenguaje de señales
S1:MAR ← PC
S2: PC ← PC+4, MBR ← MP
S3:RI ← MBR
S4: Decodificación
S5: RT2 ← RI
S6: RT3 ← R8 SLL RT2
S7: R8 ← RT3 
S1: T4, C1
S2: Td, L, C4, C2
S3: T3, C6
S4: -----------------
S5: T8, C10
S6: RA=(R8), OP=(SLL), MA=0, MB=1, C11
S7: T6, RC=(R8), SC 

e) SLR $t1, $t0, 0x0002

srl rd, rt, shamt

Instrucción tipo R
Mnemónico
SRL
rs
rt=$t0
rd=$t1
shamt=0x0002
0x2
Binario
.000000
.00000
01000
01001
00010
000010
Hexadecimal
0x00084882

SLR es una operación de tipo desplazamiento, pero en este caso los bits se desplazan a la derecha. El planteamiento del problema es exactamente igual que en el ejercicio anterior, solo que esta vez no necesitaremos guardar el resultado de la operación en RT3 porque el registro del que se lee el dato y el que se guarda es distinto.


Lenguaje de transferencias
Lenguaje de señales
S1:MAR ← PC
S2: PC ← PC+4, MBR ← MP
S3:RI ← MBR
S4: Decodificación
S5: RT2 ← RI
S6: R9 ← R8+RT2 
S1: T4, C1
S2: Td, L, C4, C2
S3: T3, C6
S4: -----------------
S5: T8, C10
S6: RA=(R8), OP=(desplazamiento), MA=0, MB=1, T5, RC=(R9), SC     

f) LUI $s0,0x0011 HAY QUE REVISAR ESTA INSTRUCCIÓN

lui rt, imm

Instrucción tipo I
Mnemónico
LUI
0
rt=$s0
0x0011
Binario
001111
00000
10000
0000000000001011

Hexadecimal
0x3C10000B

Esta operación, carga el valor inmediato que se le especifica en la parte alta del registro que le indicamos.


Lenguaje de transferencias
Lenguaje de señales
S1:MAR ß PC
S2: PC ß PC+4, MBR ß MP
S3 :RI ß MBR
S4 : Decodificación
S5: MAR ß RI
S6: MBR ß MP
S7: R16 ß MBR 
S1: T4, C1
S2: Td, L, C4, C2
S3: T3, C6
S4: -------------------
S5: T8, C1
S6: Td, L, C2
S7: RC(R16), SC     

g) SW $t4, 0x0111

sw rt, address

Instrucción tipo I
Mnemónico
SW
rs=0
rt=$t4
0x00A1
Binario
001101
00000
01101
0000000001101111

Hexadecimal
0x340D006F

Esta instrucción guarda en la dirección que le indicamos el dato que se encuentra en el registro que escribimos como primer parámetro. Por lo tanto, esta instrucción es un poco diferente a las anteriores. Primero tendremos que guardar en el registro MAR la dirección que tenemos en el registro de instrucción, después guardaremos en el registro MBR el dato que hay en el registro $t4 y por último, escribiremos en memoria principal, el dato que hay en el registro MBR en la dirección que indica el registro MAR.

Lenguaje de transferencias
Lenguaje de señales
S1:MAR ß PC
S2: PC ß PC+4, MBR ß MP
S3 :RI ß MBR
S4 : Decodificación
S5: MAR ß RI
S6: MBR ß R12
S7: MP ß MBR
S1: T4, C1
S2: Td, L, C4, C2
S3: T3, C6
S4: -------------------
S5: T8, C1
S6: RA(R12), T1, C3
S7: Td, Ta, E

h) SLT $t1, $t2, $t0

slt rd, rs, rt

Instrucción tipo R
Mnemónico
SLT
rs=$t2
rt=$t0
rd=$t1
0
0x002a
Binario
.000000
01010
01000
01001
00000
101010

Hexadecimal
0x0148482A

Esta instrucción realiza una comparación, si $t2 es menor que $t0, pone a 1 $t1, si es al contrario, pone a 0 $t1. No varía en nada con respecto a una operación ADD con respecto a señales se refiere.

Lenguaje de transferencias
Lenguaje de señales
S1:MAR ß PC
S2: PC ß PC+4, MBR ß MP
S3 :RI ß MBR
S4 : Decodificación
S5: R9 ß R10 slt R8
S1: T4, C1
S2: Td, L, C4, C2
S3: T3, C6
S4: -------------------
S5: RA(R10), RB(R8), OP(SLT), MA(0), MB(0), T5, RC(R9), SC

i) J 0x000001A

j dir

Instrucción tipo J
Mnemónico
J
0x000001A
Binario
000010

00000000000000000000011010
Hexadecimal
0x0800001A

Está es una instrucción de tipo salto. Modificará el contenido del contador de programa (PC) para que se ejecute una instrucción determinada en vez de la que tocaría a continuación. Asi que simplemente cogeremos del registro de instrucción la dirección de la siguiente instrucción y la guardaremos en el registro PC.

Lenguaje de transferencias
Lenguaje de señales
S1:MAR ß PC
S2: PC ß PC+4, MBR ß MP
S3 :RI ß MBR
S4 : Decodificación
S5: PC ß RI
S1: T4, C1
S2: Td, L, C4, C2
S3: T3, C6
S4: -------------------
S5: T8, C5

j) JR $S0

jr rs

Instrucción tipo J
Mnemónico
JR
rs=$s0
0
0x8
Binario
000000
10000
000000000000000
001000

Hexadecimal
0x02000008

Esta instrucción es parecida a la anterior con la diferencia de que la dirección no se obtiene del registro de instrucción, sino de un registro del banco de registros que hemos indicado. Simplemente modificaremos el contenido de PC con el valro de este registro.

Lenguaje de transferencias
Lenguaje de señales
S1:MAR ß PC
S2: PC ß PC+4, MBR ß MP
S3 :RI ß MBR
S4 : Decodificación
S5: PC ß R16
S1: T4, C1
S2: Td, L, C4, C2
S3: T3, C6
S4: -------------------
S5: RA(R16), T1, C5

Tercera parte:

a) ADD $t0, $t1, $t2

1) Primero ponemos en la memoria el valor inmediato 01001 ($t1).



2) Seleccionamos el banco de memoria y habilitamos el triestado (TD).



3) Activamos la lectura de la memoria y ya aparece visible en el bus de datos.


4) Capturamos el dato en MBR seleccionando doblemente C2.


5) Luego lo pasamos al bus interno seleccionando el triestado (T3).


6) Capturamos el dato en el banco de registro, nosotros lo hemos hecho en la captura 3.


7) Comprobamos que en el registro 3 se ha cargado el dato.


8) Cambiamos el registro a la posición 4.


9) Cambiamos el contenido de la dirección a 01010 ($t2).


10) Desactivamos el triestado (T3).


11) Habilitamos el triestado (TD).


12) Hacemos un flaco en C2.


13) Luego lo pasamos al bus interno seleccionando el triestado (T3).


14) Hacemos un flanco en SC.


15) Desactivamos el triestado (T3).



16) Vemos que en el registro cuatro, está ya el dato capturado.


17) Ya tenemos un dato en el registro tercero (RA=01001) y otro en el cuarto (RB=01010), por lo tanto, ya podemos operar en la ALU, mediante los multiplexores (MA, MB).


18) Ya podemos ver la salida de la suma (SALIDA ALU) y para capturar el dato de salida en uno de los registros, tenemos que llevar el dato de salida hasta el bus interno activando el triestado (T5).


19) Ya podemos ver el dato en el bus interno y por lo tanto, lo podemos capturar en el banco, seleccionamos el registro donde lo queremos guardar, un nuestro caso, será el registro cinco ($t0) y hacemos una captura en SC.


20) Al final vemos que en el registro cinco ($t0), se ha guardado el resultado que ha salido de la ALU.


El resto de apartados se harían de la misma forma y pongo en este enlace todas las fotos por si no se ven bien.

No hay comentarios:

Publicar un comentario

 

Blogger news

Visitas al Blog

Blogroll

About