lunes, 27 de mayo de 2013

Practica 5: Memorias.


Práctica Tema 5: Sistema de memorias.

Duración: Dos sesiones.

Herramientas: Simulador LOGISIM, Práctica de memorias (Colgado en Campus Virtual).

Descripción: Durante la práctica se harán los 5 problemas propuestos que hay en el
pdf. Estos ejercicios consisten en aprender a usar dos componentes muy importante
del Logisim, los componentes RAM y ROM. En el pdf antes de pedirte que realice los
ejercicios, te describe cómo funciona estos dos componentes, básicamente te dicen el
comportamiento que tienen y el funcionamiento de los pines de estos componentes.
Para terminar está explicación previa a los ejercicios, te describen como modificar los
conteniendo de memoria utilizando la herramienta de cambio. Estas herramientas las
puestas utilizar de dos formas distintas, o bien para editar y consultar valores del
circuito o para editar la dirección que se visualiza.

Tras la introducción pasemos a los ejercicios:

Para empezar para crear una memoria RAM, tenemos que buscar en el menú y
seleccionar la herramienta ¨memoria¨ y luego ¨RAM¨.

En la RAM poseemos 4 pines que son:
-¨Sel¨, es el selector, permite elegir cual chip vamos a utilizar para la lectura de
datos en caso de poseer más de un chip.
-¨Triángulo¨, permite carga de escritura o datos.
-¨Out¨, significa lectura de datos.
-¨Clr¨, sirve para resetear el contenido de la memoria.

En el primer ejercicio nos pide introducir una memoria RAM de 64Kx8 y realizar un
circuito que permita leer y escribir en ella. En la imagen vamos a ver como se compone
la RAM.






En el ejercicio 2 como ya hemos dicho antes, la memoria es de 64Kx8, sabemos que el
bus de datos tiene que ser de 8bits, y el bus de direcciones realizando la operación:

64K = 2^10*2^6(1K*64)=2^16

Nos sale que el bus de direcciones ha de ser de 16 bits.

Luego en el siguiente ejercicio nos pide un aumento de memoria, por ejemplo 64Kx16,
para que el bus de direcciones que calculamos antes sea el mismo (16). La cantidad de
memoria direccionable sigue siendo 64K. Una vez dicho esto pasamos a explicar que
significa el ¨x16¨ ya que antes era ¨x8¨, esto sirve para indicar como es la
entrada/salida de datos. La única diferencia es que como antes teníamos una salida de
8bits(x8), y como ahora es el doble pues tendremos otro chip adicional de 64x8, por lo
cual si sumamos las salidas de datos de las memorias, tenemos los 16bits(x16) que es
lo que queríamos.

Ahora un detalle, como tenemos dos chips por ejemplo, para referirnos a uno u otro
cuando tomamos o escribimos un datos, simplemente nos referiremos a ellos dos
como uno, es decir que si seleccionamos uno, también seleccionamos el otro.

En el ejercicio 3 nos pide que ampliemos la memoria a 128Kx16, ¿Cómo realizamos
esta ampliación de memoria?







El bus de datos sigue siendo de 16 bits, tal y como dijimos en el ejemplo anterior
tenemos 2 chips de 64x8 como poco, y si 128K= 64K * 2, pues necesitaremos el doble
que antes, es decir, 4 chips. Estos 4 chips van conectados al mismo bus de direcciones
y de datos. Quedaría tal y como viene en la imagen.






Otro pequeño detalle, una diferencia entre intercambiar RAM por ROM, en la ROM sólo
tenemos 3 pines (en la RAM teníamos 4 pines).Para esta diferencia sólo hay que
sustituir la línea de cables donde corresponda.

Los ejercicios 4 y 5 se realiza de la misma manera que los ejercicios que ya hemos hecho.En el ejercicio 4 nos pide ampliar la memoria hasta 256Kx16. Quedaría tal y como viene en la siguiente imagen.



Para finalizar, en el ejercicio 5 nos pide transformar la estructura del anterior punto para que los primeros 64K sean de memoria ROM , quedaría tal y como viene en la siguiente imagen.



Dificultades: La dificultad de esta práctica dependerá del manejo que poseas con el
Logisim, pero si sabe la teoría y sabes manejar el Logisim, es una práctica no muy
difícil, ya que en el pdf dónde vienen los ejercicios de esta práctica te van indicando
todo lo que tienes que hacer.


