30
IEC FRANCISCO JAVIER TORRES VALLE CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES 54 DESCRIPCIÓN DE CIRCUITOS DIGITALES IV

Circuitos

Embed Size (px)

Citation preview

Page 1: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

54

D E S C R I P C I Ó N D E C I R C U I T O S D I G I T A L E S

IV

Page 2: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

55

4.1 PROYECTOS EN WARP 5.0

El objetivo de este capítulo es enseñarte a crear proyectos en VHDL utilizando Warp de Cypress Semiconductors. Así como diferentes métodos prácticos para la síntesis de los circuitos digitales más comunes.

PROCEDIMIENTO

1. Una vez en Windows haz click en el botón de inicio, selecciona Programas > Warp R5.0 > Galaxy.

Figura 4.1

2. Cuando te encuentres dentro del Galaxy, selecciona File > New.

Figura 4.2

3. Posteriormente debe aparecer un cuadro de dialogo como el que se muestra a continuación. Para crear un proyecto con el que quieres programar un dispositivo debes de seleccionar la segunda opción (Project [Target - Device]).

4. Cuando selecciones la opción de Project [Target - Device] aparecerá una ventana que te pide que pongas un nombre a tu proyecto, escribe el nombre de nuevo. En el segundo cuadro de texto te pide que especifiques el directorio en donde debe de guardar tu proyecto, puedes hacer un directorio nuevo desde esa misma ventana con solo escribir el nombre, por ejemplo c:\nuevo, o puedes buscar una carpeta ya existente con la opción Browse. Cuando hayas terminado de especificar los nombres haz click en el botón de Siguiente.

Figura 4.3

5. Aparecerá una ventana con título Add Files to Project, esta ventana se usa cuando ya tienes archivos que quieres agregar a tu proyecto, pero en esta ocasión por tratarse de un proyecto totalmente nuevo no es necesario especificar nada dentro de esta ventana. Solo haz click en el botón de Siguiente.

Page 3: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

56

Figura 4.4

6. La siguiente ventana lleva el título de Select Target Device, esta ventana es muy importante ya que es aquí donde debes de especificar el PLD en el que vas a trabajar. Los PLD's que se usan cuando se está aprendiendo son los pequeños (generalmente 16V8, 22V8 ó 22V10), estos PLD's están en la ventana como SPLD. Haz doble click sobre este texto, te aparecerá una lista de los SPLD's más comunes, selecciona el SPLD que te interese y nuevamente aparecerá una lista donde hay varios tipos del mismo SPLD, por ejemplo PALCE16V8-10PC/PI. Esta parte es importante, ya que debes de seleccionar un SPLD que tenga un encapsulado de tipo PDIP, para que lo puedas montar en tu protoboard. En la parte inferior aparece información sobre el SPLD que te interese. Cuando escojas el SPLD adecuado haz click en Finalizar.

Figura 4.5

7. Luego de lo anterior, aparecerá una ventana que te pregunta si deseas guardar tu nuevo proyecto, solo haz click en Sí.

8. Ahora ya tienes un nuevo proyecto donde se encuentra suficiente información para que el compilador te genere el archivo .jed. Pero te falta agregar el código que habrá de compilarse. Selecciona File > New > Text File, o puedes hacer click en el icono de nuevo. Escribe lo siguiente dentro del archivo de texto: library ieee;

Elige File > Save As y en la opción de Guardar en, selecciona el nombre de la carpeta que usaste en el paso número 4 (c:\nuevo). Una vez que hayas seleccionado el directorio, escribe el nombre de archivo, se sugiere el nombre nuevo, con la extensión .vhd, ya que de esta manera se especifica un archivo que contiene un código en VHDL. Luego de hacer esto, guarda tu archivo.

9. Cierra el archivo de texto.

10. Selecciona Project > Add Files, te aparecerá una ventana que debe de tener tu archivo nuevo.vhd , haz click en Add, y posteriormente en OK.

Figura 4.6

11. Tu archivo de texto se ha convertido en un archivo de VHDL y está dentro de tu proyecto, todo lo que programes, será compilado en el dispositivo que especificaste. En tu ventana de proyecto (si no se encuentra abierta, la puedes activar haciendo View > Project Window) debe de aparecer un icono en forma de hoja que tiene el nombre de tu proyecto. Haz click en esta hoja y te debe de aparecer un archivo con la instrucción: library ieee; solo que ahora la palabra library está

Page 4: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

57

en color azul porque es una palabra reservada. Esto demuestra que haz hecho correctamente el procedimiento.

Figura 4.7

12. Si la configuración de colores es la normal, notarás que todas las palabras reservadas se muestran en color azul y los comentarios en color rojo. Ahora ya puedes comenzar a hacer tu descripción en VHDL.

4.2 SIMULACIÓN DE PROYECTOS

Active - HDL de la empresa Aldec Inc. es un simulador que utiliza un archivo de post - síntesis creado por WARP. Éste es un archivo .vhd con los retardos de tiempo del código sintetizado en el dispositivo seleccionado. Este tema tiene por objetivo dar una pequeña introducción a este simulador de VHDL en las siguientes tres secciones.

1. Formato de simulación 1164/VHDL.

2. Simulación.

3. Tipos de señales de estimulación.

FORMATO DE SIMULACIÓN 1164/VHDL

El archivo de entrada para Active - HDL es un modelo de simulación post - síntesis generado cuando se compila un archivo .vhd en el dispositivo elegido. En WARP es posible crear archivos con diferentes formatos para simulación post - síntesis. Active - HDL requiere de un archivo con el formato de simulación IEEE - 1164 / VHDL.

Para crear este archivo post - síntesis debes seguir el siguiente procedimiento.

1. Una vez que se ha creado un nuevo proyecto en Galaxy, dentro del menú Project selecciona Compiler Options.

Figura 4.8

2. Lo anterior abrirá la ventana de opciones de compilación, dentro de esta se encuentra una sección para elegir el formato de los retardos para simular el circuito Simulation—Timing Model. Aquí es donde debes de seleccionar el formato 1164/VHDL.

Figura 4.9

3. Asegúrate que se encuentre habilitado el cuadro de Enable Testbench Output.

4.2.1 PROCESO DE SIMULACIÓN

El proceso de simulación lo podemos resumir en los siguientes siete pasos.

Page 5: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

58

1. Cargar un archivo con el formato de

simulación 1164/VHDL.

2. Iniciación de la simulación.

3. Agregar señales.

4. Asignar señales de estimulación.

5. Correr la simulación.

6. Observación de la simulación.

7. Guarda la simulación.

1. - CARGA DEL ARCHIVO

El primer paso es abrir el programa Active-HDL Sim que normalmente se encuentra en Menu Inicio > Programas > Warp > Active-HDL Sim. Para cargar el archivo selecciona Open Vhdl dentro del Menú File.

Figura 4.10

Es importante mencionar que el archivo con el formato 1164/VHDL se crea en el subdirectorio vhd dentro del directorio de trabajo del proyecto una vez que éste es compilado. Si se selecciona por accidente el archivo .vhd creado por el usuario, el compilador del programa generará varios errores y no podrá ser simulado. Una vez que el archivo apropiado es cargado, se desplegarán una serie de mensajes dentro de la ventana de compilación. Uno de los mensaje que debería aparecer cuando el archivo es compilado correctamente es el siguiente: -- Compile success 0 Errors 0 Warnings Analysis time: 3.0 [s].

2. - INICIACIÓN DE LA SIMULACIÓN

Para iniciar la simulación, activa el simulador utilizando la opción Initialize Simulation, dentro del menú Simulation. Después abre una ventana para el análisis de señales Waveform Window, si es que no se encontrara ya una abierta.. Para crear una nueva ventana de este tipo, haz clic en el icono dentro de la barra estándar de trabajo o selecciona File > New Waveform..

3. - AGREGANDO SEÑALES

El siguiente paso es agregar señales a la ventana de análisis, para esto selecciona Add Signals...en el menú Waveform. La ventana para agregar señales aparecerá con una lista de todas las señales de entrada, salida, entrada/salida y nodos internos de conexión disponibles en el diseño. Para agregar alguna de las señales que se encuentran en esta lista basta con hacer doble clic sobre el nombre de la señal. Si deseas agregar varias señales al mismo tiempo, puedes seleccionarlas mediante la tecla control y haciendo clic sobre cada señal que deseas agregar para después hacer clic sobre el botón Add que se encuentra en la parte inferior de la ventana.

Figura 4.11

4. - TIPOS DE SEÑALES DE ESTIMULACIÓN

Las señales de estimulación son utilizadas para definir diferentes impulsos a los puertos de entrada del diseño que esta siendo simulado. Para seleccionar alguno de estos tipos primero selecciona la señal y después selecciona Waveform > Stimulators..., a continuación se describe brevemente los diferentes tipos de señales de estimulación de Active-HDL Sim.

Page 6: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

59

Figura 4.12

CLOCK

Sirve para definir señales de reloj definidas con los siguientes parámetros: frecuencia, valor inicial, ciclo de trabajo y tiempo de inicio.

CUSTOM

Un estimulador personalizado se crea editando los valores deseados en la ventana de simulación. Estado en el modo de edición, al estimulador de entrada se le puede asignar un estado bajo o un estado alto presionando '1' o '0' respectivamente.

FORMULA

Un estimulador del tipo formula produce una señal definida por una simple sintaxis. La señal es definida con secuencias pares de valor - tiempo. Con la componente tiempo indicamos el momento en el que la señal asume el valor especificado. La unidad del tiempo es en picosegundos. Para repetir durante un periodo especificado, se agrega el modificador -r. La sintaxis del estimulador tipo formula se muestra a continuación. <valor> <tiempo> [,<valor> <tiempo>, <valor> <tiempo>, ...] [ -r <periodo>]

