Vamos a por el tercer punto de la lección, ¿cómo describir en VHDL una máquina de estados finitos? Supongamos una máquina de Moore, la descripción VHDL pasa por definir dos procesos, un proceso que define la función del estado siguiente y la sincronización de la máquina y un segundo proceso que define la función de salida. Vamos a suponer que previamente hemos definido un package al que hemos llamado my fsm que incluye las definiciones de el conjunto de estados internos, que serán los estado S0, S1, S2, etcétera, que define el número de señales de entrada como nN y que define que el número de señales de salida será M. Y que además podemos suponer hemos aprovechado para definir la función estado siguiente y la función de salida. Bien, aquí lo que hacemos es definir que vamos a trabajar con este package que acabamos de decir y definimos una entity Moore Fsm donde definimos las entradas y las salidas de la máquina de estados finitos. Habrá dos entradas de un bit, clock y reset, una entrada x que la definimos como un vector desde n menos uno hasta cero, es decir estamos diciendo que la entrada x será un bus de n líneas, de n bits y la salida que también la definimos como un vector de m posiciones, es decir que y también será un bus en este caso de m bits. La arquitectura de la máquina de estados finitos incluye la declaración de una señal current state, que es de tipo state, el tipo state you lo hemos declarado en el package y dos procesos, el proceso next state que define el estado siguiente y el proceso output state que nos va a definir las salidas. El proceso next state es sensible a reset y a clk y simplemente lo que hace es que cuando detecta un reset igual a uno pone el current state a S0, suponiendo que S0 es el estado inicial de la máquina de estados finitos y después cada vez que llega un flanco de subida por la señal de reloj y esta es la manera que tiene VHDL de describir un flanco de subida de la señal clk entonces en current state ponemos el resultado de aplicar la función f a current state y a la entrada x. Bien, como veis es un muy sencillo, el proceso output state que es, puesto que esto lo hemos definido como una máquina de Moore, es sensible solo a current state simplemente lo que hace es introducir en y el valor de aplicar la función de salida h al estado actual current state. Las funciones f y h pueden estar definidos en el package, como estamos suponiendo aquí o podemos obviar el package definiendo las funciones dentro de los propios procesos. Aquí podemos ver como en el proceso next state hemos incluido la definición de la función f dentro de un case, de hecho este case, toda esta parte sustituye la sentencia en la cual poníamos current state igual es decir, cargábamos current state con el valor f de current state y la entrada x. Fijaros simplemente lo que dice, volvemos a empezar cuando reset es igual a uno current state lo pone al estado inicial, cada vez que llega un flanco de subida por la señal de reloj dependiendo del valor de current state, aquí tenemos la case, cuando la current state es S0 aquí pondríamos todas las instrucciones necesarias para ejecutar la función f de S0 y x. Cuando current state es igual a S1 pues aquí podríamos todas las instrucciones que ejecutan la función f de S1 y x, y el traslado de su valor a current state y así sucesivamente. Y lo mismo podemos hacer con la salida. Aquí hemos sustituido otra vez por este case, hemos sustituido la sentencia y h de current state, ¿de acuerdo? Veamos un ejemplo concreto. Volvamos al contador binario ascendente de tres bits que vimos al principio de la lección. Recordamos que tenía una única entrada count enable que cuando se mantenía a uno, a cada pulso de reloj el valor del contador aumentaba en uno. Hemos definido un tipo state que puede tomar los valores del 0 al 7, hemos definido un por de entrada count enable de un bit y hemos definido un por de salida y de tres bits. El proceso next state es sensible a reset y a clk diría lo siguiente. En principio si reset igual a uno ponemos current state a cero. Current state es una variable de tipo state y por lo tanto puede tomar los valores de 0 a 7. A partir de aquí cada vez que llegue un pulso por la señal de reloj si current state es cero entonces si count enable es uno pasamos al estado uno, ponemos uno en el valor de current state. Si el estado actual es uno y count enable es uno entonces pasamos al estado dos y así sucesivamente hasta que cuando encontramos que current state es siete, si count enable es igual a uno entonces volvemos al estado cero y cerramos el ciclo. ¿Qué pasa cuando count enable es igual a cero? La verdad es que estrictamente hablando aquí deberíamos añadir algo así como si count enable es igual a uno pon uno en el current state en caso contrario, si count enable es igual a cero entonces en current state pon un cero end if, ¿vale? Pon un cero diciendo que el estado actual se mantiene en el valor que tenía cero, y esto lo tendríamos que hacer en cada una de las sentencias. Bueno lo que ocurre es que esta última parte no es necesario escribirla porque al fin y al cabo el VHDL es un lenguaje de programación y como tal si una variable no cambia de valor no es necesario decirlo explícitamente. Bien, pues fijaros como de esta manera en el propio proceso next state hemos introducido la definición de la función estado siguiente, de la función f. Otro tanto podríamos hacer con la función h, con la función de salida. Dentro del proceso output state sensible en este caso solo a current state porque lo hemos definido como una máquina de Moore, que le vamos a decir es que cuando el estado actual es cero la salida ha de cero cero cero, ser cuando el estado actual es uno la salida ha de ser cero, cero, uno, etcétera. Recordemos que en el contador las salidas coinciden con el estado, ¿de acuerdo? Bueno, pues para ver si habéis comprendido todo esto os dejo una pequeña pregunta. Aquí os muestro una porción de código VHDL que corresponde al proceso next state de un contador bidireccional de dos bits, en el que hemos definido el tipo state igual a cero, uno, dos, tres y dos ports de entrada count enable y up down. Cuando up down es igual a cero el contador cuenta hacia arriba, cuando es igual a uno cuenta hacia abajo. Como veis la sentencia case esta sin terminar. Falta estas porciones de aquí. La pregunta que quiero que respondáis es la siguiente, ¿cuál es la porción de código que deberíamos incluir en la parte marcada en amarillo? Exactamente aquí. ¿De acuerdo? Pues adelante. Bien, hemos llegado al final de la lección. Como resumen decir que hemos definido lo que son las máquina de estados finitos, las Fsm por el nombre de ingles de finite state machines. Hemos estudiado cual es la frecuencia máxima de funcionamiento de una máquina de estados finitos. Hemos visto un modelo genérico de descripción de VHDL de una máquina de estados finitos con dos procesos concurrentes, uno que calcula la función estado siguiente y otro que calcula la función de salida. Pues eso es todo. Hasta la próxima lección.