FAQs:

¿ Donde puedo encontrar la RAM ?
En el menú, pinchamos en la carpeta memoria y seleccionamos la RAM.

¿ Donde puedo encontrar la ROM ?
En el menú, pinchamos en la carpeta memoria y seleccionamos la ROM.

¿ Para que sirven los pines de la RAM ?
-¨Sel¨, es el selector, permite elegir cual chip vamos a utilizar
para la lectura de datos en caso de poseer más de un chip.
-¨Triángulo¨, permite carga de escritura o datos.
-¨Out¨, significa lectura de datos.
-¨Clr¨, sirve para resetear el contenido de la memoria.

¿ Como cambio los bit de datos o direcciones de la RAM o ROM ?
Pinchas sobre ella, y en el menú que se desplegá a la izquierda puedes encontrar ambas.

¿ Que significa ancho incompatible y como lo soluciono ?
Debes revisar las dos piezas indicadas ya que el numero de bits de datos sera distinto
en estas piezas

¿ Como hago que un pin sea tri-estado ?
Pinchas sobre el y en el menú que se desplegá a la izquierda puedes encontrar “¿ tres-estados”
solo tienes que marcar si.

¿ Como consigo unir varias salidas en una sola entrada o al contrario ?
En el panel del explorador vais a wiring dentro encontrareis una pieza llamada
separador.

Práctica 4: Unidad de control

Práctica 4
Por Iván Piña Arévalo.
En esta práctica utilizaremos el programa Logisim, que podemos obtener a través del campus virtual. El principal objetivo de esta práctica es que el alumno realice las funciones de la unidad de control, Esta práctica consta de tres actividades.
Sean las siguientes instrucciones:
a)  ADD $t0, $t1, $t2
b)  ADDI $s0,$s1, 0x0011
c)  ORI $t0, $t2, 0x00A1
d)  SLL $t0, $t0, 0x0002
e)  SLR $t1, $t0, 0x0002
f)  LUI $s0, 0x0011
g)  SW $t4, 0x0111
h)  SLT $t1, $t2, $t0
i)  J 0x000001A
j)  JR $S0
1- Traducir a lenguaje hexadecimal.
En esta actividad se nos pide traducir al lenguaje hexadecimal, este apartado ya lo desarrollamos en el tema 2, lenguaje ensamblador “MIPS”
Por este motivo no nos explayaremos demasiado con el fin de no aburrir a los usuarios. Aún así, es importante recordar que para traducir la instrucción a lenguaje hexadecimal, debemos tener en cuenta el tipo de instrucción (R, I, J) ya que su tipo determinara la estructura de la instrucción. Estos formatos responden a las siguientes estructuras.


1)       ADD $t0, $t1, $t2
Hexadecimal: 0x012A4020
Suma el contenido de los registros $t1 y $t2 y almacena el resultado en $t0.
2)        ADDI $s0,$s1, 0x0011
Hexadecimal: 0x22300011
Suma $s1 y 0x0011 y almacena el resultado en $s0.
 
3)      ORI $t0, $t2, 0x00A1
Realiza una operación OR entre $t2 y 0x00A1, almacenando el valor en $t0.
Hexadecimal: 0x354800A1

4)        SLL $t0, $t0, 0x0002
Esta instrucción realiza un desplazamiento lógico a la izquierda en $t0, 0x0002 es el número de que indica las rotaciones a realizar, almacenándose el resultado de la operación en el registro $t0.
Hexadecimal: 0x0084080

5)        SLR $t1, $t0, 0x0002
Esta operación realiza un desplazamiento lógico hacia la derecha con el contenido del registro $t0, 0x002 es el valor que indica el número de posiciones a rotar. El resultado del desplazamiento se almacena en $t1.
Hexadecimal: 0x00084882


6)        LUI $s0,0x0011
Esta instrucción carga un valor inmediato (en este caso 0x0011) en el registro $s0.
Hexadecimal: 0x3C100011

7)        SW $t4, 0x0111
Esta instrucción toma el valor inmediato como una dirección de memoria y la almacena en $t4. Esta instrucción es de tipo I
Hexadecimal: 0xAC0C0111