EJEMPLO '0000' 0 ps, '1111' 100000 ps, '0011' 200000 ps -r 300000

PREDEFINIDOS

Los estimuladores predefinidos son una serie de señales tipo clock con diferentes frecuencias o señales del tipo formula que pueden ser asignados a las señales. Para agregar un nuevo estimulador a esta lista, lo puedes hacer en la misma ventana dentro del cuadro Predefined.

VALOR

Con este tipo de estimulador asignamos un valor constante a la señal especificada.

HOTKEY

Con este estimulador podemos estar cambiando el valor de la señal presionando una tecla. Cuando asignamos este tipo de estimulador es conveniente asignar una lista de valores. Cada que presionemos la tecla asignada, estaremos cambiando entre los valores de esta lista.

Para una descripción más completa de las características del simulador consulta la ayuda del programa.

5. - CORRIENDO LA SIMULACIÓN

Para correr la simulación selecciona Simulation > Run. La simulación se detendrá después que la duración especificada haya sido terminada. En este momento las señales de estimulación para los puertos de entrada pueden ser alterados y producirán efectos sobre la simulación cuando esta continué. Para volver a iniciar la simulación selecciona Simulation > Restart Simulation.

6. - OBSERVANDO LA SIMULACIÓN

Varias propiedades pueden ser manipuladas para mejorar la apariencia de la simulación. A continuación se describen brevemente algunas de estas propiedades.

BUS

La líneas individuales que forman un bus pueden ser mostradas y editadas. Para mostrarlas haz clic sobre "+" que se encuentra a junto al nombre el bus. Las señales de estimulación pueden ser asignadas a cada línea del bus o al bus completo.

COLOR

Las señales de la simulación pueden ser de diferentes colores para una mejor claridad cuando varias señales son desplegadas. Para agregar color a todas las señales visibles, selecciona Waveform > Colorize Waveforms, esto asignará diferentes colores, arbitrariamente a cada señal dentro de la ventana de simulación. Para asignar color a cada señal, haz clic con el boton derecho sobre el nombre de la señal y selecciona la opción Properties..

Page 7: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

60

ZOOM

Para aumentar o reducir la escala de tiempo de la simulación, selecciona View > Zoom > In/Out/Full.

BOOKMARKS

Para colocar marcas sobre la ventana de simulación primero selecciona Waveform > Select Mode. Cuando este modo se encuentra seleccionado, es posible colocar marcas sobre diferentes puntos de la simulación para una rápida referencia a ciertos puntos importantes de la misma. Para colocarlas primero haz clic con el botón izquierdo en donde deseas colocar una marca, después selecciona Search > Toggle Bookmark. Utilizando Next/Previous Bookmark del mismo menú puedes cambiar entre una marca y otra dentro de la simulación. Las marcas son desplegadas como un triángulo azul sobre la escala de tiempo en la ventana de simulación. Para eliminar alguna marca selecciona Waveform > Edit Mode y después haz clic con el botón izquierdo sobre la marca que deseas eliminar.

MODO DE MEDICIÓN

Para entrar al modo de medición selecciona Waveform > Measurement Mode. En este modo es posible desplegar el tiempo exacto entre dos eventos de la simulación. Para obtener esta información coloca el puntero sobre una transición negativa o positiva, cuando el puntero es colocado sobre alguna transición debe cambiar a color verde, presiona el botón izquierdo sobre la transición y arrastra el puntero hasta otra transición de cualquier señal dentro de la ventana de simulación y entonces suelta el botón. La medida exacta entre estas dos transiciones se desplegara como una etiqueta entre las dos transiciones. Si la etiqueta no es mostrada o no se ve completa, amplia el alto de la fila haciendo clic con el botón derecho sobre alguna de las señales que intervienen en la medición y después selecciona Properties, dentro de la venta de propiedades aumenta la altura modificando el valor del cuadro de texto Height. Para eliminar alguna etiqueta de medición selecciona Waveform > Edit Mode, después seleciona la etiqueta y presiona suprimir

7. - GUARDANDO LA SIMULACIÓN

Existen dos formas de guardar la simulación. Guardar solamente la simulación de la ventana activa o guardar todas las simulaciones de las

ventas de simulación abiertas. La extensión de los archivos de simulación en Active-HDL Sim es .awf.

4.3 COMPARADORES

El objetivo de este tema es crear, sintetizar, y simular la descripción de circuitos comparadores de magnitud utilizando WARP.

PROCEDIMIENTO 1. Primero crearemos un proyecto para el

ejemplo del comparador visto en el tema 3.1.2 Antes que nada debemos crear el proyecto dentro de un directorio en el que se encontrarán todos los archivos del proyecto (.pfg, .vhd, .jed, .rpt, etc. ). Se sugiere crear primero una carpeta para todos los proyectos VHDL y dentro de esa carpeta crear otra carpeta para el presente proyecto, por ejemplo c:\vhdl_proj\comparador_1, con el nombre comparador_1.

Figura 4.13

2. Seleccionaremos un 22V10 con empaquetado tipo DIP para sintetizar el código.

3. Ahora creamos un nuevo archivo de texto para editar el código (File > New > Text File). Este archivo debe ser guardado con extensión .vhd y en la misma carpeta del proyecto. Se sugiere guardarlo como:

c:\vhdl_proj\comparador_1\comparador1.vhd

4. A continuación se muestra la tabla de funcionamiento de este comparador y basándose en ella haremos el código de descripción en VHDL. Primero utilizaremos el estilo de

Page 8: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

61

descripción de flujo de datos, que es el mismo que se utilizó cuando se expuso el ejemplo en el tema 3.1.2.

TABLA DE FUNCIONAMIENTO

ENTRADAS SALIDAS

x < y x_men_y '1'

x < y equals '0'

x < y x_may_y '0'

x = y x_men_y '0'

x = y equals '1'

x = y x_may_y '0'

x > y x_men_y '0'

x > y equals '0'

x > y x_may_y '1'

5. Abajo se muestra el listado del comparador correspondiente al estilo de descripción de flujo de datos. Este listado debemos editarlo dentro del archivo comparador_1.vhd. ENTITY comparador IS

PORT ( x: IN bit_vector(3 DOWNTO 0); y: IN bit_vector(3 DOWNTO 0); x_may_y: OUT bit; equals: OUT bit; x_men_y: OUT bit

); END comparador; ARCHITECTURE comparador OF comparador IS BEGIN

equals <= '1' WHEN x = y ELSE '0';

x_may_y <= '1' WHEN x > y ELSE '0';

x_men_y <= '1' WHEN x < y ELSE '0';

END comparador;

6. Como se puede observar no se cargó ninguna librería, y no es necesario hacerlo porque el tipo bit es un tipo predefinido en WARP y en muchos otros sintetizadores de VHDL. Por esto no necesitamos de ninguna librería para poder utilizarlo. Además, recuerde que la última declaración de puertos no lleva ;

Una vez que se terminó de editar el código, procedemos a guardar los cambios en el archivo y

a agregarlo al presente proyecto. Para agregarlo lo hacemos desde el menú Project y dentro de éste hacemos clic en Add Files... (Project > Add Files...). Una vez que aparece la ventana para agregar archivos al proyecto, seleccionamos el archivo comprador_1.vhd y presionamos el botón "Add".

Si por error hacemos clic en la opción Add All Files, todos los archivos .vhd dentro de la carpeta del proyecto se agregaran al mismo. En este caso el único archivo .vhd que debería estar dentro de la carpeta del proyecto es comparador_1.vhd, lo cual en esta ocasión no nos afectará. En caso de que hubiera más de un archivo .vhd y no deseamos tenerlo dentro del proyecto basta con seleccionarlo en la ventana de proyecto y presionar la tecla suprimir, o también desde Project > Remove Selected Source File(s). Si la ventana de proyecto no está visible entonces seleccionamos View > Reset Docking Windows.

Figura 4.14

7. Una vez editado y agregado el archivo al proyecto se procede a sintetizar el código en el 22V10. Seleccionamos Compile > Project o también lo podemos hacer presionado el icono de compilación.

Figura 4.15

Si el archivo tiene errores, estos aparecerán en la ventana de salida (Output Window). Dentro de "Errors & Warnings" en la ventana de salida se

Page 9: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

62

muestra una lista completa de los errores así como una descripción de cada error. Para acceder rápidamente a la línea en la cual ocurrió el error, basta con hacer doble clic sobre el error e inmediatamente el programa se colocará sobre la línea en donde se encuentra dicho error. Los errores pueden ser algunos de los siguientes: omitir algún punto y coma, no escribir correctamente algún identificador, sintaxis incorrecta de las instrucciones utilizadas, o uso incorrecto de los operadores. Recordemos que VHDL es un lenguaje en el que los tipos de datos son sumamente importantes y no se pueden mezclar a menos que se utilicen las librerías adecuadas.

8. La ventana de proyecto tiene 3 modos o vistas: "Source Files View", "Hierarchy View", y "Output Files View". En la primera se muestran los archivos que se han agregado al proyecto. La "Vista de Jerarquía" es útil cuando se hacen diseños jerárquicos, ya que en esta se muestra cual es el orden de importancia que hay entre ellos. Dentro de la "Vista de Archivos de Salida" aparecen los archivos que se generaron durante la compilación, los cuales fueron creados dentro de la carpeta del proyecto. Tales archivos de salida son: .jed, .rpt y un .vhd que se encuentra dentro de la carpeta "vhd" que está en la misma carpeta del proyecto (ver tema 4.2).

Figura 4.16

En el archivo .rpt se muestra un informe de los resultados de la compilación. En éste se encuentran

