Hola.
Esta lección y la siguiente las
dedicaremos a la especificación estructural de nuestro procesador.
El método de desarrollo que estamos aplicando es el
llamado top down o descendente.
Primero realizamos una descripción funcional que ya abordamos en la lección
anterior y luego una descripción más estructural a nivel de diagrama de bloques,
interconectados entre sí, donde cada bloque se describe a un nivel funcional.
Este será el tema que trataremos en esta lección y en la siguiente.
Posteriormente para finalizar realizaremos la
implementación de cada uno de estos bloques.
En primer lugar definamos qué es un diagrama de bloques.
Esta es la especificación funcional de nuestro procesador,
esta que tenemos aquí, y para extraer el diagrama de bloques
debemos identificar cuál es la información a procesar,
cuáles son las transferencias de información, este bloque de aquí,
y cuáles son las operaciones que nuestro procesador deberá realizar.
Así pues como información a procesar tenemos las entradas externas
que pueden ser los puertos de entrada IN0 a IN7 o bien
la propia instrucción que viene de la memoria.
También tenemos que procesar la información hacia las salidas externas,
es decir la información que va hacia los puertos de salida OUT0 a OUT7.
Y la información que enviamos a través de la
señal "number" para indicar cuál es la siguiente instrucción a ejecutar.
Y finalmente los datos internos,
los elementos de memoria interna que eran del X0 al X15,
los 16 elementos de memoria internos.
Y de acuerdo con la especificación funcional, las transferencias
de información que debemos ser capaces de hacer son las siguientes.
Debemos que poder transferir, o bien el contenido de un elemento de memoria,
o bien el valor de una constante que está en la propia instrucción hacia un puerto
de salida, hacia la salida de "number" le tenemos que poder enviar
o bien su propio valor incrementado en 1, en uno o bien el valor N que estaría
dentro de la propia instrucción, siendo N el de la siguiente instrucción a ejecutar.
Y en relación con los elementos de memoria sobre cualquiera de estos
elementos de memoria, tenemos que poder transferir o bien una constante que está
dentro de la propia instrucción, o bien el valor que viene por un puerto de entrada,
o bien el resultado de una determinada función f.
Y por último respecto a las operaciones a realizar siempre son de este tipo:
una función f que trabaja con dos operandos que
vienen de sendos elementos de memoria Xi y Xj.
Este es el diagrama de bloques propuesto
y pasaremos ahora a describir brevemente cada uno de ellos.
Empezamos por los datos internos, los datos internos recordemos
son el X0 ... X15 que son los elementos de memoria que los habíamos puesto,
que los hemos puesto en lo que hemos llamado en este diagrama de bloques el banco de registros.
el bloque del banco de de registros.
En este banco de registros están estos 16 componentes cada uno de
ellos capaz de almacenar palabras o números de de ocho bits.
Asumimos que este bloque tiene dos salidas:
la Xi y la Xj para proporcionar datos
a los recursos de cálculo que ya hemos visto que eran funciones de dos operandos.
Asimismo este bloque está controlado por la instrucción
en curso que define qué registro se debe actualizar: el índice k,
y cuáles son los dos registros que tenemos que
enviar hacia estas dos salidas del banco de registros.
Y esta sería la descripción breve de nuestro banco de registros, que
es el encargado de almacenar y gestionar los datos internos del procesador.
Veamos ahora los bloques relacionados con la transferencia de
datos primero y con las operaciones después.
El primer bloque que trataremos será el de selección de salidas.
Este bloque es el encargado de realizar la transferencia de datos hacia los puertos
de salida, estos ocho puertos de salida que tenemos aquí.
¿Y qué datos va a transferir?
Pues va a transferir o bien el contenido de un elemento
de memoria, o bien un valor constante que está en la propia instrucción.
Por lo tanto sus entradas son una entrada que va a venir de los elementos
de memoria la Xj o bien una constante que está en la propia instrucción.
Es por lo tanto la propia instrucción quien controla el
funcionamiento de este bloque.
A continuación veamos el bloque "go to".
Este bloque "go to" actualiza el valor de su salida "number".
"Number" recordemos indica el número de la siguiente instrucción a ejecutar.
Y para poder actualizar su valor este bloque internamente tiene
que almacenar el valor actual de "number" y poderlo
actualizar en función de la instrucción que le llegue.
Es un bloque controlado por la instrucción en
curso y el tratamiento que hace de las instrucciones es el siguiente:
distingue entre aquellas instrucciones de salto o bifurcación de todas las demás.
En el caso de las instrucciones de bifurcación incondicional o salto
incondicional, como esta de aquí, lo que hace este bloque es
coger el valor N de la propia instrucción y
con ese valor actualiza el contenido de "number".
Eso es un salto incondicional.
La siguiente instrucción que ejecutaremos es la de la posición N.
Y aquí tenemos lo que sería el equivalente a una instrucción de
bifurcación o salto condicional.
Si el registro indicado por el índice i,
el Xi correspondiente cumple una determinada condición,
que es la que nos especifica la propia instrucción, si se cumple actualizaremos
el valor de "number" con la N que también viene en la propia instrucción.
Y si no se cumple actualizaremos el valor de "number" con "number" más uno.
En el resto o para el resto de instrucciones sencillamente
el valor de "number" se actualiza con "number" más uno.
Es decir, en las de bifurcación o salto puede, en las de salto
incondicional se actualiza con N y en las de salto condicional puede actualizarse
con N o con "number" más uno dependiendo si se cumple o no la condición.
Y con esto ya tendríamos definidas las
entradas salidas de nuestro bloque "go to".
El bloque siguiente va a ser el bloque de selección de entrada,
este que tenemos aquí arriba.
Y este es el encargado de transferir datos desde la entrada, desde alguno de estos
ocho puertos de entrada, hacia el banco de registros que teníamos aquí.
Por lo tanto, este es un bloque que como todos los otros está controlado
por la instrucción en curso, y que define si la entrada es, o bien una constante
A que está en la propia instrucción, o bien uno de estos ocho
puertos de entrada, o bien el resultado que vendría por aquí
de una operación que ha realizado alguno de nuestros recursos de cálculo.
De todos estos valores, el seleccionado se transferirá hacia esta salida que es la
que entra al banco de registros para poder actualizar el registro k correspondiente.
Por último, tenemos nuestro bloque de recursos de cálculo
o de cómputo que siempre ejecuta funciones de esta forma,
es decir, hay una función f que identifica cuál de los recursos de
cálculo disponibles dentro de este bloque vamos a utilizar
y se indica cuáles son los dos operandos que vienen de nuestro banco de registros
Los dos operandos son el contenido del registro Xi y
el contenido del registro Xj.
Y este que vemos aquí es el diagrama de bloques completo,
incluyendo la memoria externa,
memoria externa, dónde se almacenan los programas;
y que tiene como entrada el número de la instrucción siguiente a ejecutar y como
salida dicha instrucción que a su vez viene al diagrama
de bloques para facilitar la ejecución de los distintos bloques.
Luego tenemos el número de la siguiente instrucción a ejecutar que lo
enviamos a la memoria, para que la memoria nos devuelva dicha instrucción.
ya habíamos definido el conjunto de instrucciones pero
nos quedaban algunas cositas por especificar.
Este es el conjunto de instrucciones.
En operaciones la f vamos a tener sólo dos operaciones,
la suma y la resta, que acabarán definiendo los recursos
necesarios, los recursos de cálculo necesarios de nuestro procesador.
También faltaba por definir el número de elementos de memoria de
nuestro banco de registros, que asumimos que va a ser de 16.
Luego los índices i, j y k que tienen que poder
representar a cualquiera de esos 16 registros, necesitarán ser números
de cuatro bits para poder representar cualquiera de esos 16 registros.
Y finalmente, tenemos que definir el tamaño máximo de un
programa que será de 256 instrucciones.
Luego, el numerito N que aparece en nuestras intrucciones tiene
que ser capaz de identificar a cualquiera de esas 256 instrucciones
y por lo tanto, necesitará ser un numerito, un número, de ocho bits.
La codificación final de todas estas instrucciones,
junto con sus distintos parámetros la veremos más adelante.
Ahora que hemos visto como íbamos conformando nuestro diagrama de bloques,
con sus interconexiones y las principales tareas que
debían desarrollar cada uno de ellos;
vamos a describir estos cinco bloques a nivel funcional.
Empezaremos por el bloque de selección de entrada que tenemos marcado aquí.
Y para definir el funcionamiento de este bloque, vamos en primer lugar a marcar
en la descripción funcional de nuestro procesador las instrucciones
que actualizan el valor de alguno de los elementos de memoria Xk.
Y aquí podemos ver el resultado: estas tres instrucciones que tenemos aquí.
El assign value k, el data input k, j
y el when operation, cuando hay una
operación con los índices i, j, k, f.
Estas tres instrucciones son las que nos permiten identificar en qué casos,
en qué momentos, hay que llevar información o bien de la constante A, que
está en la propia instrucción, o bien de un puerto de entrada IN0 ... IN7,
o bien del resultado de una operación, hacia adentro del banco de registros.
Así pues, las entradas del bloque de selección de entrada son,
los ocho puertos de entrada, la entrada resultado
que viene del bloque de recursos de cálculo y la instrucción en curso.
La salida de este bloque de selección de entrada, es la información proveniente
de alguna de estas fuentes que hay que enviar al banco de registros.
Y la descripción funcional de este, de este bloque es la que tenemos aquí.
Obsérvese, que las tres instrucciones que habíamos resaltado en nuestro,
en nuestra descripción funcional del procesador, en nuestro algoritmo funcional
del procesador, son las que se tratan explícitamente dentro de este
case que tenemos aquí, para indicar para cada una de ellas cuál
es la acción a realizar sobre la salida de este bloque.
Mientras que, si la instrucción que estamos ejecutando no tiene que modificar
ningún contenido del banco de registros, es decir,
es cualquiera de las otras que no hemos marcado en nuestro algoritmo funcional
del procesador, entonces no nos importa que valor tenga esta señal
y por eso en todos los otros casos, decimos que no nos importa
el valor que acabe habiendo en la salida de este bloque.
Veamos ahora el bloque de selección de de salida.
Para definir el funcionamiento de este bloque,
marcaremos en la especificación funcional global de nuestro procesador todas
aquellas instrucciones que actualizan el valor de algunos de los puertos de salida.
Y que son estas dos que tenemos aquí.
El data output y el output value.
Luego las entradas de este bloque de selección de salida,
son la entrada reg que viene del banco de registros y la instrucción en curso.
Y esta de aquí es la especificación funcional de
de este bloque, donde detallamos el comportamiento
del bloque para las instrucciones que tienen algún
efecto sobre los puertos de salida y que coinciden con estas dos de aquí.
Mientras que, cuando la instrucción no tienen ningún efecto sobre los puertos de
salida observemos que lo que hay que hacer, lo que se hace es sobre el
puerto OUTi dejamos el mismo valor que ya había en el puerto OUTi.
Es decir, los puertos de salida son como elementos de memoria y
si una instrucción no modifica el valor de los puertos de salida,
entonces estos mantienen el mismo valor que ya tenían antes de dicha instrucción.
Este tipo de salidas se conoce como
salida registrada y funcionan como un elemento de memoria.
Más adelante, veremos como se implementan estos elementos de memoria.
Y a modo de resumen de esta sesión diremos que hemos desarrollado
una descripción estructural en forma de diagrama de bloques,
con cinco módulos o bloques que se han definido a partir de la,
del algoritmo de descripción funcional global de nuestro procesador.
Y que se ha basado en la observación de: ¿cuáles son nuestros datos internos?
¿Cuáles son las transferencias de datos que hay que realizar?
y ¿cuáles son las posibles operaciones
que tienen que ser capaz de hacer o realizar nuestros recursos de cálculo?
También hemos realizado la descripción funcional de dos de esos bloques,
el bloque de selección de entradas y el bloque de selección de salidas.
Y en la próxima sesión continuaremos con este tipo de descripciones.
Con esto damos por cerrada esta sesión.