Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Índice
Índice .................................................................................................................................................................................. 1
1. Introducción..................................................................................................................................................................... 3
2. Encender un LED............................................................................................................................................................ 4
2.1. Diseño del circuito ............................................................................................................................................................................ 5
2.2. Síntesis e implementación del circuito............................................................................................................................................ 10
2.3. Programación de la FPGA.............................................................................................................................................................. 11
3. Puertas lógicas, interruptores y pulsadores .................................................................................................................. 15
3.1. Diseño del circuito .......................................................................................................................................................................... 15
3.2. Simulación del circuito .................................................................................................................................................................... 17
3.3. Síntesis e implementación del circuito............................................................................................................................................ 20
4. Decodificador de 2 a 4 .................................................................................................................................................. 21
4.1. Diseño del decodificador ................................................................................................................................................................ 21
4.2. Comprobación del diseño ............................................................................................................................................................... 23
4.3. Implementación del diseño ............................................................................................................................................................. 24
4.4. Creación de un bloque.................................................................................................................................................................... 24
5. Decodificador de 3 a 8 .................................................................................................................................................. 27
5.1. Diseño del decodificador con bloques ............................................................................................................................................ 28
6. Decodificador de 4 a 16 ................................................................................................................................................ 30
6.1. Diseño del decodificador con bloques prediseñados ..................................................................................................................... 31
6.2. Comprobación del diseño ............................................................................................................................................................... 33
7. Convertidor de hexadecimal a 7 segmentos ................................................................................................................. 35
7.1. Diseño del convertidor de hexadecimal a 7 segmentos ................................................................................................................ 35
7.2. Implementación .............................................................................................................................................................................. 39
8. Codificadores ................................................................................................................................................................ 42
8.1. Codificador de 4 a 2 sin prioridad ................................................................................................................................................... 42
8.2. Codificador de 4 a 2 con prioridad, línea activa y habilitación........................................................................................................ 42
8.3. Codificador de 4 a 2 con conversión a 7 segmentos...................................................................................................................... 44
9. Extensión de la capacidad de un codificador ................................................................................................................ 46
9.1. Codificador de 8 a 3 a partir de codificadores de 4 a 2 .................................................................................................................. 46
9.2. Inclusión del convertidor a siete segmentos................................................................................................................................... 47
9.3. Codificador mayores....................................................................................................................................................................... 47
10. Comparadores ............................................................................................................................................................ 48
10.1. Comparador de un bit ................................................................................................................................................................... 48
10.2. Comparador de dos bits ............................................................................................................................................................... 48
10.2.1. Diseño del comparador ....................................................................................................................................................... 50
11. Comparadores en cascada ......................................................................................................................................... 51
12. El multiplexor............................................................................................................................................................... 55
12.1. Especificaciones ........................................................................................................................................................................... 55
12.2. Diagrama de bloques del circuito ................................................................................................................................................. 55
12.3. Diseño........................................................................................................................................................................................... 57
13. El sumador .................................................................................................................................................................. 60
13.1. Especificaciones ........................................................................................................................................................................... 60
13.2. Diseño........................................................................................................................................................................................... 60
14. Sumador/restador ....................................................................................................................................................... 63
14.1. Especificaciones ........................................................................................................................................................................... 63
14.2. Diagrama de bloques.................................................................................................................................................................... 63
14.2.1. Bloque sumador/restador .................................................................................................................................................... 64
14.2.2. Bloque de visualización....................................................................................................................................................... 66
14.3. Diseño........................................................................................................................................................................................... 68
14.4. Comprobación del diseño ............................................................................................................................................................. 69
15. Unidad aritmético lógica .............................................................................................................................................. 71
15.1. Especificaciones ........................................................................................................................................................................... 71
15.2. Diagrama de bloques.................................................................................................................................................................... 71
15.3. Diseño........................................................................................................................................................................................... 74
15.3.1. Multiplicador por 2 ............................................................................................................................................................... 74
15.3.2. Circuito comparador, "mayor" ............................................................................................................................................. 75
15.3.3. Circuito operación lógica AND ............................................................................................................................................ 75
15.3.4. Multiplexor de 4 entradas datos con habilitación ................................................................................................................ 76
15.3.5. Codificador con prioridad de 4 entradas ............................................................................................................................. 77
15.3.6. Componente de mayor jerarquía......................................................................................................................................... 78
15.4. Implementación y comprobación .................................................................................................................................................. 78
16. Elementos de memoria ............................................................................................................................................... 79
16.1. Especificaciones ........................................................................................................................................................................... 79
16.2. Diseño........................................................................................................................................................................................... 79
16.3. Implementación ............................................................................................................................................................................ 79
17. Interruptor con pulsador .............................................................................................................................................. 81
17.1. Ideas ............................................................................................................................................................................................. 81
1. Introducción
El objetivo de esta prácticas guiadas es introducir al alumno en el diseño con esquemáticos mediante el uso
de herramientas CAD (computer aided design). Estas prácticas parten de un nivel elemental y se pretende que
puedan ser seguidas como complemento en un curso básico de electrónica digital. Estas prácticas se han
desarrollado en el departamento de Tecnología Electrónica 1 de la Universidad Rey Juan Carlos.
Estas prácticas consistirán en un grupo de ejercicios con los que aprenderemos a programar una FPGA
utilizando la herramienta gratuita de diseño electrónico digital ISE-WebPACK de Xilinx 2. En las prácticas de
este curso realizaremos diseños con esquemáticos: puertas lógicas, bloques combinacionales y secuenciales.
Una vez que hayamos realizado el diseño en la herramienta, lo sintetizaremos y lo implementaremos en la
FPGA. La síntesis es la tarea que transforma un diseño desde un nivel de descripción a otro nivel de
descripción más bajo. En nuestro caso, el diseño lo tendremos en esquemáticos y la herramienta lo
transformará en una descripción que indica las conexiones internas y configuración de la FPGA para que
funcione de la misma manera a como funcionaría nuestro diseño original en esquemáticos. Por suerte, la
síntesis la realiza la herramienta automáticamente, durante la síntesis nosotros nos ocuparemos de
supervisar el proceso, analizando los errores y advertencias (warnings) que aparezcan.
Antes de implementar el diseño en la FPGA es recomendable simular el diseño para comprobar que
funciona correctamente. Es más fácil detectar errores de diseño mediante simulación, que en la placa.
Imagina que has implementado el diseño en la FPGA y que ésta no hace nada. Para descubrir el fallo
tendrías que usar un polímetro o un osciloscopio y comprobar los niveles de tensión de los pines. Además
con el inconveniente de que sólo tienes accesibles los puertos de entrada y salida, y no las señales internas
del diseño. Mediante la simulación puedes comprobar todas las señales (internas y externas) y directamente
de un vistazo, sin recurrir a medidas eléctricas.
Una vez que tenemos el diseño verificado por simulación, lo implementaremos en la FPGA. La herramienta
de diseño creará un fichero de configuración (con extensión .bit). Este fichero contiene la información de la
implementación de nuestro diseño en la FPGA. Para programar la FPGA, en nuestro caso, utilizaremos un
cable JTAG, que es un cable que cumple un protocolo de depuración y programación: Boundary Scan.. Este
cable se conecta al puerto paralelo de nuestro ordenador.
Una vez programada la FPGA, nuestro diseño estará implementado en la FPGA y por lo tanto estará
funcionando. Dependiendo del diseño implementado, interactuará con el exterior de distinta manera y
podremos comprobar su correcto funcionamiento.
Para las prácticas utilizaremos la placa Pegasus de Digilent 3, que contiene una FPGA de Xilinx de modelo
Spartan-II XC2S200 con encapsulado PQ208. Esta FPGA tiene 200000 puertas lógicas equivalentes y 140 pines
disponibles para el usuario. Con esta capacidad podemos hacer diseños digitales bastante grandes.
La placa Pegasus contiene distintos periféricos que nos facilitarán la tarea del diseño, como por ejemplo: 8
LED, 4 displays de 7 segmentos, 4 botones, 8 interruptores, un puerto PS/2 (para ratón o teclado), y puerto
VGA (para conectar un monitor), y varios puertos de expansión. En la figura 1.1 se muestra la placa Pegasus,
y en la que se señalan varios de sus componentes. La foto de la placa no coincide exactamente con la versión
de la placa que tenemos en el laboratorio y hay algunos componentes que no están en el mismo lugar,
aunque sí todos los que se han señalado.
1 http://gtebim.es
2 Herramienta gratuita que se puede descargar en http://www.xilinx.com
3 http://www.digilentinc.com
VGA
Alimentación
Jumpers de
configuración
PS/2
Display
LED
7 segmentos
Pulsadores Interruptores
Figura 1.1: Placa Pegasus de Digilent
A medida que vayamos avanzando con la práctica iremos aprendiendo la funcionalidad de la placa. Aún así
se puede consultar en la página web de la asignatura (http://gtebim.es/docencia/EDI) el manual de la
placa (en inglés), y una versión resumida de dicho manual en español.
Bueno, es hora ya de empezar con las practicas ...
2. Encender un LED
Cuando nos enfrentamos por primera vez a diseñar mediante una metodología y herramientas nuevas, lo
más aconsejable es empezar con ejemplos lo más sencillos posibles. Y a partir de éstos se irá aumentando la
complejidad del diseño. Son muchas cosas las que pueden fallar, tanto en el uso de las herramientas de
diseño como en la placa de la FPGA. Por consiguiente, si de primeras probamos con un diseño complejo, en
caso de que no funcione correctamente no sabremos si es el diseño que está mal o es algún paso que no
hemos realizado bien.
De manera similar, los informáticos realizan un programa llamado "Hello world" (hola mundo), que es un
programa muy sencillo que simplemente saca por pantalla dicho texto. Nosotros, como no tenemos pantalla,
encenderemos un LED. También podríamos usar el display de 7 segmentos, pero su uso es algo más
complicado y lo que queremos es la mayor sencillez.
Ya hemos visto que la placa Pegasus tiene 8 LED disponibles para utilizar, cada uno de estos LED van
conectados a distintos pines de la FPGA, de los 140 pines que hay disponibles. La conexión de los LED se
muestra en la figura 2.1. En ella se indican qué pines de la FPGA están conectados a los LED. Por ejemplo el
LED número 0, está conectado al pin 46. Para facilitar esta identificación, la placa lleva impresos la
identificación del LED y el pin asociado de la FPGA. Así, podemos ver cómo al lado del LED 0 (LD0) de la
placa está el número 46 entre paréntesis. Podemos apreciar que esto se cumple para casi todos los
componentes: pulsadores, interruptores, ...
'1' → Encendido Spartan-II
'0' → Apagado PIN LED
46 LD0
390Ω 45 LD1
44 LD2
43 LD3
42 LD4
41 LD5
37 LD6
36 LD7
de tensión de ese pin de la FPGA). Por el contrario, si ponemos un '0' lógico en el pin 45, mantendremos
apagado el LED 1 (LD1), puesto que no circulará corriente por él.
Así pues, éste será el objetivo del primer ejercicio, poner un '1' en el pin 46 y un '0' en el pin 45. Si después de
programar la FPGA el LED 0 se enciende y el LED 1 se apaga habremos cumplido el objetivo. Con el resto de
pines que van a los otros LED no haremos nada, en teoría, haciéndolo así no deberían lucir, ya que por
defecto la FPGA pone resistencias de pull-down en los pines no configurados, y una resistencia de pull-down
pone la salida a tierra.
Nos puede aparecer una ventana con el Tip of the day que son indicaciones que hace la herramientas cada vez
que la arrancamos. Si las leemos habitualmente podemos ir aprendiendo poco a poco. Pinchamos en Ok, con
lo que se cierra dicha ventana.
Normalmente la herramienta abre el último proyecto que se ha realizado. Así que lo cerramos pinchando en:
File→Close Project.
Para empezar a crear nuestro nuevo proyecto, pinchamos en File→New Project... y nos saldrá la ventana New
Project Wizard – Create New Project como la mostrada en la figura 2.2. En ella pondremos el nombre del
proyecto, que lo llamaremos led0, indicamos la ruta donde guardaremos el proyecto
(C:/practica/edi/tunombre). Respecto al nombre y a la ruta, no es conveniente trabajar desde un
dispositivo de memoria USB, ni tampoco incluir en la ruta o el nombre ni acentos ni eñes, ni caracteres
extraños, lo más conveniente es limitarse a caracteres alfanuméricos, y usar el guión bajo en vez del espacio.
Para el último recuadro de la ventana, donde pone Top-Level Source Type seleccionaremos Schematic, ya que
nuestro diseño lo haremos mediante esquemáticos.
Mirar en la FPGA
Mirar en la FPGA
Figura 2.4: Ventana para la selección del dispositivo del nuevo proyecto
En las dos siguientes ventanas pinchamos en Next sin rellenar nada y en la última pinchamos en Finish.
Ya tenemos el proyecto creado y ahora nos disponemos a crear nuestro diseño. Para ello creamos una nueva
fuente pinchando en Project→New Source.
Esto hará saltar a una nueva ventana que nos pedirá que seleccionemos el tipo de fuente que queremos crear.
Como estamos trabajando en esquemáticos, seleccionamos Schematic, y nombramos al fichero led0. Este paso
se muestra en la figura 2.5. Posteriormente pinchamos en Next y en la siguiente ventana en Finish.
Seleccionar led0.sch
Símbolos
Opciones Fuentes
Procesos
Figura 2.7: Apariencia de la herramienta para empezar a realizar el esquema del circuito
En la figura 2.7 se han señalado algunas pestañas que utilizaremos durante el proceso de diseño y a las que
se hará referencia durante el ejercicio. Así que familiarízate con sus nombres y vuelve a esta figura si durante
la práctica no sabes a qué pestaña nos estamos refiriendo. Si quieres, pincha en ellas para ver el aspecto que
tienen.
La ventana de opciones permite cambiar el comportamiento de la herramienta al dibujar el esquemático. La
ventana de símbolos nos permite dibujar las puertas lógicas y los distintos componentes de nuestro diseño.
En la ventana de fuentes se muestran los ficheros de nuestro diseño (en este caso sólo hay uno: led0.sch). Y
por último, en la ventana de procesos se indica a la herramienta los comandos que se quieren ejecutar.
Para empezar a diseñar volvemos a la ventana de símbolos. En ella, seleccionamos la categoría General y
tomamos el símbolo vcc. Una vez que los hemos seleccionado podemos apreciar que el puntero del ratón
cambia de forma cuando lo situamos en el plano del circuito. Si pinchamos en cualquier parte del plano se
situará el símbolo correspondiente a Vcc, que es la fuente de alimentación, y por tanto, en electrónica digital
es un '1' lógico (ver la figura 2.8). A veces la herramienta tarda un poco en situarlo, así que no desesperes y
no pinches varias veces con el ratón, pues colocarías varias Vcc por tu circuito.
Cuando hayas colocado tu fuente de alimentación, seguramente la veas un poco pequeña. Para ampliar la
zona puedes pinchar en View→Zoom→Zoom In (o bien pulsar F8).
Siempre que se haya seleccionado un símbolo, al pinchar con el ratón en el mapa del circuito se añade dicho
símbolo. Esto puede resultar incómodo ya que podemos estar añadiendo componentes sin querer. Para
quitar esta opción y tener en cursor del ratón en modo de selección (con su flechita habitual) basta con pulsar
la tecla de escape (Esc) o bien pulsar el icono de la flechita que está en la barra de herramientas .
Si por error hemos incluido un símbolo más de una vez, para borrarlo vamos al modo selección (tecla Esc) y
pinchamos encima del símbolo que queramos eliminar. Éste cambiará a color rojo, y entonces o bien lo
borramos con la tecla Supr, o bien pinchamos con el botón derecho del ratón y del menú seleccionamos
Delete. Como podrás apreciar viendo dicho menú, también puedes copiar y cortar de la misma manera que
se hace en Windows.
Ya tenemos nuestro primer diseño hecho. Le damos a guardar (es algo que deberías hacer de vez en cuando),
y procederemos a implementarlo en la FPGA. Fíjate que cuando no has guardado, el nombre del circuito que
está en la pestaña del esquemático tiene un asterisco.
Figura 2.13: Aspecto de la subventana de procesos una vez que se ha sintetizado e implementado el diseño
correctamente. En la ventana de la derecha, en el proceso de síntesis ha habido advertencias (warnings) que no
siempre son importantes, y por eso tiene un símbolo triangular de color amarillo
su caperuza
está perdida y
pisoteada por el
suelo del labo
Representación:
Después de la orden de programar la FPGA, aparece un cuadro que muestra la evolución y, si todo ha salido
bien, la herramienta nos avisará de que hemos tenido éxito en la programación mostrando un aviso como el
de la figura
Figura 3.1: Esquema eléctrico de las conexiones de los interruptores y pulsadores en la placa Pegasus
Para los pulsadores, cuando están pulsados transmiten un 1-lógico a la entrada y cuando no están pulsados
ponen 0 voltios a la entrada. Observa que los pulsadores tienen un pequeño circuito con resistencias y un
condensador, esto es para eliminar los rebotes que se producen al pulsar y así enviar una señal sin ruido.
Figura 3.6: Buffer que queremos conectar a la misma entrada (BTN0) que la del inversor
Para conectar la entrada del buffer al puerto de entrada BTN0 necesitamos un cable. Los cables los
implementan pinchando en Add→Wire, o bien con el icono , o bien tecleando CTRL+W. Una vez que hemos
seleccionado este comando, veremos que en la ventana de opciones aparecen las opciones para situar los
cables. En ella seleccionamos la primera opción: Use the Autorouter to add one o more line segments between the
points you indicate. Y posteriormente pinchamos al cable que está entre la salida del puerto BTN0 y la entrada
del inversor; sin soltar el botón del ratón, nos dirigimos a la entrada del buffer. Puede pasar que la
herramienta dé un mensaje que diga: The pin 'I' is already connected to a net. Only one net is allowed to connect to
a pin. Con esto quiere decir que sólo se puede conectar un cable a un pin. Pero lo que sí se puede hacer es
conectarlo al cable que une el pin con la entrada del inversor. Puede ser que tengas poco espacio entre el pin
y la entrada del inversor. Para alargar ese cable, puedes seleccionar y arrastrar el pin de entrada a la
izquierda. Ahora será más fácil conectar la entrada del buffer con el cable.
Para comprobar que hemos hecho la conexión bien podemos pinchar en Tools→Check Schematic, y revisamos
la ventana inferior (Console) para ver si ha detectado algún error o advertencia.
Grabamos el esquemático: File→Save (esto deberías hacerlo regularmente).
Debido a que es un diseño pequeño podríamos probar el circuito directamente en la placa, sin embargo
vamos a simularlo antes para aprender el proceso.
Figura 3.9: Selección de los ficheros fuente según el tipo de actividad que se vaya a realizar
Como ahora queremos simular el circuito para comprobar su funcionamiento, seleccionamos Sources for:
"Behavioural Simulation" . Como resultado de esta selección, la ventana de procesos cambia. Por lo tanto, si en
cualquier momento ves que la ventana de procesos no está como piensas que debería estar, comprueba que
has seleccionado el menú de fuentes adecuado. Por ejemplo, puede pasar que quieras sintetizar el diseño y
no aparezca el comando, entonces mira qué opción tienes seleccionada.
Ahora crearemos un nuevo fichero para simular nuestro diseño. Mediante un cronograma, este fichero
indicará al simulador qué valores toman las entradas en función del tiempo. En la ventana de procesos
pinchamos dos veces en Create New Source. Y nos saldrá una ventana como la de la figura 3.10, que es similar
a la que ya vimos en la figura 2.5.
"forma de onda", así que nuestro banco de pruebas lo definiremos con las formas de onda de los puertos de
entrada (ahora veremos cómo y por qué).
La siguiente ventana nos pide que seleccionemos el diseño que vamos a probar con el banco de pruebas. En
nuestro caso solo hay uno: swt0. Y así que pinchamos en Next y en la siguiente ventana en Finish.
Surgirá una ventana que nos pide mucha información (figura 3.11). Como nuestro circuito no tiene reloj ni
elementos de memoria (ya los estudiaremos en el tema 7) es un circuito combinacional, y por tanto, en el
apartado de Clock Information, seleccionamos Combinatorial (or internal clock). Además, deseleccionamos la
casilla GSR (FPGA) y el resto de opciones las dejamos como están y pinchamos en Finish.
Eje
Eje temporal
temporal
Puertos
Puertos de
de entrada
entrada
Puertos
Puertos de
de salida
salida
Valores
Valores de
de las
las señales
señales en
en el
el tiempo
tiempo
Ahora nosotros tenemos que asignar los valores de los puertos de entrada, para que a partir de ellos el
simulador calcule los de salida. Inicialmente, la ventana asigna a todos los puertos de entrada el valor '0'.
Nosotros vamos a asignar diversos valores para comprobar el funcionalidad de nuestro circuito en distintos
casos.
Antes de asignar los valores, vamos a agrupar las señales entre sí, para comprobar de manera más fácil los
resultados de la simulación. SW0 y SW1 van a las entradas de una puerta AND cuya salida es LD0. Así que las
vamos a poner juntas. Esto se hace pinchando en el nombre del puerto y arrastrándolo hasta donde
queramos. Hacemos lo mismo con el resto: SW2, SW3 y LD1 juntas; y por último BTN0 junto con LD2 y LD3.
Pinchando en los recuadros azules del cronograma de los puertos de entrada modificamos su valor. El ancho
de estos cuadrados se define en la ventana de la figura 3.11, nosotros los dejaremos con su valor por defecto.
Como tenemos un diseño pequeño, los valores de las entradas que vamos a asignar cubrirán todas las
posibilidades para cada puerta. Así, haremos que las entradas SW0 y SW1, de la puerta AND, tomen todos los
valores de la tabla de verdad. En la figura 3.13 se muestran los valores que se quieren asignar a los puertos
de entrada y los intervalos de tiempo en que se asignarán. También se muestra los valores que deben salir
(los valores de los LED) y que más adelante comprobaremos si coinciden con los de la simulación.
LD0: AND LD1: OR LD2: NOT
tiempo SW0 SW1 LD0 tiempo SW2 SW3 LD1 tiempo BTN0 LD2 LD3
0-100ns 0 0 0 0-100ns 0 0 0 0-200ns 0 1 0
100-200 0 1 0 100-200 0 1 1 200-400 1 0 1
200-300 1 0 0 200-300 1 0 1
300-400 1 1 1 300-400 1 1 1
Figura 3.13: Asignación de valores a los puertos de entrada de modo que cubran todas las posibilidades de la tabla de
verdad
Asignando los valores de la figura 3.13 obtendremos un cronograma como el mostrado en la figura 3.14.
Cuando lo tengamos hecho lo grabamos y comprobaremos cómo aparece en la ventana de fuentes:
tb_swt0.tbw, y cómo dentro de él está nuestro diseño 4: UUT – swt0(swt0.sch).
4 UUT indica el componente que se está comprobando, es el acrónimo del inglés: Unit Under Test
Diseño digital con esquemáticos y FPGA. v1.8 - 04/06/2008 19
3. Puertas lógicas, interruptores y
Departamento de Tecnología Electrónica
pulsadores
4. Decodificador de 2 a 4
En este ejercicio implementaremos un decodificador de 2 a 4 como los que hemos visto en clase. Un
decodificador de 2 a 4 recibe dos entradas que están codificadas en binario y según que número esté
codificado activa la salida correspondiente a ese número. Por ejemplo, si el número de la entrada es 102,
activará la salida 2, ya que 102 es dos en binario. Además, los decodificadores suelen tener una señal de
habilitación (enable) que en caso de no estar activa, todas las salidas estarán también inactivas
independientemente del valor del resto de entradas.
Por tanto, nuestro decodificador será un bloque como el mostrado en la figura 4.1, cuya tabla de verdad
también se muestra.
DECOD 2a4
S0 E A1 A0 S3 S2 S1 S0
A0
S1 0 X X 0 0 0 0
A1 1 0 0 0 0 0 1
S2 1 0 1 0 0 1 0
1 1 0 0 1 0 0
E S3 1 1 1 1 0 0 0
Figura 4.2: Inversores colocados a las entradas para formar los términos mínimos
Ahora conectamos un cable a la salida de cada inversor (mediante el icono ). El otro lado del cable lo
dejamos al aire: pinchamos en un punto más alejado a la derecha y pulsamos la tecla ESC. El extremo del
cable tendrá un cuadradito rojo que indica que sin conectar (al aire).
Vamos a nombrar los terminales de cada cable que hemos dejado al aire. Seleccionamos Add→Net Name
(también hay un icono ). Y en la ventana de opciones, en el apartado Name ponemos el nombre del cable.
Para el negado de A1 lo llamamos N_A1, y el negado de A0 lo llamamos N_A0. Para colocarlo nos ponemos al
final del cable y pinchamos encima. Para colocar el segundo, cambiamos el nombre y repetimos la operación.
Llegados a este punto, deberíamos tener:
A continuación incluiremos 4 puertas AND de dos entradas que se encargarán de crear los 4 términos
mínimos. Por ahora simplemente las creamos una debajo de la otra, y conectamos un cable a la salida de
cada una de ellas.
Figura 4.4: Inversores y las cuatro puertas AND para formar los términos mínimos
Ahora vamos a conectar las entradas de cada una de las puertas. La puerta de arriba será la del término
mínimo cero (m0) y la de abajo m3. Para unir los cables de los puertos de entrada (negados o no) con las
entradas de las puertas usamos el comando Add→Net¸ y dejamos la opción por defecto: Use the Autorouter to add
one or more line segments between the points you indicate. Al unir los cables veremos que en las uniones se forma
un cuadradito que indica la conexión entre cable. Al terminar de unir los cables tendremos un circuito como
el siguiente. Si te equivocas, usa CTRL+Z para deshacer la última unión.
actúa como una compuerta en el sentido que si E='0' la salida vale '0' (inhabilitada) y si E='1' la salida vale lo
que la otra entrada (ver figura 4.6).
E → Habilitación E='0' → Salida inhabilitada E='1' → Salida habilitada
m0 m0 m0
S0 S0='0' S0=m0
E E='0' E='1'
Figura 4.6: Puerta AND como habilitación
Añadimos las puertas y las conectamos con la señal de habilitación. El circuito debería quedarnos como la
siguiente figura
Figura 4.10: Selección del componente para el que vamos a crear un símbolo
Pinchamos en Next y aparecerá una ventana con las entradas y salidas del módulo. En ella podemos cambiar
el lugar donde aparecerán (derecha o izquierda) y el orden. Ponemos el mismo orden de la figura 4.11.
Esquema
Esquema en
en puertas
puertas Símbolo
Símbolo
5. Decodificador de 3 a 8
Hemos realizado el decodificador de 2 a 4, utilizando dos interruptores encendíamos uno de los cuatro
primeros LED. Ahora vamos a construir un decodificador que encienda uno de los 8 LED, utilizaremos para
ello los tres primeros interruptores.
Aunque este ejercicio ya se ha explicado en clase, vamos a repasarlo un poco. En la figura 5.1 se muestra el
bloque final que queremos obtener y la tabla de verdad. La tabla de verdad es muy similar a la del
codificador de 2 a 4 (figura 4.1).
Podríamos hacer el ejercicio de la misma manera que el decodificador de 2 a 4, sin embargo, si lo hacemos
uniendo dos decodificadores de 2 a 4 lograremos diseñarlo de manera mucho más rápida y entendible. Es
difícil de entender el funcionamiento de un diseño grande en puertas, mientras que si lo hacemos con
bloques es más claro.
S0
A0
S1 E A2 A1 A0 S7 S6 S5 S4 S3 S2 S1 S0
A1
0 X X X 0 0 0 0 0 0 0 0
DECOD 3a8
S2
A2 1 0 0 0 0 0 0 0 0 0 0 1
S3 1 0 0 1 0 0 0 0 0 0 1 0
1 0 1 0 0 0 0 0 0 1 0 0
S4 1 0 1 1 0 0 0 0 1 0 0 0
S5 1 1 0 0 0 0 0 1 0 0 0 0
1 1 0 1 0 0 1 0 0 0 0 0
S6 1 1 1 0 0 1 0 0 0 0 0 0
E 1 1 1 1 1 0 0 0 0 0 0 0
S7
todas '0'
E A2 A1 A0 S7 S6 S5 S4 S3 S2 S1 S0
1 0 0 0 0 0 0 0 0 0 0 1
1 0 0 1 0 0 0 0 0 0 1 0
A2 = '0'
1 0 1 0 0 0 0 0 0 1 0 0
1 0 1 1 0 0 0 0 1 0 0 0
Intenta realizarlo tú mismo, y si no te sale puedes ver la solución en la figura 5.5. A continuación vamos a
diseñarlo.
Símbolos
Símbolos del
del proyecto
proyecto
Símbolo
Símbolo del
del decodificador
decodificador de
de 22 aa 44
Decodificador
Decodificador de
de 22 aa 44
En el mapa del circuito añadimos dos referencias a decod2a4, que como ya hemos dicho, un decodificador es
para las 4 primeras salidas y el otro para el resto.
Ahora realizamos las conexiones entre los decodificadores decod2a4 y las entradas y salidas del nuevo
decodificador decod3a8. Incluyendo también las señales de habilitación de cada uno de ellos, usando para
ello puertas AND. Nota que para la habilitación del decodificador superior, la puerta AND debe tener la
entrada de A2 negada. El circuito final se muestra en la figura 5.5.
Figura 5.6: Conexión de los puertos del diseño con los pines de la FPGA
Una vez implementado, comprueba que funciona correctamente y compáralo con los valores de la tabla de
verdad y la simulación.
6. Decodificador de 4 a 16
¿Y cómo haríamos un decodificador de 4 a 16 con decodificadores de 2 a 4? el proceso es muy similar al
anterior. La figura 6.1 muestra este decodificador y su tabla de verdad. Ésta se puede dividir en 4 partes, una
por decodificador.
S0 E A3 A2 A1 A0 S15 S14 S13 S12 S11 S10 S9 S8 S7 S6 S5 S4 S3 S2 S1 S0
A0
S1 0 X X X X 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
A1 S2 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
decod 1
S3 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
A2 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
S4
1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
A3 S5
DECOD4a16
1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
decod 2
S6 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
S7 1 0 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
S8 1 0 1 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
S9 1 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
decod 3
1 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
S10 1 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
E
S11 1 1 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
S12 1 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0
decod 4
S13 1 1 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
S14 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
S15
todas '0'
E A3 A2 A1 A0 S15 S14 S13 S12 S11 S10 S9 S8 S7 S6 S5 S4 S3 S2 S1 S0 decod 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 activo cuando
1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
A3 = '0'
1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
A2 = '0'
1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
Así que usaremos cuatro decodificadores de 2 a 4 para las 16 salidas. Además necesitaremos crear la lógica
que se encargue de habilitar cada decodificador. Si nos fijamos en las señales A3 y A2 de la tabla de verdad, y
de cómo habilitan a cada decodificador, podemos extraer la tabla de verdad de la figura 6.3. En ella se ponen
las señales de habilitación de cada decodificador (E3, E2, E1, E0) en función de la habilitación general (E) y las
entradas A3 y A2. Podemos ver que la tabla de verdad se corresponde con la tabla de verdad de un
decodificador de 2 a 4 (figura 4.1), así que para las señales de habilitación de los cuatro decodificadores
usaremos otro decodificador de 2 a 4.
Señales de habilitación de los 4 decodificadores
E A3 A2 E3 E2 E1 E0
0 X X 0 0 0 0 Ningún decodificador habilitado
1 0 0 0 0 0 1 decodificador 0 habilitado
1 0 1 0 0 1 0 decodificador 1 habilitado
1 1 0 0 1 0 0 decodificador 2 habilitado
1 1 1 1 0 0 0 decodificador 3 habilitado
inhabilitado 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 inhabilitado →
Figura 6.7: Valores introducidos en el cronograma para la simulación del decodificador de 4 a 16
Una vez introducidos los valores en el cronograma:
• Guardamos el fichero del banco de pruebas
• Habiendo seleccionando el fichero tb_decod4a16 en la ventana de fuentes, desde la ventana de procesos damos
la orden de simular: Simulate Behavioral Model (dentro de Xilinx ISE Simulator)
• El resultado de la simulación saldrá sólo para 1000 ns, como nuestro banco de pruebas lo queremos para 3000
ns, le indicaremos que simule el tiempo restante. Para ello ejecutamos dos veces el comando "Simulation→Run
For Specified Time". El tiempo especificado por defecto para la simulación son 1000 ns. Este tiempo se puede
modificar (figura 6.8) y además, como se muestra en la figura, existe un botón para ejecutar la simulación.
• Finalmente comprobamos si los valores a las salidas son correctos.
Tiempo de simulación
Simular por el tiempo especificado
Figura 6.8: Comando para simular por un tiempo especificado
En la figura 6.9 se muestran los resultados de la simulación, se puede observar cómo se van activando las
salidas consecutivamente mientras la señal de habilitación (E) esté a uno. Cuando ésta vale 0, no hay ninguna
salida activa.
E C E C E C E C E C E C E C E C
D D D D D D D D
A A A A A A A A
8 F
9 F
A F
B C D E F F B
G B G B G B F G B F G B F G B F G B G
E C E C E C E C E C E C E C E C
D D D D D D D D
Figura 7.2: Codificación de los segmentos para mostrar los 16 números hexadecimales
Existen también otros visualizadores de 14 ó 16 segmentos, para poder representar todos los caracteres
alfanuméricos. También se usan las matrices de puntos que tienen distintas resoluciones.
En nuestra placa, para activar el display de la derecha, debemos poner la señal AN_0='0'. El pin
correspondiente de la FPGA es el P60, como puedes ver en la placa encima de donde están los displays. En la
placa también se muestran los pines correspondientes a cada segmento, para encender un segmento tenemos
que poner su pin correspondiente a cero. Funcionan por tanto con lógica negada. Cuando no quieres que se
encienda un display tendrás que poner un uno, por ejemplo en los pines de las señales AN_1, AN_2 y AN_3,
correspondientes a los otros tres displays. Así, para representar el uno, tendrías que poner los segmentos B y C
a cero y el resto a uno, poniendo también la señal AN_0=0.
Con esta información ya podemos hacer el diseño, más adelante, en otros ejercicios, veremos las conexiones
eléctricas y cómo encender varios displays.
HEX7SEG
SEG_A
I0
SEG_B
Número codificado: I1 SEG_C
A los interruptores: SEG_D Salida a los 7 segmentos
SW0, SW1, SW2, SW3 I2
SEG_E
I3 SEG_F
SEG_G
SEG_DT Punto decimal del display
AN_0
AN_1 Encendido de los displays
AN_2 AN0: display de la derecha
Habilitación: E
AN_3
Figura 7.4: Tabla de verdad del convertidor hexadecimal a 7 segmentos (salidas a nivel bajo)
Así que vamos a realizarlo por otro método. Hemos visto en clase que mediante decodificadores se pueden
implementar funciones lógicas. Normalmente no es un método muy eficiente en puertas, es decir, si
realizamos la función lógica a partir del mapa de Karnaugh suelen salir muchas menos puertas que
haciéndolo con decodificadores. Esto se debe a que el decodificador obtiene todos los términos mínimos,
sean o no necesarios para la ecuación, y además, al hacerlo con los términos mínimos, se implementa la
ecuación en la primera forma normal (1FN), ésta suele ser de bastante mayor tamaño que la ecuación
obtenida por Karnaugh. Esto último lo has podido comprobar si hiciste el primer ejercicio propuesto del
tema 3 5.
Sin embargo, cuando necesitamos obtener varias funciones lógicas a partir de un mismo grupo de entradas
(como es el caso) el uso de decodificadores no es tan descabellado, ya que un término mínimo puede ser
utilizado en varias salidas. Es decir, en nuestro caso necesitamos siete funciones lógicas, una para cada
segmento, y por tanto un término mínimo puede ser usado en varias funciones. Además, ya tenemos el
decodificador implementado y encima disponemos de una FPGA con 50000 ó 200000 puertas equivalentes,
por lo que excedernos en el número de puertas para un diseño pequeño como el nuestro no es problemático.
5 Disponible en http://laimbio08.escet.urjc.es/assets/files/docencia/EDI/pbs3_02.pdf
Diseño digital con esquemáticos y FPGA. v1.8 - 04/06/2008 36
7. Convertidor de hexadecimal a 7
Departamento de Tecnología Electrónica
segmentos
Quizás ahora estés intentando recordar de clase cómo se diseñaban funciones lógicas con decodificadores.
Bueno, es muy fácil, simplemente tenemos que unir con una puerta OR todos los términos mínimos de la
función. Por ejemplo, la salida A del display es la OR de los términos mínimos 1, 4, 11 y 13 (m1, m4, m11, m13).
Mira la figura 7.5, en ella se han tomado estas salidas para crear la función que implementa el segmento A.
Para la A tomamos las salidas 1, 4, 11 y 13
I3 I2 I1 I0 A I0 A0 S0
0 0 0 0 0 I1 A1 S1
0 0 0 1 1 m1 I2 A2 S2
SEG_A
0 0 1 0 0 I3 A3 S3
0 0 1 1 0 E E S4
0 1 0 0 1 m4 S5
0 1 0 1 0 S6
0 1 1 0 0 S7
0 1 1 1 0 S8
1 0 0 0 0 S9
1 0 0 1 0
S10
1 0 1 0 0
S11
1 0 1 1 1 m11
S12
1 1 0 0 0
S13
1 1 0 1 1 m13
S14
1 1 1 0 0
1 1 1 0 0 S15
I3 I2 I1 I0 A m1 I3 I2 I1 I0 A
SEGA m0
0 0 0 0 0 m4 0 0 0 0 1 m0 m2
0 0 0 1 1 m1 m11 0 0 0 1 0
m3
0 0 1 0 0 0 0 1 0 1 m2
m13 m5
0 0 1 1 0 0 0 1 1 1 m3 m7
m4 SEGA
0 1 0 0 1 Los números 1, 4, B y D 0 1 0 0 0
0 1 0 1 0 0 1 0 1 1 m5 m8
pondrán un 1 en la salida, m9
0 1 1 0 0 y por tanto, no lucirá el 0 1 1 0 1 m6
0 1 1 1 0 0 1 1 1 1 m7 m10
segmento A. El resto m12
1 0 0 0 0 pondrá un 0 y lucirá 1 0 0 0 1 m8
1 0 0 1 0 A A 1 0 0 1 1 m9 m14
1 0 1 0 0 1 F
4 F 1 0 1 0 1 m10 m15
G B G B
1 0 1 1 1 m11 C C
1 0 1 1 0
1 1 0 0 0
E D E D
1 1 0 0 1 m12 Negar la salida para que los
1 1 0 1 1 m13 1 1 0 1 0 números que hacen lucir el
A A
Figura 7.6: Formas equivalentes de realizar el circuito: a la izquierda con lógica negada. A la derecha, con lógica
afirmada y negando la salida pues el segmento luce cuando hay un cero
Para el resto de segmentos haremos lo mismo: uniremos mediante una puerta OR todos sus términos
mínimos (también lo podríamos hacer de la manera en que muestra en la derecha de la figura 7.6).
Empecemos a diseñarlo, nos mantenemos en el mismo proyecto que en el anterior. Primero, como venimos
de la simulación, seleccionamos en la ventana de fuentes (Sources) la opción de Synthesis Implementation.
Ahora creamos una nueva fuente de tipo esquemático llamada hex7seg. Tenemos la ventana de opciones y de
símbolos activas.
En la ventana de símbolos, en la subventana de categorías (Categories) escogemos la primera de ellas que hace
referencia a nuestro proyecto (C:/practicas/edi/...). Y en la ventana de símbolos estará el decodificador de
4 a 16 que creamos en el ejercicio anterior. Incluimos una referencia a este símbolo en nuestro nuevo diseño,
y realizamos las conexiones del decodificador con las salidas al display según la tabla de verdad de la figura
7.4 y el ejemplo de la figura 7.5. Conecta también las 4 entradas del decodificador, llámalas I0, I1, I2, I3. Y
la habilitación E.
Quizás veas que si sigues conectando cables a las siete puertas OR que tienes que incluir, se va enmarañar
todo el circuito. Para evitar esto, una mejor opción es nombrar los cables, ya que si dos cables tienen el
mismo nombre, aunque no estén unidos se consideran como el mismo cable. Veámoslo para el segmento B.
Según la tabla de verdad de la figura 7.4, el segmento B no luce para los números 5, 6, B, C, E y F (m5, m6,
m11, m12, m14 y m15), por tanto necesitamos una puerta OR de 6 entradas. La situamos en el plano y le
conectamos ya la salida SEG_B (para no olvidarnos luego de qué salida se trata). Ver figura 7.7.
Ahora, a la primera entrada de la puerta OR le conectamos un cable corto. Esto es necesario porque los
cables son los que reciben el nombre y no las entradas de las puertas o componentes. Y por el mismo motivo,
a la salida S5 del decodificador le conectamos otro cable corto (ver figura 7.8). Verás que el final de ambos
cables están en rojo, esto es porque están desconectados.
S0
S1
S2
S3
S4
S5
S6
S7
S8 SEG_B
S9
S10
S11
S12
S13
S14
S15
Figura 7.7: Paso 1, ponemos la puerta OR de 6 Figura 7.8: Paso 2, conectamos un cable pequeño a la
entradas salida S5 del decodificador y a una entrada de la
puerta OR
Ahora pinchamos en "Add→Net Name" y en la ventana de opciones rellenamos en el apartado Name el nombre
m5, ya que vamos a poner el término mínimo m5. A continuación pinchamos en el esquemático cerca de los
cables que hemos puesto (figura 7.9).
Por último, repetimos la operación con el resto de las entradas de la puerta OR (figura 7.10).
Al poner un nombre a un cable que ya existe. Por ejemplo, en la figura 7.9, si nombramos a una pata de la OR
como m5, estamos conectando esa pata al cable m5 que ya existe y que es una salida del decodificador. En caso
de que nos hayamos equivocado de término mínimo, y nombramos una pata de la OR con un término
mínimo equivocado, tendremos que borrar el cable y volverle a conectar uno nuevo, porque si
renombramos, estaremos renombrando tanto ese cable que está en la pata de la OR como el cable de la salida
del decodificador. De todos modos, si intentásemos renombrar el cable sin borrarlo, seguramente aparecerá
una advertencia que indica que ese otro nombre ya existe, pues corresponde a otra salida del decodificador.
7.2. Implementación
Esta vez, en vez de simular el circuito vamos a implementarlo directamente, ya que la funcionalidad del
circuito es muy fácilmente comprobable en la placa, pues sólo tenemos que ver si el display luce bien o no.
Lo primero que haremos es seleccionar la ventana de procesos y la de fuentes. En la ventana de fuentes verás
una imagen similar a la de la figura 7.12. En ella puedes apreciar que de los dos esquemáticos que tenemos,
el convertidor de hexadecimal a 7 segmentos está por encima del decodificador. El convertidor debe de tener
el símbolo , que significa que es el diseño de más alta jerarquía. Si no estuviese tendrías que pinchar con
el botón derecho del ratón encima de él y seleccionar "Set as Top Module".
Aquí se escriben
las restricciones
Fichero
Fichero de
de restricciones
restricciones .ucf
.ucf
Ahora tenemos que escribir los puertos en el fichero UCF, que en realidad es lo que hace la herramienta
PACE. El texto que tenemos que escribir se muestra en el código 7.1. El formato de estos ficheros es muy
sencillo:
• Los comentarios se consideran a partir del signo #
• Cada puerto de nuestro diseño se conecta con la línea:
NET "Nombre_del_Puerto" LOC = "Nombre_del_Pin"
Con estas indicaciones, y tras identificar los pines en la placa, ya la podrías hacer tú solo. Sin embargo, por
ser la primera vez, a continuación se muestra el contenido del fichero. Aún así, intenta entender el
significado, ya que para las siguientes ocasiones tendrás que escribirlo tú solo.
#Numero codificado en los interruptores SW0, SW1, SW2, SW3
NET "I0" LOC = "P89" ;
NET "I1" LOC = "P88" ;
NET "I2" LOC = "P87" ;
NET "I3" LOC = "P86" ;
#Enable en el SW7
NET "E" LOC = "P81" ;
#7 segmentos
NET "SEG_A" LOC = "P74" ;
NET "SEG_B" LOC = "P70" ;
NET "SEG_C" LOC = "P67" ;
NET "SEG_D" LOC = "P62" ;
NET "SEG_E" LOC = "P61" ;
NET "SEG_F" LOC = "P73" ;
NET "SEG_G" LOC = "P68" ;
#Punto decimal
NET "SEG_DT" LOC = "P63" ;
Código 7.1: Conexión de los puertos del diseño con los pines de la FPGA
Debes estar atento a que los nombres que hemos puesto en el fichero UCF coincidan con los nombres de los
puertos de tu diseño. El código 7.1 está hecho para los nombres de la figura 7.3. Si por descuido has puesto
otros nombres en el diseño, o bien cambias los nombres del diseño, o cambias el UCF.
Guarda el fichero UCF una vez que lo hayas terminado.
Sintetiza el diseño, y posteriormente impleméntalo. Esto ese hacía desde la ventana de procesos, "Synthesize-
XST", "Implement Design". Observa si hay algún error, sobre todo después de la implementación. Si te has
equivocado al nombrar los puertos te saldrá un mensaje diciendo qué puerto falta, si es así, corrige el UCF o
el esquemático y repite el proceso.
Finalmente pincha dos veces en "Generate Programming File" y luego en "Configure Device (iMPACT)" para
programar la FPGA, si no te acuerdas de estos pasos repasa el apartado 2.3.
Ahora comprueba que se visualizan correctamente los números según estén los interruptores del cero al tres.
Si ves que algún número no se visualiza correctamente, identifica qué segmento está mal y revisa el
esquemático. Comprueba también que la habilitación funciona. Quizás crea que no funciona nada, y lo que
sucede es que tienes el circuito deshabilitado (SW7='0').
8. Codificadores
En esta práctica realizaremos varios codificadores. Primero haremos un codificador de 4 a 2. En un principio
lo haremos sin prioridad y luego incluiremos un módulo que establezca las prioridades. Posteriormente, en
el capítulo 9 utilizaremos varios codificadores para realizar uno de 8 a 3.
Figura 8.1: Entradas y salidas del codificador, tabla de verdad y obtención del esquema en puertas lógicas
La realización de este circuito es sencilla, y simplemente tienes que implementar el esquema de puertas
mostrado a la derecha de la figura 8.1, e indicar los pines a los que van conectados. Las conexiones con los
pulsadores y LED se muestra a la izquierda de la figura 8.1.
Así que crea un nuevo proyecto llamado codif4a2, una fuente del mismo nombre, conecta los pines
correspondiente y bájalo a la FPGA. Como puedes ver, la entrada I0 no está conectada en el esquema de
puertas, por lo tanto, no hace falta que la crees ni que le asignes pines.
Ahora debes comprobar que funciona bien. ¿Qué debe suceder? Está mostrado para algunos casos en la
figura 8.2.
Entrada activa
ninguna BTN0 BTN1 BTN2 BTN3 BTN1 y BTN2
(pulsador)
LEDs LD1 LD0 LD1 LD0 LD1 LD0 LD1 LD0 LD1 LD0 LD1 LD0
encendidos y
00 00 01 10 11 11
codificación
I1
entrada salidas S0
activa S1 S0 A Diferencia entre
-- 0 0 0 pulsar I0 y no I2 S1
I0 0 0 1 pulsar nada I3
I1 0 1 1
I2 1 0 1
1 1 1 A se enciende cuando
I3 A
cualquier entrada I0
esté activa:
I0 + I1 + I2 + I3
Figura 8.3: Esquema del codificador que incluye la señal A, que indica si hay algún línea de entrada activa
Si quieres puedes bajar a la placa este circuito, poniendo la señal A como el LED 7 o bien continuar
realizando las modificaciones que queremos realizar. Llama al proyecto codif4a2.
Ahora queremos incluir un módulo que determine las PRIOR CODIF
prioridades, de manera que, aunque dos botones estén BTN0 I0 P0 P0
S0
S0
pulsados, sólo una línea de entrada del decodificador BTN1 I1 P1 P1 SA
S1
esté activa. Pondremos la prioridad más alta para el BTN2 I2 P2 P2
BTN3 I3 P3 P3 A A
bit más significativo, de modo que si I2 e I1 estuviesen
pulsados, el codificador mostrase un 102 y no un 112
como estaba haciendo hasta ahora (recuerda el caso de puede haber más de como máximo sólo habrá
la derecha de la figura 8.2). El esquema que queremos una que valga 1 una señal que valga 1
implementar se muestra en la figura 8.4 Figura 8.4: Bloque de prioridades previo al codificador
¿Cómo hacemos un módulo que establezca las prioridades? Podemos usar las puertas AND ya que sabemos
que si una de las entradas de estas puertas es cero, la salida será cero. Mientras que si es uno, la salida será lo
que la otra entrada valga. Así la señal prioritaria pasará directamente y la señales menos prioritarias
dependerán del valor de la prioritaria. En la figura 8.5 se muestra un esquema que establece la prioridad de
I3 sobre I2. Cuando I3='1' se pone un cero en la salida P2, mientras que si I3='0' la señal P2 valdrá lo que
valga I2.
Si I3='1' entonces P2='0' Si I3='1' entonces P2=I2
'0' I2
I2 P2 I2 P2
'0' '1'
circuito más sencillo debido a que ese caso nunca se va a dar. Esta libertad no la tengo con las X en las
entradas.
Para terminar nos quedaría unir los módulos tal como se muestra en la figura 8.4, sin embargo, antes vamos
a incluir la señal de habilitación (Enable). Cuando la señal de habilitación vale cero (Enable='0') hace que
todas las salidas valgan '0'. Si está habilitado, el circuito funciona normalmente. Además, los codificadores
con habilitación incluyen una nueva señal de salida (EO: enable out), que nos permitirá conectar varios
codificadores y extender su capacidad. Esta señal nos indica si el codificador está habilitado pero no hay
ninguna señal de entrada activa, nos diferencia de cuando el codificador no está habilitado. El bloque que
queremos realizar se muestra en la figura 8.7
CODIF EI I3 I2 I1 I0 S1 S0 A EO
EO LED7
BTN0 I0 0 X X X X 0 0 0 0
BTN1 I1 S0 LED0 1 0 0 0 0 0 0 0 1
BTN2 I2 S1 LED1 1 0 0 0 1 0 0 1 0
BTN3 I3 1 0 0 1 X 0 1 1 0
A LED6 1 0 1 X X 1 0 1 0
SW7 EI
1 1 X X X 1 1 1 0
Figura 8.7: Bloque y tabla de verdad del codificador con prioridad y habilitación
Como vemos de la tabla de verdad de la figura 8.7, la salida EO vale '1' cuando A0='0' y EI='1'. A estas
alturas, esta condición nos debería ser fácil de implementar en puertas lógicas.
El circuito final nos quedará como muestra la figura 8.8.
PRIOR EO
I0 P0
A
I1 P1
S0
P2
I2
S1
P3
I3
EI
Figura 8.8: Esquema en puertas del codificador con prioridad y habilitación
Implementa este diseño en la FPGA, poniendo los pines que se muestran en el bloque de la izquierda de la
figura 8.7 y comprueba que funciona correctamente.
seleccionamos la categoría de nuestro proyecto (la 2ª fila donde sale la ruta de nuestro proyecto). En la
subventana de Symbols estarán los tres símbolos de nuestro proyecto: codif4a2, decod4a16 y hex7seg. El
símbolo decod4a16 está dentro del hex7seg y por eso aparece. Nosotros usaremos el codif4a2 y el hex7seg. La
conexión de los circuitos se haría como muestra la figura 8.9. Como el codificador es de 4 a 2, tiene dos
salidas para indicar el número (S0 y S1), el resto de entradas del conversor a 7 segmentos (I2 e I3) irán a
tierra (a cero), para que los número que muestre sean del 0 al 3. Si estuviesen las dos a '1', mostraría los
números del 12 a 15. Y si no las pusieses a ningún valor, tendrías un valor indeterminado en las entradas del
decodificador, y quién sabe que número te saldría. Esto es: Las entradas siempre deben tener un valor
determinado, no se deben dejar "al aire".
I0 EO LED7
SW4 I0
I1
SW5 I1 S0
I2
SW6 I2 S1
I3
SW7 I3
A
EI S0
LED0
S1
G_CODIF LED1
I4 EO
BTN0 I0 S2
I5 LED2
BTN1 I1 S0
I6
BTN2 I2 S1
I7
BTN3 I3 A
A LED6
SW0 EI
EI
ENTRADAS SALIDAS
Señales internas de G_CODIF P_CODIF G_CODIF P_CODIF CODIF8a3
los codificadores Señales externas
EI I3 I2 I1 I0 EI I3 I2 I1 I0 S1 S0 A EO S1 S0 A EO
de 4 a 2 (puertos) del
EI I7 I6 I5 I4 I3 I2 I1 I0 S2 S1 S0 A EO codificador de 8 a 3
0 X X X X 0 X X X X 0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1
1 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 1 0
ninguna entrada de
1 0 0 0 0 1 0 0 1 X 0 0 0 1 0 1 1 0 0 0 1 1 0 S1 y S2 del CODIF8a3
G_CODIF activa →
1 0 0 0 0 1 0 1 X X 0 0 0 1 1 0 1 0 0 1 0 1 0 lo proporciona P_CODIF
habilita a P_CODIF
1 0 0 0 0 1 1 X X X 0 0 0 1 1 1 1 0 0 1 1 1 0
1 0 0 0 1 0 X X X X 0 0 1 0 0 0 0 0 1 0 0 1 0
alguna entrada de S1 y S2 del CODIF8a3
1 0 0 1 X 0 X X X X 0 1 1 0 0 0 0 0 1 0 1 1 0
G_CODIF activa →
1 0 1 X X 0 X X X X 1 0 1 0 0 0 0 0 1 1 0 1 0 lo proporciona G_CODIF
deshabilita a P_CODIF
1 1 X X X 0 X X X X 1 1 1 0 0 0 0 0 1 1 1 1 0
Figura 9.3: Tabla de verdad del codificador de 8 a 3 con las señales internas
Ahora implementa en la placa el diseño de la figura 9.3:
• Crea un nuevo proyecto llamado CODIF8a3
• Añade una copia del codificador de 4 a 2 que creaste en la práctica anterior (capítulo 8): "Proyect→Add Copy of
Source..." y busca el "c:/practicas/edi/tunombre/codif4a2/codif4a2.sch"
• Crea un símbolo de este codificador: Tools→Symbol Wizard
• Crea una nueva fuente de tipo esquemático llamada codif8a3 (Proyect→New Source)
• Realiza el circuito de la figura 9.2
• Crea el fichero UCF con los pines que la figura 9.2 indica
• Baja el circuito a la FPGA
• Comprueba que funciona correctamente
10. Comparadores
Ya hemos aprendido a realizar varios diseños: puertas lógicas, decodificadores, codificadores y un
convertidor de hexadecimal a siete segmentos. Ahora vamos a hacer un comparador, primero lo haremos de
un sólo bit y luego, con comparadores de un bit construiremos uno de dos bits.
A B IGUAL AM BM COMPA1
0 0 1 0 0 IGUAL
0 1 0 0 1 BM = m1 = A·B A
AM
1 0 0 1 0 B BM
1 1 1 0 0
AM = m2 = A·B
IGUAL=(A·B)+(A·B)=A⊕B
Figura 10.1: Tabla de verdad, ecuaciones lógicas, y entradas y salidas del comparador de un bit
El diseño de este circuito es bien fácil, sólo son tres puertas, dos puertos de entrada y tres de salida (figura
10.1). Cierra el proyecto anterior, abre uno nuevo llamado compa y crea un nuevo fichero llamado compa1.
Una vez que tengas el plano del circuito, añade las puertas lógicas, recuerda que tienes puertas AND con
una entrada negada para implementar la función ⎯⎯ A ·B y A· ⎯⎯
B (estas se llaman and2b1 y tienen una bolita de
negación en una de sus entradas). También tienes funciones XNOR para implementar la salida IGUAL.
Pon los puertos con los mismos nombres de la figura 10.1. Cuando tengas el circuito listo guárdalo (CRTL+S)
y comprueba el esquemático (Tools→Check Schematic).
Si el diseño está bien pasaremos a implementarlo en la FPGA. A SW0
Ahora asignamos los pines, ya sabes como se hace, o bien con el fichero UCF o B SW1
con la herramienta PACE. Los vas a asignar como muestra la tabla 10.1: AM LD0
IGUAL LD1
Recuerda que en los pines tienes que poner el que indica en la placa, por
ejemplo para SW0 pondrás P89. BM LD2
Y por fin implementa el comparador y comprueba que funciona bien. Tabla 10.1: Tabla de
asignación de señales
COMPA2 COMPA2
2
A0 A(1:0)
bit más
significativo A1 IGUAL IGUAL
AM AM
B0 BM BM
bit más 2
significativo B1 B(1:0)
Figura 10.3: Tabla de verdad del comparador de dos bits ordenada desde los bits más significativos a los menos
Fíjate en la tabla de verdad de la figura 10.3:
• Cuando A1<B1 entonces A es menor que B: IGUAL=0 ; AM=0 ; BM = 1
• Cuando A1>B1 entonces A es mayor que B: IGUAL=0 ; AM=1 ; BM = 0
Diseño digital con esquemáticos y FPGA. v1.8 - 04/06/2008 49
Departamento de Tecnología Electrónica 10. Comparadores
B0 BM_0
COMPA1
IGUAL_1
A1 AM
AM_1
B1 BM_1
COMPA2
IGUAL_10
A0
AM_10 IGUAL
A1
BM_10
B0
B1
COMPA2
A2 IGUAL_32 AM
A3 AM_32
B2 BM_32
B3 BM
bits 3 y 2
B0_MSB
B1_MSB
Figura 11.2: Comparador de dos bits que se puede poner en cascada
El bloque (COMP2_CAS) de la figura 11.2, además de los dos bits correspondientes que quiere comparar, recibe
las entradas de la comparación de los bits menos significativos. Por tanto, los comparadores se pueden
conectar directamente, como se muestra en la figura 11.3. Fíjate el valor de las entradas de comparación del
comparador de los bits menos significativos: cuando no hay más bits que comparar, se ponen como si fuesen
iguales (IGUAL_LSB='1').
Comparador de Comparador de
los bits menos A2 los bits más
significativos A3 significativos
COMP2_CAS COMP2_CAS
A0 A0_MSB A0_MSB
A1 A1_MSB A1_MSB
B2
B3
Figura 11.3: Comparador de 4 bits conectando dos comparadores de dos bits en cascada
¿Cómo podríamos hacer un comparador para que se pueda conectar en cascada? Simplemente tenemos que
quitar el comparador de los bits menos significativos de la figura 11.1 y hacer que lo que eran sus salidas
sean ahora las entradas del bloque. Esto se muestra en la figura 11.4, compáralo con el de la figura 11.1.
Entradas de las
comparaciones de los bits
menos significativos (LSB)
IGUAL_LSB
IGUAL
AM_LSB
BM_LSB
Bits más
significativos: COMPA2
A0_MSB IGUAL AM
A1_MSB
AM
B0_MSB BM
B1_MSB BM
Ahora queremos conectar cada una de las líneas de los buses a las entradas del comparador. Para ello
empezamos añadiendo un conector al bus con el comando Add→Bus Tap. Al seleccionar éste comando, en la
ventana de opciones podemos elegir la orientación del terminal triangular. Éste tiene que ir en el lado del
bus, así que para el bus A tendrías que seleccionar Top, mientras que para el bus B seleccionarías Bottom. El
diseño debería quedar como muestra la figura 11.6.
Nombre
Nombre
Increase
Increase the
the name
name
Ahora conectamos los buses a los puertos de entrada de nuestro diseño. Esto se hace igual que hemos hecho
hasta ahora. Como lo conectamos al bus, que ya tiene nombre, el puerto de entrada adquiere el mismo
nombre que el bus.
Por último, realizamos las interconexiones entre los comparadores, les conectamos los puertos de salida, y
los valores de las entradas, igual que se muestra en la figura 11.3 y en la 11.8.
12. El multiplexor
El diseño que acabamos de realizar está bien pero ahora nos gustaría que el circuito no sólo indique con los
LED qué número es mayor, sino que también nos muestre el número mayor por el display de siete
segmentos.
A partir de ahora se van a dar las especificaciones del sistema que queremos realizar, de modo que sean
suficientes para diseñar el circuito. Posteriormente se darán algunas explicaciones de cómo se puede realizar.
Intenta realizar el diseño sin mirar la solución o al menos pensarlo. Luego, si no te sale, o si lo quieres
comprobar, consulta la solución.
Habitualmente, la empresa de ingeniería o el ingeniero tiene que realizar el diseño de un sistema a partir de
unas especificaciones que le da el cliente o su jefe. No siempre el cliente tiene las cosas claras o sabe explicar
lo que quiere. Por tanto, la tarea de realizar las especificaciones dura varias sesiones en las que las dos partes
se ponen de acuerdo en las prestaciones del diseño, el coste, el tiempo en que el producto va a estar
disponible, ...
12.1. Especificaciones
Comparador de dos números de 4 bits. El circuito debe comparar dos números de 4 bits (A y B) que estarán
codificados por medio de los interruptores de la placa. El circuito indicará a través de tres LED el resultado
de la comparación:
• Si A>B lucirá el led LD0 de la placa, en otro caso permanecerá apagado
• Si A=B entonces LD1 se encenderá, en otro caso permanecerá apagado
• Si A<B entonces LD2 se encenderá, en otro caso permanecerá apagado
Además, el circuito mostrará por un display de siete segmentos el número mayor. En caso de que sea A el
número mayor, lo mostrará por el display de la derecha (AN0), en caso de que A sea menor lo mostrará por el
display de la izquierda (AN3), y en caso de que sean iguales se mostrará por los dos displays anteriores (el de la
izquierda y el de la derecha: AN0 y AN3).
Los 4 interruptores de la derecha corresponderán con el número A, de modo que:
• A(0) será el interruptor SW0
• A(1) será el interruptor SW1
• A(2) será el interruptor SW2
• A(3) será el interruptor SW3
Los 4 interruptores de la izquierda corresponderán con el número B, de modo que:
• B(0) será el interruptor SW4
• B(1) será el interruptor SW5
• B(2) será el interruptor SW6
• B(3) será el interruptor SW7
Con esta información se debe diseñar el circuito con bloques e implementarlo en la FPGA. Aunque muchos
de los bloques ya estén hechos y no volvamos a repetir cómo se hacen, deberás saber cómo se realizan en
puertas.
MUX
A
A 1 S
S
0 B
B
AM
AM Si AM='1', por la salida S tendremos A
Si AM='0', por la salida S tendremos B
Figura 12.1: Multiplexor de dos entradas de datos y una de selección
En nuestro caso las entradas de dato del multiplexor tendrán más de un bit, por lo tanto tendríamos que usar
una variante de este multiplexor con entradas de tipo bus. Por ejemplo, un multiplexor de dos bits se
realizaría como muestra la figura 12.2. En la figura se puede observar que se usa un multiplexor de un bit de
ancho para cada bit y que todos los multiplexores tienen la misma señal de selección.
A(1) A(1)
A(1:0)
2 0 S(1)
A(0)
MUX2_2b B(1) 1
A(1:0) equivalente
2 AM
0 2 S(1:0) 2 S(1:0)
B(1:0) 2
1
A(0)
B(1)
B(1:0) 2 0
S(0)
AM B(0) B(0)
1
AM
AM
Figura 12.2: Multiplexor de dos entradas de datos de dos bits de ancho
Al realizar un diseño, normalmente no hay una única solución para un circuito, sin embargo hay algunas
que son más ventajosas que otras. Unas pueden tener menor número de puertas, otras podrán ser más
complicadas o ser más rápidas (tienen menos retardos).
Por ejemplo, una opción valida para nuestro diseño sería hacerlo como muestra la figura 12.3. En este diseño
se convierten los números A y B a siete segmentos, dichas señales convertidas se han llamado A_7SEG y B_7SEG
respectivamente. Estas señales pasan por un multiplexor que las va a seleccionar según el valor de AM (según
si A>B). Este valor será el que salga por el display. Por otro lado, se muestran también las señales AN_0 y AN_3,
que harán que se encienda uno de los dos displays o los dos a la vez si son iguales. El display de la derecha
(AN_0) se encenderá cuando A>B (AM='1') ó cuando A=B (IGUAL='1'). El display de la izquierda (AN_3) se
encenderá cuando A<B (BM='1') ó cuando A=B (IGUAL='1').Fíjate que hay una puerta NOR debido a que las
señales AN funcionan con lógica negada.
HEX7SEG
A_7SEG
SEG(6:0) SEG_A
4 MUX
A(3:0) I(3:0) SEG_B
7
1 SEG_C
7
B_7SEG SEG_D
HEX7SEG
0 SEG_E
7
SEG_F
SEG(6:0) SEG_G
4
B(3:0) I(3:0)
COMP4 4
A(3:0)
AM
AN_0
IGUAL
B(3:0) BM
AN_3
Otra alternativa para realizar el circuito es la mostrada en la figura 12.4. Fíjate que en ella no sólo hay un
menor número de componentes (sólo hay un convertidor de hex a 7 segmentos) sino que además las
entradas del multiplexor utilizado tienen 4 elementos en vez de siete, lo que hace que sea bastante menor.
Así que esta alternativa es más sencilla y será la que implementemos. Seguramente haya otras alternativas y
alguna de ellas se te ha podido ocurrir a ti.
MUX HEX7SEG SEG_A
4 SEG_B
A(3:0) 1 SEG_C
4
I(3:0) 7
4 SEG(6:0) SEG_D
B(3:0) 0
SEG_E
SEG_F
COMP4 4
SEG_G
A(3:0)
AM
AN_0
IGUAL
B(3:0) BM
AN_3
12.3. Diseño
Del circuito de la figura 12.4 ya hemos realizado todos los bloques excepto el multiplexor.
Creamos un nuevo proyecto llamado mux7seg. Ahora vamos a añadir el convertidor de 7 segmentos que
hicimos en el ejercicio Y añadimos una copia de la fuente del circuito que hicimos en el ejercicio 7, el
convertidor de hexadecimal a siete segmentos (el proyecto se llamaba hex7seg). Para ello tenemos copiamos
y añadimos al proyecto el decodificador y el convertidor:
(Proyect→Add Copy of Source...) y seleccionamos los ficheros decod4a16.sch y hex7seg.sch
Vamos a realizar alguna modificación al convertidor para luego crear un módulo: seleccionamos todas las
salidas AN que habíamos creado y las eliminamos. Pues ahora las vamos a gobernar desde fuera del
convertidor. La señal SEG_DT la podemos dejar. Una vez que lo hayamos hecho, guardamos y comprobamos
el esquemático (Tools→Check Schematic y también Tools→Hierachical Check).
Si todo sale bien, ahora creamos un símbolo de este diseño: (Tools→Symbol Wizard) y seleccionamos el
hex7seg.Ordenamos los puertos si no estuviesen ordenados.
A continuación vamos a crear un multiplexor de 2 entradas de dato y una de selección, con 4 bits en cada
entrada de dato. Creamos una nueva fuente llamada mux2_4bit. Podríamos crear el multiplexor con puertas
como se muestra en la figura 12.1 (con la diferencia que ahora cada línea de datos tiene 4 bits) sin embargo
para tardar menos vamos a usar los multiplexores de dos entradas de 1 bit que tiene el ISE: ventana de
símbolos, selecciona la categoría Mux, y dentro de los símbolos selecciona el m2_1. El multiplexor diseñado
debería quedar parecido a como lo muestra 12.5. Hemos llamado a las entradas D0 y D1, que se refieren al
dato que se selecciona cuando SEL vale 0, y cuando SEL vale 1, respectivamente.
Figura 12.5: Multiplexor de 2 datos de 4 bits cada dato (una señal de selección)
Guarda el diseño, comprueba el esquemático y crea un símbolo de este multiplexor para poder usarlo en el
diseño de más alto nivel: el que va a reunir a todos, como el de la figura 12.4.
Creamos el diseño de más alto nivel de nuestro circuito, que será como el de la figura 12.4. Añadimos nueva
fuente llamada mux7seg.sch.
Necesitamos un comparador, o bien usamos el comparador que hemos creado en la práctica 11 (ya sabes
cómo se importa) o bien podemos usar el comparador de la biblioteca de Xilinx. Si coges el de Xilinx, dentro
de la ventana de opciones, en la categoría Comparator, escoge el compm4. Este comparador es de 4 bits, y tiene
como salidas GT (A mayor) y LT (A menor). Nos falta el igual, pero lo podemos obtener fácilmente, ya que
¿cuándo A y B serán iguales? pues cuando ni A sea mayor que B¸ ni A sea menor que B. Y esto que acabamos
de decir en álgebra de Boole se traduce como: IGUAL = ⎯⎯⎯ GT · ⎯⎯⎯
LT . Otra manera de decirlo es que A y B son
iguales cuando no ocurre que A sea mayor que B, o que A sea menor que B: IGUAL = ⎯⎯⎯⎯⎯⎯⎯⎯⎯
GT+LT . Fíjate que las dos
expresiones son equivalentes por el teorema de De Morgan. Aún así, si te lías, puedes hacer la tabla de
verdad.
El diseño final del circuito podría quedarte como lo muestra la figura 12.6. Fíjate que entre otros, también se
han añadido los puertos que van a los LED (AM, BM, IGUAL) Asegúrate que entiendes todo.
13. El sumador
En clase se ha explicado el sumador, y en este ejercicio simplemente aplicaremos la teoría para realizarlo. Así
que las especificaciones van a ser muy sencillas. Después de leer las especificaciones puedes intentar hacerlo
tú sólo o ir al apartado siguiente donde se explica el diseño del sumador.
13.1. Especificaciones
Sumador de dos números de 4 bits. El circuito debe sumar dos números sin signo de 4 bits (A y B) que estarán
codificados por medio de los interruptores de la placa. El circuito mostrará en el display de la derecha el
resultado de la suma y en caso de que haya desbordamiento encenderá el LED de la izquierda (LD7), además
encenderá el punto decimal del display cuando haya desbordamiento.
La correspondencia de los interruptores con los números A y B es la misma que la del ejercicio 12 (apartado
12.1). Esto es, los cuatro de la derecha se corresponden con la señal A y los cuatro de la izquierda con B.
Además el sumador recibirá el acarreo de entrada por medio del pulsador de la derecha (BTN0).
Opcionalmente también se podrá sacar el resultado codificado en binario por los cuatro LED de la derecha
(de LD0 a LD3).
13.2. Diseño
Empezaremos realizando el diseño de un sumador de 1 bit, para luego ir juntando estos sumadores de un
bit. Realizando lo que se llama un sumador en paralelo con acarreo en serie (también llamado en cascada).
Si queremos sumar dos números de un bit, podemos realizar un semisumador (HA: half adder), con el que
obtenemos el resultado de la suma (S) y el acarreo (C). En la figura 13.1 se muestra la tabla de verdad de la
suma y el acarreo, y el circuito que lo implementa. La obtención de este circuito a partir de la tabla de verdad
ya te debería ser fácil si has estudiado el tema 3: Álgebra de Boole y funciones lógicas.
HA
A B S C
A S
0 0 0 0
0 1 1 0
1 0 1 0 C
1 1 0 1 B
Una vez que tenemos un sumador completo de 1 bit, la realización de un sumador de 4 bits es bastante fácil.
Simplemente tenemos que conectar los acarreos consecutivamente del bit menos significativo al más
significativo. Y conectar las entradas de A y B en paralelo, en sus sumadores correspondientes. El diseño se
muestra en la figura 13.3.
bits más bits menos
significativos A3 B3 A2 B2 A1 B1 A0 B0 significativos
(MSB) (LSB)
A B A B A B A B
C2 C1 C0 CI
CO CO CI CO CI CO CI CO CI
Acarreo de salida S S S S
(o desbordamiento) Acarreo de
entrada a cero
S3 S2 S1 S0
Figura 13.3: Sumador de 4 bits a partir de sumadores completos
Para diseñar el sumador de 4 bits creamos una nueva fuente llamada sum4bits.sch. En ella incluimos los
bloques FA que acabamos de realizar. Los podemos colocar verticalmente, como muestra la figura 13.4 ó bien
rotarlos y voltearlos (rotate & mirror). Al contrario que como sale en la figura 13.3, el acarreo de entrada CI, lo
vamos a poner como puerto de entrada (figura 13.4), para así poder conectar varios módulos en cascada, o
en nuestro caso introducirlo cuando apretemos el pulsador BTN0.
CI 4
S(3:0)
4
A(3:0)
4 CO
B(3:0)
SUM4BITS
modificamos en el ejercicio 12. Los pasos para importarlo estaban descritos en el apartado 12.3, pero los
recordamos:
• Añadir una copia de algunas las fuentes de los circuitos que hicimos en el ejercicio12 (el proyecto se llamaba
mux7seg). Estos son el decodificador de 4 a 16: decod4a16.sch y el bloque que lo contenía, el convertidor a 7
segmentos: hex7seg.sch. Para ello ejecutamos el comando Proyect→Add Copy of Source... y seleccionamos los
ficheros decod4a16.sch y hex7seg.sch
• El convertidor vamos a modificarlo un poco, vamos a eliminar el puerto SEG_DT¸ en ese diseño la teníamos
siempre a uno, ahora la quitamos completamente. Guardamos el diseño, y comprobamos el esquemático
(Tools→Check Schematic y también Tools→Hierachical Check).
• Por último creamos un símbolo del convertidor (Tools→Symbol Wizard) y seleccionamos el hex7seg. Asegúrate
que los puertos estén ordenados.
Ahora creamos una nueva fuente llamada top_sumador.sch que va a contener el sumador y el convertidor de
hexadecimal a 7 segmentos. La hemos nombrado con el prefijo top para indicar que es el diseño que contiene
al resto de componentes del circuito.
Ya deberías poder terminar el diseño tú solo, aún así, a continuación se muestra una implementación posible
(figura 13.6). Si no has sabido hacerla por ti mismo intenta entender todo el circuito propuesto.
14. Sumador/restador
Queremos hacer un circuito que reste, para ello podríamos hacer un circuito restador de un bit a partir de la
tabla de verdad de la resta. Esto se haría de manera similar a como se hace el semi-sumador y el sumador
completo (ver figuras 13.1 y 13.2). Y aunque esto es un buen ejercicio que conviene que sepas hacer, en esta
práctica vamos a aprovechar los conocimientos de representación numérica que vimos en el tema 2. En aquel
tema vimos que usando el complemento a 2 (Ca2) podíamos realizar una resta sumando. Así que nos
ahorramos realizar un nuevo bloque restador y lo que haremos será calcular el complemento a dos del
sustraendo y sumarlo al minuendo.
14.1. Especificaciones
Sumador/restador de dos números de 4 bits. El circuito debe sumar o restar dos números codificados en
complemento a 2 con 4 bits (OPA y OPB) y cuyos valores estarán determinados por la posición de los
interruptores de la placa. El circuito mostrará en el display de la derecha el resultado de la suma o la resta.
Los operandos vendrán dados por los interruptores. El minuendo (o uno de los sumandos: OPA) se codificará
mediante los 4 interruptores de la derecha (de SW0 a SW3), y el sustraendo (o el otro sumando: OPB) con los
cuatro interruptores de la izquierda (de SW4 a SW7). Recuerda que los números vienen codificados en
complemento a 2.
EL pulsador BTN0 indicará qué operación se realiza. Cuando esté pulsador se hará la resta, mientras que
cuando no esté pulsado se efectuará la suma.
El resultado de la operación (suma o resta) se mostrará por el primer display de 7 segmentos. El resultado se
deberá mostrar en el display en signo magnitud (para que lo podamos entender los humanos). Para mostrar
el signo negativo se utilizará el punto decimal, es decir, si el punto decimal está luciendo significa que el
resultado es el número mostrado pero negativo.
En caso de que haya desbordamiento (overflow) el display mostrará la letra E.
Además los cuatro LED de la derecha (de LD0 a LD3) mostrarán el resultado directo (en complemento a 2).
El resultado se dará por el display de siete segmentos de la derecha. Se usará LD7 para el acarreo de salida y
LD6 para el desbordamiento en la resta. El pulsador BTN0 se usará para indicar que se realiza la suma o la
resta. Cuando BTN0 esté pulsado se mostrará la suma, cuando no esté pulsado se mostrará la resta.
RESUL(3:0)
4
LEDS
acarreo C
desbordamiento OV
8 A
VISUALIZACION
F G B
E C
D
CI 4
S(3:0) S(3:0)
4
OPA(3:0)
A(3:0) CO
Ca2(B)
0
4 4
CA2 B(3:0)
4 1
OPB(3:0)
RES_SUM
Figura 14.2: Esquema inicial del módulo sumador/restador (sin visualización)
Se podría realizar el diseño así, sin embargo los diseñadores digitales han tendido siempre a minimizar el
número de bloques y puertas del diseño. En este caso se puede hacer una versión más compacta. Esto
ocurría sobre todo hace unos años, cuando tenían que hacer el diseño en componentes discretos o con
dispositivos programables con poco espacio. Ahora esto no es tan crítico, aún así, a continuación veremos
cómo hacer el circuito más compacto.
El complemento a dos de un número se realiza complementando cada bit y añadiéndole 1 al resultado. Y
podríamos realizarlo como se muestra en la figura 14.3, utilizando el sumador de cuatro bits para añadir 1.
Acarreo de entrada = '1' :
sumamos 1
también se podía poner el
acarreo de entrada a cero VCC SUM4BITS
y poner un uno en A(0)
CI
Ca2(B)
El otro sumando El resultado es el
vale '0' complemento a 2 de B
4
A(3:0) 4
S(3:0) S(3:0)
CO
4
OPB(3:0) B(3:0)
complementar
cada bit
0
4 4
B(3:0)
4 1
OPB(3:0)
RES_SUM
Figura 14.4: Otra versión del circuito sumador/restador (sin visualización)
Pero esto todavía no es el circuito final, ya que los inversores y el multiplexor aún se pueden sustituir por
algo más pequeño. Con el multiplexor estamos eligiendo la señal OPB complementada o no según el valor de
RES_SUM. Esto es equivalente a utilizar una XNOR, ya que según el valor de una entrada deja pasar la otra tal
cual o complementada (ver figura 14.5).
equivalente a XNOR
Sel B S
0 0 0 1 B
Sel=0 → S=B S
S 0 1 0 Sel
1 0 0 Sel=1 → S=B
B 1
1 1 1
Sel
Figura 14.5: Equivalencia entre el circuito con multiplexor y el circuito con puerta XNOR
Quizá te sorprenda que se utilice una XNOR y no una XOR, ya que eso es lo que vimos en teoría. Esto se
debe a que la señal de sumar/restar (RES_SUM) está complementada. En este ejercicio se suma cuando
RES_SUM=1, mientras que en la teoría se suma cuando vale cero. Es por esto que sale una XNOR, ya que la
XNOR es equivalente a una XOR con una de las entradas negadas. Esta entrada negada es la señal RES_SUM.
En la figura 14.6 se muestra esta equivalencia.
equivalente equivalente
B B B
S S S
Sel Sel Sel
OPB(0)
OPB(1)
4
B(3:0)
OPB(2)
OPB(3)
Figura 14.7: Penúltima versión del circuito sumador/restador (sin visualización)
Bueno, quizás podamos pensar que la figura 14.7 corresponde el diseño definitivo, pero no es así, ya que
tenemos que ocuparnos del acarreo de salida y el desbordamiento. El acarreo de salida se deja como está,
para así poder conectar varios sumadores/restadores en cascada.
Pero el desbordamiento hay que analizarlo. Como estamos trabajando en complemento a dos, el
desbordamiento funciona de manera diferente. ¿Cuándo se desbordaba la suma en complemento a dos?
cuando los sumandos tienen el mismo signo y el resultado tenga el signo contrario. Si no te acuerdas de esto
repasa los ejercicios propuestos del tema 2. De todos modos en la figura 14.8 se muestra un ejemplo para
refrescarte la memoria.
éste es OPB y por ser suma éste es OPB
suma coincide con B resta
A3 A2 A1 A0
A B A B A B A B
C2 C1 C0 RES_SUM
CO CO CI CO CI CO CI CO CI
S S S S
DE S3 S2 S1 S0
Desbordamiento
y S(3)='1', significará que tenemos un número negativo, y por lo tanto tendremos que calcular su
• Si OV='0'
complemento a 2 y encender el punto decimal.
Cuando tenemos condiciones de tipo "Si.... entonces", éstas se pueden implementar fácilmente con un
multiplexor. En la figura 14.11 se muestra esta "traducción".
S(3:0)
Ca2
S(3) 1 0
El número 14 4
muestra la E 1110
OV 1 0
A
HEX7SEG
F G B
I(3:0) 7
SEG(6:0)
E C
D
S(3) SEG_DT
Ca2
1000 1000
S(3) 1 1 0
4
1110
1000
OV 1 0
0
4
A
1000 HEX7SEG
F G B
I(3:0) 7
SEG(6:0)
Se muestra un 8 E D
C
S(3) SEG_DT
1 0 encenderá el punto:
signo −
14.3. Diseño
Creamos un nuevo proyecto llamado addsub. Añadimos una copia de las siguientes fuentes del ejercicio 13
(el sumador)
• decod4_16.sch
• hex7seg.sch
• ha.sch
• fa.sch
• sum4bits.sch
Y del ejercicio del multiplexor (ejercicio 12), añadimos una copia de:
• mux2_4bit.sch
Crea un símbolo para el sumador, convertidor de siete segmentos y el multiplexor de dos entradas con 4 bits.
Primero vamos a crear el bloque sumador/restador (recuerda la figura 14.1 y el apartado 14.2.1). Para ello,
vamos a crear un nuevo fichero de tipo esquemático para crear el bloque sumador/restador, lo llamamos
addsub.sch y en él implementamos el diseño de la figura 14.7 con el añadido de la parte del desbordamiento
(figura 14.9). Aunque el resultado final se muestra en la figura 14.13, intenta no copiarlo, sino hacerlo tú solo,
y si acaso comprobarlo luego. Al terminar crea un símbolo.
Figura 14.14: Esquemático del circuito Ca2 que calcula el complemento a 2 de un número
Ahora creamos un nuevo fichero para la unidad de visualización, lo vamos a llamar visualiza.sch. En él
implementamos el circuito de la figura 14.11, resultando el esquemático mostrado en la figura 14.15. Al
terminar, comprueba el esquemático y crea un símbolo de este circuito.
Figura 14.15: Esquemático del circuito Visualiza, que se encarga de mostrar el resultado por el display de siete
segmentos
Y ya sólo falta crear la unidad de más alto nivel llamada top_addsub.sch, que se encargará de unir los
bloques sumador/restador y visualiza. El diagrama de bloques se mostró en la figura 14.1 y su realización en
el ISE se muestra a continuación (figura 14.16).
15.1. Especificaciones
Realizar una unidad aritmético lógica con dos operandos de 4 bits (OPA y OPB) y 4 operaciones.
Los operandos vendrán dados por los interruptores. El operando OPA se codificará mediante los 4
interruptores de la derecha (de SW0 a SW3), y el operando OPB con los cuatro interruptores de la izquierda (de
SW4 a SW7).
Las operaciones que se realizarán son: suma, multiplicación por 2, mayor y la operación lógica AND. Para
realizar una operación se deben de pulsar uno de los 4 pulsadores:
• BTN0: realiza la suma S=OPA+OPB
• BTN1: multiplica por 2 el operando OPA. S=2xOPA
• BTN2: devuelve el número mayor entre OPA y OPB
• BTN3: aplica la función lógica AND entre los bits de OPA y OPB
En caso de que se pulsen dos o más pulsadores al mismo tiempo, tendrá prioridad el pulsador que esté más
a la derecha en la placa. Por ejemplo si se pulsan BTN1 y BTN3 al mismo tiempo, el resultado será la
multiplicación por 2 (BTN1) y no la función lógica AND.
Para el caso de la operación suma, multiplicación y mayor, se considera que los operandos OPA y OPB están
codificados en binario puro (sin signo). Para la operación lógica AND, no es necesario considerar ninguna
codificación.
El resultado de la operación se mostrará por los cuatro LED de la derecha (de LD0 a LD3), además se mostrará
por el display de la derecha.
Según qué operación se esté realizando LD7 mostrará:
• En la suma: el acarreo de salida
• En la multiplicación: el desbordamiento
• En la operación "mayor que": se mantendrá apagado
• En la operación lógica AND, se mantendrá apagado
Cuando no haya ningún botón pulsado, todos los LED permanecerán apagados, y también el display.
CO 4 OV 4 4
R_SUM R_MULT R_MAY R_AND
OPER(1:0) 2
11 10 01 00
Códigos de operación 4
R_(3:0)
00 : AND
01 : MAYOR
10 : MULT
11 : SUMA
Tenemos que conectar BTN0 a la entrada de mayor prioridad (I3), y BTN3 a la de menor prioridad (I0). Si te
fijas en la tabla de verdad, cuando I3=1, la salida del codificador vale S="11", por lo tanto, es justo el código
de operación de la suma (figura 15.2). Por tanto, las salidas del codificador van directamente a la selección
del multiplexor (OPER). Si hubiésemos tomado el código de la suma como OPER="00", simplemente
tendríamos que invertir la salida del codificador. Así que, incluyendo el codificador para los pulsadores de
entrada, el circuito queda como muestra la figura 15.4.
OPA(3:0) OPA(3:0) OPB(3:0) OPA(3:0) OPB(3:0)
4 4
4 4 4
OPA(3:0) OPB(3:0)
4 4
Códigos de operación
00 : AND
01 : MAYOR
+ MULT2 MAYOR AND
10 : MULT
11 : SUMA 4 4
CO R_SUM OV R_MULT R_MAY R_AND 4
CODIF 4
BTN3 I0 EO
BTN2 I1 S0 OPER(1:0) 2
11 10 01 00
BTN1 I2 S1
BTN0 I3 4
A OP_ACT R_(3:0)
'1' EI
CODIF 4
BTN3 I0 EO
BTN2 I1 S0 OPER(1:0) 2 SEL 11 10 01 00
BTN1 I2 S1 EN
BTN0 I3 OP_ACT R(3:0)
A 4
'1' EI A
AN_0
HEX7SEG F G B
OV 0 I(3:0) 7 E C
SEG(6:0) D
LD7
CO 1
LEDS
OPER(0)
OPER(1)
Figura 15.5: Diagrama de bloques del circuito
Fíjate en la señal LD7 y asegúrate que entiendes por qué es así, si no lo entiendes, quizás te ayude la siguiente
figura:
OPER(0) 0 '0' 0
OV 0
1 1 LD7
LD7 LD7
CO 1
OV 0 OV 0
CO 1 CO 1 OPER(0)
OPER(1)
OPER(0) OPER(0)
OPER(1) OPER(1)
15.3. Diseño
Muchos de los bloques de la figura 15.5 ya los tenemos hechos, lo que nos permitirá ahorrar tiempo.
Creamos un nuevo proyecto llamado alu. Añadimos una copia (Proyect→Add Copy of Source) de las
siguientes fuentes del ejercicio 13 (el sumador)
• decod4_16.sch
• hex7seg.sch
• ha.sch
• fa.sch
• sum4bits.sch
Y del ejercicio del multiplexor (ejercicio 12), añadimos una copia de:
• mux2_4bit.sch
Crea un símbolo del conversor a siete segmentos (hex7seg.sch), el sumador de 4 bits (sum4bits.sch) y el
multiplexor (mux2_4bit.sch). Haz también que las señales tengan un orden razonable (sobre todo en el
convertidor de 7 segmentos). Para obtener el mismo orden que ya as obtenido en otras prácticas puedes
seguir los siguientes pasos:
• Abre el hex7seg.sch
• Ejecuta Tools→Symbol Wizard.
• Selecciona Using Schematic : hex7seg y más abajo selecciona Use Reference Symbol, allí pincha en Browse y busca
en el directorio del sumador el fichero hex7seg.sym para que coja el mismo símbolo y con el mismo orden.
Repite esto para el sumador y el multiplexor.
Ya tenemos el sumador, el convertidor de siete segmentos y el multiplexor de dos entradas con 4 bits.
También podríamos coger el comparador que hemos realizado en la práctica 11, sin embargo para éste
usaremos el símbolo que proporciona el ISE.
A continuación vamos a ir haciendo cada uno de los bloques que nos faltan de la figura 15.5.
15.3.1. Multiplicador por 2
Tenemos que multiplicar el operando OPA por 2. Si te acuerdas del tema 2, (sistemas de numeración y
codificación), la multiplicación por 2 en binario era similar a la multiplicación por 10 en decimal.
Simplemente hay que desplazar los números hacia la izquierda. Y en el bit menos significativo se pone un
cero. Si hubiese un uno en el bit más significativo habría que indicar que ha habido desbordamiento.
Este circuito por lo tanto es muy sencillo, se muestra en la figura 15.7, en donde también se han incluido
varios ejemplos para demostrar el funcionamiento.
Multiplicador x2 Ejemplos:
A3 A 2 A1 A0
6: 01102 5: 01012 9: 10012
0 x2 x2 x2
OV S3 S2 S1 S0 overflow
no cabe en 4 bits
Figura 15.7: Circuito multiplicador por 2
Para hacer este circuito creamos una nueva fuente llamada mult2.sch y creamos este sencillo circuito.
Recuerda que en el ISE no es posible conectar señales ni puertos con distinto nombre, así que tendremos que
poner un buffer, como ya hemos hecho alguna vez. Realizamos el circuito con buses, quedando como
muestra la figura 15.8.
4
R_AND 4 R_AND 0
00
R_MAY 4
R_MAY 4 1
01
4
4
0
R_MULT 10 R(3:0) OPER(0) 4
4
1 R(3:0)
R_SUM 4 11
4
R_MULT 0
2
R_SUM 4 EN
1
OPER(1:0) EN
OPER(0)
OPER(1)
Figura 15.11: Construcción de un multiplexor con habilitación de 4 entradas de datos a partir de multiplexores de dos
entradas de datos
Al final del multiplexor se le ha añadido la habilitación, una para cada bit. Para poner las señales de
selección en los multiplexores pequeños tenemos que analizar qué grupos de señales selecciona cada bit. Por
ejemplo, cuando OPER(1)='0' se selecciona a R_AND o a R_MAY, mientras que cuando OPER(1)='1' se selecciona
a R_MULT o a R_SUM. Quizás te ayude la siguiente figura.
4
R_AND 4 R_AND 0 habilitación
00
R_MAY 4
R_MAY 4 1
01
4
4
0
R_MULT 10 R(3:0) OPER(0) 4
4
1 R(3:0)
R_SUM 4 11
4
R_MULT 0
2
R_SUM 4 EN
1
OPER(1:0) EN
OPER(0)
OPER(1)
Si OPER(1)='1' , entonces OPER(0)
selecciona entre R_MULT y R_SUM
Figura 15.12: Señales de selección en los multiplexores pequeños
Así que creamos una nueva fuente llamada mux4d_4b_e.sch (indica que tiene 4 datos, de 4 bits y
habilitación). El esquemático del circuito se muestra a continuación (figura 15.13). Llama a los puertos de
entrada con un nombre genérico (D00, D01, D10, D11), para que puedas utilizarlo en otras ocasiones y
entender a qué puerto se corresponden ya que si los llamases R_AND, R_MAY,... si lo utilizas en otro diseño
no sabrás qué entrada de selección los activa, ni el significado de esos nombres.
16.1. Especificaciones
Diseñar un circuito que al apretar el pulsador BTN0 encienda LD0 y que cuando se deje de pulsar mantenga
encendido el LED. Para apagar el LED debemos de pulsar BTN1.
16.2. Diseño
Este circuito se podría realizar con un latch S-R, pero como no hay latches de este tipo en la biblioteca de
Xilinx, usaremos un biestable J-K activado por flanco de subida.
Creamos un nuevo proyecto llamado led_on.sch. Y creamos una
fuente con el mismo nombre. En la ventana de símbolos escogemos
la categoría Flip_Flop, y escogemos el símbolo fjkc. Que se
corresponde con un biestable J-K, con clear asíncrono. La señal
clear (CLR) funciona a nivel alto, es decir con un '1' lógico se pone
el biestable a cero.
El funcionamiento del biestable J-K ya lo conoces: un uno en la
entrada J pone a uno el biestable; un uno en la entrada K lo pone a
cero; si las dos entradas están a cero se mantiene el valor mientras
que si las dos están a uno, invierte el valor guardado.
Figura 16.1: Esquemático del circuito que
Por tanto, el esquemático será como el mostrado en la figura 16.1.
enciende y apaga el LED
Cuando lo tengas, guarda el diseño para implementarlo.
16.3. Implementación
Cuando los circuitos tienen señal de reloj hay que especificar quién es la señal de reloj y su frecuencia. Para
ello ejecutamos el comando "Create Timming Constraints", que se encuentra en la ventana de procesos, en el
apartado "User Constraints". Nos saldrá una ventana como la de la figura 16.2.
En ella hay un hueco para poner el periodo. Como nuestro reloj es de 50MHz, su periodo es 1/50MHz = 20
ns. Ya que 1MHz= 106 Hz. Y por otro lado: 1 ns = 10-9 ns. Así que en dicho hueco ponemos el número 20, y la
herramienta se encarga de poner los nanosegundos y el tiempo que el reloj está a nivel alto (50% por
defecto), lo dejamos como está, guardamos y cerramos el Xilinx Constraints Editor.
Figura 16.3: Especificación del periodo de reloj en el editor de restricciones del ISE
Ahora tenemos que asignar los pines, con la herramienta PACE no siempre sale bien, así que lo hacemos
editándolo a mano.
Al abrir el fichero UCF vemos que ya tiene algo escrito. Esto lo ha escrito el Xilinx Constraints Editor, ya que
en el fichero UCF también se guarda la información de la señal de reloj.
Aunque ya sabes cómo se rellena el fichero UCF, ya que hay algunas novedades, a continuación se muestra
cómo debe quedar.
NET "CLK" TNM_NET = "CLK";
TIMESPEC "TS_CLK" = PERIOD "CLK" 20 ns HIGH 50 %;
NET "LED0" LOC = "P46" ;
NET "BTN0" LOC = "P59" ;
NET "BTN1" LOC = "P58" ;
NET "CLK" LOC = "P77" ;
Código 16.1: Especificación del periodo de reloj en el editor de restricciones del ISE
Guarda el fichero, e implementa el circuito en la placa. Y comprueba que funciona.
Esto que acabamos de realizar no se puede hacer con un circuito combinacional, necesitaríamos mantener el
dedo pulsado para que la luz se mantenga encendida. Con este circuito hemos logrado memorizar cuál fue
la última tecla pulsada, la de encender o apagar.
Como curiosidad, decir que hemos usado un biestable J-K, y por tanto si pulsamos las teclas de encendido y
apagado se debería de cambiar el estado en que estaba, pero date cuenta que es prácticamente imposible
pulsar ambas teclas a la vez. Y lo que es más, ten en cuenta que el reloj va a 50MHz (50 millones de ciclos en
un segundo), por tanto, si mantienes pulsadas ambas teclas durante un segundo, lo que sucederá es que el
LED se apagará y encenderá 25 millones de veces. Nuestros ojos (y nuestro cerebro) no son capaces de
percibir este parpadeo y por lo tanto, lo que percibimos es que el LED luce menos (la mitad).
17.1. Ideas
Se nos pueden ocurrir varias ideas para implementar el circuito. Antes de seguir leyendo intenta pensar
cómo lo harías tú.
17.1.1. Conectando el pulsador a la entrada del biestable T
En principio podemos pensar en el biestable T, ya que cuando T='1' FTC
cambiará el valor del biestable, y por tanto, se apagará o se encenderá BTN0 T Q LED0
según como estuviese anteriormente.
Podemos realizar el circuito mostrado en la figura 17.1. Escogemos el CLK
biestable T con señal de clear asíncrono (CLR). Este biestable está en la CLR
BTN0-T
CLK
50 MHz
LED0-Q
Vcc
FTC
Atención:
Circuito MAL DISEÑADO T Q LED0
FD FD FTC
B C
BTN0 D Q D Q T Q LED0
CLR
Clk
Clk
BTN0
B
C
LED0
Figura 17.5: Obtén el cronograma de las señales para el circuito de la figura 17.4
Te deberá salir que por cada pulso largo de BTN0, el circuito lo transforma en un pulso de único ciclo de reloj:
la se señal F . Este pulso de F hace que el biestable T cambie sólo una vez por cada pulso de BTN0.
Si no sabes cómo obtener el cronograma, puedes simular el circuito, o bien, en el apartado 17.3 se muestra la
solución. Es muy importante que entiendas cómo se obtiene, ya que en el examen suelen caer problemas de
este tipo, normalmente algo más complejos.
Implementa el circuito en la placa. Seguramente veas que funciona correctamente. Sin embargo, si estás
usando la placa Basys, puedes apreciar que no funciona del todo bien. Eso es porque al presionar el pulsador
se producen rebotes que forman varios pulsos. La placa Pegasus tiene condensadores en las entradas de los
pulsadores para evitar esos rebotes (recuerda la figura de la derecha de la figura 3.1). La placa Basys no los
tienes, y para evitar esos rebotes tendrías que poner un contador que elimine los pulsos que se produzcan
durante un tiempo después de recibir un pulso, que puede ser de unos 200 ms.
Clk
BTN0
B
C
LED0
Figura 17.6: Solución al cronograma de las señales para el circuito de la figura 17.4
18.1. Especificaciones
Hacer que LD0 parpadee a una frecuencia de dos segundos. Esto es, permanecerá encendido durante un
segundo y apagado durante el segundo siguiente, y así sucesivamente. La frecuencia del reloj de la placa es
de 50MHz.
18.2. Diseño
Lo que tenemos que hacer es un divisor de frecuencia y esto se hace con contadores. El reloj de la placa
Pegasus va a 50MHz. Como 1MHz = 106 Hz entonces el reloj tiene 50 millones de ciclos en un segundo.
Nosotros queremos obtener una señal que vaya a 1 Hz, esto es, que tenga un periodo de un segundo. Esta
señal será la que hará cambiar cada segundo el valor del LED, por lo que el LED tendrá una frecuencia de 0,5
Hz (2 segundos de periodo).
El esquema de lo que queremos hacer se muestra en la figura 18.1: tenemos una señal de reloj que realiza 50
millones de ciclos por segundo. Por tanto, nosotros dividiremos la frecuencia contando hasta 50 millones, ya
que entonces habrá pasado un segundo. Al final de la cuenta, el circuito pondrá durante un sólo ciclo de
reloj su salida a uno, y el resto del tiempo a cero. Pasado otro segundo (después de volver a contar otros 50
millones), volverá a poner la salida a uno. Esta salida, irá a un biestable T que cambiará de estado cada
segundo (cada vez que se termina la cuenta) y por tanto apagará o encenderá el LED cada segundo, que es
nuestro objetivo. Evidentemente, la señales de entrada y salida no están a escala.
(no está a escala)
T=1 s
T=20 ns
T=20 ns
DivFrec Biestable T
Clk Clk1Hz T Q LED
Cada segundo le
Clear
50 Mz 1 Hz Clk llega un '1' y
entonces cambiará
de estado (se
encenderá y apagará)
conta5 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0
CLK
'1' CE CONT5 T100NS
50 MHz
CLK Clk
T100NS
CLEAR
10 MHz
50MHz 10MHz
Tsalida=100ns
5x20ns
Figura 18.2: Bloque que cuenta hasta 5, con sus entradas y salidas
Creamos un nuevo proyecto llamado segundero en C:\practicas\edi\tunombre. Recuerda: sin espacios, eñes,
tildes, ..... Dentro del proyecto creamos una nueva fuente para realizar este contador llamada conta5.sch.
Dentro de la ventana de símbolos, vamos a la categoría de contadores (counter) y allí escogemos el contador
cb4cle. Esto es un Contador Binario de 4 bits, con Clear asíncrono, carga paralelo de dato (Load) y
habilitación (Enable). Fíjate que se han marcado en mayúsculas y negrita las letras que hacen formar el
nombre del contador.
Cómo hacer para contar 5 ciclos de reloj. La figura 18.3 muestra el esquemático. En él, las salidas Q0 a Q3
llevan la cuenta. Cada vez que hay un flanco de subida del reloj CLK, el contador incrementa su cuenta, ya
Diseño digital con esquemáticos y FPGA. v1.8 - 04/06/2008 84
Departamento de Tecnología Electrónica 18. Parpadeo de un LED
que el count enable (CE) está siempre a uno. Por otro lado hay una señal de carga de dato (L: Load), esta señal
se pone a uno cuando la salida Q2 está a uno. Esto ocurre cuando se llega a 4, pues en el resto de los casos (de
0 a 3) la salida Q2 permanece a cero. La secuencia de la cuenta se muestra en la figura 18.5.
Figura 18.3: Esquemático del contador de cinco Figura 18.4: Otra versión del esquemático del contador de
ciclos de reloj cinco ciclos de reloj (más genérica)
Como se ve en la figura 18.2, al llegar a 4 Q3 Q2 Q1 Q0 Cuenta
0 0 0 0 0
debemos de inicializar el contador. La puesta a 0 0 0 1 1
cero la haremos siempre síncrona. Y por tanto, 0 0 1 0 2
activaremos la señal de carga L para introducir 0 0 1 1 3
un cero (inicializar síncronamente) en el 0 1 0 0 4 Iniciar la cuenta
0 0 0 0 0 cuando Q2=1 entonces
contador. Aunque existe un CLEAR asíncrono que 0 0 0 1 1 hacemos CONT5=1
inicializa el contador, por ser asíncrono, nosotros 0 0 1 0 2
no lo usaremos para contar (sí lo podríamos 0 0 1 1 3
0 1 0 0 4 Iniciar la cuenta
utilizar para inicializar el circuito, al arrancar la 0 0 0 0 0
primera vez, por ejemplo, pero no para contar). 0 0 0 1 1
.....
Figura 18.5: Secuencia del contador
En la figura 18.4 se muestra un contador de 5 más genérico que el de la figura 18.3, ya que la entrada CE no
está fija a uno. Por lo tanto, permite conectar el contador a otra cuenta anterior. El fin de cuenta: CONT5, será
cuando Q2='1' y CE='1', como en nuestro caso CE es siempre uno, los circuitos son equivalentes.
Al terminar este diseño, guárdalo y crea un símbolo. Es bastante recomendable que lo simules para que
veas el funcionamiento del contador.
Ahora, a la salida de conta5 tenemos una señal de 10MHz (100ns). Utilizaremos esta señal, y contaremos 10
ciclos de esta señal. A la salida de nuestro nuevo contador tendremos una señal de 1MHz (1000ns=1µs).
El esquema que queremos realizar se muestra a continuación.
Aquí contamos
f=10MHz ciclos de T100NS
f=1MHz
T=100ns no de reloj, y por eso
f=50MHz T=1µs=1000ns
es la entrada de CE
T=20ns
conta5 conta10
‘1’ CE T100NS CE Hemos conseguido
T1US divididir la frecuencia
T100NS Clk T1US
Clk Clk por 50=5x10
CLEAR CLEAR
4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0
CLK
50 MHz
T100NS
10 MHz
8 9 0 1 2 3 4 5 6 7 8 9 0
T1US
1 MHz
Se inicializa cuando la
cuenta sea 9 y CE=1
19.1. Especificaciones
• La primera parte consistirá en hacer un segundero digital que vaya de 0 a 9 y se muestre por el primer display
de 7 segmentos. El punto decimal parpadeará cada segundo. Esto es, que en un segundo se apague y se
encienda. Por tanto, tendrá un periodo de un segundo.
• La segunda parte será hacer un reloj, los dos displays de la derecha se mostrarán los 60 segundos de un
minuto: irá por tanto de 0 a 59. Los dos displays de la derecha mostrarán los 60 minutos de una hora. Por
tanto, también irá de 0 a 59. Además, el punto decimal del medio parpadeará cada segundo. Esto es, que en
un segundo se apague y se encienda. Por tanto, tendrá un periodo de un segundo.
CLEAR
CLEAR CLEAR
T1S
Entrada de 100 ms T500MS Salida de un segundo
Salida de medio segundo
Figura 19.2: Esquema para obtener una señal de medio segundo y de un segundo.
Otra alternativa es hacerlo con un único contador de 10, pero detectando cuándo llega a cinco. La cuenta de
medio segundo se activará cuando el contador valga 4 (de 0 a 5) o cuando el contador valga 9. En ambos
casos hay que incluir la condición que la CE='1' (en este caso la señal CE es la señal T100ms. La figura 19.3
muestra esta otra alternativa.
Figura 19.3: Alternativa al circuito que obtiene una señal de un segundo y otra de medio segundo
Esta alternativa tiene varios puntos interesantes: por un lado utilizamos sólo un contador. Pero lo más
importante que hay que tener en cuenta es lo relativo a la señal que detecta el 4 en binario. En este caso hay
que detectar los unos y los ceros porque como la cuenta no termina en cuatro, los números 5, 6 y 7 también
tienen que Q2='1'.
Otro aspecto interesante es que la señal de periodo medio segundo (T500MS) se forma con la OR de las señales
que identifican la cuenta de 4 y 9. Por último, no olvides incluir la señal CE en las detecciones, porque si no, la
señal no duraría un sólo pulso de reloj, sino todo el tiempo que el contador estuviese a 4 o a 9. La figura 19.4
puede ayudarte a entender esto.
Figura 19.6: Esquemático del circuito que muestra las unidades de segundo
Quizás te hayas fijado que sólo hay una letra de cada segmento para los cuatro displays, es decir, sólo hay
una A, B, C,..., G para los cuatro. Y luego hay una señal de control AN para cada segmento. Así que, ¿cómo
podríamos mostrar números diferentes en cada display?
Lo que se hace es multiplexar en el tiempo. Esto es, se divide el tiempo en cuatro partes, y se asigna cada
parte a un display. Así, en un ciclo va a estar encendido el primer display con un número determinado, y en el
siguiente ciclo, el siguiente display con otro número. Y así los cuatro, al final, cada display lucirá sólo un
cuarto de tiempo (así que lucirán con menos intensidad), pero lo hará tan rápido que nuestro ojo no notará
que gran parte del tiempo no está luciendo.
Lo que queremos generar se muestra en la figura 19.7.
T=1 ms
T1ms
Minutos Segundos
CUENTA4MS 0 1 2 3 0 1 2 3
decenas unidades decenas unidades
AN_0
AN_1
DM UM DS US
AN_2
AN_3 AN_2 AN_1 AN_0
AN_3
Según el valor de CUENTA4MS
NumDispl US DS UM DM US DS UM DM se selecciona las unidades o
decenas de minutos o segundos
4 x 1 ms
Figura 19.7: Cronograma para mostrar los minutos y segundos por los displays.
Quizá te preguntes para qué tanto rollo y por qué no se saca por la FPGA cada uno de los 7 segmentos de los
cuatro displays. Esto se hace así para ahorrar pines de la FPGA. Haz cuentas: 7 segmentos más el punto
decimal por 4 displays son 32 pines. Estos son muchos pines, nuestra FPGA tiene 208 pines, pero no todos son
utilizables como entradas/salidas. Por lo que estaríamos desperdiciando un alto porcentaje de los pines
disponibles para algo que en realidad no es necesario. Con esta alternativa se usan 8 pines (más las 4 señales
de encendido: AN_0,..., pero éstas se tienen que añadir también a los 32 pines de antes).
Y ahora, ¿se te ocurre cómo hacer el circuito que implementa el reloj? ¿cómo generar las señales AN_0,...,AN_3
y NumDispl de la figura 19.7?
Intenta pensarlo antes de mirar la solución ya que todos los conceptos necesarios para implementarlos se
han visto ya.
19.3.1. Implementación
Varias cosas fundamentales tenemos que hacer en este diseño:
Tenemos que ampliar el bloque segundero (recuerda las segundero
figuras 19.2 y 19.3) de modo que saque una salida adicional T1MS
de periodo 1 ms. Para esto simplemente tienes que sacar la CE T500MS
señal de periodo 1 ms como salida. Esto es, hacer un bloque Clk T1S
como muestra la figura 19.8 CLEAR
Luego, utilizaremos la señal de 1 ms (T1MS) para contar cuatro
cuentas de 1 ms. Obteniendo la señal CUENTA4MS (figura 19.7), que Figura 19.8: Nueva versión del segundero
irá de 0 a 3, esto es, de 00 a 11.
Posteriormente ampliar el reloj que hemos hecho en el apartado 19.2. Lo ampliamos para que cuente
decenas de segundo (DS), unidades de minuto (US) y decenas de minuto (DM).
Luego queremos según en qué cuenta estemos de la señal CUENTA1MS se seleccione las unidades o decenas
de minutos o segundos. Por ejemplo, si CUENTA1MS=00 entonces queremos que por el display entren las
unidades de segundo (US), y así para el resto según se muestra en la figura 19.7. Ya hemos visto cómo se
realiza esto: para seleccionar se utilizan los multiplexores (recuerda el capítulo 12). En este caso es de 4
alternativas, por tanto dos bits para la señal de selección (CUENTA4MS), y con 4 bits cada alternativa. La figura
19.9 muestra cómo se podría realizar esta parte.
4
US 00 A
HEX7SEG
F G B
DS 4
01 I0
4 I1 7 C
E D
4 I2 SEG(6:0)
UM 10 I3
NumDispl(3:0)
DM 4 11
CUENTA4MS(1:0)
Figura 19.9: Selección de las unidades o decenas de minuto o segundo según el valor de CUENTA4MS
En el capítulo no vimos cómo hacer un multiplexor de 4 entradas de datos (y dos bits de selección) a partir de
multiplexores de dos entradas de dato (1 bit de selección). Esto se ha explicado en clase y la figura 19.10 te lo
recuerda. Aunque las señales de dato (A, B, C y D) sólo tienen bit y no 4, la extensión es similar (recuerda la
figura 12.2).
MUX4
A 0
A 00 B 1
B 01
Z 0
C 10 Z
1
D 11
C 0
D 1
SEL1
SEL0
SEL0 SEL1
Figura 19.10: Multiplexor de 4 entradas de dato a partir de multiplexores de dos entradas de dato
Por último, para generar las señales de encendido de los displays nos podemos fijar que sólo uno está
activo en cada momento (aunque a nivel bajo). Cuando CUENTA4MS=00 se activa AN_0, cuando CUENTA4MS=01
se activa AN_1, y así sucesivamente. Esto ya hemos visto que se realiza con un decodificador. Estamos
decodificando el valor de la cuenta con las señales de encendido de los displays.
Ya estando tan avanzados en el curso, intenta hacerlo por ti mismo. Si lo logras, comprueba con un reloj que
tengas si es un buen reloj, es decir, si se retrasa o adelanta. Si funciona bien significa que ya sabes bastante
electrónica digital, sabes realizar un reloj digital. Si no te sale y estás perdido, a continuación se muestra un
solución.
19.3.2. Solución
Como el diseño es bastante grande, se dará la solución por partes.
Primero, en la figura 19.11 se muestra cómo hacer la decodificación del control de los displays. El contador de
4 milisegundos obtiene un número de 0 a 3 que se decodifica y activa las señales AN_0, AN_1, AN_2 ó AN_3.
Fíjate que hay que invertirlas por ser a nivel bajo.
La señal del punto decimal, que va a separar segundos de minutos. Se genera igual que en el contador de 10
segundos (capítulo 19.2), sin embargo la salida queremos que esté activa solamente cuando esté activo AN_2.
Ya que es ese punto decimal el que queremos que luzca, por eso ponemos la puerta NAND. Fíjate que se
pone antes de invertirla. Por último, ponemos una puerta NAND, porque SEG_DT es activo a nivel bajo.
Figura 19.13: Multiplexor para la selección del dígito a mostrar por los displays