las ecuaciones que resultaron durante el proceso de síntesis, la asignación de pines, y un informe de utilización del dispositivo. En ocasiones es complicado realizar algunas descripciones y, aunque el código se sintetiza, durante la simulación hace algo diferente a lo que esperábamos. La función del sintetizador, en este caso WARP, es la de interpretar nuestra descripción en VHDL para generar la lógica de salida. En estos casos posiblemente la descripción no corresponde exactamente a lo que queremos. Para corregir la descripción es útil consultar las ecuaciones, ya que en estas nos podemos dar cuenta que es lo que estamos describiendo realmente. En temas posteriores se presentan algunos ejemplos en los que se exponen con más detalle este tipo de problemas.

SIMULACIÓN

9. Ahora que ya hemos logrado sintetizar el código y obtenido los archivos .jed y .vhd de postsíntesis procedemos a simular la descripción. Las simulaciones las haremos en Active-HDL Sim como se explicó en tema 4.2. Podemos abrir el programa desde Galaxy desde Tools > Active-HDL Sim.

Figura 4.17

10. Una vez iniciado el simulador, ahora abrimos el archivo .vhd de postsíntesis como se explica a continuación. Primero seleccionamos File > Open VHDL.

Page 10: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

63

Figura 4.18

Para después abrir el archivo .vhd de postsíntesis, el cual debería estar (si seguiste correctamente todos los pasos) en el subdirectorio: c:\vhdl_proj\comparador_1\vhd\comparador1.vhd

Figura 4.19

11. Hecho lo anterior ahora agregamos las señales y/o puertos que deseamos simular. Seleccionamos Waveform > Add Signals...

Figura 4.20

Ahora seleccionamos los puertos como se explicó en el tema 4.2. En este ejercicio seleccionaremos solamente los puertos declarados en la entidad, tal y como se muestra en la figura 4.22

12. Lo siguiente es asignar señales de estimulo a los puertos de entrada. Al bus "x" le asignaremos un estimulador tipo formula usando la siguiente formula. 0000 0 ns, 0001 1 us, 0010 2 us, 0011 3 us, 0100 4 us, 0101 5 us, 0110 6 us, 0111

7 us, 1000 8 us, 1001 9 us, 1010 10 us, 1011 11 us, 1100 12 us, 1101 13 us, 1110 14 us, 1111 15 us -r 16 us

Y al bus "y" también le asignaremos un estimulador del mismo tipo con la siguiente formula. 0000 0 ns, 1111 1 us, 1110 2 us, 1101 3 us, 1100 4 us, 1011 5 us, 1010 6 us, 1001 7 us, 1000 8 us, 0111 9 us, 0110 10 us, 0101 11 us, 0100 12 us, 0011 13 us, 0010 14 us, 0001 15 us -r 16 us

13. Una vez que asignamos los estimuladores iniciamos la simulación seleccionando: Simulation > Initialize Simulation.

14. Una vez iniciada la simulación ahora corremos la simulación. Para poder correrla existen tres opciones: correr completamente la simulación (el máximo es de 2ms+3), correrla y que se detenga en un momento especifico, o adelantar la simulación solamente por algún tiempo. Para correr la simulación completamente seleccionamos Simulation > Run. Si queremos correr la simulación y especificar un tiempo en el que debe detenerse seleccionamos Simulation > Run Until... . Para correr la simulación "por pasos" o por tiempos especificados, seleccionamos Simulation > Run For. El tiempo de paso se especifica a un lado del icono de Run For. Esta última opción es la más practica al momento de simular descripciones.

Figura 4.21

Si deseas utilizar Run For cerciórate que el tiempo de "paso" sea de 1 us. Ya que cuando asignamos los estimuladores el valor de los buses de entrada cambia cada 1 us. Si deseas utilizar Run Until... bastara con especificar un tiempo de 32 us para observar como se comporta el ciclo de asignaciones que especificamos mediante la formula, el tiempo mínimo para comprobar todos los valores (por lo menos un ciclo) es de 16 us.

15. A continuación en la figura 4.23 se muestran los resultados de la simulación. Si seguiste correctamente todos los pasos deberías obtener algo similar a lo mostrado en la siguiente figura.

Page 11: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

64

Figura 4.22

Figura 4.23

Figura 4.24

Page 12: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

65

4.4 MULTIPLEXORES

En este tema el objetivo es elaborar descripciones de circuitos multiplexores utilizando los tres estilos de descripción de VHDL.

PROCEDIMIENTO

Para la síntesis utilizaremos un 22V10 siguiendo la siguiente tabla de funcionamiento en los tres estilos de descripción.

TABLA DE FUNCIONAMIENTO

selec salida

00 a

01 b

10 c

11 d

4.4.1 DESCRIPCIÓN DE FLUJO DE DATOS LIBRARY ieee; USE ieee.std_logic_1164.ALL; LIBRARY cypress; USE cypress.std_arith.ALL ; ENTITY multiplexor IS

PORT(a, b, c, d: IN std_logic_vector (3 DOWNTO 0);

selec: IN std_logic_vector (1 DOWNTO 0);

salida: OUT std_logic_vector (3 DOWNTO 0));

END multiplexor; ARCHITECTURE data_flow OF multiplexor IS BEGIN

salida <= a WHEN selec = 0 ELSE b WHEN selec = 1 ELSE c WHEN selec = 2 ELSE d WHEN selec = 3 ;

END data_flow;

El listado anterior corresponde a un multiplexor 4 a 1. El bus de salida es seleccionado mediante las señales de selección selec(1) y selec(0) (std_logic_vector es un arreglo de datos del tipo std_logic). Como habrás notado se hizo el llamado a una librería no mencionada anteriormente, la librería "cypress". Esta librería es de Cypress Semiconductors y fue desarrollada para facilitar la

descripción de circuitos digitales utilizando WARP. De esta librería se llamó el paquete std_arith, el cual contiene muchas funciones que facilitan el uso de vectores tipo std_logic con enteros. De no haber utilizado este paquete no podríamos hacer ninguna de la comparaciones que están en la asignación condicional WHEN... ELSE. Es decir, no es posible hacer la comparación "selec = 3" porque "selec" es del tipo std_logic_vector y "3" es un número entero. El paquete std_logic_1164 contiene los tipos de datos std_logic y std_logic_vector que comúnmente utilizamos por lo que es necesario cargar el paquete para poder utilizar estos tipos, sin embargo, no contiene funciones de comparación entre tipos std_logic (o arreglos de este) y enteros. Como la librería es de propia del sintetizador, es decir, que siempre esta cargada dentro del área de trabajo del proyecto o "work", podemos llamar el paquete como se muestra a continuación. USE work.std_arith.ALL;

SIMULACIÓN

Para la simulación se sugiere que asignes un estimulador tipo formula a los vectores de entrada, y al vector "selec" le asignes un estimulador tipo "HOTKEY". Una vez que agregaste las señales a la simulación, selecciona con el puntero el vector "selec", después seleccionas Waveform > Stimulators..., cuando aparezca el cuadro de estimuladores selecciona "HOTKEY" dentro de "Stimulator type", y en "Press new hotkey" escribe la letra "s" o cualquier otra.

Figura 4.25

Cada que presiones la tecla "s" el vector s estará cambiando de valor, por omisión la lista de valores de asignación incluye el '0' y el '1' solamente, en

Page 13: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

66

este caso necesitamos generar valores para un vector de 2 bits. Para poder hacerlo, en el mismo cuadro de dialogo cámbiate a la sección de "Hotkeys". En esta parte aparecerán las teclas que ya han sido asignadas dentro del archivo para ser utilizadas como estimuladores, así como la lista de valores de asignación de cada tecla. Para modificar la lista de valores de la tecla "s" (la que estamos utilizando), con el puntero colócate en el cuadro de secuencia y escribe la nueva lista de valores.

Figura 4.26

Ahora puedes correr la simulación poco a poco utilizando Simulation > Run For, o presionando la tecla "F5". Y cada que lo desees presionas la tecla "s" para cambiar el valor del vector "selec". En la figura 4.24 se muestran los resultados de la simulación.

A continuación se muestran las ecuaciones obtenidas utilizando el estilo de descripción de flujo de datos. Estas ecuaciones deben ser las mismas para cualquier estilo que utilicemos, ya que estamos describiendo el mismo multiplexor sólo que de manera diferente y esto no implica que las ecuaciones vayan a ser distintas. Cuando compiles este multiplexor, en cualquiera de los tres estilos, consulta las ecuaciones dentro del archivo .rpt y verifica que sean iguales.

4.4.2 DESCRIPCIÓN COMPORTAMENTAL LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE work.std_arith.ALL;

ENTITY multiplexor IS PORT(a: std_logic_vector

(3 DOWNTO 0); b: std_logic_vector

(3 DOWNTO 0); c: std_logic_vector

(3 DOWNTO 0); d: std_logic_vector

(3 DOWNTO 0); selec: std_logic_vector

(1 DOWNTO 0); salida: OUT std_logic_vector

(3 DOWNTO 0)); END multiplexor; ARCHITECTURE behavorial OF multiplexor IS BEGIN

PROCESS(selec, a, b, c, d) VARIABLE selec_int: integer;

BEGIN selec_int := to_integer(selec); CASE selec_int IS

WHEN 0 => salida <= a ;

WHEN 1 => salida <= b ;

WHEN 2 => salida <= c ;

WHEN 3 => salida <= d ;

WHEN OTHERS => NULL;

END CASE; END PROCESS;

END behavorial;

Page 14: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

67