8)        SLT $t1, $t2, $t0
Esta instrucción comprueba si el registro $t2 es menor que el registro $t0.
Por tanto si t2<t0 à t1=1 (Si el contenido del registro t2 es menor que el registro t0 en t1 se guarda un 1, y si t2>=t0 à t1=0 (si el contenido del registro t2 es mayor o igual que el registro t0 en t1 se guarda un 0.
Hexadecimal: 0x0148482A

9)        J 0x000001A
Esta instrucción carga un valor inmediato en el registro contador de programa.
Hexadecimal: 0x00800001A



10)   JR $S0
Esta instrucción carga en PC el contenido del registro $s0.  
Hexadecimal: 0x0200001A

2- Utilizando la CPU descrita en clase teórica y el lenguaje de transferencia de registro, realizar la secuencia de transferencias y acciones.

 
       ADD $t0, $t1, $t2    


S1: MAR ← PC
T4, C1
S2: PC ← PC+4
C4
S2: MBR ← MP
Td, L, C2
S3: RI ← MBR
T3, C6
S4: Decodificación

S5:RT3 <- RA+RB
RA=01001, MA=0
RB=01010, MB=0
OP= ADD, C11
S6: RC ← RT3  (“envía al registro el resultado de la operación)
T6, RC=01000, SC=0
S7: Ciclo de comprobación de interrupciones










      ADDI $s0,$s1, 0x0011     


S1: MAR ← PC
T4, C1
S2: PC ← PC+4
C4
S2: MBR ← MP
Td, L, C2
S3: RI ← MBR
T3, C6
S4: Decodificación

S5: RT2←RI
T8,C10
S6: Rt3 ← RT2 + R17
RA=10001, MA=0, MB=1
OP= ADD, C11
S7: RC ← RT3
T6, RC=S0, SC
S8:Ciclo de comprobación de interrupciones



            ORI $t0, $t2, 0x00A1  


S1: MAR ← PC
T4, C1
S2: PC ← PC+4
C4
S2: MBR ← MP
Td, L, C2
S3: RI ← MBR
T3, C6
S4: Decodificación

S5: RT3 ← RI(0x00A1) OR R10
T8, C10,  MB=1, C11
S6: RC ← RT3
T6, RC= 01000, SC
S8: Ciclo de comprobación de interrupciones


 

       SLL $t0, $t0, 0x0002 
Instrucciones
Señales
S1: MAR ← PC
T4, C1
S2: PC ← PC+4
C4
S2: MBR ← MP
Td, L, C2
S3: RI ← MBR
T3, C6
S4: Decodificación

S5: RT2 ← RI
T8, C10
S6: ALU ← RT2
MB=1
S7: RT3← $t0 SLL RT2
RA=01000, MA=0
S8: RC ←RT3
T6, RC=01000, SC
S9: Ciclo de comprobación de interrupciones





        SLR $t1, $t0, 0x0002
 Instrucciones
Señales
S1: MAR ← PC
T4, C1
S2: PC ← PC+4
C4
S2: MBR ← MP
Td, L, C2
S3: RI ← MBR
T3, C6
S4: Decodificación

S5: RT2 ← RI (0x0002)
T8, C10
S6: RT3 ← RT2 SLR R0
Código operación=OR, MA=0, MB=1
S7: RC ← RT3
T6, RA=01001, SC  
S8: Ciclo de comprobación de interrupciones. 







f          LUI $s0,0x0011  
Instrucciones
Señales
S1: MAR ← PC
T4, C1
S2: PC ← PC+4
C4
S2: MBR ← MP
Td, L, C2
S3: RI ← MBR
T3, C6
S4: Decodificación

S5: RC ← RI (0x0011)
T8, RC=10000,SC
S6: Ciclo de comprobación de interrupciones


 
 
g        SW $t4, 0x0111
Instrucciones
Señales
S1: MAR ← PC
T4, C1
S2: PC ← PC+4
C4
S2: MBR ← MP
Td, L, C2
S3: RI ← MBR
T3, C6
S4: Decodificación

S5: MAR ← RI (0x0111)
T8, C1
S6: MBR ← MP
TD, C2
S7: RC ← MBR
T3, RC= 01100  SC
S8: Ciclo de comprobación de interrupciones








        J 0x000001A
Instrucciones
Señales
S1: MAR ← PC
T4, C1
S2: PC ← PC+4
C4
S2: MBR ← MP
Td, L, C2
S3: RI ← MBR
T3, C6
S4: Decodificación

S5: PC ← RI(0x000001A)
T8
S6: Ciclo de reconocimiento de interrupciones.


