En esta lección completaremos las especificaciones de nuestro procesador cuya descripción estructural ya vimos como un diagrama de bloques formado por cinco bloques. Dos de ellos ya fueron definidos en la lección anterior, solo falta la definición de los tres bloques restantes. Empezaremos por el bloque "banco de registros" que es el que tenemos marcado aquí dentro del diagrama de bloques. Este bloque está formado por un conjunto de 16 elementos de memoria de "X0" a "X15" y los valores almacenados en estos elementos de memoria pueden ser actualizados a través del valor de la entrada "to X(k)" que tenemos aquí. Esta entrada viene del bloque de selección de entradas. También pueden ser leídos los contenidos de estos registros hacia dos salidas X(i) y X(j). Las instrucciones que trabajan con el banco de registros, que actualizan algunos de los registros o elementos de memoria o que leen algunos de estos registros, las vamos a marcar en azul en nuestra descripción algorítmica funcional del procesador. Vemos que son muchas de ellas las que hacen referencia o hacen uso de este banco de registros. Es importante observar que en relación con las operaciones de lectura del banco de registros, en el caso de una instrucción tipo data output, el registro X(j) es el que sale por la derecha del banco de registros y se conecta a la entrada del bloque de selección de salida. Aquí vemos el X(j) y ese mismo X(j) es la entrada del bloque de selección de salidas. En el caso de la instrucción operation, operación, ambas salidas la X(i) y la X(j) del banco de registros se leen simultáneamente y se conectan a las entradas del bloque dedicado a los recursos de cálculo. El resultado de la operación debe almacenarse, este resultado debe almacenarse en el registro X(k) X(k) a través del bloque de selección de entradas. Y por último en el caso de las instrucciones de salto condicional, estas dos que tenemos aquí, "jump si positivo" o "jump si negativo", es el registro X(i), la salida de la izquierda de nuestro banco de registros, sobre el que se establece la condición a verificar, es el que sale por la izquierda de nuestro banco de registros y se conecta al bloque "go to" que es donde en realidad se valora si se cumple o no se cumple la citada condición. Luego las entradas del banco de registros son el "reg_in" y la instrucción en curso. Mientras que sus salidas son "left_out" y right_out y este loop constituye la especificación funcional del banco de registros donde esta expresión que tenemos aquí "program(number)" hace referencia a la instrucción en curso, es decir el contenido del programa según un number es la instrucción que estamos procesando. En el caso de instrucciones que actualizan registros pero que no leen el valor de los registros como son el "assign_value" y el "data_input", que solo actualizan un determinado registro X(k) con el valor que había en "reg_in" en ambos casos, pero que no se lee ninguna información de los registros hacia la salida, pues las salidas "left_out" y "right_out" en ambos casos se dejan a un valor indeterminado. En el caso de las instrucciones tipo "data_output" el valor del registro X(j) tiene que enviarse a través de la salida "right_out" y esto es lo que hacemos aquí, mientras que por la salida "left_out" no importa lo que tengamos, luego don´t care. En el caso de "operation" ambos registros X(i) y X(j) deben ser leídos hacia el exterior, luego deben ser leídos hacia "left_out" y "right_out" y esto es lo que hacemos aquí. Y aquí, y al mismo tiempo, el resultado de la operación que nos llegará a través de la señal "reg_in" debe almacenarse en el registro X(k). En el caso de las dos instrucciones de salto condicional, el registro indicado por el índice i, el X(i) debe ser leído hacia la salida "left_out" en ambos casos, porque es la salida que se irá al bloque "go to". Mientras que en estos casos la otra salida no no tiene ninguna relevancia y la dejamos en el valor indeterminado. Y finalmente en el caso de las instrucciones de salto incondicional, esta de aquí, y "output_value" el contenido del banco de registros ni se actualiza ni se lee, por lo tanto todas sus salidas se dejan en indeterminado en estos dos casos. La especificación del bloque de recursos de cálculo es muy simple, pues solo hay una instrucción que utiliza este bloque y que es esta que tenemos aquí, es "operation i j k f", y por lo tanto este bloque lo que necesita para trabajar es la información de la instrucción en curso, que le indicará que función o recurso de cálculo tiene que utilizar, los dos operandos de entrada que vienen del banco de registros y una salida para el resultado que es la que enviará a través del bloque de selección de entrada de nuevo hacia el registro X(k) de nuestro banco de registros. Así pues, este bloque de recursos de cálculo tiene dos entradas de datos, "left_in" y "right_in", una entrada de control "f", que nos indicará la operación a realizar, ya dijimos una suma o una resta, y una señal de salida "result" que es donde estará el resultado de la operación que hayamos realizado. Su funcionamiento se describe mediante este simple algoritmo, si el valor de "f" es igual a cero entonces el resultado es la suma de las dos entradas, "left_in" más "right_in". Y si no, es decir si "f" es igual a uno, entonces el resultado es el valor de la diferencia entre "left_in" y "right_in". left in menos right in. Por ultimo abordamos el bloque "go to", que actualiza en cada paso de ejecución del programa el valor de la salida "number" que indica la posición de memoria donde se encuentra la siguiente instrucción a ejecutar y que en la mayoría de casos corresponde al valor de la posición de la instrucción en curso incrementado en uno. Esto es así excepto cuando la instrucción en curso se trata de una bifurcación o salto incondicional o condicional, y en este segundo caso si se cumple la condición. Por lo tanto el bloque "go to" tiene dos entradas, tiene la instrucción propiamente dicha, para saber de qué instrucción se trata, y la entrada "data", que recordemos está conectada a la salida del banco de registros. Y es sobre esa entrada sobre la que se validará, se verificará si se cumple la condición en aquellas instrucciones de salto condicional. También hemos visto una salida "number" que, como ya hemos comentado, representa o contiene el número de la siguiente instrucción a ejecutar. Esta de aquí es la especificación funcional de este bloque donde vemos que si la instrucción es un "jump" incondicional, lo que hacemos es actualizar el valor de "number" "number" con el número "n" que venía en la propia instrucción. Si por el contrario la instrucción es un salto condicional, estos dos casos de aquí, entonces el nuevo valor de "number" es "n" si y solo si se cumple la condición, es decir, si se cumple la condición, "number" toma el valor "n" que venía en la propia instrucción y lo mismo en la otra instrucción de salto condicional, si se cumple la condición "number" toma el valor "n" que venía en la propia instrucción. Si no se cumple esta condición en ambos casos, "number" se incrementa en uno. Y para cualquier otra instrucción que no sea un salto condicional o incondicional, "number" siempre se incrementa en uno. Y con esto llegamos al final de esta sesión, cuyo resumen podría ser que hemos completado la descripción estructural de nuestro procesador y hemos descrito el funcionamiento de los tres bloques que nos faltaban, que eran: el banco de registros, los recursos de cálculo y el bloque "go to". Y con esto damos por cerrada esta sesión. Gracias y hasta la próxima.