Dentro del proceso se hace uso de un objeto de datos del tipo variable declarado como entero. Al inicio del proceso se hace la asignación "selec_int <= to_integer ( selec ) ;", esto es para poder usar enteros en la instrucción CASE, de otra manera tendríamos que indicar todos los casos utilizando los valores naturales de un vector, es decir, "00", "01", "10", y "11" para este ejemplo. Esto es solamente para facilitar la descripción y no significa que obtengamos una mejor síntesis del código en el dispositivo. Es necesario que "selec_int" sea una variable para que se le asigne inmediatamente el valor actual del vector "selec" y estemos describiendo el correctamente el funcionamiento del multiplexor. Si quisiéramos utilizar una señal en vez de una variable tenemos que hacerlo de la siguiente manera. ARCHITECTURE behavorial2 OF multiplexor IS

SIGNAL selec_int:integer; BEGIN

selec_int <= to_integer( selec ); PROCESS(selec_int, a, b, c, d) BEGIN

CASE selec_int IS WHEN 0 =>

salida <= a ; WHEN 1 =>

salida <= b ; WHEN 2 =>

salida <= c ; WHEN 3 =>

salida <= d ; WHEN OTHERS =>

NULL; END CASE;

END PROCESS; END behavorial2;

Si observas con cuidado podrás ver que seguimos describiendo exactamente los mismo. Tanto el procesos como la asignación son de naturaleza concurrente, por lo que selec_int tiene siempre el valor actual de selec y lo convertimos a un tipo entero para facilitar la descripción. Trata de imaginar la asignación "selec_int <= to_integer ( selec )" como un circuito combinacional cuya función es cambiar el tipo de datos con el estamos manejando el vector selec y cuya salida (selec_int) se la conectamos (piensa en señales como cables) al proceso, que viene siendo otro circuito que "procesa" la información que se le suministra y obtiene finalmente la lógica de salida. A continuación se muestra un diagrama a bloques que trata de representar lo que estamos haciendo en la arquitectura anterior (behavorial2).

Figura 4.27

4.4.3 DESCRIPCIÓN ESTRUCTURAL

Para la descripción estructural primero debemos realizar la descripción de un multiplexor 2 a 1 para después interconectar tres de ello como se muestra en la figura siguiente.

Figura 4.28

Para realizar descripciones estructurales lo recomendable es utilizar varios archivos .vhd, cada uno para una entidad o paquete en particular. Crea un proyecto para la descripción estructural del multiplexor 4 a 1. Ahora crea un nuevo archivo de texto y copia la siguiente descripción. LIBRARY ieee; USE ieee.std_logic_1164.ALL; PACKAGE multiplexor IS

COMPONENT mux_2_a_1 PORT( in1: IN std_logic_vector

(3 DOWNTO 0); in2: IN std_logic_vector

(3 DOWNTO 0); sel: IN std_logic; out1: OUT std_logic_vector

(3 DOWNTO 0));

Page 15: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

68

END COMPONENT; END multiplexor; LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY mux_2_a_1 IS

PORT (in1, in2: IN std_logic_vector (3 DOWNTO 0);

sel: IN std_logic; out1: OUT std_logic_vector

(3 DOWNTO 0)); END mux_2_a_1; ARCHITECTURE data_flow OF mux_2_a_1 IS BEGIN

out1 <= in1 WHEN sel = '0' ELSE in2;

END data_flow;

Guarda este archivo como mux_2_a_1.vhd dentro de la carpeta de trabajo del proyecto. Como podrás ver estamos creando un paquete con nombre "multiplexor" el cual se agrega a la librería del proyecto work. Además se tienen que llamar las librerías que se necesiten antes del paquete y antes de la entidad. Ahora abre un nuevo archivo de texto y copia en él la siguiente descripción. -- mux_structural.vhd LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE work.multiplexor.ALL; -- llamado al paquete multiplexor que se -- encuentra en la librería -- del proyecto ENTITY multiplexor IS PORT ( a,b,c,d: IN std_logic_vector

(3 DOWNTO 0); selec: IN std_logic_vector

(3 DOWNTO 0); salida: OUT std_logic_vector

(3 DOWNTO 0)); END multiplexor; ARCHITECTURE structural OF multiplexor IS

SIGNAL salida1, salida2: std_logic_vector(3 DOWNTO 0);

BEGIN u1: mux_2_a_1 PORT MAP(a, b, selec(0),

salida1); u2: mux_2_a_1 PORT MAP(c, d, selec(0),

salida2); u3: mux_2_a_1 PORT MAP ( salida1,

salida2, selec(1), salida); END structural;

Guarda este archivo como mux_structural.vhd, y agrega ambos archivos al proyecto (Proyect > Add Files...). Compila el proyecto y comprueba que las ecuaciones de salida siguen siendo las mismas ya que estamos describiendo el mismo

funcionamiento. Dentro de la ventana de proyecto en la "vista de jerarquía" (Hierarchy View) aparece el orden en que los componentes están siendo utilizados dentro del diseño jerárquico.

Figura 4.29

Una vez que has compilado y simulado este multiplexor utilizando los tres estilos podrás ver que no hay ninguna diferencia entre usar un estilo u otro. Lo importante es describir el mismo funcionamiento para obtener los mismo resultados. De hecho, mientras estemos describiendo exactamente lo mismo no importa el número de líneas que se hagan, porque VHDL no es un lenguaje de programación de software.

4.5 SUMADORES

El diseño de circuitos aritméticos eficientes es un tema fundamental en el diseño de circuitos digitales, por lo que es importante para el diseñador estar familiarizado con las opciones disponibles en la selección de algoritmos eficientes en sus aplicaciones. Está práctica tiene por objetivo familiarizarte en el diseño de circuitos sumadores utilizando algoritmos eficientes en VHDL.

4.5.1 SUMADOR TOTAL

El componente básico usado en la adición de dos operandos es conocido como "sumador total". Este sumador total representa el componente con el cual podemos formar sumadores de cualquier número de bits. A continuación se muestra la tabla de funcionamiento y la representación esquemática de un sumador total, y basándose en la tabla se hará la descripción de sumador total en VHDL, para posteriormente diseñar un circuito sumador de 4 bits utilizando un 22V10.

Page 16: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

69

Figura 4.30

TABLA DE FUNCIONAMIENTO

ENTRADAS SALIDASa b ci co suma0 0 0 0 00 0 1 0 10 1 0 0 10 1 1 1 01 0 0 0 11 0 1 1 01 1 0 1 01 1 1 1 1

LIBRARY ieee; -- full_adder.vhd USE ieee.std_logic_1164.ALL; PACKAGE adder IS

COMPONENT full_adder PORT(ci: IN std_logic;

a, b: IN std_logic; sum: OUT std_logic; co: OUT std_logic);

END COMPONENT; END adder; LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE work.std_arith.ALL; ENTITY full_adder IS

PORT(ci: IN std_logic; a, b: IN std_logic; sum: OUT std_logic; co: OUT std_logic);

END full_adder; ARCHITECTURE data_flow OF full_adder IS

SIGNAL entradas: std_logic_vector (2 DOWNTO 0);

SIGNAL salidas: std_logic_vector (1 DOWNTO 0);

BEGIN entradas <= a&b&ci ; salidas <= "00" WHEN entradas = 0 ELSE

"01" WHEN entradas = 1 ELSE "01" WHEN entradas = 2 ELSE "10" WHEN entradas = 3 ELSE "01" WHEN entradas = 4 ELSE

"10" WHEN entradas = 5 ELSE "10" WHEN entradas = 6 ELSE "11" WHEN entradas = 7;

sum <= salidas(0); co <= salidas(1) ;

END data_flow;

Si conoces las ecuaciones del circuito también puedes utilizarlas para hacer la descripción. ARCHITECTURE data_flow OF full_adder IS BEGIN

sum <= a XOR b XOR C; co <= (a AND b) OR

(a AND ci) OR (b AND ci);

END data_flow;

Crea un nuevo proyecto en c:\vhdl_proj\prac5\ y llámalo sumador. Después crea un nuevo archivo de texto y copia en él la descripción anterior. Guarda el archivo de texto como full_adder.vhd dentro de la carpeta de trabajo del proyecto. Agrega el archivo al proyecto y compila el proyecto utilizando la arquitectura data_flow. Abre el reporte de compilación y observa las ecuaciones. Ahora compila el proyecto utilizando la segunda arquitectura data_flow. Vuele a abrir el proyecto y observa las ecuaciones. ¿Por qué son las mismas ecuaciones? porque estamos describiendo el mismo funcionamiento y el estilo o el número de líneas que utilices no importa siempre y cuando este describiendo exactamente el mismo circuito.

4.5.2 SUMADOR DE CUATRO BITS

Para hacer la descripción utilizaremos cuatro unidades del sumador total (u1 a u4) y las conectaremos como se muestra continuación.

Figura 4.31

Abre un nuevo archivo de texto y copia en él la siguiente descripción. -- sumador de 4 bits utilizando -- un sumador total

Page 17: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

70

LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE work.std_arith.ALL; USE work.adder.ALL; ENTITY sumador IS

PORT (ci: IN std_logic; a, b: IN std_logic_vector

(3 DOWNTO 0); sum: OUT std_logic_vector

(3 DOWNTO 0); co: OUT std_logic);

END sumador; ARCHITECTURE structural OF sumador IS

SIGNAL c1, c2, c3: std_logic; BEGIN

u1: full_adder PORT MAP (ci, a(0), b(0), sum(0), c1 ) ;

u2: full_adder PORT MAP (c1, a(1), b(1), sum(1), c2 ) ;

u3: full_adder PORT MAP (c2, a(2), b(2), sum(2), c3);

u4: full_adder PORT MAP (c3, a(3), b(3), sum(3), co);

END structural;

Guarda el archivo de texto en la carpeta de trabajo del proyecto (c:\vhdl_proj\prac5) como sumador.vhd. Compila el proyecto y observa lo que sucede. Si estas usando la versión 5.0 o 5.2 de WARP, la compilación te indicará los siguientes errores. Error: Logic equation has too many product terms on signal co. Error: Logic equation has too many product terms on signal sum(2). Error: Logic equation has too many product terms on signal sum(3).