i             JR $S0
Instrucciones
Señales
S1: MAR ← PC
T4, C1
S2: PC ← PC+4
C4
S2: MBR ← MP
Td, L, C2
S3: RI ← MBR
T3, C6
S4: Decodificación

S5: PC ← $s0
RA=10000, T1, C5
S6: Ciclo de comprobación de interrupciones


3-  Simular las instrucciones con nuestra ALU.
En este apartado explicaremos como realizar  este ejercicio de la forma más sencilla y correcta. Comenzaremos relatando como realizar el primer ciclo de la instrucción (es común para todas las instrucciones).
Para comenzar debemos abrir el triestado T4 (para obtener la dirección de memoria donde se encuentra la instrucción). Despues de haber abierto T4, activamos la señal de carga del registro MAR (Mar se comunica con memoria, por lo que en la dirección de memoria que le hemos enviado a MAR se encuentra la instrucción, la instrucción se encuentra en memoria codificada en hexadecimal). Despues de este paso, abriremos la memoria en modo lectura, de esta forma, la instrucción se almacena en el registro MBR. A la vez, deberemos activar la señal de carga del contador (C4) para sumar un ciclo y poder pasar a la siguiente instrucción.
Por último, la instrucción almacenada en MBR deberemos enviarla al registro RI, para hacerlo debemos activar el triestado T3 (envía al bus el contenido de MBR) y la señal de carga de RI (C6). El último ciclo se emplea para la decodificación de la instrucción, por lo que no es necesario realizarlo nosotros.

a)      ADD $t0, $t1, $t2
Para realizar esta operación, deberemos llevar los datos a la Unidad Aritmetico Logica, por lo que debemos sacarlos del banco de registro, para ello, seleccionamos los registros empleando RA y RB respectivamente, después debemos activar a  0 los multiplexores A y B (esto significa que los datos provienen del banco de registros, si viniesen de los registros  temporales, habría que colocarlos a 1).  Ya tenemos los datos en la ALU, pero falta el código de operación, por lo que habremos de seleccionar en este caso el valor que haga referencia a la operación suma (los valores de operación pueden variar de una ALU a otra). Por último, almacenaremos el resultado en el registro $t0, para esto, activamos la señal T5 para enviar el resultado al bus de datos, simultáneamente, seleccionamos el registro $t0 con la señal RC y cargamos el resultado obtenido de la ALU con la señal SC.
b)      ADDI $s0, $s1, 0x0011
En esta operación simplemente debemos sumar el valor 0x0011 y el valor contenido en $s1, almacenando el resultado en $s0. En el ciclo de captación ya hemos dispuesto 0x0011 en el registro RI.
Lo primero a realizar será enviar el dato de RI  a un registro temporal (por ejemplo a RT2), para hacerlo, activaremos la señal de salida T8 y la señal C10 de carga. Despues de esto, debemos enviar el valor de $s1 a la ALU, es decir, seleccionaremos $s1 con RA y en el triestado MA colocaremos un 0 para indicar de donde viene el valor. En MB deberemos colocar 1 ya  que el valor proviene de un registro temporal. Seleccionaremos el código de operación en la operación suma y enviaremos el resultado al banco de registros, donde se encuentra $s0. Activaremos T5, seleccionamos $s0 con RC y para cargar el valor en el registro activamos la señal SC.

c)       ORI $t0, $t2, 0x00A1
Primero debemos llevar el dato de $t2 y el inmediato a la ALU. Es decir, activar la señal C6 (sacar el dato de RI) y activar la señal C10 (cargar el valor en registro temporal RT2), MB=1 (dato en registro temporal). Después, en RA seleccionamos el registro $t2 y colocamos en MA 0 para indicar que la carga viene del banco de registros. Seleccionamos el código de operación  OR en la ALU y esta vez debemos almacenar el resultado en RT3, ya que el bus contiene el valor inmediato, para almacenarlo activamos la señal de carga C11. A partir de aquí comienza el sexto ciclo. Ahora enviaremos el resultado de la operación OR al registro $t0. Comenzaremos activando la señal de salida T6 y seleccionamos $s0 en el banco de registro con RC y activamos la señal de carga SC para almacenar el valor en el registro seleccionado.