Abre el reporte de compilación y observa las ecuaciones. La descripción no se pudo compilar porque las ecuaciones tienen demasiadas sumas de productos. El sintetizador de WARP siempre trata de evitar retroalimentaciones para que el circuito funcione con la mayor velocidad posible. Nosotros deseamos que los nodos c1, c2, y c3 queden en un pin de salida del 22V10 para de esta forma hacer las conexiones como se muestran en el diagrama a bloques del sumador de 4 bits. Para lograrlo basta con describir la entidad como se muestra a continuación. ENTITY sumador IS

PORT ( ci: IN std_logic; a, b: IN std_logic_vector

(3 DOWNTO 0); sum: OUT std_logic_vector

(3 DOWNTO 0);

co, c1, c2, c3: INOUT std_logic); END sumador;

De esta forma enviamos los nodos c1, c2, y c3 a la salida de una macroceldas, en el caso del 22V10 a un pin de salida, y así evitamos que el sintetizador elimine el nodo porque ya lo declaramos como puerto.

4.5.3 SYNTHESIS OFF

Otra forma de evitar que se simplifique el nodo es utilizando directivas de síntesis. En este caso utilizaremos la directiva synthesis_off que está incluida en WARP. Esta directiva nos permite controlar la forma en que el sintetizador factoriza y obtiene las ecuaciones de salida y de esta manera evitar que la ecuación de un nodo se incluya en la ecuación de otro nodo y así evitar retroalimentaciones. Para entender como funciona esta directiva observe el siguiente ejemplo. ENTITY synthesis_off IS

PORT ( a, b, c: IN bit; y: OUT bit);

END synthesis_off; ARCHITECTURE simplifica_nodo OF synthesis_off IS

SIGNAL x: bit; BEGIN

x <= a AND b; y <= x OR c;

END simplifica_nodo;

Cuando compilemos el archivo la ecuación del nodo "x" se sustituye en la ecuación del puerto "y" como se muestra abajo. y = a * b + c

Lo que trataríamos de hacer entonces sería declara el nodo "x" como puerto y no como señal de interconexión, pero observa que es lo que sucede. x = a * b y = a * b + c

La ecuación de "x" se sigue sustituyendo en la ecuación del puerto "y". Como habíamos mencionado, el sintetizador siempre busca que el circuito que le estamos describiendo funcione a la mayor frecuencia posible. Al obtener las ecuaciones de la forma anterior evitamos que exista una retroalimentación desde el pin del puerto "x", ya que si retroalimentamos tenemos que esperar el tiempo de retardo de las compuertas

Page 18: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

71

que intervienen en las ecuaciones de "x" para que después el valor de "x" se incorpore a las ecuaciones del puerto "y". Por lo que el tiempo de retardo para el puerto "y" sería mayor. Sin embargo, aunque lo mejor es que nuestro circuito funcione a mayor velocidad, en ocasiones necesitamos que el nodo quede en una macrocelda para que después se retroalimente hacia otras ecuaciones. Ya sea por que lo necesitamos en el diseño del circuito o por las limitaciones del dispositivo programable. Es aquí donde las directivas de síntesis nos permiten controlar el proceso de síntesis. Observa el siguiente ejemplo en el que se muestra como utilizar la directiva synthesis_off. ENTITY synthesis_off IS

PORT ( a, b, c: IN bit; y: OUT bit);

END synthesis_off; ARCHITECTURE no_simplifica_nodo OF synthesis_off IS

SIGNAL x: bit; ATTRIBUTE synthesis_off OF x: SIGNAL IS

true; BEGIN

x <= a AND b; y <= x OR c;

END no_simplifica_nodo;

Las ecuaciones que resultan del proceso de síntesis son las siguientes. /y = /c * /x x = a * b

Ahora las ecuaciones tienen menos términos y obligamos a que el nodo "x" quede en una terminal, obligándolo a quedar en una macrocelda para que después se retroalimente. Para el circuito sumador de cuatro bits podemos utilizar esta directiva de la siguiente forma. ARCHITECTURE structural OF sumador IS

SIGNAL c1, c2, c3: std_logic; ATTRIBUTE synthesis_off OF c1, c2, c3:

SIGNAL IS true; BEGIN

u1: full_adder PORT MAP (ci, a(0), b(0), sum(0), c1 ) ;

u2: full_adder PORT MAP (c1, a(1), b(1), sum(1), c2 ) ;

u3: full_adder PORT MAP (c2, a(2), b(2), sum(2), c3);

u4: full_adder PORT MAP (c3, a(3), b(3), sum(3), co);

END structural;

Esta directiva sólo puede ser aplicada a señales, para una explicación más detallada de esta y otras directivas de síntesis consulta la ayuda del programa (Help > Help Topics). Para diseño de circuitos aritméticos y no aritméticos que sean grandes o complejos, lo mejor es hacer descripciones estructurales y utilizar las directivas de síntesis cuando sea necesario.

4.6 REGISTROS

Existen dos métodos para implementar lógica registrada en VHDL: mediante instanciación de registros (utilizando librerías de componentes) o utilizando procesos para realizar la descripción comportamental del registro.

Por ejemplo, si se desea utilizar un registro D y un contador de 4 bits, basta con realizar la instanciación de dichos componentes después de incluir los paquetes apropiados.