d)      SLL $t0, $t0, 0x0002
En esta operación primero debemos llevar el dato (almacenado en $t0) y el valor inmediato (almacenado en RI) a la ALU. Seleccionamos $t0 en el banco de registros con RA y colocamos 0 en MA para indicar de donde proviene el dato, después, activamos T8 para enviar el valor inmediato al bus de datos y activamos C10 para almacenarlo en RT2, también debemos activar MB, en este caso un 1, y seleccionar el código de desplazamiento a la izquierda en nuestra ALU. Almacenaremos el resultado en RT3 (el bus interno está ocupado por el valor inmediato).Aquí comienza un nuevo ciclo, después de esto, solo nos queda almacenar el resultado en el registro $t0, para hacerlo, activamos T6 para enviar el valor que contiene RT3 al bus interno, seleccionamos el registro con RC y por último activamos la señal de carga SC.
e)      SRL $t1, $t0, 0x0002
Esta operación es exactamente igual a la anterior, salvo porque el desplazamiento se realiza a la derecha, como lo único que varía el código de operación, no consideramos necesario repetirlo.
f)       LUI $s0, 0x0011
En esta instrucción cogeremos el valor  0x0011 y lo almacenaremos en $s0, para hacerlo, activamos T8 para volcar el valor al bus interno (el valor se encuentra en el registro RI) y a continuación seleccionamos $s0 con RC y activamos la señal de carga SC.
g)       SW $t4, 0x0111.
En esta instrucción buscaremos en memoria el valor que se encuentra en la dirección 0x011 y  lo almacenaremos posteriormente en el registro $t4.
Para buscar en memoria el dato, activamos T8 y C1 para almacenar el valor en el registro MAR, a continuación activamos td y abrimos la memoria en modo lectura. Después, activamos T3 para volcar el dato en el bus interno, y finalmente seleccionamos con Rc el registro $t4 y almacenamos el valor activando la señal de carga SC.



h)      SLT $t1, $t2, $t0
  Activaremos RA y MA para llevar el contenido de $t2 a la ALU. A su vez, activamos RB  y MB para hacer lo mismo con $t2. Seleccionamos el código de operación para la resta. Deberemos almacenar los indicadores de la resta, para lo cual deberemos activar C8. Procederemos a activar las señales T7, C9 y MA para llevar el contenido del registro de estado a la ALU mediante RT1. (incompleto.)
i)        J 0x000001A
Para realizar este salto, activaremos las señal T8 y C5 para llevar el valor inmediato desde RI hasta PC.

j)        JR $s0
Activaremos las señales RA y T! para volcar el dato de $s0 en el bus interno, después lo cargaremos en PC activando C5


Dificultades:
El correcto manejo de la estructura de una cpu, para solucionar esta dificultad lo principal es conocer cada una de las partes que la componen y cuál es su función, sin embargo, posee caracteres repetitivos que ayudan a la comprensión (por ejemplo todas las señales que empiezan por “c” son de carga)


FAQS

¿Cómo abro el archivo que tiene el circuito?
Primero abres el Logisim y con Archivo/abrir lo seleccionas y se abrirá.

¿Como paso las instrucciones a hexadecimal?
Primero lo pasas a binario, mirando en el apéndice Hennessy Patterson del tema 2 como se codifican. Una vez que lo tienes en binarios, separas los bits en grupos de cuatro y cada grupo lo traduces a hexadecimal. Al final te tienen que quedar 8 dígitos.

¿Cómo meto las instrucciones en el circuito?
En modo para hacer funcionar el circuito, pinchas en la RAM que hay arriba, que hace las veces de memoria principal, y pones en cada uno de los cuadritos la instrucción que quieres que se ejecute.

¿Cómo meto datos en el banco de registros del archivo de la CPU?
En el menú de la izquierda haces doble clic en donde pone BANCO. Una vez allí, buscas el registro que quieres, el de arriba a la izquierda es el R0 y desde allí los siguientes van en vertical, y luego a la linea siguiente. Una vez localizado, en el modo para hacer funcionar el circuito, pinchas en los números del registro y metes lo que quieres.

¿Cómo reinicio el circuito?
Abajo a la derecha hay un botón que pone RESET. En cuanto lo pulses se resetearán todos los datos del circuito.

¿Por qué se me pone el cable del bus en color rojo?
Porque tienes abiertos dos o más triestados a la vez, por lo que hay un conflicto y los datos salen erróneos. Para solucionarlo, tan sólo cierra los sobrantes.