EJEMPLO USE work.rtlpkg.ALL; -- paquetes de WARP USE work.lpmpkg.ALL; . . . -- DSRFF: definido en rtlpkg d1: dsrff PORT MAP(d, s, r, clk, q ; -- Mcounter: definido en lpmpkg c1: Mcounter GENERIC MAP (4)

PORT MAP (data, clk, one, one, one, count, zero, rst, zero, zero, zero, zero zero, zero, OPEN);

Otra forma de registrar elementos es incluir un proceso que sea sensible a las transiciones de una señal de reloj o que espere una transición de reloj utilizando la instrucción WAIT, de esta manera el compilador asigna un registro a las señales afectadas dentro del proceso. Existen 4 formas básicas para describir registros, cada una de ellas se explica a continuación. PROCESS BEGIN WAIT UNTIL clk = '1'; . . . END PROCESS;

Este proceso no tiene lista sensible, por lo que comienza con una instrucción WAIT. Las instrucciones dentro del proceso se comenzarán a ejecutar cuando exista una transición positiva de la

Page 19: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

72

señal de reloj "clk". Todas las asignaciones a señales dentro del proceso serán registradas, ya que estas sólo cambian de valor en las transiciones de reloj y lo retienen por lo menos hasta la siguiente transición. PROCESS (clk) BEGIN

IF ( clk'event AND clk ='1' ) THEN . . . END IF;

END PROCESS;

Este proceso es sensible solamente a los cambios en la señal "clk", como se indica en la lista sensible. La primera instrucción, IF... THEN, dentro del proceso restringe al resto de las instrucciones a ser ejecutadas únicamente durante la transición positiva de la señal "clk", por lo que ahora también todas las señales que reciban una asignación dentro de la instrucción IF... THEN serán registradas y mantendrán dicho valor recibido por lo menos hasta la siguiente transición de reloj. PROCESS(rst, clk) BEGIN

IF rst = '1' THEN . . . ELSIF(clk'event AND clk='1') THEN . . . END IF;

END PROCESS;

Este proceso es sensible a los cambios en la señal de reloj "clk" y la señal de reinicio "rst", como es indicado en la lista sensible. Mediante este método de descripción comportamental es posible registrar señales y además tener un "reset" asíncrono. La primera instrucción checa primero el estado de la señal "rst". Las señales que son asignadas dentro de esta porción de la estructura IF... THEN... ELSIF, se asume que son registradas asíncronamente con la señal de "reset" asignada, y serán sintetizadas en registros con capacidad para realizar dicha acción. Si la condición de "reset" no se cumple, el resto de la instrucción IF... THEN... ELSIF, funciona como el proceso explicado anteriormente. PROCESS(rst, pst, clk) BEGIN IF rst = '1' THEN . . . ELSIF pst = '1' THEN . . . ELSIF (clk'event AND clk='1') THEN

. . . END IF; END PROCESS;

Este proceso es sensible a los cambios en la señales "clk", "rst" y "pst", como se indica en la lista sensible. De esta forma es posible realizar la descripción de registros con "preset" y "reset" asíncronos. La primera instrucción dentro del proceso checa el estado de la señal "rst". Todas las señales que son asignadas dentro de la primera porción de la estructura, se asume que serán registradas mediante la señal de "rst" asíncrono. La segunda condición checa el estado de la señal "pst", y todas las señales que sean asignadas dentro de esta porción del proceso son registradas asíncronamente mediante la señal de "preset" asíncrono "pst". Si las dos primeras condiciones no se cumplen, el resto de la instrucción IF... THEN... ELSIF, representa el funcionamiento síncrono del registro.

EJEMPLO

A continuación se muestra una forma de realizar la descripción de un registro de 32 bits con "reset" asíncrono. PROCESS(r, clk2) BEGIN

IF (r = '1') THEN q <= x"123DEABC" ;

ELSIF (clk2'event AND clk2='1') THEN q <= d;

END IF; END PROCESS;

Asumiendo que "q" y "d" son declarados como señales o puertos de 32 bits, entonces este código ejemplifica la implementación de un registro de 32 bits con d(i) como entrada, q(i) como salida, "clk2" como la señal de reloj, y "r" como la señal de "reset" asíncrono para algunos registros y también como señal de "preset" asíncrono para otros. Esto significa que cuando se cumple la condición: r = '1', la asignación q <= x"ABC123DE" provocará que algunos registros sean puestos en alto mientras que otros van a quedar en un estado de cero lógico.

EJEMPLOS

A continuación realice la descripción de los siguientes registros de acuerdo con su tabla de funcionamiento.

Page 20: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

73

REGISTRO NO. 1

Elabore la descripción del registro utilizando un 22V10 y posteriormente trate de implementar la descripción en un 16V8, simule la descripción y obtenga sus conclusiones.

TABLA DE FUNCIONAMIENTO

ENTRADAS SALIDAS

reset d clk q

1 0 transición positiva 0

1 1 transición positiva 1

0 - - 0 ENTITY reg1 IS

PORT(reset: IN bit; d: IN bit;

clk: IN bit; q: OUT bit);

END reg1; ARCHITECTURE areg OF reg1 IS BEGIN

PROCESS(clk, reset, d) BEGIN IF reset = '0' THEN q <= '0'; ELSIF clk'event AND clk = '1' THEN q <= d;

END IF; END PROCESS;

END areg;

REGISTRO NO. 2

Elabore la descripción del registro utilizando un 22V10 y posteriormente utilice un 16V8, simule la descripción en ambos casos y obtenga sus conclusiones. TABLA DE FUNCIONAMIENTO

ENTRADAS SALIDAS

reset d clk q

1 0 transición positiva 0

1 1 transición positiva 1

0 - transición positiva 0 ENTITY reg2 IS

PORT(reset, d,clk: IN bit; q: OUT bit);

END reg2;

ARCHITECTURE areg2 OF reg2 IS BEGIN

PROCESS(clk, reset, d) BEGIN IF clk'event AND clk = '1' THEN IF reset = '0' THEN

q <= '0'; ELSE q <= d; END IF; END IF;

END PROCESS; END areg2;

REGISTRO NO. 3

Elabore la descripción del siguiente registro utilizando un 22V10, simule la descripción y obtenga sus conclusiones.

TABLA DE FUNCIONAMIENTO

ENTRADAS SALIDAS

enable d clk q

1 0 transición positiva 0

1 1 transición positiva 1

0 - - Z LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY reg2 IS

PORT(enable: IN std_logic; d: IN std_logic;

clk: IN std_logic; q: OUT std_logic);

END reg2; ARCHITECTURE areg2 OF reg2 IS SIGNAL q_tmp: std_logic; BEGIN -- lógica registrada

PROCESS(clk, reset, d) BEGIN IF clk'event AND clk = '1' THEN

q_tmp <= d; END IF; END IF;

END PROCESS;

-- buffer q <= q_tmp WHEN enable = '1' g 'Z';

END areg2;

Page 21: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

74

4.7 CONTADORES

La finalidad de un contador es computar el número de ocurrencias de un evento que se da en intervalos aleatorios o uniformes. En los siguientes ejemplos se muestran diferentes tipos de contadores y la forma más común de describir su comportamiento con VHDL.

EJEMPLOS LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY counter IS

PORT( clk, load: IN std_logic; data: IN unsigned(3 DOWNTO 0); count: BUFFER unsigned(3 DOWNTO 0));

END counter; ARCHITECTURE archcounter OF counter IS BEGIN

PROCESS( clk, load, count, data ) BEGIN

IF( clk'event AND clk= '1' ) THEN IF load = ’1’ THEN

count <= data; ELSE

count <= count + 1; END IF;

END IF; END PROCESS;

END archcounter;

La instrucción USE ieee.numeric_std.ALL es para incluir el tipo de datos unsigned, así como las funciones aritméticas y lógicas que nos permiten manipular objetos de datos que manejen este tipo. En este ejemplo en particular nos interesa la función "+" definida para ser utilizada con el tipo unsigned y enteros. Ya que el operador "+" en VHDL originalmente está definido únicamente para ser utilizado con enteros. La arquitectura que describe al contador utiliza el estilo comportamental. En este diseño el contador funciona ascendentemente y, además, realiza carga paralela de datos síncronamente con la señal de reloj dependiendo del valor del puerto de control "load".

Dentro del proceso, la instrucción IF ( clk’event AND clk= ’1’ ) THEN... implica que el funcionamiento del contador, conteo y carga paralela, tome lugar durante la transición positiva de la señal de reloj "clk". La siguiente instrucción IF... THEN... define la operación de conteo o de carga paralela del circuito dependiendo de la condición: load = '1'. A continuación se expone un contador similar pero con reset síncrono.

LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY counter IS PORT (clk, load, reset: IN std_logic;

data: IN unsigned(3 DOWNTO 0); count: BUFFER unsigned(3 DOWNTO 0));

END counter; ARCHITECTURE archcounter OF counter IS BEGIN

PROCESS(clk, reset, load, count, data) BEGIN

IF ( clk’event AND clk= '1' ) THEN IF reset = '1' THEN

count <= (OTHERS => '0'); ELSIF load = '1' THEN

count <= data; ELSE

count <= count + 1; END IF;

END IF; END PROCESS;

END archcounter;

En este ejemplo se describe un contador ascendente, con reset síncrono dependiendo de la entrada "reset", además, con capacidad de carga paralela de datos mediante el puerto de control "load". Al igual que el ejemplo anterior, la instrucción IF (clk'event AND clk = '1' ) aparece al principio e implica que todas las operaciones del contador se ejecuten durante la transición positiva de la señal de reloj "clk". La subsecuente instrucción IF describe la operación de reset síncrono durante la transición positiva del reloj. El resto de las operaciones, el conteo y la carga paralela, son descritas en las siguientes cláusulas ELSIF y ELSE dentro de la misma instrucción IF, por lo que podemos observar que la operación de reset tiene precedencia sobre las operaciones de carga y conteo. Así, si reset no es '1', entonces la operación de conteo depende de la señal "load". Como podemos ver las operaciones de carga y conteo son identificas al contador en el ejemplo anterior.

Ahora se expone a continuación un contador con reset asíncrono y con capacidad para salida en alta impedancia. LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY cnt_oe IS

PORT(clk, reset, oe: IN std_logic; count_io: INOUT std_logic_vector

(7 DOWNTO 0));

Page 22: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

75

END ldcnt; ARCHITECTURE arch_cnt_oe OF cnt_oe IS

SIGNAL count: std_logic_vector (7 DOWNTO 0);

BEGIN PROCESS(clk, reset, count) BEGIN

IF reset = '0' THEN count <= (OTHERS => '0');

ELSIIF ( clk’event AND clk=’1’ ) THEN count <= count + 1;

END IF; END PROCESS; count_io <= count WHEN oe = ’1’ ELSE

(OTHERS => 'Z'); END arch_cnt_oe;

Este diseño desempeña un contador ascendente con reset asíncrono. Cuando se cumple la condición: reset = '0', se produce un reset asíncrono en el contador. Cuando esta condición no se satisface, la operación de conteo funciona síncronamente con la señal de reloj "clk". Además, independientemente de las señal de reset, el uso de los buffers de tres estados en los pines de I/O es posible mediante el uso del puerto de entrada "oe". Así, cuando se satisface la condición oe = '1', el conteo es conducido hacia los pines de salida. De lo contrario presentarán alta impedancia en los pines del circuito. Conceptualmente, el código en VHDL del contador se implementa de la siguiente manera.

Figura 4.32

A continuación se elabore la descripción en VHDL para los siguientes contadores de cuatro bits de acuerdo a su tabla de funcionamiento y posteriormente realice las simulaciones. Elija el dispositivo que más convenga.

CONTADOR NO. 1

ENTRADAS SALIDAS

reset up_down clk conteo

1 1 transición positiva ascendente

1 0 transición positiva descendente

0 - - 0 ENITTY counter IS

PORT(reset: IN bit; ud: IN bit; clk: IN bit; conteo: INOUT integer RANGE 0 TO 15 );

END counter; ARCHITECTURE counter OF counter IS BEGIN

PROCESS(reset,ud,clk) BEGIN

IF reset = '1' THEN conteo <= 0;

ELSIF (clk'event AND clk = '1') THEN IF ud = '1' THEN

conteo <= conteo + 1; ELSE

conteo <= conteo - 1; END IF;

END IF; END counter;

CONTADOR NO. 2

ENTRADAS SALIDAS

reset up_down clk conteo

1 1 transición positiva ascendente

1 0 transición positiva descendente

0 - transición positiva 0 ENITTY counter IS

PORT(reset: IN bit; ud: IN bit; clk: IN bit; conteo: INOUT integer RANGE 0 TO 15 );

END counter; ARCHITECTURE counter OF counter IS BEGIN

PROCESS(reset,ud,clk) BEGIN

IF (clk'event AND clk = '1') THEN IF reset = '1' THEN

conteo <= 0; ELSIF ud = '1' THEN

conteo <= conteo + 1; ELSE

conteo <= conteo - 1; END IF;

END IF; END counter;

Page 23: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

76

CONTADOR NO. 3

ENTRADAS SALIDAS

reset oe up_down clk conteo

1 1 1 transición positiva ascendente

1 1 0 transición positiva descendente

0 1 - - 0

0 0 - - Z

** NOTA

Aunque se encuentre la salida del circuito en alta impedancia, el conteo y reset asíncrono deben seguir funcionando internamente. LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENITTY counter IS

PORT(reset: IN std_logic; ud: IN std_logic; oe: IN std_logic; clk: IN std_logic; conteo: INOUT unsigned (3 DOWNTO 0) );

END counter; ARCHITECTURE counter OF counter IS

SIGNAL count_tmp: unsigned(3 DOWNTO 0); BEGIN

PROCESS(reset,ud,clk) BEGIN

IF reset = '1' THEN count_tmp <= (OTHERS => '0');

ELSIF (clk'event AND clk = '1') THEN IF ud = '1' THEN

count_tmp <= count_tmp + 1; ELSE

count_tmp <= count_tmp - 1; END IF;

END IF;

-- instanciación de los buffers conteo <= count_tmp WHEN oe = '1' ELSE

(OTHERS 'Z'); END counter;

CONTADOR NO. 4

ENTRADAS SALIDAS

reset oe up_down clk conteo

1 1 1 transición positiva

ascendente 0-9

1 1 0 transición positiva

descendente 9-0

0 1 - - 0

0 0 - - Z

** NOTA

Aunque se encuentre la salida del circuito en alta impedancia, el conteo y reset asíncrono deben seguir funcionando internamente. En el momento de cambio de sentido ascendente/descendente, el contador no debe de iniciar la cuenta, por ejemplo: si el contador está funcionando ascendentemente y se encuentra en el número 5 cuando se cambia a descendente, en la siguiente transición positiva se debe continuar la cuenta con un 4, después un 3... etc. LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENITTY counter IS

PORT(reset: IN std_logic; ud: IN std_logic; oe: IN std_logic; clk: IN std_logic; conteo: INOUT unsigned (3 DOWNTO 0) );

END counter; ARCHITECTURE counter OF counter IS

SIGNAL count_tmp: unsigned(3 DOWNTO 0); BEGIN

PROCESS(reset,ud,clk) BEGIN

IF reset = '1' THEN count_tmp <= (OTHERS => '0');

ELSIF (clk'event AND clk = '1') THEN IF ud = '1' THEN

count_tmp <= count_tmp + 1; IF count_tmp = 9 THEN

count_tmp <= (OTHERS => '0'); END IF;

ELSIF ud = '0' THEN count_tmp <= count_tmp - 1; IF count_tmp = 0 THEN

count_tmp <= "1001"; END IF;

END IF; END IF;

-- instanciación de los buffers conteo <= count_tmp WHEN oe = '1' ELSE

(OTHERS 'Z'); END counter;

Page 24: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

77

4.8 ALU DE CUATRO BITS

Realice la descripción en VHDL para la siguiente unidad aritmético - lógica de acuerdo a la tabla de funcionamiento utilizando un 22V10. El circuito consta de 2 bus de entrada "a" y "b", de 4 bits cada uno y mediante el bus "s", de 3 bits, se selecciona la operación a realizar en la ALU. Dicha operación se realiza combinacionalmente y en el momento que ocurre una transición positiva en la señal de reloj el resultado de dicha operación se registra en los flip-flop's tipo D del 22V10. Además, la salida registrada será conducida hacia los pines de salida (I/O pads) únicamente cuando se habiliten los buffers de tres estados mediante la entrada de control "oe", de lo contrario deberán encontrarse en alta impedancia.

ENTRADAS SALIDAS s(2) s(1) s(0) clk oe output cout

0 0 0 transición positiva 0 a AND

b 0

0 0 1 transición positiva 0 a OR b 0

0 1 0 transición positiva 0 a XOR

b 0

0 1 1 transición positiva 0 NOT a 0

1 0 0 transición positiva 0 a + 0 0

1 0 1 transición positiva 0 a + b acarreo de

la suma

1 1 0 transición positiva 0 a + b' acarreo de

la suma

1 1 1 transición positiva 0 a - 1 0

- - - - 1 Z 0

** NOTA

b' = NOT b

4.8.1 DESCRIPCIÓN ESTRUCTURAL

La descripción se realiza utilizando tres archivos, los cuales contienen: la entidad TOP, el módulo y el paquete respectivamente. El módulo realiza todas las operaciones dela ALU pero

solamente con un bit, y en la entidad TOP se realiza la interconexión de cuatr de estos módulos para formar la ALU de cuatro bits.

ENTIDAD TOP LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE work.modulo_alu.ALL; ENTITY alu IS

PORT(a: IN std_logic_vector(3 DOWNTO 0); b: IN std_logic_vector(3 DOWNTO 0); cin: IN std_logic ; clk: IN std_logic ; reset: IN std_logic ; oe: IN std_logic ; s: IN std_logic_vector(2 DOWNTO 0); cout: OUT std_logic;

output: OUT std_logic_vector(3 DOWNTO 0) );

END alu ; ARCHITECTURE a_alu OF alu IS SIGNAL c2, c3, c4: std_logic; SIGNAL salida_r: std_logic_vector

(3 DOWNTO 0); ATTRIBUTE synthesis_off OF c2, c3, c4:

SIGNAL IS true; BEGIN x0: modulo PORT MAP(a(0), b(0), cin,

clk, reset, s, c2, salida_r(0));

x1: modulo PORT MAP(a(1), b(1), c2, clk, reset, s, c3, salida_r(1));

x2: modulo PORT MAP(a(2), b(2), c3, clk, reset, s, c4, salida_r(2));

x3: modulo PORT MAP(a(3), b(3), c4, clk, reset, s, cout, salida_r(3));

-- instanciación de los biffers

output <= (OTHERS=>'Z') WHEN oe='1' ELSE salida_r;

END a_alu;

MÓDULO LIBRARY ieee ; USE ieee.std_logic_1164.ALL; ENTITY modulo IS PORT (in1: IN std_logic; in2: IN std_logic; cin: IN std_logic; clk: IN std_logic; reset: IN std_logic; selec: IN std_logic_vector(2 DOWNTO 0); cout: OUT std_logic ; salida_r: INOUT std_logic); END modulo; ARCHITECTURE a_modulo OF modulo IS SIGNAL salida_comb: std_logic ; BEGIN PROCESS(in2, in1, selec, cin)

Page 25: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

78

CONSTANT uno: std_logic := '1'; BEGIN CASE selec IS WHEN o"0" => salida_comb <= in1 AND in2; cout <= '0'; WHEN o"1" => salida_comb <= in1 OR in2; cout <= '0'; WHEN o"2" => salida_comb <= in1 XOR in2; cout <= '0'; WHEN o"3" => salida_comb <= NOT in1; cout <= '0'; WHEN o"4" => salida_comb <= in1; cout <= '0' ; WHEN o"5" => salida_comb<=in2 XOR in1 XOR cin; cout <= ( in1 AND cin ) OR

( in2 AND cin ) OR ( in2 AND in1 );

WHEN o"6" => salida_comb<= (NOT in2) XOR in1

XOR cin; cout <= (in1 AND cin) OR (( NOT in2 ) AND cin) OR (( NOT in2 ) AND in1); WHEN o"7" => salida_comb<=uno XOR in1 XOR cin; cout <= ( in1 AND cin) OR (uno AND cin ) OR ( uno AND in1 ) ; WHEN OTHERS => NULL; END CASE; END PROCESS; PROCESS( salida_comb, clk, reset ) BEGIN IF rising_edge( clk ) THEN salida_r <= salida_comb; END IF; END PROCESS; END a_modulo;

PAQUETE LIBRARY ieee; USE ieee.std_logic_1164.ALL; PACKAGE modulo_alu IS COMPONENT modulo PORT(in1: IN std_logic; in2: IN std_logic ; cin: IN std_logic ; clk: IN std_logic ; reset: IN std_logic ; selec: IN std_logic_vector(2 DOWNTO 0); cout: OUT std_logic ; salida_r: INOUT std_logic ) ; END COMPONENT; END modulo_alu;

4.8.2 DESCRIPCIÓN COMPORTAMENTAL

LIBRARY ieee ; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY aluIS PORT (in1: IN unsigned(3 DOWNTO 0); in2: IN unsigned(3 DOWNTO 0); cin, clk: IN std_logic; oe: IN std_logic; reset: IN std_logic; selec: IN integer RANGE 0 TO 7; cout: OUT std_logic ; salida: INOUT unsigned(3 DOWNTO 0);

); END alu; ARCHITECTURE alu OF alu IS SIGNAL comb, reg: unsigned(3 DOWNTO 0); SIGNAL c: unsigned(4 DOWNTO 0); SIGNAL c1,c2,c3

ATTRIBUTE synthesis_off OF c1, c2, c3: SIGNAL IS true

BEGIN c(0) <= cin; cout <= c(4); c1 <= c(1); c2 <= c(2); c3 <= c(3); PROCESS(in2, in1, selec, cin) CONSTANT uno: unsigned:= "0001"; BEGIN

FOR i IN in1'range LOOP CASE selec IS WHEN 0 => comb(i) <= in1(i) AND in2(i); c(i+1) <= '0'; WHEN 1 => comb(i) <= in1(i) OR in2(i); c(i+1) <= '0'; WHEN 2 => comb(i) <= in1(i) XOR in2(i);

c(i+1) <= '0'; WHEN 3 => comb(i) <= NOT in1(i); c(i+1) <= '0'; WHEN 4 => comb(i) <= in1(i); c(i+1) <= '0' ; WHEN 5 => comb(i) <= in2(i) XOR in1(i) XOR

c(i); c(i+1) <= (in1(i) AND c(i)) OR

(in2(i) AND c(i)) OR (in2(i) AND in1(i);

WHEN 6 => comb(i) <= (NOT in2(i)) XOR

in1(i) XOR c(i); c(i+1) <= (in1(i) AND c(i)) OR ((NOT in2(i)) AND c(i)) OR ((NOT in2(i)) AND in1(i)); WHEN 7 => comb(i) <= uno(i) XOR in1(i)

XOR c(i); c(i+1) <= (in1(i) AND c(i)) OR

Page 26: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

79

(uno(i) AND c(i)) OR (uno(i) AND in1(i)) ;

WHEN OTHERS => NULL; END CASE;

END LOOP; END PROCESS; PROCESS( comb, clk, reset ) BEGIN IF rising_edge( clk ) THEN reg <= comb; END IF; END PROCESS;

salida <= reg WHEN oe = '0' ELSE (OTHERS => 'Z');

cout <= '0' WHEN selec = 7 ELSE

c(4); END alu;s

4.9 MÁQUINAS DE ESTADO

Una máquina de estados es un circuito secuencial que es diseñado para seguir un patrón de funciones previamente definidas. Existen dos tipos de máquinas de estado: Mealy y Moore. En una máquina de estados de Moore, las salidas están únicamente en función del estado presente. Si es una máquina de estados de Mealy, las salidas están en función del estado presente y de las entradas. Una máquina de estados se compone de tres partes:

1. REGISTRO DEL ESTADO PRESENTE.

Este registro es un conjunto de n flip-flops sincronizados con la misma señal de reloj para almacenar el estado presente en la máquina.

2. LÓGICA COMBINACIONAL PARA GENERAR EL SIGUIENTE ESTADO.

3. Una máquina de estados solamente puede estar en un estado a un tiempo dado, es decir no puede hacer dos cosas a la vez. La lógica combinacional permite que en cada transición activa del reloj, la máquina vaya de un estado a otro o se mantenga en el mismo dependiendo de las condiciones definidas por el diseñador.

4. LÓGICA COMBINACIONAL DE SALIDA.

Las salidas normalmente están en función del estado presente y/o también en función de las entradas (Máquina de Estados de Mealy). Es común que en una máquina de estados de Moore se desee que las salidas estén en función del siguiente estado en vez de utilizar el actual cuando se utiliza una señal de reloj de alta frecuencia.

A continuación se muestran las estructuras para máquinas de estados de Moore y Mealy

Figura 4.33 Máquina de Estados de Moore

Figura 4.34 Máquina de Estados de Mealy

Page 27: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

80

El uso del reset garantiza un comportamiento seguro del circuito. Esto asegura que la máquina siempre comience en un estado conocido y válido antes de la primera transición de reloj. Si no se utiliza el reset, no existe una forma de predecir el valor inicial de los flip-flops del registro de estado durante el encendido del dispositivo en el que se implementa la máquina de estados. Además existe la posibilidad de que la máquina comience en un estado no válido y entonces nunca comenzaría a

funcionar. Por lo que el reset siempre debe ser implementado en una máquina de estados para asegurar un correcto funcionamiento. Se prefiere el uso de reset asíncrono sobre el síncrono porque un reset asíncrono no requiere ser implementado mediante ecuaciones, minimizando la lógica combinacional del circuito. A continuación se muestran las tres formas más comunes de codificar los estados en una máquina, suponiendo que utiliza ocho estados:

ESTADOS SECUENCIA BINARÍA

ONE HOT ENCODIG

SECUENCIA GRAY

S0 000 00000001 000

S1 001 00000010 001

S2 010 00000100 011

S3 011 00001000 010

S4 100 00010000 110

S5 101 00100000 100

S6 110 01000000 101

S7 111 10000000 111

Cuando se implementa una máquina de estados en un FPGA se prefiere la codificación ONE HOT ENCODING porque estos dispositivos cuentan con bastantes flip-flops y una máquina de estados codificada de esta manera es más

eficiente y las herramientas de síntesis generan circuitos con área optimizada y mejor desempeño. Aunque también es posible que el usuario asigne los valores de los estado como mejor convenga.

Page 28: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

79

EJEMPLO

Figura 4.35 Diagrama de Estados -- Máquina de Estados del tipo Mealy LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY mealy IS

PORT ( clk: IN std_logic; reset: IN std_logic; entradas: IN std_logic_vector

(3 DOWNTO 0); salidas: OUT std_logic_vector

(3 DOWNTO 0)) ; END mealy; ARCHITECTURE comportamental OF mealy IS

-- ONE HOT ENCODED state machine TYPE states IS (S0, S1, S2, S3, S4); ATTRIBUTE enum_encoding OF states: TYPE IS "00001 " & -- S0 -- atributo de WARP "00010 " & -- S1 "00100 " & -- S2 "01000 " & -- S3 "10000" ; -- S4 SIGNAL state, next_state: states ; BEGIN -- registro del estado presente PROCESS(clk, reset) BEGIN

IF reset='0' THEN

state <= S0; ELSIF clk'event and clk = '1' THEN

state <= next_state ; END IF;

END PRCESS; -- lógica combinacional para definir el -- siguiente estado PROCESS(entradas, state) BEGIN

CASE state IS WHEN S0 =>

IF entradas = "0001" THEN next_state <= S1;

END IF; WHEN S1 =>

IF entradas = "1001" THEN next_state <= S1;

ELSIF entradas <= "1011" THEN next_state <= S4;

ELSIF entradas = "0101" THEN

next_state <= S2; END IF;

WHEN S2 => IF entradas = "0111" THEN

next_state <= S1; ELSIF entradas = "0010" THEN

next_state <= S2 ;

Page 29: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

81

ELSIF entradas = "1100" THEN next_state <= S3;

END IF; WHEN S3 =>

IF entradas = "0101" THEN next_state <= S4;

END IF; WHEN S4 =>

IF entradas = "0011" THEN next_state <= S2;

ELSIF entradas = "0100" THEN next_state <= S3;

ELSIF entradas = "0110" THEN next_state <= S4;

ELSIF entradas = "1110" THEN next_state <= S0 ;

END IF; WHEN OTHERS =>

NULL; END CASE;

END PROCESS; -- lógica combinacional de salida salidas <= "1000" WHEN (state= S1) ELSE

"0110" WHEN (state=S1 AND entradas="1001") ELSE

"1100" WHEN (state=S2) ELSE "0000" WHEN (state= S2 AND

entradas="0010") ELSE "0011" WHEN (state=S3) ELSE "0111" WHEN (state=S4) ELSE "0101" WHEN (state= S4 AND

entradas="0110") ELSE "1011"; -- asignación en el estado de

-- reset S0 END comportamental;

EJEMPLO

Elabore la descripción en VHDL del siguiente problema mediante máquina de estados definiendo su diagrama de estados, frecuencia de trabajo y dispositivo a utilizar. Se desea diseñar el circuito de control para lavadora de la siguiente figura.

Figura 4.36

El ciclo de lavado es de la siguiente manera:

1. - Suponiendo que esta vacía al principio, cuando se presione el botón de "INICIO", activo en ALTO, se enciende la válvula de agua fría.

2. - En el momento que el nivel del agua llegue al SENSOR, activo en ALTO, se apaga la válvula de agua fría y se enciende la de agua caliente durante dos minutos.

3. - Después se apaga la válvula de agua caliente y se enciende el motor durante cuatro minutos.

4. - Transcurridos los cuatro minutos, se apaga el motor y se enciende la válvula de desagüe durante tres minutos.

5. - Una vez que se ha vaciado la lavadora se cierra la válvula de desagüe y el ciclo de lavado comenzará nuevamente cuando se vuelva a presionar el botón de inicio. LIBRARY ieee; USE ieee.std_logic_1164.ALL; ENTITY lavadora IS

PORT( clk: IN std_logic; inicio: IN std_logic; sensor: IN std_logic;

vaf: OUT std_logic; vac OUT std_logic; motor: OUT std_logic; des: OUT std_logic );

END lavadora; ARCHITECTURE state_machine OF lavadora IS

TYPE states IS (S0,S1,S2,S3,S4,S5,S6,S7,S8,S9,S10);

SIGNAL state, nex_state: states; SIGNAL outputs: std_logic_vector

(3 DOWNTO 0); CONSTANT vaf_on: std_logic_vector

(3 DOWNTO 0):="0001"; CONSTANT vac_on: std_logic_vector

(3 DOWNTO 0):="0010"; CONSTANT mot_on: std_logic_vector

(3 DOWNTO 0):="1000"; CONSTANT des_on: std_logic_vector

(3 DOWNTO 0):="0100"; CONSTANT all_off: std_logic_vector

(3 DOWNTO 0):="0000"; BEGIN -- REGISTRO DE ESTADO

PROCESS(clk, inicio, next_state) BEJÍN

IF inicio = '0' THEN state <= S10; -- todo apagado

ELSIF clk'event AND clk = '1' THEN state <= next_state;

END IF; END PROCES;

-- LÓGICA COMBINACIONAL PARA DEFINIR EL

Page 30: Circuitos

IEC FRANCISCO JAVIER TORRES VALLE

CAPÍTULO IV: DESCRIPCIÓN DE CIRCUITOS DIGITALES

82

-- SIGUIENTE ESTADO PROCESS(clk, state, sensor) BEGIN

CASE state IS WHEN S0 =>

IF sensor='0' THEN next_state <= S0;

ELSIF sensor='1' THEN next_state <= S1; END IF;

WHEN S1 => next_state <= S2; WHEN S2 => next_state <= S3; WHEN S3 => next_state <= S4; WHEN S4 => next_state <= S5; WHEN S5 => next_state <= S6; WHEN S6 => next_state <= S7; WHEN S7 => next_state <= S8; WHEN S8 => next_state <= S9; WHEN S9 => next_state <= S10; WHEN S10 =>

IF inicio = '0' THEN next_state <= S10;

ELSE next_state <= S0;

END IF; WHEN OTHERS => NULL; END CASE; END IF; END PROCESS; -- LÓGICA COMBINACIONAL DE SALIDA outputs <= all_off WHEN (state=S10) ELSE

vaf_on WHEN (state=S0 AND sensor='0') ELSE

vac_on WHEN (state=S1) ELSE vac_on WHEN (state=S2) ELSE mot_on WHEN (state=S3) ELSE mot_on WHEN (state=S4) ELSE mot_on WHEN (state=S5) ELSE mot_on WHEN (state=S6) ELSE des_on WHEN (state=S7) ELSE des_on WHEN (state=S8) ELSE des_on WHEN (state=S9) ELSE all_off;

END state_machine;