Manual de la Basys2 Spartan 3E.pdf

172
pág. 1 INSTITUTO TECNOLÓGICO DE TEHUACÁN Departamento de Ingeniería Eléctrica-Electrónica Reporte de Residencia Profesional Proyecto: VIABILIDAD DE LA TARJETA BASYS2 PARA SU IMPLEMENTACIÓN EN EL CONTROL DE UN PROCESO Presenta: Mario Merino Márquez Asesor Interno: Ing. Juan José Ortiz Flores Asesor Externo: Dr. Oscar Leopoldo Pérez Castañeda Tehuacán, Puebla; a 24 Mayo de 2012

Transcript of Manual de la Basys2 Spartan 3E.pdf

Page 1: Manual de la Basys2 Spartan 3E.pdf

pág. 1

INSTITUTO TECNOLÓGICO DE TEHUACÁN

Departamento de Ingeniería Eléctrica-Electrónica

Reporte de Residencia Profesional Proyecto:

VIABILIDAD DE LA TARJETA BASYS2 PARA SU IMPLEMENTACIÓN EN EL

CONTROL DE UN PROCESO

Presenta: Mario Merino Márquez

Asesor Interno:

Ing. Juan José Ortiz Flores

Asesor Externo: Dr. Oscar Leopoldo Pérez Castañeda

Tehuacán, Puebla; a 24 Mayo de 2012

Page 2: Manual de la Basys2 Spartan 3E.pdf

pág. 2

ÍNDICE

ÍNDICE .................................................................................................................... 2

INTRODUCCIÓN ................................................................................................... 4

JUSTIFICACIÓN .................................................................................................... 6

OBJETIVOS ............................................................................................................ 8

OBJETIVO GENERAL .................................................................................... 8 OBJETIVOS ESPECÍFICOS ............................................................................. 8

ÁREA DE PARTICIPACIÓN ................................................................................. 9

PROBLEMAS A RESOLVER .............................................................................. 10

CRONOGRAMA DE ACTIVIDADES ................................................................. 10 Búsqueda y Compra de Tarjeta basada en FPGA XILINX Spartan 3E 100K ... 10

Instalación y Manejo del Software ISE Design Suite 13.4 y Digilent Adept ....... 10

Investigación de la Arquitectura de la Tarjeta basada en FPGA ....................... 10

Manejo del Lenguaje de Programación VHDL ................................................... 11

Desarrollo e Implementación de Prácticas de Circuitos Digitales básicos con

VHDL y la Tarjeta basada en FPGA ............................................................................... 11

Desarrollo e Implementación de Máquinas de Estados Finitos (FSM) .............. 11 Acondicionamiento de Entradas y Salidas de la Tarjeta basada en FPGA para

adquisición de datos y activación de actuadores............................................................ 12

Desarrollo e Implementación del Control de un Proceso por medio de la Tarjeta

basada en FPGA ............................................................................................................. 12

ALCANCES Y LIMITACIONES ........................................................................... 13

ALCANCES ................................................................................................ 13 LIMITACIONES ............................................................................................ 13

MARCO TEÓRICO .............................................................................................. 15

SISTEMAS DE CONTROL Y SISTEMAS DIGITALES .......................................... 15 DISPOSITIVOS FPGA ................................................................................. 17 FAMILIAS COMERCIALES DE FPGAS. ........................................................... 19

FPGA’s de Xilinx. ............................................................................................... 19

FPGA’s de Altera. ............................................................................................... 19

FPGA’s de Actel ................................................................................................. 20

FAMILIA XILINX SPARTAN-3E FPGA ............................................................ 21 TARJETA BASYS2 ...................................................................................... 22

Características Generales: ................................................................................. 23

TENDENCIAS TECNOLÓGICAS POR MERCADO DEL FPGA ............................. 25 Comunicaciones ................................................................................................. 25

Aeroespacial y Militar ......................................................................................... 26

Automotriz .......................................................................................................... 26

Industrial ............................................................................................................. 26

Electrónica de Consumo .................................................................................... 27

Procesamiento de Datos .................................................................................... 27

LENGUAJE VHDL ...................................................................................... 27

Page 3: Manual de la Basys2 Spartan 3E.pdf

pág. 3

Formas de describir un circuito .......................................................................... 27

Secuencia de diseño .......................................................................................... 28

Ventajas de los lenguajes HDL .......................................................................... 31

Entity ................................................................................................................... 31

Architecture ........................................................................................................ 33

Bibliotecas .......................................................................................................... 34

Paquetes ............................................................................................................ 34

PROCEDIMIENTO Y DESCRIPCIÓN DE LAS ACTIVIDADES REALIZADAS .. 35

ADQUISICIÓN DE LA TARJETA BASYS2 ......................................................... 35 DESCARGA E INSTALACIÓN DE SOFTWARE ISE DESIGN SUITE 13.4 Y ADEPT

2.6.1 SYSTEM ....................................................................................................... 36 USO DEL SOFTWARE ISE DESIGN SUITE 13.4, ADEPT 2.6.1 SYSTEM Y

CONFIGURACIÓN DE LA TARJETA BASYS2 ............................................................... 38 Entidad y Arquitectura .......................................................................... 43 Simulación............................................................................................ 47 Diseño Estructural en VHDL ................................................................. 56 Configuración de la Tarjeta Basys2 ...................................................... 66

RESULTADOS ..................................................................................................... 74

DESARROLLO DE PRÁCTICAS UTILIZANDO LA TARJETA BASYS2 .................... 74 Practica 1 – Decoder Display ............................................................................. 74

Practica 2 - Contador Ascendente ..................................................................... 77

Practica 3 - Contador con salida a Display ........................................................ 81

Practica 4 - Encendido de un motor de CD....................................................... 83

Práctica 5 - Motor Reversible ............................................................................. 85

Practica 6 – Sumador Aritmético con Salida a Display ...................................... 88

Practica 7 – Unidad Aritmética Lógica (ALU) ..................................................... 97

Practica 8 – Elementos de Memoria (Flip-Flops) Pulsador ............................. 105

Practica 9 – Maquinas de Estados Finitos (FSM) ............................................ 108

Práctica 10 – Circuito Anti rebotes (Debounce Circuit) ................................... 120

Practica 11 - Generación de una señal PWM ................................................. 125

Practica 12 - PWM con salida a display. .......................................................... 129

Practica 13 – Señal PWM con Potenciómetro. ............................................... 135

Practica 14 - Control de un motor debido a la señal de un sensor. ................. 140

Práctica 15 - Señal PWM controlada con Pushbuttons ................................... 152

Práctica 16 - Contador Parametrizable (Mod_m_Counter) .............................. 157

Práctica 17 - FIFO Buffer ................................................................................. 159

Práctica 18 – Comunicación Serial Puerto PS2 – Teclado .............................. 162

CONCLUSIONES Y RECOMENDACIONES .................................................. 171

REFERENCIAS BIBLIOGRÁFICAS ................................................................. 172

Page 4: Manual de la Basys2 Spartan 3E.pdf

pág. 4

INTRODUCCIÓN

Viabilidad de la Tarjeta Basys2 para su Implementación en el Control de un Proceso

Ante las diferentes aplicaciones a realizar dentro del campo de los Sistemas Digitales, nuevas tecnologías han emergido como herramientas a las mismas. La adquisición de datos es una de estas aplicaciones, para la cual se han utilizado diferentes herramientas como son sistemas basados en microprocesadores, microcontroladores, CPLD, entre otros.

Con la aparición de los dispositivos FPGA’s (Fiel Programmable Gate Array), se dispone de una nueva herramienta para los sistemas digitales. Su alta disponibilidad de recursos lógicos, bloques de memoria SRAM, bloques MAC, aumento de las entradas y salidas y sobre todo su reprogramación, han colocado a estos dispositivos como una de las herramientas más versátiles en estos momentos.

La opción de generar maquinas de estados finitos FSM (Finite State Machines) de forma rápida y sencilla gracias a los lenguajes HDL (Lenguajes de Descripción de Hardware), colocan a los dispositivos FPGA’s como una solución eficaz ante el diseño de sistemas digitales.

La combinación del lenguaje HDL y los dispositivos FPGA’s permiten a

los diseñadores simular, probar e implementar físicamente circuitos digitales sofisticados, reduciendo el tiempo que existe desde el diseño hasta la producción final.

En este documento se propone analizar la viabilidad de la tarjeta Basys2, basada en tecnología FPGA para su aplicación en el Control de un Proceso.

Para demostrar la viabilidad y poner a prueba la Tarjeta Basys2 se

proponen una serie de prácticas que servirán como guía de aprendizaje de las bases del Lenguaje de Programación VHDL (Very High Speed Hardware Description Language), la instalación y uso del software XILINX ISE13.4, la traducción por medio del software Digilent Adept y el manejo de la Tarjeta Basys2.

Page 5: Manual de la Basys2 Spartan 3E.pdf

pág. 5

Se recomienda al lector tener conocimientos de Electrónica Digital y Electrónica Analógica Básica para la total comprensión de los temas expuestos.

El FPGA utilizado es el XILINX Spartan 3E-100K por lo cual este documento puede servir de referencia para el manejo de otras Tarjetas tales como la Spartan-3 Starterboard, Spartan-3E Starterboard, Nexys-2 board, Pegasus, Basys o de arquitecturas semejantes.

Page 6: Manual de la Basys2 Spartan 3E.pdf

pág. 6

JUSTIFICACIÓN

Velocidad, Reprogramación, Múltiples I/0, Rendimiento, Costo

Los Dispositivos Lógicos Programables ofrecen múltiples ventajas en el diseño de sistemas digitales; son una alternativa viable ante microprocesadores, microcontroladores y ASIC’s (Circuitos Integrados de Aplicación Específica) debido a su naturaleza reprogramable, alto rendimiento y facilidad de uso; todo esto a un costo accesible.

Diseñadores de Sistemas Digitales pueden desarrollar prototipos para

el control de procesos de forma rápida y sencilla, evitando retrasos en la adecuada elección de un microprocesador o microcontrolador. Con un FPGA de gama baja se cuenta con los suficientes recursos para diseñar, probar e implementar el control de múltiples procesos.

La Tarjeta Basys2 basada en el FPGA XILINX Spartan 3E-100K es un

laboratorio completo para el diseño de circuitos digitales ya que cuenta con Memoria Flash, Interfaz programable USB2, push buttons, switches, led’s, puerto PS2, puerto VGA y 4 módulos de expansión. Al tener todo lo necesario en una sola placa se reduce el tiempo de salida del prototipo, ya que se evita el tener que diseñar un PCB (Printed Circuit Board) o utilizar protoboards que por lo general ocasionan fallos en las señales eléctricas.

El Lenguaje de Descripción de Hardware VHDL representa una

ventaja debido a lo sencilla e intuitiva que es su programación y su síntesis que no ocupa demasiados recursos; en comparación al Lenguaje Ensamblador que es más complejo y poco entendible, o el uso de Lenguajes de alto nivel como lo son C, Basic, Java para microcontroladores y microprocesadores que gastan recursos excesivamente.

El uso de múltiples microprocesadores embebidos en un FPGA

significa una de las mayores ventajas de estos dispositivos lógicos programables, la creación de un microprocesador a la medida proporciona un diseño flexible y escalable que satisface las necesidades del productor y evita el hecho de que el microprocesador, microcontrolador o ASIC elegido para el control del proceso quede obsoleto.

El mercado de los FPGA’s ha ido en aumento y XILINX, la empresa

creadora de estos dispositivos lógicos programables se coloca como líder mundial con el 56% de las ventas de FPGA’s, seguido por Altera, Lattice y

Page 7: Manual de la Basys2 Spartan 3E.pdf

pág. 7

Actel. Las aplicaciones finales que se le dan a estos dispositivos suelen ser diversas y se presentan en campos tales como telecomunicaciones, industria automotriz, industria de consumo, entre otros.

Este documento busca además de demostrar la viabilidad de la

Tarjeta Basys2 para ser utilizada en el control de un proceso, beneficiar y orientar a todos aquellos que se comienzan a sumergir dentro del campo de los dispositivos lógicos programables para el diseño de sistemas digitales a través de FPGA’s, de modo que puedan hacer consideraciones para la elección de la arquitectura que controle sus procesos.

Page 8: Manual de la Basys2 Spartan 3E.pdf

pág. 8

OBJETIVOS

Objetivo General

- Determinar la Viabilidad de la Tarjeta Basys2 para Implementar el Control de un Proceso

Objetivos Específicos

- Manejar VHDL (Very High Speed Integrated Circuit Hardware Description Language) para la Descripción de circuitos Digitales en un FPGA Spartan 3E

- Manejar la Tarjeta Basys2 basada en el FPGA XILINX Spartan 3E 100K y sus Similares

- Manejar el Software compilador y traductor necesario para utilizar el FPGA XILINX Spartan 3E 100K

- Determinar e Implementar el control de un proceso

Page 9: Manual de la Basys2 Spartan 3E.pdf

pág. 9

ÁREA DE PARTICIPACIÓN

Ingeniería Electrónica – “Ciencia Aplicada para Crear e Innovar”

El desarrollo de este documento así como las prácticas propuestas se han llevado a cabo en el Instituto Tecnológico de Tehuacán en el área de Ingeniería Eléctrica-Electrónica por parte del equipo de Residentes investigadores del área.

En la Figura1 se muestra el organigrama del Instituto Tecnológico de Tehuacán, siendo el área de Ingeniería Electrónica dentro del departamento de investigación el lugar donde se ha desarrollado este proyecto.

Figura 1 - Organigrama del Instituto Tecnológico de Tehuacán

Page 10: Manual de la Basys2 Spartan 3E.pdf

pág. 10

PROBLEMAS A RESOLVER

Cronograma de Actividades

A continuación se exponen los problemas a resolver para el desarrollo del proyecto, asi como una breve descripción de los mismos.

Búsqueda y Compra de Tarjeta basada en FPGA XILINX Spartan 3E 100K

- Duración: 2 semanas

- Objetivo: Buscar y Comprar una Tarjeta de prototipos basada en

un FPGA

- Descripción: Durante el tiempo propuesto se buscará en internet y proveedores locales una Tarjeta de Prototipos basada en un FPGA sencillo.

Instalación y Manejo del Software ISE Design Suite 13.4 y Digilent Adept

- Duración: 1 semana

- Objetivo: Descargar e instalar el software necesario para el manejo de la Tarjeta basada en el FPGA de elección

- Descripción: Durante el tiempo propuesto se descargarán e

instalarán los programas necesarios para el manejo de la Tarjeta adquirida, así como el acondicionamiento del equipo de cómputo necesario.

Investigación de la Arquitectura de la Tarjeta basada en FPGA

- Duración: 1 semana

- Objetivo: Investigar y analizar la arquitectura de la Tarjeta basada en FPGA

Page 11: Manual de la Basys2 Spartan 3E.pdf

pág. 11

- Descripción: Durante el tiempo propuesto se buscarán y analizarán las hojas de datos de la Tarjeta adquirida así como del FPGA que contenga.

Manejo del Lenguaje de Programación VHDL

- Duración: 3 semanas

- Objetivo: Conocer y manejar el lenguaje de Descripción de Hardware VHDL

- Descripción: Durante el tiempo propuesto se buscará información

acerca del lenguaje VHDL en biblioteca e internet y se aprenderán las bases del mismo para la programación de la Tarjeta basada en FPGA.

Desarrollo e Implementación de Prácticas de Circuitos Digitales básicos con VHDL y la Tarjeta basada en FPGA

- Duración: 3 semanas

- Objetivo: Diseñar e Implementar en la Tarjeta basada en FPGA circuitos digitales combinacionales y secuenciales básicos.

- Descripción: Durante el tiempo propuesto se diseñaran e

implementarán prácticas de circuitos combinacionales y secuenciales básicos programados en lenguaje VHDL y compilados a través del software necesario para la descarga hacia la Tarjeta basada en FPGA.

Desarrollo e Implementación de Máquinas de Estados Finitos (FSM)

- Duración: 3 semanas

- Objetivo: Diseñar e implementar circuitos digitales secuenciales avanzados.

Page 12: Manual de la Basys2 Spartan 3E.pdf

pág. 12

- Descripción: Durante el tiempo propuesto se diseñaran e implementarán prácticas de circuitos combinacionales avanzados utilizando para ello Maquinas de Estados Finitos (FSM). Se analizarán las diversas opciones con las que se cuenta para diseñarlas y se elegirá la más viable.

Acondicionamiento de Entradas y Salidas de la Tarjeta basada en FPGA para adquisición de datos y activación de actuadores.

- Duración: 2 semanas

- Objetivo: Acondicionar las señales eléctricas para hacer interfaces humano-sensores-actuadores-CI-tarjeta

- Descripción: Durante el tiempo propuesto se investigará acerca de

los dispositivos analógicos necesarios para hacer la interconexión de actuadores, sensores, circuitos integrados y demás dispositivos que interactúen con la tarjeta basada en FPGA para su correcto funcionamiento sin dañarla; así como las etapas de potencia necesarias.

Desarrollo e Implementación del Control de un Proceso por medio de la Tarjeta basada en FPGA

- Duración: 3 semanas - Objetivo: Controlar un Proceso a través de la Tarjeta basada en

FPGA seleccionada

- Descripción: Durante el tiempo propuesto se buscará una aplicación de control utilizando la tarjeta basada en FPGA seleccionada, se diseñará, implementará y se determinará la viabilidad de su uso.

Page 13: Manual de la Basys2 Spartan 3E.pdf

pág. 13

ALCANCES Y LIMITACIONES

Alcances

Las prácticas expuestas en este documento pretenden demostrar la viabilidad del uso de una tarjeta de desarrollo basada en FPGA para su implementación en el control de un proceso, además servirán de guía para todos aquellos que busquen diseñar sistemas digitales con dispositivos lógicos programables.

El impacto de este proyecto beneficia a la carrera de Ingeniería

Electrónica en sus cursos de Electrónica Digital y Diseño Digital con VHDL. La tarjeta Basys 2 cuenta con 4 módulos de expansión PMOD los

cuales cuentan con 4 entradas y salidas externas cada uno que nos permiten ingresar señales eléctricas de sensores u otros dispositivos, o enviar señales eléctricas para activar actuadores o establecer comunicación entre el FPGA y un ordenador.

La Tarjeta Basys2 nos permite trabajar a velocidades de 50Mhz y

controlar múltiples procesos de forma paralela, lo cual es su principal ventaja en comparación a un microcontrolador.

Limitaciones

La adquisición de la Tarjeta Basys2 en el territorio nacional es complicada; los distribuidores autorizados de la empresa Digilent se encuentran fuera del estado de Puebla. Es más sencillo pedirla directamente al proveedor en USA pero se debe pagar un impuesto aduanal.

Se debe analizar el proceso a controlar para determinar si las entradas

y salidas con las que cuenta la Tarjeta Basys2 son suficientes para su implementación.

Los componentes electrónicos con los que se cuenta dentro del área

de Ingeniería Electrónica son insuficientes, por lo cual se opta por adquirirlos en distribuidores locales generando gastos adicionales.

El voltaje de las entradas y salidas de la Tarjeta Basys2 utiliza

tecnología LVTTL de 3.3V por lo tanto se requiere acondicionar

Page 14: Manual de la Basys2 Spartan 3E.pdf

pág. 14

correctamente las señales eléctricas. Además, no cuenta con puerto serial, LCD (Liquid Crystal Display), ni convertidor analógico-digital integrados en la tarjeta, por lo que hay que comprarlos y diseñar su interfaz.

La licencia del software ISE Design Suite 13.4 utilizada es de versión

gratuita, por lo tanto para proyectos de mayor volumen o que utilicen FPGA’s mas avanzados se debe comprar la licencia completa.

El control de procesos más sofisticados está sujeto a la disposición de

recursos económicos, equipo de laboratorio disponible en el área de Ingeniería Electrónica y componentes electrónicos extras.

Page 15: Manual de la Basys2 Spartan 3E.pdf

pág. 15

MARCO TEÓRICO

Sistemas de Control y Sistemas Digitales

El control de procesos a través de tecnologías reprogramables es un área en constante crecimiento con dispositivos lógicos programables evolucionando rápidamente.

Un proceso es un conjunto de actividades o eventos que se realizan

o suceden (alternativa o simultáneamente) bajo ciertas circunstancias con un fin determinado.

Los sistemas de control son parte integrante de la sociedad moderna y

sus numerosas aplicaciones están alrededor de nosotros: Un sistema de control esta formado por subsistemas y procesos unidos con el fin de controlar las salidad de los procesos. En su forma más sencilla, un sistema de control produce una salida o respuesta para una entrada o estímulo dado. En la Figura 2 se muestra un sistema de control simple.

Figura 2 – Diagrama Sistema de Control

Los sistemas de control se dividen en sistemas en lazo abierto y en lazo cerrado. Un sistema genérico en lazo abierto se ilustra en la Figura 3 (a), formado por un subsistema llamado transductor de entrada, que convierte la forma de la entrada a la empleada por el controlador. El controlador maneja un proceso o planta. A veces, la entrada se denomina referencia, mientras que la salida se puede llamar variable controlada. Otras señales, por ejemplo las perturbaciones se muestran agregadas al controlador y a las salidas del proceso por medio de puntos de suma que dan la suma algebraica de sus señales de salida por medio de signos asociados. La característica distintiva de un sistema en lazo abierto es que no puede compensar ninguna perturbación que se sume a la señal de actuación del controlador; simplemente se comandan por la entrada.

Sistema de Control

Entrada; Estimulo

Respuesta Real

Salida; Respuesta

Respuesta Deseada

Page 16: Manual de la Basys2 Spartan 3E.pdf

pág. 16

Figura 3 – Diagramas a bloques de Sistemas de Control

a) En Lazo Abierto b) En Lazo Cerrado

La estructura genérica de un sistema en lazo cerrado se ilustra en la

Figura 3(b). En diferencia a los sitemas en lazo abierto estos compensan perturbaciones al medir la respuesta de salida, alimentando esa medida a una trayectoria de realimentación comparando esa respuesta con la entrada en el punto de suma. Si hay alguna diferencia entre las dos respuestas, el sistema acciona el proceso, por medio de una señal de actuación, para hacer la corrección. 1

El controlador (o compensador) puede ser un dispositivo lógico

programable o un microcontrolador que ejecute las acciones de control.

Un sistema digital es un conjunto de dispositivos destinados a la generación, transmisión, procesamiento o almacenamiento de señales digitales. También un sistema digital es una combinación de dispositivos diseñados para manipular cantidades físicas o información que estén representadas en forma digital; es decir, que sólo puedan tomar valores discretos.

Para el análisis y la síntesis de sistemas digitales binarios se utiliza

como herramienta el álgebra de Boole.

1 Norman S. Nise, Sistemas de Control para Ingeniería. (1

a Edición), Compañía Editorial Continental, Mexico: 2004

Page 17: Manual de la Basys2 Spartan 3E.pdf

pág. 17

Sistemas digitales combinacionales: Aquellos en los que sus salidas sólo depende del estado de sus entradas en un momento dado. Por lo tanto, no necesita módulos de memoria, ya que las salidas no dependen de los estados previos de las entradas.

Sistemas digitales secuenciales: Aquellos en los que sus salidas dependen además del estado de sus entradas en un momento dado, de estados previos. Esta clase de sistemas necesitan elementos de memoria que recojan la información de la “historia pasada” del sistema.

Dispositivos FPGA

Un FPGA (Field programable gate array) es un dispositivo lógico que contiene una matriz de celdas lógicas idénticas, con interconexiones programables (switches programables). La estructura conceptual de un dispositivo FPGA se muestra en la Figura 4. Una celda lógica puede ser configurada (programada) para realizar una función simple, y un switch programable puede ser configurado para proveer interconexión a través de las celdas lógicas. Un diseño puede ser implementado en un FPGA especificando la función de cada celda lógica y estableciendo selectivamente la conexión de cada switch programable. Una vez que el diseño y la síntesis son completados, podemos utilizar un simple cable adaptador para descargar la celda lógica deseada y la configuración del switch programable al dispositivo FPGA, para obtener el circuito digital diseñado.

Figura 4 – Estructura Conceptual FPGA

Page 18: Manual de la Basys2 Spartan 3E.pdf

pág. 18

Las celdas lógicas usualmente contienen un pequeño circuito combinacional y un flip-flop D (DFF). El método mas común para implementar un circuito combinacional configurable es a través de una tabla de búsqueda (look-up table LUT). Una LUT de n entradas puede ser considerada como una pequeña memoria de 2n-por-1. Escribiendo adecuadamente el contenido de la memoria, podemos utilizar una LUT para implementar cualquier función combinacional de n entradas. El diagrama conceptual de una celda lógica basada en una LUT de 3 entradas es

mostrado en la Figura 5 (a). La función a⊕b⊕c implementada en una LUT de 3 entradas es mostrada en la Figura 5(b). Nótese que la salida de la LUT puede ser utilizada directamente o puede ser almacenada en el Flip-Flop D.

Figura 5 - LUT (Look-up Table)

Macro Celda (Macro cell). La mayoría de los dispositivos FPGA cuentan con macro celdas o macro bloques embebidos. Estos son diseñados y fabricados a nivel de transistores, y sus funcionalidades complementan a las celdas lógicas. Comúnmente las macro celdas usadas incluyen bloques de memoria, multiplicadores combinacionales, circuitos de manejo de reloj y circuitos de interface entre entradas y salidas. Dispositivos FPGA mas sofisticados suelen contener uno o más núcleos de procesador prefabricados.2

2 Pong P. Chu, FPGA Prototyping by VHDL Examples XILINX Spartan-3 Version. (1

a Edición), John Wiley

& Sons Inc, Hoboken, New Jersey: 2008

Page 19: Manual de la Basys2 Spartan 3E.pdf

pág. 19

Familias comerciales de FPGAs.

Existen tres fabricantes mayoritarios en la distribución de FPGA’s y software de soporte, estos son Xilinx, Altera y Actel. Sin embargo, en el mercado mundial también existen otros como Lucent, Texas Instruments, Philips, QuickLogic, Cypress, Atmel, entre otros. No obstante, por la importancia de las tres primeras compañías se mencionaran algunas de las familias lógicas que ofrecen.

FPGA’s de Xilinx.

Son uno de los fabricantes más fuertes en el nivel mundial. Sus

FPGAs están basados en la tecnología SRAM, son dispositivos reprogramables (Many-Times Programable, MTP) y programables en sistema (ISP).

Sus principales familias son: XC3000, XC4000, XC Virtex y XC

Spartan. Dichos dispositivos están compuestos por módulos lógicos CLBs, basados en tablas de búsqueda. Cada CLB contiene circuitos que permiten realizar operaciones aritméticas eficientes. Los usuarios también pueden configurar las tablas de búsqueda como celdas lectura/escritura (read/write) de RAM. Asimismo, a partir de la seria XC 4000 se incluye un generador interno de señal de reloj, con 5 diferentes frecuencia.

Además de los CLBs, los FPGAs de este fabricante incluyen otros

bloques complejos que configuran la entrada de los pines físicos, estos a si ves conectan el interior del dispositivo con el exterior y los bloques son llamados bloques de Entrada/Salida (Input/Output Blocks, IOBs). Cada IOB contiene una lógica compleja que permite que un pin actué como entrada, salida o triestado (el triestado puede tomar valores de 0, 1 o de alta impedancia).

FPGA’s de Altera.

Altera ofrece dos familias de FPGAs con características diferentes,

pero conservando algunas básicas que representan las ventajas originales de las primeras familias estándar: FLEX 6000, 8000 y 10K; así como la más novedosa, APEX 20K. Las primeras familias estándar, la FLEX 6000 y la 8000 aún se utilizan ampliamente. La serie FLEX (Matriz Flexible de Elementos Lógicos, Flexible Logic Element Matrix) estándar contiene un numero considerando de compuertas en tecnología SRAM con tablas de búsqueda, agregando mayor flexibilidad a los diseños.

Page 20: Manual de la Basys2 Spartan 3E.pdf

pág. 20

La serie estándar FLEX combina la arquitectura de los CPLD con los

FPGAs. El dispositivo consiste de una arquitectura muy parecida a la de un CPLD; en su nivel más bajo de la jerarquía tiene un conjunto de tablas de búsqueda, en lugar de un bloque muy similar a un SPLD, por ello se considera un FPGA. El modulo lógico básico, nombrado por Altera, elemento lógico (Logic Element), contiene una LUT de 4 entradas, un flip-flop y un elemento de acarreo (carry) de propósito especial para circuito aritméticos. El elemento lógico también incluye circuitos en cascada, que permiten una implementación eficiente de funciones AND amplias.

Esta arquitectura agrupa elementos lógicos en grupos de 8, y los llama

bloques de arreglos lógicos (Arrays Logic Blocks, ALBs). Cada ALB, contiene una interconexión local que le permite conectarse con otro ALB y a la vez, la misma interconexión sirve para conectarse a la interconexión global de la crossbar (matriz de interconexiones), nombrada por Altera como FastTrack. Así, las interconexiones se hacen al estilo de los CPLDs, pero la configuración de los bloques de arreglos lógicos utiliza tecnología SRAM propia de los FPGAs.

FPGA’s de Actel

Actel ofrece una seria de familias OTP que resultan ampliamente

utilizadas después de haber probado satisfactoriamente un diseño (emigrar a otro FPGA). Las principales son: la serie estándar ACT, y las más nuevas por orden cronológico de aparición, sX, sX-A, mX y eX. Todas las anteriores son programables fuera del sistema (OPS). También ofrece una familia reprogramable a la llamada Pro ASIC (por ser de alta densidad de componentes, Actel no la considera parte de los FPGAs), basada en una tecnología Flash EEPROM programable en sistema (ISP).

Los FPGAs de Actel, emplean como modulo o elemento básico una

estructura tipo arreglo fijo de compuertas. La lógica del arreglo está dispuesta en renglones de módulos lógicos interconectables, rodeados hacia afuera por módulos de E/S. la estructura de interconexiones consiste en pistas o líneas fijas de interconexión, horizontales y verticales, con segmentos de alambrado. Hay muchas pistas en cada canal entre los renglones de la lógica. Las pistas verticales son menos y pasan sobre los canales horizontales y los módulos lógicos.

El FPGA de Actel utiliza tecnología antifusible que proporciona una

programación permanente y no volátil. El dispositivo tiene muchos antifusibles para conectar las entradas y salidas de los módulos de lógica y E/S, a los segmentos de alambrado de los canales. También tiene antifusible

Page 21: Manual de la Basys2 Spartan 3E.pdf

pág. 21

que interconectan los segmentos de alambrado entre las pistas para ofrecer conexiones de diferentes longitudes.

Una de las principales características de los módulos lógicos de los

FPGAs de Actel, es que los módulos no se programan para que efectúen una operación, sino que toda la programación se hace mediante antifusibles en las pistas de alambrado.3

Familia Xilinx Spartan-3E FPGA

El FPGA utilizado en este proyecto es el Spartan-3E 100K de la marca Xilinx.

Las características y capacidades de la familia Spartan-3E se han

optimizado para un alto volumen y aplicaciones de bajo costo. Debido a su excepcional bajo costo, los FPGA de la familia Spartan-3E son viables para un extenso mercado de aplicaciones electrónicas, incluyendo accesos de banda ancha, redes locales, control de procesos y equipos de televisión digital.

Celdas Lógicas, Slice, y Bloques Lógicos Configurables (CLB). El elemento mas básico de un dispositivo Spartan-3 es una celda lógica (Logic Cell LC), el cual contiene LUTs de 4 entradas y un Flip-Flop D similar al de la figura 3. Además, una celda lógica contiene un circuito de acarreo (carry), el cual es usado para implementar funciones aritméticas, y un circuito multiplexor. Las LUT pueden ser configuradas como memorias estáticas de acceso aleatorio (Static Random Access Memory SRAM) de 16-por-1 o como registros de corrimiento (Shift Register) de 16-bit.

Para incrementar la flexibilidad y mejorar el rendimiento, 8 celdas

lógicas son combinadas con una estructura especial en el ruteo interno. En términos del fabricante Xilinx, 2 celdas lógicas son agrupadas para formar un Slice, y 4 slices son agrupado para formar un bloque lógico configurable (Configurable Logic Block (CLB)).

Macro Celdas del Spartan-3. El dispositivo Spartan-3 cuenta con 4

tipos de macro bloques: multiplicador combinacional, bloque RAM, digital clock manager (DCM) y bloque de entrada/salida (IOB). El bloque multiplicador combinacional acepta dos números de 18-bits como entrada y calcula el producto. El bloque RAM es una SRAM de 18K-bit síncrona que

3 Menéndez Ortiz María Alejandra, Arquitectura FPGA para la adquisición de Datos Térmicos. Universidad

del Mar Campus Puerto Escondido Oaxaca México: 2010.

Page 22: Manual de la Basys2 Spartan 3E.pdf

pág. 22

puede ser configurada de distintas formas. El DCM usa un ciclo “digital-delayed” para reducir los problemas con los tiempos y controlar la frecuencia y fase de las señales de reloj. Las IOB controlan el flujo de datos entre los pines de E/S y la lógica interna.4 La arquitectura del Spartan-3E es mostrada en la Figura 6.

La Familia Spartan-3E cuenta con 5 miembros que ofrecen distintas

densidades, las cuales van desde los 100,000 hasta los 1.6 millones de compuertas, tal y como se muestra en la Tabla 1.

Tabla 1- Densidades Familia Spartan-3E

Las características generales del Spartan 3-E se pueden encontrar en su datasheet a través del siguiente enlace 5

www.xilinx.com/support/documentation/data_sheets/ds312.pdf

Tarjeta Basys2

La tarjeta Basys2 es una plataforma para el diseño e implementación de circuitos digitales. La tarjeta esta construida en base a un FPGA Spartan-3E de Xilinx y un controlador USB Atmel AT90USB2. La tarjeta Basys2 provee el hardware necesario listo para usarse capaz de soportar circuitos que van desde el rango de lo básico hasta el control complejo de procesos. Una amplia gama de dispositivos de E/S y todas las conexiones del FPGA son incluidas, por lo que incontables diseños pueden ser creados sin la necesidad de componentes adicionales.

4 Pong P. Chu, FPGA Prototyping by VHDL Examples XILINX Spartan-3 Version. (1

a Edición), John Wiley

& Sons Inc, Hoboken, New Jersey: 2008 5 Sitio web oficial de Xilinx sección documentación de productos.

www.xilinx.com/support/documentation/data_sheets/ds312.pdf

Page 23: Manual de la Basys2 Spartan 3E.pdf

pág. 23

Figura 6 – Arquitectura Spartan 3-E FPGA

Cuatro conectores de expansión estándar permiten a la tarjeta Basys2

crecer utilizando circuitos diseñados por el usuario o PMods. (Los PMods son módulos de E/S analógicos y digitales de bajo costo que ofrecen conversión A/D y D/A, drivers para motor, entradas de sensor y muchas otras características). Las señales en los conectores de 6 pines están protegidas contra corto circuito, garantizando una larga vida de funcionamiento en cualquier ambiente. La tarjeta Basys2 trabaja en cualquier versión del compilador Xilinx ISE tools, incluyendo la licencia gratuita WebPack.

Contiene un cable USB que le proporciona energía y es utilizado como

interfaz de programación, por lo que ninguna otra fuente de poder o cable de programación es requerido. 6 En la Figura 7 se muestra el diagrama a bloques de la tarjeta Basys2.

Características Generales:

- Xilinx Spartan 3-E FPGA, 100K or 250K gate

6 Manual de Referencia Tarjeta Basys2:http://www.digilentinc.com/Data/Products/BASYS2/Basys2_rm.pdf

Page 24: Manual de la Basys2 Spartan 3E.pdf

pág. 24

- FPGA con multiplicadores de 18-bit, 72Kbits de bloque RAM dual-port, y 500MHz+ velocidad de operación

- Puerto USB2 full-speed para la configuración y transferencia de datos hacia el FPGA (utilizando el software Adept 2.0 disponible en descarga gratuita)

- XCF02 Platform Flash ROM que almacena las configuraciones del FPGA

- Frecuencia de oscilación ajustable (25, 50, and 100 MHz), además cuenta con socket para un oscilador extra

- 3 reguladores de voltaje incluidos (1.2V, 2.5V, and 3.3V) que permiten el uso de fuentes externas de 3.5V a 5.5V.

Figura 7– Diagrama a bloques Tarjeta Basys2

- 8 LEDs, 4 displays de siete segmentos, 4 pushbuttons, 8 slide

switches, Puerto PS/2, y un puerto VGA de 8-bit - Cuatro conectores de 6-pines para E/S del usuario, y compatibles con

los circuitos Digilent PMOD. La compra, asi como la documentación completa y ejemplos acerca de

la tarjeta Basys2 se encuentran en el siguiente enlace7.

7 Documentación Completa, Compra y ejemplos de la Tarjeta Basys2 de Digilent INC.

http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,400,790&Prod=BASYS2

Page 25: Manual de la Basys2 Spartan 3E.pdf

pág. 25

Tendencias Tecnológicas por Mercado del FPGA

Las tendencias de Aplicaciones FPGA a nivel Mundial se muestran en la Figura 8.

Figura 8– Aplicaciones FPGA a nivel Mundial

Comunicaciones

De acuerdo a la empresa de consultoría industrial Gartner, durante el

ciclo fiscal 2008-2009, el mercado de la tecnología FPGAs para Comunicaciones generó aproximadamente USD $ 1,45 millones de dólares, mientras que las proyecciones para el 2012 ascienden a unos USD $ 2,096 millones de dólares.

En cuanto a la cantidad de patentes registradas con esta tecnología

para Comunicaciones, indica que a la fecha se tiene un total de 2,527 documentos y solicitudes a nivel internacional. Los campos en donde se ha generado mayor propiedad intelectual son: Comunicaciones ópticas, Comunicaciones Inalámbricas/Alámbricas, Antenas, Moduladores y Codificadores y Redes.

Page 26: Manual de la Basys2 Spartan 3E.pdf

pág. 26

Aeroespacial y Militar

El mercado de la tecnología FPGA en el 2008 fue de

aproximadamente USD$447 millones y se estima que para el 2012 sea de USD$717 millones.

Aplicaciones:

- Sistemas de radar - Enlaces de comunicaciones de alta velocidad - Misiles - Aplicaciones de alta confiablidad en el espacio - Procesamiento digital de señales robusto y de alta seguridad

Automotriz

El mercado de la tecnología FPGA en el 2008 fue de

aproximadamente USD$83 millones y se estima que para el 2012 sea de USD$358 millones.

Aplicaciones:

- GPS - Infoentretenimiento - Control de frenos - Control de luces - Sistemas de seguridad

Industrial

Los sectores industriales que mayor consumo de FPGAs registran son para aplicaciones de Sistemas de Manufactura, Equipo Médico y Monitoreo de Pacientes, Seguridad, Administración de Energía, Pruebas y Mediciones, Redes y Domótica. En el 2008 el sector industrial recaudó 852 millones de dólares (mdd) y se estima que para el 2012 ascienda a unos 1,406 mdd. La cantidad de patentes internacionales en el sector Industrial con tecnología FPGAs llega a 524 documentos y solicitudes.

Page 27: Manual de la Basys2 Spartan 3E.pdf

pág. 27

Electrónica de Consumo

En el área de electrónica de consumo, los FPGAs generaron en el 2008 un total de 469 mdd por ingresos y se estima que para el año 2012 se eleve a 672 mdd. En cuanto a propiedad intelectual a nivel internacional se han registrado 102 documentos y solicitudes. Las aplicaciones más comunes en las que son utilizados son: Audio, Video y Equipo de Oficina.

Procesamiento de Datos

El mercado de FPGAs en el 2008 para este campo sumó 312 mdd y se tiene proyectado que para el año 2012 alcance los 335 mdd. Sus principales aplicaciones han sido para el desarrollo de Súper computadoras, Tarjetas Inteligentes, Servidores, Procesadores y Computadoras Personales (PCs). 8

Lenguaje VHDL

VHDL es el acrónimo que representa la combinación de VHSIC y HDL, donde VHSIC es el acrónimo de Very High Speed Integrated Circuit y HDL es a su vez el acrónimo de Hardware Description Language.

Es un lenguaje definido por el IEEE (Institute of Electrical and

Electronics Engineers) (ANSI/IEEE 1076-1993) usado por ingenieros para describir circuitos digitales.

Aunque puede ser usado de forma general para describir cualquier

circuito se usa principalmente para programar PLD (Programable Logic Device - Dispositivo Lógico Programable), FPGA (Field Programmable Gate Array), ASIC y similares.

Formas de describir un circuito

Dentro del VHDL hay varias formas con las que podemos diseñar el

mismo circuito y es tarea del diseñador elegir la más apropiada.

8 Red Estrategica de Tecnologia FPGA (AERI – FPGA):

http://www.conacyt.gob.mx/fondos/institucionales/Tecnologia/Avance/Redes/1-FPGA-FUMEC-AERI.pdf

Page 28: Manual de la Basys2 Spartan 3E.pdf

pág. 28

Funcional: Describimos la forma en que se comporta el circuito. Esta

es la forma que más se parece a los lenguajes de software ya que la descripción es secuencial. Estas sentencias secuenciales se encuentran dentro de los llamados procesos en VHDL. Los procesos son ejecutados en paralelo entre sí, y en paralelo con asignaciones concurrentes de señales y con las instancias a otros componentes.

Flujo de datos: describe asignaciones concurrentes (en paralelo) de señales.

Estructural: se describe el circuito con instancias de componentes. Estas instancias forman un diseño de jerarquía superior, al conectar los puertos de estas instancias con las señales internas del circuito, o con puertos del circuito de jerarquía superior.

Mixta: combinación de todas o algunas de las anteriores. En VHDL también existen formas metódicas para el diseño

de máquinas de estados, filtros digitales, bancos de pruebas etc.

Secuencia de diseño

El flujo de diseño de un sistema es:

Construcción del diagrama en bloque del sistema. Elaboración del código en VHDL para cada modulo, para sus

interfaces y sus detalles internos. Como el VHDL es un lenguaje basado en texto, se puede utilizar cualquier editor para esta tarea, aunque el entorno de los programas de VHDL incluye su propio editor de texto.

Compilación. El compilador de VHDL analiza el código y determina los errores de sintaxis y chequea la compatibilidad entre módulos. Crea toda la información necesaria para la simulación.

Simulación funcional. En este tipo de simulación se comprueba que el código VHDL ejecuta correctamente lo que se pretende.

Síntesis. En este paso se adapta el diseño anterior a un hardware en concreto, ya sea una FPGA o un ASIC. Hay sentencias del lenguaje que no son sintetizables, como por ejemplo divisiones o exponenciaciones con números no constantes. El hecho de que no todas las expresiones en VHDL sean sintetizables es que el VHDL es un lenguaje genérico para modelado de sistemas (no sólo para diseño

Page 29: Manual de la Basys2 Spartan 3E.pdf

pág. 29

de circuitos digitales), por lo que hay expresiones que no pueden ser transformadas a circuitos digitales. Durante la síntesis se tiene en cuenta la estructura interna del dispositivo, y se definen restricciones, como la asignación de pines. El sintetizador optimiza las expresiones lógicas con objeto de que ocupen menor área, o bien son eliminadas las expresiones lógicas que no son usadas por el circuito.

Simulación post-síntesis. En este tipo de simulación se comprueba que el sintetizador ha realizado correctamente la síntesis del circuito, al transformar el código HDL en bloques lógicos conectados entre sí. Este paso es necesario ya que, a veces, los sintetizadores producen resultados de síntesis incorrectos, o bien realiza simplificaciones del circuito al optimizarlo.

Ubicación y enrutamiento. El proceso de ubicación consiste en situar los bloques digitales obtenidos en la síntesis de forma óptima, de forma que aquellos bloques que se encuentran muy interconectados entre sí se sitúen próximamente. El proceso de enrutamiento consiste en interconectar adecuadamente los bloques entre sí, intentando minimizar retardos de propagación para maximizar la frecuencia máxima de funcionamiento del dispositivo.

Anotación final. Una vez ha sido completado el proceso de ubicación y enrutamiento, se extraen los retardos de los bloques y sus interconexiones, con objeto de poder realizar una simulación temporal (también llamada simulación post-layout). Estos retardos son anotados en un fichero SDF (Standard Delay Format) que asocia a cada bloque o interconexión un retardo mínimo/típico/máximo.

Simulación temporal. A pesar de la simulación anterior puede que el diseño no funcione cuando se programa, una de las causas puede ser por los retardos internos del chip. Con esta simulación se puede comprobar, y si hay errores se tiene que volver a uno de los pasos anteriores.

Programación en el dispositivo. Se implementa el diseño en el dispositivo final y se comprueba el resultado. En la Figura 9 se muestra el diagrama de flujo con la secuencia de

diseño necesaria.

Page 30: Manual de la Basys2 Spartan 3E.pdf

pág. 30

Figura 9- Diagrama de Flujo Secuencia de Diseño

No

Si

No

Si

No

Si

No

Si

Inicio

Diagrama a bloques del sistema

Código en VHDL

Compilación

Simulación Funcional

Simulación Pos-Sintesis

Síntesis

Ubicación y Enrrutamiento

Anotación Final

Simulación Temporal

Programación del Dispositivo

Fin

Fichero SDF

No

Page 31: Manual de la Basys2 Spartan 3E.pdf

pág. 31

Ventajas de los lenguajes HDL

El empleo de HDL presenta ventajas respecto al empleo de

descripciones basadas en esquemáticos. Algunas de ellas son las siguientes:

1) Puesto que una descripción HDL es simplemente un fichero de texto, es mucho más portable que un diseño esquemático, que debe ser visualizado y editado empleando la herramienta gráfica específica del entorno de CAD (Computer-Aided Design - Diseño asistido por ordenador) con el que se ha creado.

2) Una descripción esquemática únicamente describe el diseño de manera estructural, mostrando los módulos y la conexión entre ellos. Por el contrario, la descripción del circuito usando un HDL puede realizarse bien mostrando la estructura, o bien describiendo el comportamiento. Es decir, los HDL permiten describir el comportamiento que se desea que tenga el circuito, sin hacer ninguna referencia a su estructura. Las herramientas de síntesis permiten generar automáticamente la estructura del circuito lógico a partir de la descripción de su comportamiento.

3) El mismo HDL que se ha usado para la descripción del circuito,

puede emplearse para describir los vectores de test y los resultados esperados del test. Los vectores de test son los valores de las señales aplicadas a los pines de entrada del circuito con la finalidad de probar si el funcionamiento del circuito es correcto. Así pues, pueden realizarse los programas de test (vectores de test e instantes en los cuales son aplicados) del circuito a medida que se diseña el propio circuito, pudiéndose con ello ir realizando diferentes pruebas a medida que se avanza en el diseño. Como ventajas añadidas, la descripción de los programas de test usando HDL es altamente portable y repetible.

Entity

La entity define la interfaz externa de la entidad de diseño. Incluye: – El nombre de la entidad de diseño. – La lista de las señales de salida y de entrada que componen la

interfaz (normalmente se aplica el convenio de escribir primero las salidas y a continuación las entradas). A cada una de estas señales se le denomina

Page 32: Manual de la Basys2 Spartan 3E.pdf

pág. 32

puerto (port). Existen tres tipos de puertos: in (entrada), out (salida) e inout (bidireccional).

La palabra reservada entity, seguida del nombre de la interfaz y de las

palabras reservadas is port, indica el comienzo de la definición de la interfaz. A continuación, se especifica el nombre de cada uno de los puertos, su dirección (in, out o inout) y su tipo. En el ejemplo mostrado en la Figura 10, todos los puertos son señales del tipo std_logic.

Finalmente, las palabras reservadas end entity, seguidas del nombre

de la interfaz, indican el final de la definición.

Figura 10 – Definición de Entidad de compuertas NOT, XOR y AND

Los nombres definidos por el usuario deben comenzar por una letra, seguida opcionalmente por cualquier secuencia de letras, números y caracteres guion bajo, con la limitación de que ni pueden aparecer dos guiones bajos seguidos, ni el guion bajo puede ser el ultimo caracter del nombre. En VHDL no se diferencia entre los caracteres en mayúscula y en

minúscula. Los tipos de señales utilizados en el lenguaje VHDL se muestran en la

Tabla 2.

TIPO Características

BIT En este tipo las señales solo toman los valores de "1" y

"0"

Booleana En este tipo las señales solo toman los valores de True y

False

Page 33: Manual de la Basys2 Spartan 3E.pdf

pág. 33

Std_logic En este tipo las señales toman 9 valores, entre ellos

tenemos: "1", "0", "Z" (para el 3er estado), "-" (para

los opcionales).

Integer En este tipo las señales toman valores enteros. Los 1 y

los 0 se escriben sin “

Bit_Vector En este tipo los valores de las señales son una cadena de

unos y ceros. Ejemplo: “1000”

Std_Logic_Vector En este tipo los valores de las señales son una cadena de

los nueve valores permisibles para el tipo std_logic.

Character Contiene todos los caracteres ISO de 8 bits, donde los

primeros 128 son los caracteres ASCII.

Tabla 2 – Tipos de Datos VHDL

Architecture

La architecture describe el comportamiento o la estructura de la

entidad de diseño. En la Figura 11 se muestra la arquitectura de las compuertas NOT, XOR y AND.9

Figura 11 – Arquitectura compuertas NOT, XOR y AND

9 Urquía Alfonso, Martín Villalba Carla, Casos prácticos de diseño de circuitos digitales con VHDL,

Universidad Nacional de Educación a Distancia (UNED) Departamento de Informática y Automática, Madrid, España: 2008

Page 34: Manual de la Basys2 Spartan 3E.pdf

pág. 34

Bibliotecas

Una biblioteca en VHDL es un lugar en donde se guarda la

información relacionada con un diseño determinado. Al comienzo de cada diseño el compilador crea automáticamente una biblioteca llamada WORK con este objetivo. Además de esta biblioteca particular existen otras bibliotecas de tipo general que contienen un conjunto de definiciones que pueden utilizarse en cualquier diseño. Un ejemplo de biblioteca general es la llamada Library IEEE, que contiene definiciones estándar para VHDL. Para utilizar una biblioteca general es necesario escribir su nombre al inicio del programa, por eso es muy común que en la primera línea de un diseño en VHDL aparezca escrito "Library IEEE", de ésta forma dicha biblioteca se hace visible para el diseño.

Paquetes

En los paquetes se guardan definiciones de tipos y objetos que

pueden ser utilizados en los diferentes diseños que invoquen su utilización. Un paquete muy utilizado es el paquete estándar IEEE_STD_LOGIC_1164.ALL; La utilización de un paquete en un diseño se realiza invocando su empleo mediante la cláusula USE y el nombre del paquete. Por ejemplo USE IEEE_STD_LOGIC_1164.ALL;

La terminación ALL, permite utilizar todas las definiciones y objetos que contiene dicho paquete. Además del estándar, existen otros paquetes de utilización general y también los diseñadores que trabajan con VHDL pueden definir sus propios paquetes, lo que les permite reutilizar diseños realizados anteriormente como parte de nuevos diseños.

Page 35: Manual de la Basys2 Spartan 3E.pdf

pág. 35

PROCEDIMIENTO Y DESCRIPCIÓN DE LAS ACTIVIDADES REALIZADAS

Adquisición de la Tarjeta Basys2

La Tarjeta Basys2 y otros instrumentos fueron solicitados a la empresa Digilent a través de su sitio web oficial www.digilentinc.com.

El catálogo completo de las tarjetas basadas en FPGA’s y CPLD’s se

encuentra en el siguiente vínculo: http://www.digilentinc.com/Products/Catalog.cfm?NavPath=2,400&Cat=10&FPGA

Cantidad Producto Descripción Precio Unitario

Sub Total

1 Basys2 Basys2 Spartan 3E FPGA Board $ 59.00 USD

$ 59.00 USD

2 Multimeter-MS821

Autorange Digital Multimeter $ 29.99 USD

$ 59.98 USD

1 PMOD-TMP PMOD-TMP Thermometer $ 24.99 USD

$ 24.99 USD

Tabla 3: Gastos en Digilent Inc

El envió desde USA se hizo a través del servicio de paquetería Fed-Ex

en un lapso de 3 días hábiles.

Cantidad Producto Descripción Precio

Unitario Sub Total

1 Envío Servicio de Paquetería Fed-Ex

$ 81.77 USD

$ 81.77 USD

1 Impuesto Impuesto Aduanal $ 30.00 USD

$ 30.00 USD

Tabla 4: Gastos de Envio

Además se utilizaron componentes electrónicos pasivos y activos para

la implementación de las prácticas que implicaron un gasto extra en el desarrollo del proyecto. Estos componentes fueron adquiridos en distribuidores locales.

Page 36: Manual de la Basys2 Spartan 3E.pdf

pág. 36

Cantidad Producto Descripción Precio Unitario

Sub Total

2 Protoboard Tablilla para Prototipos $ 9.00 USD

$ 18.00 USD

1 SN754410 Quadruple Half-H Driver $ 2.99 USD

$ 2.99 USD

1 NE555 Multivibrador 555 $ 0.95 USD

$ 0.95 USD

30 Resistor Resistores de distintos valores

$ 0.10 USD

$ 3.00 USD

5 Capacitor Capacitores Electrolíticos y Cerámicos

$ 0.30 USD

$ 1.50 USD

20 2N25 Optoacoplador MOC $ 0.80 USD

$ 16.00 USD

10 2N2222 NPN Transistor $ 0.23 USD

$ 2.30 USD

1 Motor Motro de 5V CD $ 1.00 USD

$ 1.00 USD

2 Relay Relays de 5V CD $ 1.00 USD

$ 2.00 USD

3 Cable Telefónico

Metros de Cable Telefónico $ 0.88 USD

$ 2.64 USD

Tabla 5: Gastos Extras

Por lo tanto el gasto total es de: $ 306.12 USD

Convertido a moneda nacional a una tasa de cambio de $ 13.43 MN el

gasto total es de: $ 4111.18 MN

Descarga e Instalación de Software ISE Design Suite 13.4 y Adept 2.6.1 System

Xilinx ofrece una licencia gratuita de su entorno de desarrollo y diseño para sus dispositivos reconfigurables, la versión gratuita se conoce como Webpack, en últimas versiones no se trata de un software separado del principal sino de una licencia de uso especial para el mismo, a continuación se muestran los pasos necesarios para descargar el software y obtener la licencia gratuita.

1- Ingresar y registrarse en el sitio web de Xilinx: www.xilinx.com. Al ingresar al sitio, en el menú de la parte superior se tiene la opción “Sign In”, que permite ingresar con una cuenta creada con anterioridad o registrarse con una nueva mediante el enlace “Create Account”.

Page 37: Manual de la Basys2 Spartan 3E.pdf

pág. 37

Figura 12– Página Principal de Xilinx

Para el registro se deben proporcionar algunos datos personales tales

como nombre, dirección y correo electrónico.

2- Una vez registrados en el sitio, se puede acceder a la sección de descargas, puede hacerse desde el enlace “Downloads” en la parte superior del sitio. El software que nos interesa se llama ISE Design Suite, en la página se puede seleccionar la versión a descargar así como el sistema operativo con el cual trabajaremos: hay tres opciones de descarga, instalador para Windows, instalador para Linux o los binarios. La versión más reciente del software y la utilizada en este documento es la 13.4.

3- La descarga no es directa, sino que al hacer clic en alguno de los enlaces se instala el administrador de descargas de Xilinx, es necesario permitir la ejecución del mismo, el cual permitirá pausar y continuar la descarga de los archivos, algo bastante útil ya que el software pesa 5.67 GB.

4- Una vez descargado el software, es necesario obtener una licencia

de uso, se utilizará la licencia Webpack que es gratuita, como se ha expuesto anteriormente la principal diferencia con la versión de pago es que soporta menos dispositivos, por lo tanto para el desarrollo de proyectos de mayor volumen no será de utilidad. En la misma página de descargas, a la derecha de los enlaces para descargar ISE Design Suite se encuentra el enlace “License Solution Center”

Page 38: Manual de la Basys2 Spartan 3E.pdf

pág. 38

Figura 13– Sección de Descargas

5- Una vez adquirido el software ISE Design Suite y la Licencia,

procedemos a instalarlo; basta con seguir los sencillos pasos y ubicar el directorio de la licencia. Para el uso de las tarjetas de Digilent que cuentan con conector Mini-USB como lo son la Basys2 y Nexys2 se requiere un software extra para poder realizar la comunicación: Adept de Digilent; El software puede descargarse de manera gratuita en el sitio web de Digilent www.digilentinc.com , en la sección “Software”: Digilent Adept, el paquete a descargar para Windows es Adept 2.6.1 System, 32/64-bit. Su instalación es muy sencilla, basta con hacer doble clic en el icono del software descargado y seguir las instrucciones.

Con esto se tiene instalado el software necesario para el uso de la Tarjeta Basys2.

Uso del Software ISE Design Suite 13.4, Adept 2.6.1 System y configuración de la Tarjeta Basys2

Para explicar el uso del software ISE Design Suite 13.4, Adept 2.6.1 System, la descarga y configuración de los programas hacia la Tarjeta Basys2 así como las bases del lenguaje de programación VHDL, se desarrollará una práctica sencilla que servirá de guía a través de la creación, simulación y descarga del proyecto. Iniciaremos por compuertas lógicas

Page 39: Manual de la Basys2 Spartan 3E.pdf

pág. 39

AND, OR y XOR, y estas mismas serán utilizadas para hacer un medio sumador y a su vez un sumador completo. A continuación se muestran todos los pasos que se realizarán:

Se inicia por abrir ISE Project Navigator. Al iniciar el programa, carga

automáticamente el último proyecto con el cual se trabajó. Se crea un nuevo proyecto, para ello se selecciona el menú File y después New Project, con esto se iniciará el asistente de creación de nuevo proyecto, en la primera ventana que se muestra habrá que indicar el nombre del proyecto, la carpeta de trabajo del proyecto (al introducir el nombre del proyecto se indicará automáticamente una carpeta con el mismo nombre), una descripción del proyecto (opcional) y en la parte inferior se tiene que indicar el tipo de archivo fuente que será el módulo principal del proyecto, se deja en HDL.

Figura 14– Asistente de Creación de un nuevo Proyecto

A continuación se da clic en el botón Next, lo cual mostrará la ventana

Project Settings, donde se indica el modelo del dispositivo utilizado en el proyecto, además de las herramientas a utilizar para las diferentes etapas del diseño. Para el uso de la Tarjeta Basys2, las opciones necesarias son las mostradas en la Figura 15.

Page 40: Manual de la Basys2 Spartan 3E.pdf

pág. 40

Figura 15– Opciones de Configuración de Tarjeta Basys2

Una vez indicadas las opciones adecuadas, se hace clic en el botón

Next, se mostrará un resumen del proyecto, finalmente se da clic en el botón Finish y se creará el proyecto nuevo, todavía sin ningún archivo fuente agregado, solamente se verá el nombre del archivo de proyecto en la parte superior y en la ventana Hierarchy dentro del panel Design el dispositivo seleccionado.

Ahora se procede a agregar un nuevo archivo fuente al proyecto, esto se realizará utilizando el menú Project => New Source…, con lo que aparecerá una ventana donde se debe indicar el tipo de módulo que se desea agregar al proyecto, se selecciona VHDL Module y como nombre del programa compuerta_and. Es importante que esté seleccionada la opción Add to Project. Observe la Figura 16.

Page 41: Manual de la Basys2 Spartan 3E.pdf

pág. 41

Figura 16 – Ventana New Source Wizard

Después se da clic en el botón Next lo cual mostrará la ventana

Define Module, aquí se deben indicar las características del módulo; el nombre de la entidad, el nombre de la arquitectura y las entradas y salidas con las que contará. Se debe tener algo como lo mostrado en la Figura 17.

Figura 17 – Ventana Define Module

Page 42: Manual de la Basys2 Spartan 3E.pdf

pág. 42

A continuación se da clic en el botón Next, con lo que se mostrará un resumen del nuevo archivo fuente que se ha agregado al proyecto. Por último se da clic en el botón Finish para que se agregue la nueva fuente al proyecto, se abrirá la ventana del editor donde se cargará el contenido del nuevo archivo compuerta_and.vhd (el nombre indicado para el nuevo archivo fuente con la extensión .vhd que corresponde a un módulo VHDL)

Analice el código que se presenta al terminar de crear la nueva fuente

del proyecto; la primera sección que se aprecia con dos guiones al inicio, es código predefinido que ISE Project Navigator inserta al inicio de cada módulo que se agrega a un proyecto, se puede notar que todas las líneas en esta primera sección inician con un par de guiones “–”: al igual que en los lenguajes de programación de software, VHDL permite insertar comentarios en el código, los cuales se indican mediante esos dos guiones, todo el texto que siga a estos guiones se toma como un comentario.

---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 15:11:22 05/10/2012 -- Design Name: -- Module Name: compuerta_and - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ----------------------------------------------------------------------------------

Código 1 – Código Predefinido por ISE Project Navigator

Mas adelante se tiene el siguiente código:

library IEEE; use IEEE.STD_LOGIC_1164.ALL;

Código 2– Librerías utilizadas en el programa

La instrucción library permite indicar una biblioteca externa de la cual se desee utilizar sus tipos de datos, operadores y algunas otras declaraciones; sería equiparable a la instrucción #include de los lenguajes C

Page 43: Manual de la Basys2 Spartan 3E.pdf

pág. 43

y C++. De manera similar a estos lenguajes, VHDL termina cada instrucción con punto y coma: “;”.

Después se tiene una instrucción use, que permite indicar qué

paquete se va a utilizar de la biblioteca que antes se había declarado con library. En este caso, se indica que se va a hacer uso de la biblioteca IEEE, que es una biblioteca estándar definida por el Institute of Electrical and Electronics Engineers, seguido de use se tiene STD_LOGIC_1164 lo cual hace referencia al paquete de la biblioteca que se utilizará y por ultimo se indica que de ese paquete se utilizaran todas sus declaraciones por medio de la instrucción ALL.

Cabe mencionar que VHDL es un lenguaje que no distingue

minúsculas de mayúsculas.

Entidad y Arquitectura

En VHDL, cada módulo está compuesto por dos partes: la entidad y la

arquitectura. La entidad es la sección donde se indican las conexiones (señales) del módulo con el resto de componentes, se indican el número de entradas y salidas, además del tipo de cada una de ellas. La sintaxis de declaración de entidad y de sus conexiones es la siguiente:

entity NOMBRE_ENTIDAD is port ( NOMBRE_SEÑAL1 : MODO TIPO; NOMBRE_SEÑAL2 : MODO TIPO ); end NOMBRE_ENTIDAD;

Código 3– Sintaxis de la Entidad

En primer lugar se indica el nombre de la entidad, utilizando la palabra

reservada entity, y después de la instrucción is se inicia la descripción de la entidad, en este caso de las señales o puertos mediante los cuales se comunicará con el exterior; para cada señal se indica su nombre, el modo (entrada, salida o ambos) y el tipo. Notese que las declaraciones de puertos finalizan con punto y coma, excepto la última antes del paréntesis que culmina la instrucción port.

Por lo tanto, continuando con el módulo, ISE Project Navigator ha

insertado el código mostrado en el recuadro de código 4:

entity compuerta_and is Port ( a : in STD_LOGIC; b : in STD_LOGIC;

Page 44: Manual de la Basys2 Spartan 3E.pdf

pág. 44

s : out STD_LOGIC); end compuerta_and;

Código 4 – Entidad Compuerta_and

La entidad cuyo nombre es compuerta_and, tiene tres puertos, todos

de tipo std_logic, los dos primeros denominados a y b, son entradas (in), mientras que el tercero, denominado s, es una salida (out), el diagrama esquemático de la entidad creada se puede representar de la siguiente manera:

Figura 18 – Diagrama esquemático compuerta_and

De cierta forma, se considera la declaración de la entidad como una “caja negra”, para la cual se conocen sus entradas y salidas, pero no su funcionamiento interno, el cual se describe en la arquitectura.

La arquitectura es la sección de un módulo VHDL en la que se

describe el funcionamiento de la entidad, y puede hacerse de dos maneras diferentes: describiendo su estructura interna mediante interconexiones entre compuertas y componentes que constituyen al módulo, lo que se denomina una descripción estructural, o con una descripción de lo que hace el módulo, ya sea mediante funciones booleanas o mediante una descripción algorítmica, lo que se conoce como una descripción de comportamiento. La sintaxis para declarar una arquitectura es mostrada en el recuadro de código 5.

architecture NOMBRE_ARQUITECTURA of NOMBRE_ENTIDAD is -- Aquí se declaran elementos auxiliares para usar en la descripción begin -- Aquí se realiza la descripción de la arquitectura, -- mediante la utilización de sentencias secuenciales,

Page 45: Manual de la Basys2 Spartan 3E.pdf

pág. 45

-- combinacionales o subprogramas. end NOMBRE_ARQUITECTURA;

Código 5– Sintaxis de la Arquitectura

Como se puede observar se utiliza la instrucción architecture para

iniciar la declaración de la arquitectura, después se indica su nombre y el nombre de la entidad a la cual corresponde la descripción que se realizará, se continua con la instrucción begin para indicar el inicio del código que describe el funcionamiento de la arquitectura, y finaliza con la instrucción end seguido del nombre de la arquitectura. Entre las instrucciones is y begin, es posible declarar señales, componentes o elementos auxiliares para la descripción de la arquitectura, algunos de estos elementos se verán más adelante.

ISE Project Navigator nos crea la plantilla de la arquitectura, para que

el programa compuerta_and funcione se debe describir su comportamiento; para lo cual se agrega después de la instrucción begin lo que se desea que haga el programa. El resultado se muestra en el recuadro de código 6.

architecture behavioral of compuerta_and is begin s <= a and b; end behavioral;

Código 6– Arquitectura compuerta_and

Con esto, se asigna el resultado de la operación and entre las señales de entrada a y b a la señal de salida s. Como se observa, la pareja de caracteres “<=" son el operador de asignación de señales en VHDL, también, se hace uso del operador and, que realiza la operación lógica AND entre sus dos operandos. Además del operador and, en VHDL se tienen definidos los siguientes operadores lógicos: or, nand, nor, xor y xnor. Finalmente, se termina la instrucción con un punto y coma.

Una vez que se ha adicionado este código al módulo, se procede a

guardar los cambios realizados usando el comando Save dentro del menú File o pulsando en el botón con icono de un disco flexible en la barra de herramientas. Para comprobar que no se han cometido errores en el código del módulo, se debe realizar una revisión de sintaxis, para ello, en la ventana Hierarchy, se da clic en el nombre del módulo (compuerta_and), después, en la ventana Processes, se expande la sección Synthesize – XST, de manera que se pueda ver el proceso Check Syntax tal y como se muestra en la figura 19.

Page 46: Manual de la Basys2 Spartan 3E.pdf

pág. 46

Figura 19– Revisión de Sintaxis

Para iniciar la revisión de sitanxis del código, se hace doble clic sobre el nombre del proceso o con un clic derecho y luego seleccionando el comando Run del menú contextual. Se puede observar el resultado del proceso de revisión de sintaxis en la parte inferior del programa en la ventana de resultados.

Figura 20– Resultado del Chequeo de Sintaxis

Al terminar el proceso, un icono con una palomita blanca indica que la revisión de sintaxis ha concluido exitosamente pues no se encontraron errores en el código.

Page 47: Manual de la Basys2 Spartan 3E.pdf

pág. 47

Con esto se ha revisado el código del módulo, resta comprobar que funcione correctamente, para ello se puede realizar una simulación antes de proceder a la implementación en un dispositivo reconfigurable.

Simulación

Analicemos cómo realizar una simulación del componente compuerta_and. En primer lugar, dentro de Project Navigator, en la sección Design, en la opción View, se selecciona Simulation:

Figura 21 – Simulación

A continuación, dentro de la ventana Hierarchy, se selecciona el componente que se desea simular, al hacerlo cambiarán las opciones disponibles en la ventana Processes, en este caso se muestra ISim Simulator, se da clic en el signo “+” a la izquierda de ISim Simulator con lo que se mostrarán dos procesos: Behavioral Check Syntax y Simulate Behavioral Model

Page 48: Manual de la Basys2 Spartan 3E.pdf

pág. 48

Figura 22– Ventana Processes ISim Simulator

Este último proceso es el que permitirá realizar la simulación, se hace doble clic en Simulate Behavioral Model y se espera a que inicie ISim.

Figura 23– Ventana ISim Simulator

ISim muestra por defecto cuatro ventanas o secciones, una en la parte inferior y tres en el medio: Instances and Processes, muestra las entidades, bibliotecas y procesos existentes en el módulo; Objects, despliega una lista de los puertos que forman parte del módulo, indicando con un pequeño icono con la letra I aquellos que son entradas y con la letra O los que son salidas; y la ventana de simulación, donde se despliegan nuevamente los puertos del

Page 49: Manual de la Basys2 Spartan 3E.pdf

pág. 49

módulo con líneas de tiempo que permitirán visualizar el comportamiento de cada uno de dichos puertos para cada instante de la simulación.

La tabla de verdad de una compuerta AND de dos entradas se

muestra en la Tabla 6.

b a s

0 0 0

0 1 0

1 0 0

1 1 1 Tabla 6 – Tabla de verdad compuerta AND

Se tienen cuatro combinaciones posibles de valores para las entradas a y b, para comprobar el funcionamiento del módulo es conveniente simular estos cuatro casos; para ello, se asignan valores a las entradas de manera que se tengan las cuatro combinaciones posibles y se pueda evaluar el valor que toma la salida para cada una de ellas.

Se inicia por la primera combinación, cuando ambas entradas valen 0,

para indicar que una entrada tendrá el valor 0 en el simulador, se da clic con el botón derecho del ratón sobre dicha entrada en la ventana de simulación, del menú que se despliega se selecciona la opción Force Constant…

Aparecerá la ventana Force Selected Signal; en la opción Force to

Value: escribiremos un 0 como se muestra en la Figura 24. Se hace clic en el botón OK.

Se repiten estos pasos para la señal de entrada b: se hace clic con el

botón derecho sobre el nombre de la entrada en la ventana de simulación, se selecciona la opción Force Constant…, y se establece a 0 la opción Force to Valué: se da clic en el botón OK.

Al hacer esto no se nota ningún cambio en la ventana de simulación una vez que se han indicado los valores de 0 para las dos señales, estos se notarán hasta que se ejecute la simulación. Para ello se hará uso de la barra de herramientas de ISim.

Page 50: Manual de la Basys2 Spartan 3E.pdf

pág. 50

Figura 24 – Ventana Force Selected Signal

Se da clic en el botón que tiene como icono una punta de flecha y un reloj de arena, esto ejecuta la simulación por un tiempo determinado, el cual se indica a la derecha del botón; en este caso, 1 us, la ventana de simulación ahora muestra lo que se observa en la figura 25.

Figura 25 – Resultado Simulación Valor 1

Como se puede observar, los valores en la columna Value han

cambiado de U a 0, la U indica valor desconocido, que era el caso antes de iniciar la simulación, ahora que se ha simulado por un tiempo de 1us, las entradas se encuentran en valores de 0, que fue como se “forzó”, además la señal de salida s también tiene el valor de 0, esta no se forzó, sino que toma el valor especificado en el módulo: la operación AND entre las entradas a y b, que en este caso es 0.

Ahora, cambie el valor de la entrada a por 1, para evaluar el segundo

caso de la tabla de verdad de la operación AND de dos entradas, se hace clic con el botón derecho sobre el nombre de la señal y se selecciona el comando Force Constant nuevamente; en esta ocasión se establecerá un 1 en la opción Force to value. Se hace clic en el botón para ejecutar la

Page 51: Manual de la Basys2 Spartan 3E.pdf

pág. 51

simulación por cierto tiempo, lo que nos mostrará algo como lo que se tiene en la Figura 26.

Figura 26– Resultado Simulación Valor 2

La columna Value ha cambiado a 1 para el caso de la señal a,

además, en la ventana de tiempo la línea verde a la derecha de la misma señal se encuentra más arriba y ahora con una zona sombreada debajo, esto indica que durante ese tiempo la señal se encuentra en un estado alto (1). La señal de salida s se mantiene en 0, que es correcto debido a que solamente cambiará de estado cuando ambas entradas sean 1. Ahora simule el tercer caso de la tabla de verdad, cuando a vale 0 y b vale 1.

Figura 27– Resultado Simulación Valor 3

Como se puede observar en la figura 27 la señal se mantiene en alto durante el tiempo de la simulación, pero la salida s se mantiene en 0. Por último simule el caso cuando ambas entradas valen 1.

Page 52: Manual de la Basys2 Spartan 3E.pdf

pág. 52

Figura 28– Resultado Simulación Valor 4

Observe en la figura 28 como finalmente la salida s ha cambiado a 1,

lo cual corresponde con la tabla de verdad de la operación AND, de esta forma se ha comprobado que el componente funciona correctamente.

Cabe mencionar que en cada paso, en la ventana de simulación

apareció a la derecha un valor con letras amarillas que cambió de 1,000,000 ns a 2,000,000 ns en el primer tiempo de simulación, y así hasta llegar a 5,000,000 ns. Esto indica que entre cada paso se avanzó 1 us, que es el tiempo que se configuró en la barra de herramientas.

Para poder visualizar la simulación completa se hace clic en el

botón Zoom to Full View; la simulación completa se observa en la figura 29 donde se pueden ver los cuatro pasos de simulación ejecutados, los cuales corresponden a la tabla de verdad de la compuerta AND.

Figura 29– Resultado de Simulación Completa

A continuación, se agregarán un par de componentes más: una

compuerta OR y otra XOR. Cierre ISim y vuelva a ISE Project Navigator. Desde el menú Project seleccie New Source, o también puede hacer

clic con el botón derecho sobre el nombre del proyecto o del dispositivo para el cual está destinado, donde de igual manera aparece la opción New Source. Agrege un módulo VHDL y como nombre de archivo compuerta_or, enseguida haga clic en el botón Next.

La ventana Define module debe quedar como se muestra en la figura 30.

Page 53: Manual de la Basys2 Spartan 3E.pdf

pág. 53

Figura 30 – Define Module Compuerta_or

Haga clic en el botón Next y después en Finish, con lo cual se

obtendrá el nuevo módulo compuerta_or en la ventana Hierarchy, en el editor se mostrará el código generado por Project Navigator.

El código de la arquitectura deberá ser el mostrado en el recuadro de

código siguiente: architecture Behavioral of compuerta_or is begin s <= a or b; end Behavioral;

Código 7 – Arquitectura compuerta_or

El siguiente paso es revisar la sintaxis del módulo creado, se debe seleccionar la opción Implementation en la ventana Design, después seleccionar el módulo compuerta_or y en la ventana de procesos hacer doble clic en Check Syntax, si hubo algún problema se indicará en la consola ubicada en la parte inferior.

Page 54: Manual de la Basys2 Spartan 3E.pdf

pág. 54

Figura 31– Chequeo de Sintaxis Compuerta_or

Como se puede observar en la figura 31 no se tiene ningún error de

sintaxis, por lo que ahora se prosigue a hacer la simulación del módulo. En Project Navigator, sección Design, pase View a Simulation,

enseguida se selecciona el componente compuerta_or y por último en la ventana Processes haga doble clic en Simulate Behavioral Model.

Nuevamente se abre ISim Simulator, y de manera similar a la

simulación del módulo compuerta_and, se evaluarán las cuatro combinaciones posibles según la tabla de verdad de la operación OR para dos entrada:

b a s

0 0 0

0 1 1

1 0 1

1 1 1 Tabla 7– Tabla de verdad compuerta OR

Haga clic con el botón derecho sobre la entrada a en la ventana de simulación, pero en esta ocasión no se utilizará el comando Force Constant, sino el comando Force Clock, lo cual desplegará una ventana como la mostrada en la figura 32.

Page 55: Manual de la Basys2 Spartan 3E.pdf

pág. 55

Figura 32– Ventana Define Clock

El comando Force Clock permite indicar que una entrada tendrá

valores alternados entre 0 y 1 durante la simulación, es decir, como una señal de reloj. En la ventana Define Clock se defininen algunas opciones como el periodo, ciclo de trabajo y el valor del primer pulso, para el caso de esta simulación, se configura Leading Edge Value a 0 y Trailing Edge Value a 1, mientras que Period será de 100 ns, tal y como se muestra en la figura 33.

Figura 33 – Configuración Define Clock

Page 56: Manual de la Basys2 Spartan 3E.pdf

pág. 56

Haga clic en OK y configure de manera similar la entrada b, pero variando el periodo a 200 ns

Hecho esto se ejecuta la simulación por un tiempo determinado; por defecto 1 us, se da clic en el botón Run for the time specified on the toolbar y después en el botón Zoom to Full View, el resultado es mostrado en la siguiente figura.

Figura 34 – Resultado Simulación compuerta_or

En la figura 34 se observan algunos cambios de valor entre 0 y 1 de

las señales de entrada a y b, los suficientes para evaluar las cuatro combinaciones diferentes de la tabla de verdad de la compuerta OR. Estas transiciones se consiguen al usar la opción Force Clock para las señales a y b, además, notese que al configurar el periodo de la señal b como el doble con respecto al periodo de la señal a, las transiciones corresponden de manera exacta con las de la tabla de verdad.

Por último practique creando el módulo de la compuerta XOR. Para

agregar el módulo, siga los mismos pasos que con los módulos anteriores. Después de haber creado el modulo, chequee la sintaxis, y prosiga a la simulación; para comprobar la simulación obsérvese la tabla de verdad de la compuerta XOR.

b a s 0 0 0

0 1 1

1 0 1

1 1 0 Tabla 8– Tabla de Verdad Compuerta XOR

Diseño Estructural en VHDL

Una de las características más potentes del lenguaje VHDL, es la posibilidad de utilizar los módulos que se han desarrollado para construir módulos más grandes, es decir, un módulo VHDL puede convertirse en componente de otro módulo, de esta forma se reutilizan o aprovechan

Page 57: Manual de la Basys2 Spartan 3E.pdf

pág. 57

módulos ya diseñados con anterioridad, o se puede dividir un diseño complejo en varios diseños más simples.

Utilizar módulos VHDL para construir otros módulos se

denomina diseño estructural, que difiere del diseño por comportamiento que se ha utilizado en la creación de las compuertas AND, OR y XOR.

Se aprovecharán dos de los componentes que se han creado hasta

este momento para crear un componente nuevo: Un Medio Sumador. Como primer paso observe la tabla de verdad de un medio sumador el

cual cuenta con un par de entradas (A y B) y un par de salidas: suma (S) y acarreo (C):

B A C S

0 0 0 0

0 1 0 1

1 0 0 1

1 1 1 0 Tabla 9: Tabla de Verdad Medio Sumador

Expresado en ecuaciones booleanas:

C= A·B S= A⊕B

Se utilzarán como componentes los módulos compuerta_and y

compuerta_xor para crear un nuevo módulo llamado medio_sumador. Por lo tanto agrege un nuevo módulo llamado medio_sumador, en el asistente indique cuatro señales, dos entradas (A y B) y dos salidas (C y S) como se muestra en la figura 35.

Se finaliza con el asistente y para obtener el código creado

por Project Navigator. Antes de utilizar un componente, es necesario declararlo, esta

declaración se realiza en el código de la arquitectura, entre la declaración del nombre de arquitectura y la instrucción begin, se incluye el nombre de la entidad que se utilizará como componente, además de la declaración de sus señales (mediante la instrucción port), la sintaxis es la mostrada en el recuadro de Código 8.

Page 58: Manual de la Basys2 Spartan 3E.pdf

pág. 58

Figura 35– Modulo Medio Sumador

architecture NOMBRE_ARQUITECTURA of NOMBRE_ENTIDAD is component NOMBRE_ENTIDAD_COMPONENTE port( NOMBRE_SEÑAL1: DIRECCIÓN TIPO; NOMBRE_SEÑAL2: DIRECCIÓN TIPO ); end component; begin end NOMBRE_ARQUITECTURA;

Código 8 – Sintaxis declaración de componente.

La instrucción port dentro de la declaración del componente es prácticamente una copia de las señales que se declaran en el código de entidad del módulo que se usa como componente. Por ejemplo, la declaración de componente del módulo compuerta_and sería la siguiente:

component compuerta_and is port( a : in std_logic; b : in std_logic; s : out std_logic ); end component;

Código 9– Declaración component compuerta_and

Page 59: Manual de la Basys2 Spartan 3E.pdf

pág. 59

Con este ejemplo ya se pueden agregar las declaraciones de los

componentes compuerta_and y compuerta_xor en el módulo medio_sumador.

architecture behavioral of medio_sumador is component compuerta_and is port( a : in std_logic; b : in std_logic; s : out std_logic ); end component; component compuerta_xor is port( a : in std_logic; b : in std_logic; s : out std_logic ); end component; begin end behavioral;

Código 10– Declaración de componentes para medio_sumador

Ya se han declarado los componentes, ahora se debe hacer uso de

ellos, esto se hace mediante una instanciación de componente, en la que se indica el componente del cual se crea una instancia y las conexiones de sus señales, esta es la sintaxis:

ETIQUETA: NOMBRE_COMPONENTE port map( CONEXION1, CONEXION2 );

Código 11– Sintaxis Instanciación de componentes

La etiqueta es obligatoria, permite identificar entre diferentes

instanciaciones del mismo componente. La etiqueta va seguida del nombre del componente y después se indican las conexiones de las señales del componente, es decir, se indica con qué entradas, salidas o señales auxiliares se conectarán las señales que forman parte de la interfaz del componente. Para el caso del medio sumador, las entradas A y B se conectarán con las entradas a y b de ambas compuertas, mientras que la salida del módulo compuerta_and se conectará con la señal de salida C y la salida del módulo compuerta_xor con la señal de salida S.

Page 60: Manual de la Basys2 Spartan 3E.pdf

pág. 60

ACARREO: compuerta_and port map( A, B, C ); SUMA: compuerta_xor port map( A, B, S );

Código 12 – Instanciación compuerta_and y compuerta_xor

De esta forma, el código final del módulo medio_sumador es el siguiente:

library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity medio_sumador is port( A : in STD_LOGIC; B : in STD_LOGIC; C : out STD_LOGIC; S : out STD_LOGIC ); end medio_sumador; architecture behavioral of medio_sumador is component compuerta_and is port( a : in std_logic; b : in std_logic; s : out std_logic ); end component; component compuerta_xor is port( a : in std_logic; b : in std_logic; s : out std_logic ); end component; begin

ACARREO: compuerta_and port map( A, B, C ); SUMA: compuerta_xor port map( A, B, S ); end behavioral;

Código 13 – Programa completo Medio_sumador

Al guardar el código del módulo medio_sumador, la jerarquía de archivos del proyecto cambia.

Page 61: Manual de la Basys2 Spartan 3E.pdf

pág. 61

Los módulos compuerta_and y compuerta_xor aparecen anidados dentro del módulo medio_sumador, indicando que se están utilizando como componentes de este, además, se muestran las etiquetas que se han utilizado para instanciar los componentes.

Córrase la sintaxis para observar que este bien estructurado el módulo

de medio_sumador.

Figura 36 – Chequeo de Sintaxis medio_sumador

El resultado de la simulación se muestra en la figura 37.

Figura 37– Simulación medio_sumador

Page 62: Manual de la Basys2 Spartan 3E.pdf

pág. 62

De manera similar a la creación del medio_sumador, elabore un sumador_completo para demostrar las ventajas del diseño estructural y como teniendo los módulos hechos se pueden realizar diseños de mayor tamaño muy fácilmente.

La construcción de un sumador_completo de un bit a partir de dos

medios sumadores y una compuerta OR se muestra en la figura 38.

Figura 38 – Diagrama esquemático sumador completo

Agregue un nuevo módulo VHDL al proyecto, el cual se llamará sumador_completo, tendrá tres entradas: EntradaA, EntradaB y Cin (acarreo de entrada), y dos salidas: Suma y Cout (Acarreo de salida).

Agregue la declaración de los componentes que serán utilizados:

medio_sumador y compuerta_or, de manera que quede algo como lo expuesto en el recuadro de código 14.

architecture behavioral of sumador_completo is component medio_sumador port( A : in STD_LOGIC; B : in STD_LOGIC; C : out STD_LOGIC; S : out STD_LOGIC ); end component; component compuerta_or port ( a : in std_logic; b : in std_logic; s : out std_logic

Page 63: Manual de la Basys2 Spartan 3E.pdf

pág. 63

); end component; begin end behavioral;

Código 14– Declaración medio_sumador y compuerta_or

Hecho esto toca realizar la instanciación de los componentes e indicar

sus conexiones, no debe haber ningún problema para la conexión de las señales del módulo sumador_completo (EntradaA, EntradaB, Cin, Suma y Cout), pero seguro habrá duda sobre cómo realizar las conexiones entre los componentes, por ejemplo, ¿cómo indicamos que la salida S del primer medio sumador debe conectarse a la entrada A del segundo? La respuesta es: mediante señales auxiliares. Las señales auxiliares podrían ser algo afín a variables temporales en otros lenguajes de programación (como las usadas en los ciclos, o las usadas para permitir una mayor claridad de código), en VHDL permiten realizar la conexión entre señales de varios componentes. En la siguiente figura se muestran en rojo las señales auxiliares de las que se haran uso para realizar las interconexiones de los componentes del módulo sumador_completo.

Figura 39– Interconexión de señales auxiliares

De manera similar a los componentes, las señales deben ser declaradas antes de poder utilizarse, y también como el caso de los componentes, las señales auxiliares se declaran después de la línea que indica el nombre de la arquitectura y antes de la instrucción begin. La sintaxis para declarar una señal es la siguiente (código 15):

Page 64: Manual de la Basys2 Spartan 3E.pdf

pág. 64

signal NOMBRE_SEÑAL : tipo;

Código 15– Sintaxis declaración de señal auxiliar

El código para agregar las señales s1, c1 y c2 al módulo es el

mostrado en el recuadro de código 16. Signal s1 : std_logic; signal c1, c2 : std_logic;

Código 16– Señales auxiliaries para sumador_completo

Nótese que el tipo de las señales auxiliares debe coincidir con el tipo

de las señales de los componentes con los que se desea realizar la conexión.

A continuación se crean dos instancias del módulo medio_sumador y

una del módulo compuerta_or, y se utilizarán las señales s1, c1 y c2 para interconectar dichas instancias.

MS0: medio_sumador port map( EntradaA, EntradaB, c1, s1 ); MS1: medio_sumador port map( s1, Cin, c2, Suma ); COR: compuerta_or port map( c1, c2, Cout );

Código 17– Instanciación sumador_completo

El código completo del módulo sumador_completo se muestra en el

recuadro de código 18. library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity sumador_completo is Port ( EntradaA : in STD_LOGIC; EntradaB : in STD_LOGIC; Cin : in STD_LOGIC; Suma : out STD_LOGIC; Cout : out STD_LOGIC ); end sumador_completo; architecture behavioral of sumador_completo is component medio_sumador port( A : in STD_LOGIC; B : in STD_LOGIC; C : out STD_LOGIC; S : out STD_LOGIC

Page 65: Manual de la Basys2 Spartan 3E.pdf

pág. 65

); end component; component compuerta_or port ( a : in std_logic; b : in std_logic; s : out std_logic ); end component; signal s1 : std_logic; signal c1, c2 : std_logic; begin MS0: medio_sumador port map( EntradaA, EntradaB, c1, s1 ); MS1: medio_sumador port map( s1, Cin, c2, Suma ); COR: compuerta_or port map( c1, c2, Cout ); end behavioral;

Código 18 – Módulo sumado_completo

En cuanto se guarda el código, la jerarquía del proyecto se modifica como antes ocurrió con el módulo medio_sumador.

Figura 40 – Jerarquía sumador_completo

Page 66: Manual de la Basys2 Spartan 3E.pdf

pág. 66

Nótese que todos los módulos anteriores se han anidado dentro del módulo sumador_completo, además de que hay dos apariciones del módulo medio_sumador, correspondiendo con las instancias que se han creado del mismo. A continuación se realiza una revisión de sintaxis, si no hay problemas proceda con la simulación. Para comprobar la simulación observe la tabla de verdad para el sumador completo de 1 bit:

Cin EntradaB EntradaA Cout Suma

0 0 0 0 0

0 0 1 0 1

0 1 0 0 1

0 1 1 1 0

1 0 0 0 1

1 0 1 1 0

1 1 0 1 0

1 1 1 1 1 Tabla 10 – Tabla de Verdad sumador_completo

Para facilitar la simulación, utilize la opción Force Clock, colocando una frecuencia de 100 ns para EntradaA, 200 ns para EntradaB y 400 ns para Cin. El resultado se muestra en la figura 41.

Figura 41– Simulación Sumador_completo

La figura 41 engloba todas las combinaciones de la tabla de verdad,

con lo que podemos observar que el módulo funciona correctamente. Además, en la simulación es posible ver los valores que toman las señales auxiliares, de forma que sea más fácil depurar y encontrar posibles errores lógicos en el módulo.

Configuración de la Tarjeta Basys2

Después de haber revisado que el código sea el correcto y que los

módulos funcionen como se desea mediante la simulación, el siguiente paso

Page 67: Manual de la Basys2 Spartan 3E.pdf

pág. 67

es indicar a qué pines del dispositivo lógico programable corresponderán las entradas y salidas del módulo que se ha desarrollado.

Estas entradas y salidas deben ser asociadas con pines o puertos del

dispositivo en el que se desee implementar el diseño, de manera que se pueda conectar el módulo con el resto del circuito que se a diseñando.

Para este diseño, se deberán conectar las tres entradas con tres interruptores (switches), mientras que las dos salidas serán conectadas a dos leds de la tarjeta de desarrollo, la siguiente figura indicamos a qué elemento de la tarjeta se conectará cada puerto del módulo sumador_completo.

Figura 42– Asignación de switches y leds sumador_completo

Como se puede observar, debajo de cada señal a conectar se

encuentra entre paréntesis una letra y un número, así es como se indican los pines del encapsulado del dispositivo que se este configurando, en este caso una Basys2. Una vez que se sabe a qué pin del FGPA se asociarán los puertos del módulo, se debe indicarlo en el proyecto, para ello en primera instancia se hace uso de la aplicación PlanAhead: se selecciona el

Cout (M11)

Suma (M5)

Cin (K3)

EntradaA (L3)

EntradaB (P11)

Page 68: Manual de la Basys2 Spartan 3E.pdf

pág. 68

módulo sumador_completo en la ventana Design, se debe asegurar de que esté seleccionada la opción Implementation, después, en la ventana Processes, se expande la categoría User Constraints, y se hace doble clic en el proceso I/O Pin Plannig (Plan Ahead) – Post-Synthesis.

Figura 43 – I/O Pin Planning

Espere unos instantes y se abrirá el programa PlanAhead,

probablemente antes de cargar PlanAhead se muestre un mensaje que indica que se agregará un archivo de restricciones de usuario (UCF), a lo que se indica que si (Yes).

Page 69: Manual de la Basys2 Spartan 3E.pdf

pág. 69

Figura 44 – Indicación para agregar archivo UCF

Si todo ha salido correctamente se debe tener en pantalla la ventana

PlanAhead. En la parte superior se muestran dos pestañas en las cuales se pueden ver los gráficos que representan el dispositivo que se esta por configurar: la pestaña de la izquierda despliega los pines del FPGA en un arreglo matricial (Package), mientras que la de la derecha representa el dispositivo en su totalidad (Device).

Debajo de esas imágenes, se encuentra una sección con dos

pestañas: I/O Ports y Package Pins, si se selecciona I/O Ports y se expanden las opciones All ports y Scalar ports se mostrarán los puertos que forman parte del módulo sumador_completo, haciendo clic en uno de ellos se pueden arrastrar hacia la imagen que representa los puertos del dispositivo donde deberemos soltarlo estando ubicados en el pin al que se desea asociar el puerto o también se puede hacer mediante la columna site en la cual solo se escribe la letra y el número del pin deseado. (Figura 45)

Figura 45 – Ventana PlanAhead

Page 70: Manual de la Basys2 Spartan 3E.pdf

pág. 70

Una vez que se han asociado todos los puertos del

módulo sumador_completo con pines del FPGA. Haga clic en el botón para guardar el diseño de Plan Ahead y cierre para continuar en ISE Project Navigator. Nótese que un nuevo archivo se ha agregado al proyecto, el nombre de este archivo corresponde con el módulo que se va a enviar al dispositivo reconfigurable y tendrá como extensión .ucf.

Una vez realizado lo anterior, se selecciona el

módulo sumador_completo en la ventana Hierarchy, después, en la ventana Processes haga clic con el botón derecho en Generate Programming File, se selecciona la opción Process Properties lo cual abrirá un diálogo en el que se deberá asegurar de 2 cosas: que en la categoría General Options (figura 46) esté habilitada la opción Create Bit File, y que en la categoría Startup Options (figura 47), la propiedad FPGA Start-Up Clock esté configurada a JTAG Clock.

Figura 46– General Options

Haga clic en el botón OK para cerrar el diálogo y enseguida doble clic en el proceso Generate Programming File (Figura 48), iniciará la creación del archivo de configuración .bit que se descargará al FPGA. Si el proceso termina con éxito, se habrá creado el archivo sumador_completo.bit dentro de la carpeta del proyecto.

Page 71: Manual de la Basys2 Spartan 3E.pdf

pág. 71

Figura 47 – Startup Options

Figura 48– Generate Programming File

Ahora se procede a enviar este archivo al FPGA, para ello se utilizará el software Adept 2.6.1 System de Digilent. Conecte la tarjeta Basys2 a un puerto USB disponible de una computadora, Windows reconocerá que se ha conectado un nuevo dispositivo y procederá a asociarlo con el controlador

Page 72: Manual de la Basys2 Spartan 3E.pdf

pág. 72

adecuado. Abra el software Adept, y si la tarjeta se encuentra conectada adecuadamente, se debe tener algo como lo que se muestra en la figura 49.

Figura 49– Software Adept 2.6.1 System

Una vez detectada la tarjeta toca configurar el FPGA: haga clic en el botón Browse (Figura 50) a la derecha de donde aparece el dispositivo FPGA, se abre un diálogo de Windows en el que se debe indicar el archivo de configuración sumador_completo.bit que se generó antes en Project Navigator.

Por último haga clic en el botón Program a la derecha del

botón Browse e inicie el proceso de carga del archivo de configuración al FPGA. Durante la programación, un led de color rojo, que se encuentra a un lado de los pines de alimentación externa de la tarjeta se enciende, una vez terminado el proceso se indica si ha sido exitoso en la ventana de mensajes de Adept, si no ha habido problemas, el FPGA ha sido configurado y se puede probar si funciona.

Con esto se termina la explicación del desarrollo de un nuevo proyecto

y su descarga hacia la tarjeta Basys2.

Page 73: Manual de la Basys2 Spartan 3E.pdf

pág. 73

Figura 50– Búsqueda de archivo .bit

Teniendo las bases del manejo de la tarjeta se procedió al desarrollo

de nuevas prácticas las cuales son expuestas en los resultados. El diseño de las prácticas involucra adquisición de datos y control de procesos.

Page 74: Manual de la Basys2 Spartan 3E.pdf

pág. 74

RESULTADOS

Desarrollo de Prácticas utilizando la Tarjeta Basys2

Las prácticas expuestas a continuación se desarrollaron con la Tarjeta Basys2 basada en el Xilinx Spartan 3E, estas prácticas tienen como objetivo demostrar la viabilidad del uso de la tarjeta Basys2 como arquitectura base en el control de un proceso.

El diseño estructural con VHDL permite agregar módulos y crear

prácticas cada vez más complejas. El diseño estructural, la asignación de pines y la descarga hacia la tarjeta se explica de forma breve en este documento y para no extender de más las prácticas se omiten dentro del desarrollo de las mismas.

Se recomienda tener bases del lenguaje VHDL y de electrónica digital

para comprender en su totalidad las practicas expuestas.

Practica 1 – Decoder Display

En la siguiente práctica se diseñará un Decoder para el Display de 7 segmentos de la Tarjeta Basys2. Con los switches de la tarjeta se pretende ingresar un número binario el cual será desplegado en los leds y en el display de 7 segmentos. El diagrama esquemático se muestra en la figura 1.1

Figura 1.1 – Esquemático Decoder_Display

En base al diagrama esquemático se declara la entidad la cual se

muestra en la figura 1.2. Notese el bus de datos utilizado en cada entrada y salida.

Page 75: Manual de la Basys2 Spartan 3E.pdf

pág. 75

Figura 1.2 – Asignación de Entidad

A continuación se muestra el código de la entidad creado por el ISE

Project Navigator: library IEEE; use IEEE.STD_LOGIC_1164.ALL; -- Uncomment the following library declaration if using -- arithmetic functions with Signed or Unsigned values --use IEEE.NUMERIC_STD.ALL; -- Uncomment the following library declaration if instantiating -- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity Display is Port ( a : in STD_LOGIC_VECTOR (3 downto 0); Led : out STD_LOGIC_VECTOR (3 downto 0); Sel_Disp: out STD_LOGIC_VECTOR (3 downto 0); d : out STD_LOGIC_VECTOR (6 downto 0)); end Display;

Código 1.1 - Entidad con sus respectivas señales

Enseguida agregue el código mostrado en el recuadro de código 1.2 a

la arquitectura para que el módulo funcione correctamente.

Page 76: Manual de la Basys2 Spartan 3E.pdf

pág. 76

architecture Behavioral of Display is begin -- Los Leds del Display se activan con 0 process (a) begin case a is when "0000" => d <= "0000001"; -- 0 when "0001" => d <= "1001111"; -- 1 when "0010" => d <= "0010010"; -- 2 when "0011" => d <= "0000110"; -- 3 when "0100" => d <= "1001100"; -- 4 when "0101" => d <= "0100100"; -- 5 when "0110" => d <= "0100000"; -- 6 when "0111" => d <= "0001111"; -- 7 when "1000" => d <= "0000000"; -- 8 when "1001" => d <= "0001100"; -- 9 when "1010" => d <= "0001000"; -- a when "1011" => d <= "1100000"; -- b when "1100" => d <= "1110010"; -- c when "1101" => d <= "1000010"; -- d when "1110" => d <= "0110000"; -- e when "1111" => d <= "0111000"; -- f when others => d <= "0000000"; end case; end process; Led <= a; -- ANO = F12, AN1 = J12, AN2 = M13, AN3 = K14 -- El display seleccionado se enciende con valor en bajo 0 Sel_Disp <= "1010"; end Behavioral;

Código 3.2 Arquitectura terminada

El código inicia con el nombre de la arquitectura, en este caso se le

dejo el nombre que automáticamente le da el programa (Behavioral), después de ello se inicia con un proceso con la entrada (a), y dentro del proceso la condición case donde se incluyen los valores que la salida (d) puede tomar, dependiendo del valor que se le asigne a la entrada (a). Al finalizar el proceso, se agrega una línea (Led <= a;) en la cual solo se le asigna el valor que tiene la entrada (a) a la salida (Led), esta última corresponde a los 4 leds de la tarjeta.

Cabe mencionar que los leds de los displays se encienden con un

valor en bajo. La última línea antes de terminar la arquitectura (Sel_Disp <= "1010";)

es para la selección del display a utilizar.

Page 77: Manual de la Basys2 Spartan 3E.pdf

pág. 77

Para finalizar se comprueba el correcto funcionamiento del modulo

Display_7seg a través de la siguiente tabla se verdad:

a(entrada) Leds Display 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111

0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111

0 1 2 3 4 5 6 7 8 9 a b c d e f

Tabla 1.1 – Tabla de verdad Display_7seg

Compile y Pruebe el funcionamiento del Programa con la Tarjeta

Basys2.

Practica 2 - Contador Ascendente

En esta práctica se diseñará un contador ascendente. Para que un contador funcione se necesita un generador de pulsos (reloj), y en este caso será utilizado el reloj de la tarjeta Basys2, recuerde que el reloj de la tarjeta es de 50 Mhz lo que significa un problema ya que el ojo humano es incapaz de ver pulsos a esa velocidad, es por ello que dentro del proyecto será necesario hacer un reloj más lento que el de la tarjeta; a continuación se describe paso a paso el desarrollo del proyecto.

Se inicia creando un nuevo proyecto, con el nombre de

contador_ascendente y la entidad contadorAD que cuenta con las entradas clk y reset y la salida Q de 4 bits.

El código de la entidad se muestra en el recuadro de código 2.1

Page 78: Manual de la Basys2 Spartan 3E.pdf

pág. 78

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.std_logic_unsigned.all;

entity contadorAD is Port ( clk : in STD_LOGIC; reset:in std_logic; Q : out STD_LOGIC_VECTOR (3 downto 0)); end contadorAD;

Código 2.1 - Entidad contadorAD

Se declara una señal auxiliar auxiliar en la arquitectura:

signal aux : std_logic_vector( 3 downto 0 ); Esta señal aux sustituye a la señal Q dentro de la arquitectura debido

a que la señal Q es una salida (out), y no se puede leer una salida. Se utilizarán otras dos señales auxiliares para el diseño del reloj a baja

frecuencia. signal divisor : std_logic_vector( 24 downto 0 ); signal reloj_lento : std_logic;

Código 2.2 - Declaración de señales auxiliares

La primera señal como se puede observar en el recuadro de código

2.2 es un vector de 24 bits que permite dividir la frecuencia de 50MHZ del reloj de la tarjeta Basys2; la segunda señal será el reloj a baja frecuencia que se utilizará para el contador.

Después de haber declarado las señales auxiliares, se iniciará un

proceso con las señales de reloj_lento y reset, este proceso será el que realizará el conteo ascendente, el código del proceso se muestra a continuación:

Page 79: Manual de la Basys2 Spartan 3E.pdf

pág. 79

begin -- Proceso que lleva la cuenta de 4 bits process( reloj_lento, reset ) begin if reset = '1' then aux <= "0000"; elsif reloj_lento'event and reloj_lento = '1' then aux <= aux + 1; end if; end process; Q <= aux;

Código 2.3 - Proceso contador ascendente

Como se observa en el código 2.3 se inicia con un begin después de

haber declarado las señales auxiliares, este begin indica el inicio de la arquitectura; después de eso sigue la declaración de un proceso con las señales: reloj_lento y reset, a continuación se encuentra un nuevo begin el cual indica el inicio del proceso, enseguida se tiene una sentencia if para el reset, con la cual cada que reset tome el valor de ‘1’ la señal aux toma el valor de “0000”, después continua con la sentencia elsif, en la cual se indica que cada vez que reloj_lento tenga un flanco de subida la señal aux se incrementará en 1.

Enseguida se le asigna el valor de la señal aux a la señal Q la cual es

la salida que se mostrará en los leds. Ahora lo único que falta es el proceso para el reloj_lento, el cual es

mostrado continuación: -- Contador auxiliar que corre con el cristal de la tarjeta (50 MHz) -- permite reducir la frecuencia process( clk, reset ) begin if ( reset = '1' ) then divisor <= ( others => '0' ); elsif clk'event and clk = '1' then divisor <= divisor + 1; end if; end process; -- Tomamos el bit más significativo del contador auxiliar para -- dividir la frecuencia de operación reloj_lento <= divisor( 24 );

Código 2.4 - Proceso para crear un reloj lento

Page 80: Manual de la Basys2 Spartan 3E.pdf

pág. 80

Para el reloj lento se diseñó un contador ascendente, solo que esta vez se utilizó el reloj de la tarjeta y se incrementó en 1 el valor de la señal divisor en cada flanco de subida de clk, por lo tanto contará hasta llegar al valor máximo el cual es 2^ 24, debido a que la señal es de 24 bits. Teniendo este contador solo basta con asignar el bit más significativo de la señal divisor a la señal reloj_lento, esto se observa en la última línea del código anterior (reloj_lento <= divisor( 24 );). El código completo se muestra en el recuadro de código 2.5.

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.std_logic_unsigned.all; entity contadorAD is Port ( clk : in STD_LOGIC; reset:in std_logic; Q : out STD_LOGIC_VECTOR (3 downto 0)); end contadorAD; architecture Behavioral of contadorAD is signal aux : std_logic_vector( 3 downto 0 ); signal divisor : std_logic_vector( 24 downto 0 ); signal reloj_lento : std_logic; begin -- Proceso que lleva la cuenta de 4 bits process( reloj_lento, reset ) begin if reset = '1' then aux <= "0000"; elsif reloj_lento'event and reloj_lento = '1' then aux <= aux + 1; end if; end process; Q <= aux; -- Contador auxiliar que corre con el cristal de la tarjeta (50 MHz) -- permite reducir la frecuencia process( clk, reset ) begin if ( reset = '1' ) then divisor <= ( others => '0' ); elsif clk'event and clk = '1' then divisor <= divisor + 1; end if; end process; -- Tomamos el bit más significativo del contador auxiliar para -- dividir la frecuencia de operacion reloj_lento <= divisor( 24 );

Page 81: Manual de la Basys2 Spartan 3E.pdf

pág. 81

end Behavioral;

Código 2.5 - Módulo contadorAD

Finalmente se hace un chequeo de sintaxis, si no hay algún error, se

asignan lo pines, se crea el archivo .bit y se descarga a la tarjeta Basys2 por medio del software Adept para probar el programa.

Cabe mencionar que la velocidad del reloj_lento depende del número

de bits que se le asignen a la señal auxiliar divisor.

Practica 3 - Contador con salida a Display

A continuación se diseñará un contador ascendente como el de la Practica 2 y se desplegará el resultado de la cuenta en los Displays de 7 segmentos de la tarjeta Basys2.

Se crea un nuevo proyecto y un módulo VHDL con el nombre

cont_display. entity cont_display is Port ( clk : in STD_LOGIC; reset:in std_logic; sal : out STD_LOGIC_VECTOR (6 downto 0)); end cont_display;

Código 3.1 Entidad cont_display

Como se puede observar en el recuadro de código 3.1 la entidad es

similar a la de la práctica 2 con la diferencia que la salida es de 7 bits, esto es debido a que se enviará el resultado de la cuenta a los displays.

Enseguida se muestra el código correspondiente a la arquitectura el

cual cuenta con un reloj a baja frecuencia y un proceso que despliega el resultado en el display.

architecture Behavioral of cont_display is signal divisor : std_logic_vector( 24 downto 0 ); signal reloj_lento : std_logic; signal cuenta:integer; begin process (reloj_lento,reset) begin

Page 82: Manual de la Basys2 Spartan 3E.pdf

pág. 82

if (reset='1') then cuenta<=0; elsif (reloj_lento'event and reloj_lento = '1') then cuenta<= cuenta + 1 end if; end process; -- Contador auxiliar que corre con el cristal de la tarjeta (50 MHz) -- permite reducir la frecuencia process( clk,reset ) begin if ( reset = '1' ) then divisor <= ( others => '0' ); elsif clk'event and clk = '1' then divisor <= divisor + 1; end if; end process; -- Tomamos el bit más significativo del contador auxiliar para -- dividir la frecuencia de operacion reloj_lento <= divisor( 24 ); --asiganamos las salidas al display de 7 segmentos sal<= "0000001" when cuenta=0 else "1001111" when cuenta=1 else "0010010" when cuenta=2 else "0000110" when cuenta=3 else "1001100" when cuenta=4 else "0100100" when cuenta=5 else "0100000" when cuenta=6 else "0001111" when cuenta=7 else "0000000" when cuenta=8 else "0001100" when cuenta=9 else "0001000" when cuenta=10 else "1100000" when cuenta=11 else "0110001" when cuenta=12 else "1000010" when cuenta=13 else "0110000" when cuenta=14 else "0111000"; end Behavioral;

Código 3.2 - Arquitectura cont_display

Como se observa en el recuadro de código 3.2 se utiliza una condición when para hacer la traducción entre el valor de cuenta y el valor asignado a la salida sal que despliega el resultado en el display.

Para probar el programa cont_display se asignan los pines a la

Tarjeta Basys2 con PlanAhead, compile y baje el programa al FPGA para verificar su funcionamiento.

Page 83: Manual de la Basys2 Spartan 3E.pdf

pág. 83

Practica 4 - Encendido de un motor de CD

Materiales:

- 1 Optoacoplador 2N25 - 1 Transistor NPN 2N2222 - 1 Protoboard

- 1 Resistor 330 Ω - 1 Resistor 10K Ω - 1 Relevador de 5V - Alambre telefónico - 1 Motor de CD @ 5V

La tarjeta Basys2 cuenta con 4 módulos de expansión PMOD con 4

entradas/salidas cada uno. Utilizando una de estas salidas se encenderá un motor de CD de 5V por medio de uno de los switches de la tarjeta.

Se crea un nuevo proyecto y módulo VHDL llamado encender_motor.

La entidad es mostrada en el recuadro de código 4.1 entity encender_motor is Port ( start_stop : in STD_LOGIC; motor : out STD_LOGIC); end encender_motor;

Código 4.1 - Entidad encender_motor

El funcionamiento de la arquitectura es simple y es idéntico al de un

interruptor, solo se debe enviar el valor de la entrada start_stop a la salida motor.

architecture Behavioral of encender_motor is begin motor <= start_stop; end Behavioral;

Código 4.2 – Arquitectura encender_motor

Como se puede observar el módulo es bastante sencillo. Compile y

descargue el programa hacia la tarjeta Basys2 para comprobar el funcionamiento.

Page 84: Manual de la Basys2 Spartan 3E.pdf

pág. 84

Una vez teniendo el programa se debe hacer un acondicionamiento de

la señal de salida de la tarjeta Basys2 para que esta pueda encender el motor. La principal dificultad radica en el hecho de que la tarjeta tiene una salida de 3.3 V y se necesitan 5V para que el motor funcione.

Cabe mencionar que los motores de CD consumen bastante corriente

eléctrica y si se le exigue corriente de más a la Tarjeta Basys2 se puede dañarla por siempre. Es por ello que se utiliza un opto-acoplador 2N25 el cual es un dispositivo que aísla a la tarjeta del circuito de potencia del motor.

Además se necesita un Transistor 2N2222 en su configuración de

amplificador para activar un relevador el cual funcionará como un interruptor para encender o detener el motor según la acción de control enviada desde el switch de la tarjeta Basys2. Por medio de una fuente externa de 5V se obtiene la potencia eléctrica necesaria para que el motor y el circuito externo funcionen sin problemas.

El diagrama eléctrico del acondicionamiento de señal es mostrado en la figura 4.1

Se arma el circuito externo en un protoboard y para probar su

funcionamiento. Nota importante: Las tierras GND de la tarjeta Basys y del circuito

externo de acondicionamiento de señal deben estar acopladas.

Figura 4.1 – Acondicionamiento de Señal

Page 85: Manual de la Basys2 Spartan 3E.pdf

pág. 85

Práctica 5 - Motor Reversible

Materiales:

- 3 Opto-Acoplador 2N25 - 1 Protoboard - 3 Resistor 330 Ω - 3 Resistor 1K Ω - 1 Puente H SN754410 - Alambre telefónico - 1 Motor de CD @ 5V

Teniendo la experiencia de la práctica 4 para hacer el

acondicionamiento de señal necesario para utilizar las salidas de la Tarjeta Basys2, se pretende en esta práctica que el Motor de CD encienda y cambie su sentido de rotación al enviar la acción de control desde los switches de la tarjeta.

Se inicia la práctica creando un nuevo proyecto y módulo VHDL

llamado puente_h. La entidad se muestra en el recuadro de código 5.1 entity puente_h is Port ( start : in STD_LOGIC; sentido : in STD_LOGIC; s1 : out STD_LOGIC; led_start: out std_logic; led_sent: out std_logic; s2 : out STD_LOGIC; enable: out std_logic); end puente_h;

Código 5.1 - Entidad puente_h

Como se puede apreciar en el código 5.1 se cuenta con una entrada start, para encender o apagar el motor, una entrada sentido, para cambiar el sentido de rotación del motor, dos salidas s1 y s2, las cuales enviarán un pulso dependiendo del valor de la entrada sentido y otras dos salidas led_start y led_sent para indicar que el motor está en marcha y para indicar el sentido de rotación respectivamente, estos dos leds serán de la tarjeta.

Page 86: Manual de la Basys2 Spartan 3E.pdf

pág. 86

Figura 5.1 – Configuración y conexión CI SN754410

Para poder controlar el sentido de rotación del motor se necesita un puente H, en este caso como es un motor pequeño de 5 volts, se utilizará el integrado SN754410. Este Circuito integrado es capaz de controlar el sentido de rotación de 2 motores de CD, a la vez. El diagrama del circuito integrado se muestra en la figura 5.1, además de los pines en los cuales debe ser conectado el motor:

Como se puede observar en la figura 5.1 el integrado tiene dos pines

de alimentación debido a que puede controlar 2 motores, dos pines de enable, cuatro entradas (1A, 2A, 3A y 4A) y cuatro salidas (1Y, 2Y, 3Y y 4Y), en esta práctica se utilizarán 2 entradas y dos salidas (véase la conexión del motor izquierdo figura 5.1).

Para diseñar el código de la arquitectura se debe saber que para que

sean activadas las salidas 1Y y 2Y, necesitamos un pulso de enable en el pin 1, y a su vez para ser activadas estas salidas, necesitan un pulso en 1A para activar 1Y, y un pulso en 2A para activar 2Y.

El código de la arquitectura del modulo puente_h se muestra en el

recuadro de código 5.2 architecture Behavioral of puente_h is begin enable<= not start; led_start<= start;

Page 87: Manual de la Basys2 Spartan 3E.pdf

pág. 87

process (sentido) begin if sentido='0' then --SENTIDO DEL MOTOR HACIA LA IZQUIERDA s1<= '1'; s2<='0'; led_sent <= '0'; else --SENTIDO DEL MOTOR HACIA LA DERECHA s1<='0'; s2<='1'; led_sent <= '1'; end if; end process; end Behavioral;

Código 5.2 - Arquitectura puente_h

Como se puede observar en la arquitectura el sentido de rotación del

motor se controla a través de la sentencia if que manda un pulso en alto o bajo a las salidas s1 y s2 las cuales se conectarán al puente H en las entradas 1A y 2A. El enable controla el encendido y apagado del motor habilitando el chip.

Como se utilizan 3 salidas que son conectadas a un circuito externo,

son necesarios 3 opto-acopladores. El acondicionamiento de señal propuesto se muestra en la figura 5.2.

Finalmente cheque la sintaxis, asigne pines, arme en el protoboard el

circuito externo y descargue el programa hacia la tarjeta Basys2 para comprobar el funcionamiento.

En el siguiente enlace se muestra un video del programa funcionando

sobre la tarjeta Basys2: http://youtu.be/gWH4DcUR6oQ

Page 88: Manual de la Basys2 Spartan 3E.pdf

pág. 88

Figura 5.2 Acondicionamiento de señal

Practica 6 – Sumador Aritmético con Salida a Display

A continuación se diseñará un Sumador de 3 bits con carry de

entrada; la salida del sumador será desplegada en los Leds de la Tarjeta Basys2 en código binario y a su vez en los Displays de 7 Segmentos.

Para comprender mejor el diseño del programa observe el diagrama a

bloques de la figura 6.1; como se puede observar este es un diseño de tipo estructural donde se mapea el programa de Encidende7Segmentos hacia el Top Module (Programa Maestro) Sumador_Arith.

Page 89: Manual de la Basys2 Spartan 3E.pdf

pág. 89

Figura 6.1 Diagrama a Bloques Sumador Aritmético

La entidad del Sumador Aritmético se muestra en el código 6.1; cabe

mencionar que dentro de la entidad se agregan las salidas de ánodos y segmentos para realizar posteriormente el mapeo por software.

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity Sumador_Arith is Port ( a : in STD_LOGIC_VECTOR (2 downto 0); -- dato "a" de 3

bits b : in STD_LOGIC_VECTOR (2 downto 0); -- dato "b" de 3

bits cin : in STD_LOGIC; -- Carry in de 1 bit reloj_tarjeta : in STD_LOGIC; reset : in STD_LOGIC;

segmentos : out std_logic_vector( 6 downto 0 );

-- encender display anodos : out std_logic_vector( 3 downto 0 );

-- multiplexar display suma : inout STD_LOGIC_VECTOR (5 downto 0)); -- Salida

de a + b + cin end Sumador_Arith;

Código 6.1 Entidad Sumador Aritmético

Como se observa se agregó la librería

IEEE.STD_LOGIC_UNSIGNED.ALL para poder realizar operaciones con operadores aritméticos (+, - , *, /) esta es una gran ventaja ya que ahorra código y facilita la programación. (La librería

Page 90: Manual de la Basys2 Spartan 3E.pdf

pág. 90

IEEE.STD_LOGIC_UNISGNED.ALL ya no es soportada por la IEEE por lo que se utiliza en su lugar la IEEE.NUMERIC_STD.ALL; en esta práctica se utiliza la librería IEEE.STD_LOGIC_UNISGNED.ALL por la sencillez en el manejo de los operadores aritméticos sin necesidad de castear el tipo de variable. En practicas posteriores se analizará la librería IEEE.NUMERIC_STD.ALL y como castear correctamente).

Para agregar un módulo previamente hecho y mapearlo al diseño se

necesita Inicializar el componente antes del inicio de la arquitectura (código 6.2) y después mapearlo dentro de la arquitectura (código 6.3). En esta práctica se utiliza el código Enciende7Segmentos.vhd mostrado en el recuadro de código 6.4:

COMPONENT Enciende7Segmentos PORT( valor0 : IN std_logic_vector(3 downto 0); valor1 : IN std_logic_vector(3 downto 0); valor2 : IN std_logic_vector(3 downto 0); valor3 : IN std_logic_vector(3 downto 0); reloj_50MHz : IN std_logic; reset : IN std_logic; segmentos : OUT std_logic_vector(6 downto 0); anodos : OUT std_logic_vector(3 downto 0) ); END COMPONENT;

Código 6.2 Inicialización del Componente

ETI: Enciende7Segmentos PORT MAP( valor0 =>numerobcd (3 downto 0) , valor1 => numerobcd (7 downto 4), valor2 => numerobcd(11 downto 8), valor3 => numerobcd(15 downto 12), segmentos =>segmentos , reloj_50MHz => reloj_tarjeta, reset => reset, anodos => anodos );

Código 6.3 Mapeo del Componente

entity Enciende7Segmentos is Port ( valor0 : in STD_LOGIC_VECTOR (3 downto 0); valor1 : in STD_LOGIC_VECTOR (3 downto 0); valor2 : in STD_LOGIC_VECTOR (3 downto 0); valor3 : in STD_LOGIC_VECTOR (3 downto 0); segmentos : out STD_LOGIC_VECTOR (6 downto 0); reloj_50MHz : in std_logic; reset : in std_logic;

Page 91: Manual de la Basys2 Spartan 3E.pdf

pág. 91

anodos : out std_logic_vector( 3 downto 0 ) ); end Enciende7Segmentos; architecture Behavioral of Enciende7Segmentos is signal activo : std_logic_vector( 1 downto 0 ); signal divisor : std_logic_vector( 15 downto 0 ); signal reloj_1KHz : std_logic; signal valor_aux : std_logic_vector( 3 downto 0 ); begin -- Proceso que genera una señal de 1 KHz a partir del cristal -- de 50 MHz de la tarjeta de desarrollo. process(reloj_50MHz,reset) begin if reset = '1' then divisor <= (others => '0'); reloj_1KHz <= '0'; elsif reloj_50MHz'event and reloj_50MHz = '1' then divisor <= divisor + 1; if ( divisor = 25000 ) then reloj_1KHz <= not reloj_1KHz; divisor <= ( others => '0' ); end if; end if; end process; -- Proceso que multiplexa los displays process( reloj_1KHz, reset) begin if reset = '1' then activo <= "00"; anodos <= "1111"; elsif rising_edge(reloj_1KHz) then activo <= activo + 1; case activo is when "00" => anodos <= "1110"; valor_aux <=

valor0; when "01" => anodos <= "1101"; valor_aux <=

valor1; when "10" => anodos <= "1011"; valor_aux <=

valor2; when others => anodos <= "0111"; valor_aux <=

valor3; end case;

Page 92: Manual de la Basys2 Spartan 3E.pdf

pág. 92

end if; end process; -- a -- --- -- f| g | b -- --- -- e| | c -- --- -- d -- Activa los segmentos adecuados -- Por hacer: manejar el punto decimal y ampliar a más caracteres. with valor_aux select segmentos <= -- abcdefg "1001111" when "0001", --1 "0010010" when "0010", --2 "0000110" when "0011", --3 "1001100" when "0100", --4 "0100100" when "0101", --5 "0100000" when "0110", --6 "0001111" when "0111", --7 "0000000" when "1000", --8 "0000100" when "1001", --9 "0001000" when "1010", --A "1100000" when "1011", --b "0110001" when "1100", --C "1000010" when "1101", --d "0110000" when "1110", --E "0111000" when "1111", --F "0000001" when others; --0 end Behavioral;

Código 6.4 Programa Enciende7Segmentos

Como se puede observar el Programa Enciende7Segmentos se

encarga del multiplexado de los displays para ello genera un reloj que proporciona una señal de 1khz a partir de la señal de reloj de la tarjeta Basys2 de 50Mhz, con esto inicia un proceso que lleva una cuenta a velocidad de 1khz la cual se guarda en la señal activo de 2 bits cuyo resultado multiplexea los displays de manera automática con una tasa de refresco de 1khz/4_displays = 250Hz (T=4ms).

Page 93: Manual de la Basys2 Spartan 3E.pdf

pág. 93

Figura 6.2 – Diagrama esquemático de los displays de 7 Segmentos de la Tarjeta Basys2

Como se puede observar en el código 6.2 para inicializar un

componente se utiliza la entidad del código VHDL previamente diseñado. La forma general de inicializar cualquier componente se muestra en el código 6.5.

COMPONENT Nombre_del_programa GENERIC( Variables_genericas: natural; N : integer ); PORT( Entradas : IN std_logic; Bus_Entradas : IN std_logic_vector(N downto 0); Salidas : OUT std_logic; Bus_Salidas : OUT std_logic_vector(N downto 0); ); END COMPONENT;

Código 6.5 – Inicialización de componentes (Forma General)

La forma general de mapear un componente hacia otro programa se

muestra en el código 6.6 Nombre_del mapeo: Nombre_del_programa GENERIC MAP ( Variables_genericas => , N => ) PORT MAP( Entradas => , Bus_Entradas => , -- Después del => se ingresa el

puerto, Salidas => , -- señal, constante o variable a

mapear

Page 94: Manual de la Basys2 Spartan 3E.pdf

pág. 94

Bus_Salidas => , );

Código 6.6 – Mapeo de componentes (Forma General)

A continuación se muestra el código de la arquitectura del sumador

aritmético (Código 6.7) en donde se observa la inicialización del componente Enciende7Segmentos y el Mapeo del mismo llamado ETI

architecture Behavioral of Sumador_Arith is -- Declaración de Señales Auxiliares signal A_aux, B_aux : STD_LOGIC_VECTOR (5 downto 0); -- Largo del

vector de 6 bits para porder hacer la suma signal Suma_aux: STD_LOGIC_VECTOR ( 15 downto 0 ); -- Señal auxiliar

para hacer el resize signal numerobcd : std_logic_vector( 15 downto 0 ); -- 16 bits para

encender los 4 displays -- Llamada al archivo componente "Enciende7Segmentos" component Enciende7Segmentos Port ( valor0 : in STD_LOGIC_VECTOR (3 downto 0); valor1 : in STD_LOGIC_VECTOR (3 downto 0); valor2 : in STD_LOGIC_VECTOR (3 downto 0); valor3 : in STD_LOGIC_VECTOR (3 downto 0); segmentos : out STD_LOGIC_VECTOR (6 downto 0); reloj_50MHz : in std_logic; reset : in std_logic; anodos : out std_logic_vector( 3 downto 0 ) ); end component; -- Función que recibe un valor binario de 16 bits y devuelve su

representación -- BCD de cuatro dígitos (16 bits). -- Usa el algoritmo de corrimiento y suma 3. function bin_a_bcd( bin : std_logic_vector(15 downto 0))

return std_logic_vector is variable i : integer := 0; variable resultado : std_logic_vector( 15 downto 0 ) :=

"0000000000000000"; variable copiabin : std_logic_vector( 15 downto 0 ) :=

bin; begin -- Aquí va el código de la función for i in 0 to 15 loop resultado( 15 downto 1 ) := resultado( 14 downto

0 ); resultado( 0 ) := copiabin( 15 ); copiabin( 15 downto 1 ) := copiabin( 14 downto 0

Page 95: Manual de la Basys2 Spartan 3E.pdf

pág. 95

); copiabin( 0 ) := '0'; -- unidades if i < 15 and resultado( 3 downto 0 ) > "0100"

then resultado( 3 downto 0 ) := resultado( 3

downto 0 ) + "0011"; end if; -- decenas if i < 15 and resultado( 7 downto 4 ) > "0100"

then resultado( 7 downto 4 ) := resultado( 7

downto 4 ) + "0011"; end if; -- centenas if i < 15 and resultado( 11 downto 8 ) > "0100"

then resultado( 11 downto 8 ) := resultado( 11

downto 8 ) + "0011"; end if; -- millares if i < 15 and resultado (15 downto 12) > "0100"

then resultado ( 15 downto 12 ) := resultado ( 15

downto 12 ) + "0011"; end if; end loop; return resultado; end bin_a_bcd; -- Inicio de la Arquitectura begin -- Utilización de los 3 LSB de "a" y "b" para hacer una Suma con

vectores de 6 bits A_aux (2 downto 0) <= a; B_aux (2 downto 0) <= b; --process (A_aux, B_aux, cin, reloj_tarjeta) --begin --if reloj_tarjeta'event and reloj_tarjeta = '1' then suma <= A_aux + B_aux + cin; --end if; --end process; suma_aux (5 downto 0) <= suma; numerobcd <= bin_a_bcd(Suma_aux);

Page 96: Manual de la Basys2 Spartan 3E.pdf

pág. 96

-- Mapeo del controlador de displays ETI: Enciende7Segmentos port map( valor0 =>numerobcd (3 downto 0) , -- unidades valor1 => numerobcd (7 downto 4), -- decenas valor2 => numerobcd(11 downto 8), -- centenas valor3 => numerobcd(15 downto 12),-- millares segmentos =>segmentos , reloj_50MHz => reloj_tarjeta, reset => reset, anodos => anodos ); end Behavioral;

Código 6.7 – Arquitectura Sumador_Arith

Dentro del código de la arquitectura se puede observar la función

bin_a_bcd la cual recibe un valor binario de 16 bits y devuelve su representación BCD de cuatro dígitos (16 bits) usando un algoritmo de corrimiento y sumando “011”.

Recordemos que las señales auxiliares, la inicialización de los

componentes y las funciones (function nombre_de_la_función) se declaran antes del inicio (begin) de la arquitectura.

El Sumador Aritmético se resume en “suma <= A_aux + B_aux +

cin;” donde se suma el dato A, el dato b y el Cin de manera mas simple. La salida suma es enviada a una señal auxiliar suma_aux de 16 bits

asignándole a los 6 bits menos significativos de suma_aux los 6 bits de suma (suma_aux (5 downto 0) <= suma); esto debido a que la función bin_a_bcd requiere un ancho de bus de 16 bits. El resultado de la función bin_a_bcd es asignado a la señal numerobcd de 16 bit, quedando de la siguiente manera el casteo de la función (numerobcd <= bin_a_bcd(Suma_aux);)

Al final se mapean las señales al componente Enciende7Segmentos

utilizando los 4 bits del bus de 16 bit de la señal numerobcd necesarios de cada display para representar las unidades, decenas, centenas y millares. Este código será de bastante utilidad para prácticas posteriores donde se necesite mostrar en valor BCD números binarios.

Page 97: Manual de la Basys2 Spartan 3E.pdf

pág. 97

Practica 7 – Unidad Aritmética Lógica (ALU)

Una Unidad Aritmética Lógica es un circuito digital que calcula operaciones aritméticas (como suma, resta, multiplicación, etc.) y operaciones lógicas (and, or, not, sll, slr, etc), entre dos números.

A continuación se diseñará una ALU con 2 entradas de 3 bits y 2

líneas de selección que permitirán elegir entre las siguientes opciones (Tabla 7.1).

Sel X Y Suma (a+b) 0 0 Multiplicación (a-b) 0 1 Corrimiento a la Izq de “a” 1 0 Corrimiento a la Der de “a” 1 1

Tabla 7.1 – Operaciones de la ALU

Se utilizará la función bin_a_bcd de la práctica anterior para mandar el

resultado de la operación hacia los displays de 7 segmentos y se utilizará el diseño estructural para mapear el programa de Salida y multiplexeo de displays (Disp_hex_mux.vhd) el cual es una versión mejorada del programa Enciende7Segmentos.vhd que incluye punto decimal (DP).

Esta vez se utilizará la librería IEEE.NUMERIC_STD.ALL y se

explicará como hacer conversión entre los tipos de datos y los casteos de salida.

El diagrama a bloques de la ALU se muestra en la figura 7.1

Figura 7.1 – Diagrama Esquemático de la ALU

Page 98: Manual de la Basys2 Spartan 3E.pdf

pág. 98

El código del programa disp_hex_mux.vhd que será mapeado hacia el top module ALU es mostrado en el recuadro de código 7.1

entity disp_hex_mux is port( clk, reset: in std_logic; hex3, hex2, hex1, hex0: in std_logic_vector (3 downto

0); dp_in: in std_logic_vector (3 downto 0); an: out std_logic_vector (3 downto 0); sseg: out std_logic_vector (7 downto 0) ); end disp_hex_mux; architecture Behavioral of disp_hex_mux is constant N : integer :=18; signal q_reg , q_next : unsigned (N-1 downto 0) ; signal sel: std_logic_vector (1 downto 0 ) ; signal hex: std_logic_vector (3 downto 0 ); signal dp: std_logic; begin -- register process (clk, reset) begin if reset = '1' then q_reg <= ( others => '0' ) ; elsif (clk'event and clk='1') then q_reg <= q_next; end if; end process; -- next-state logic for the counter q_next <= q_reg + 1; -- 2 MSBs of counter to control 4-to-1 multiplexing -- and to generate active-low enable signal sel <= std_logic_vector (q_reg(N-1 downto N-2)); process (sel, hex0, hex1, hex2, hex3, dp_in) begin case sel is when "00" => an <= "1110"; hex <= hex0; dp <= dp_in(0); when "01" => an <= "1101"; hex <= hex1;

Page 99: Manual de la Basys2 Spartan 3E.pdf

pág. 99

dp <= dp_in(1); when "10" => an <= "1011"; hex <= hex2; dp <= dp_in(2); when others => an <= "0111"; hex <= hex3; dp <= dp_in(3); end case; end process; -- hex-to-7- segment led decoding with hex select sseg (6 downto 0) <= "0000001" when "0000", "1001111" when "0001", "0010010" when "0010", "0000110" when "0011", "1001100" when "0100", "0100100" when "0101", "0100000" when "0110", "0001111" when "0111", "0000000" when "1000", "0001100" when "1001", "0001000" when "1010", --a "1100000" when "1011", --b "1110010" when "1100", --c "1000010" when "1101", --d "0011000" when "1110", --P "0111000" when others; --f --decimal point sseg(7) <= dp; end Behavioral;

Código 7.1 – disp_hex_mux (Salida a Displays y Multiplexeo)

El código completo de la ALU se muestra en el recuadro de código

7.2; tómese en cuenta el uso de la librería IEEE.NUMERIC_STD.ALL, la inicialización del componente disp_hex_mux y el mapeo del mismo, así como el uso de la función bin_a_bcd.

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity ALU is Port ( Dato_A : in STD_LOGIC_VECTOR (2 downto 0); Dato_B : in STD_LOGIC_VECTOR (2 downto 0);

Page 100: Manual de la Basys2 Spartan 3E.pdf

pág. 100

Sel : in STD_LOGIC_VECTOR (1 downto 0); clk : in STD_LOGIC;

reset : in STD_LOGIC;

segmentos : out std_logic_vector( 7 downto 0 ); --

Componente para encender display anodos : out std_logic_vector( 3 downto 0 ); --

Componente para multiplexar display Salida : out STD_LOGIC_VECTOR (5 downto 0)); end ALU; architecture Behavioral of ALU is -- Declaración de Señales Auxiliares signal a: unsigned (Dato_A'range); signal b: unsigned (Dato_B'range); signal Salida_aux: unsigned (Salida'range); signal numerobcd : unsigned( 15 downto 0 ); -- 16 bits para

encender los 4 displays --=========================================================== -- Llamada al archivo componente "disp_hex_mux" --=========================================================== COMPONENT disp_hex_mux PORT( clk : IN std_logic; reset : IN std_logic; hex3 : IN std_logic_vector(3 downto 0); hex2 : IN std_logic_vector(3 downto 0); hex1 : IN std_logic_vector(3 downto 0); hex0 : IN std_logic_vector(3 downto 0); dp_in : IN std_logic_vector(3 downto 0); an : OUT std_logic_vector(3 downto 0); sseg : OUT std_logic_vector(7 downto 0) ); END COMPONENT; --

==================================================================================

-- Función que recibe un valor binario de 16 bits y devuelve su representación

-- BCD de cuatro dígitos (16 bits). -- Usa el algoritmo de corrimiento y suma 3. function bin_a_bcd( bin : unsigned(15 downto 0)) return

unsigned is variable i : integer := 0; variable resultado : unsigned( 15 downto 0 ) :=

"0000000000000000";

Page 101: Manual de la Basys2 Spartan 3E.pdf

pág. 101

variable copiabin : unsigned( 15 downto 0 ) := bin; begin -- Código de la función for i in 0 to 15 loop resultado( 15 downto 1 ) := resultado( 14 downto

0 ); resultado( 0 ) := copiabin( 15 ); copiabin( 15 downto 1 ) := copiabin( 14 downto 0

); copiabin( 0 ) := '0'; -- unidades if i < 15 and resultado( 3 downto 0 ) > "0100"

then resultado( 3 downto 0 ) := resultado( 3

downto 0 ) + "0011"; end if; -- decenas if i < 15 and resultado( 7 downto 4 ) > "0100"

then resultado( 7 downto 4 ) := resultado( 7

downto 4 ) + "0011"; end if; -- centenas if i < 15 and resultado( 11 downto 8 ) > "0100"

then resultado( 11 downto 8 ) := resultado( 11

downto 8 ) + "0011"; end if; -- millares if i < 15 and resultado (15 downto 12) > "0100"

then resultado ( 15 downto 12 ) := resultado ( 15

downto 12 ) + "0011"; end if; end loop; return resultado; end bin_a_bcd; -- Inicio de la Arquitectura begin -- Proceso de la ALU PROCESS (a, b, Sel) BEGIN

Page 102: Manual de la Basys2 Spartan 3E.pdf

pág. 102

CASE Sel IS WHEN "00" => Salida_aux <= RESIZE(a,Salida_aux'length) +

RESIZE(b,Salida_aux'length); WHEN "01" => Salida_aux <= RESIZE((a *

b),Salida_aux'length); WHEN "10" => Salida_aux <= RESIZE((a(1 downto 0) &

a(2)),Salida_aux'length); -- Rot izq WHEN "11" => Salida_aux <= RESIZE((a(0) & a(2 downto

1)),Salida_aux'length); -- Rot derecha WHEN OTHERS => null; END CASE; END PROCESS; --Conversión de entradas Dato_A y Dato_B a unsigned y asignación a

señales auxiliares a <= UNSIGNED(Dato_A); b <= UNSIGNED(Dato_B); --Salida a Leds Salida <= std_logic_vector (Salida_aux); -- Conversión a BCD llamada a Función numerobcd <= bin_a_bcd (RESIZE (Salida_aux,numerobcd'length)); --===================================================== -- Mapeo del controlador de displays --===================================================== Inst_disp_hex_mux: disp_hex_mux PORT MAP( clk => clk, reset => reset, hex3 => std_logic_vector (numerobcd(15 downto 12)), hex2 => std_logic_vector (numerobcd(11 downto 8)), hex1 => std_logic_vector (numerobcd(7 downto 4)), hex0 => std_logic_vector (numerobcd(3 downto 0)), dp_in => "1111", an => anodos, sseg => segmentos ); end Behavioral;

Código 7.2 – ALU

Como podemos observar en el código 7.2, la selección de las

operaciones se hace con un CASE donde la entrada Sel es la referencia y

Page 103: Manual de la Basys2 Spartan 3E.pdf

pág. 103

dependiendo del valor asignado a Sel desde los switches de la tarjeta Basys2 se realiza la operación mostrada en la tabla 7.1.

La muestra del poder y versatilidad de VHDL se observa en la

multiplicación. Al multiplicar 2 números de 3 bits se necesita una salida de 6 bits para representar el número máximo que sería 7*7 = 49. Esto ocasiona una discrepancia en el ancho de los vectores; para ello se llama a la función RESIZE.

RESIZE (a, Salida_aux’lenght) Esto quiere decir que se redimensiona a de 3 bits al ancho de la señal

auxiliar salida_aux de 6 bits; de igual forma se utiliza el RESIZE para hacer el llamado de la función bin_a_bcd de un ancho de 6 bits a 16 bits sin necesidad de mandar la salida_aux a otra señal auxiliar de 16 bits y recortarla como en la práctica 6.

numerobcd <= bin_a_bcd

(RESIZE(Salida_aux,numerobcd'length)); Observe la declaración de las señales de tipo unsigned a y b; esto es

debido a que con la librería IEEE.NUMERIC_STD.ALL no se pueden hacer implícitamente operaciones aritméticas entre vectores (std_logic_vector) de las 2 entradas Dato_A y Dato_B.

signal a: unsigned (Dato_A'range); signal b: unsigned (Dato_B'range); Se asigna el contenido de Dato_A y Dato_B a las señales auxiliaries

de tipo unsigned a y b con las siguientes líneas; nótese la palabra UNSIGNED antes de la asignación que convierte de tipo std_logic_vector a Unsigned.

a <= UNSIGNED(Dato_A); b <= UNSIGNED(Dato_B); Por último analice el casteo de Salida que convierte la Salida_aux de

tipo unsigned a std_logic_vector la cual encenderá los leds de la Tarjeta Basys2. De igual forma se hace la misma conversión en las entradas hex del componente disp_hex_mux.vhd para encender los displays.

Salida <= std_logic_vector (Salida_aux);

Page 104: Manual de la Basys2 Spartan 3E.pdf

pág. 104

De esta forma se hace el manejo entre entradas o salidas de tipo std_logic_vector a señales de tipo signed o unsigned.

Para probar la ALU asigne los pines a la Tarjeta Basys2, compile y

verifique su funcionamiento. La asignación de pines se muestra en el recuadro de código 7.3

# PlanAhead Generated physical constraints NET "Dato_A[0]" LOC = P11; NET "Dato_A[1]" LOC = L3; NET "Dato_A[2]" LOC = K3; NET "Dato_B[0]" LOC = B4; NET "Dato_B[1]" LOC = G3; NET "Dato_B[2]" LOC = F3; NET "Salida[0]" LOC = M5; NET "Salida[1]" LOC = M11; NET "Salida[2]" LOC = P7; NET "Salida[3]" LOC = P6; NET "Salida[4]" LOC = N5; NET "Salida[5]" LOC = N4; NET "Sel[0]" LOC = E2; NET "Sel[1]" LOC = N3; NET "anodos[0]" LOC = F12; NET "anodos[1]" LOC = J12; NET "anodos[2]" LOC = M13; NET "anodos[3]" LOC = K14; NET "reloj_tarjeta" LOC = B8; NET "reset" LOC = G12; NET "segmentos[0]" LOC = M12; NET "segmentos[1]" LOC = L13; NET "segmentos[2]" LOC = P12; NET "segmentos[3]" LOC = N11; NET "segmentos[4]" LOC = N14; NET "segmentos[5]" LOC = H12; NET "segmentos[6]" LOC = L14; NET "segmentos[7]" LOC = N13;

Código 7.3 – Asignación de pines ALU

Nota: En algunos casos con la utilización de la librería

IEEE.NUMERIC_STD.ALL se requiere convertir variables, señales o constantes de tipo integer, real, natural, etc a unsiged o signed e incluso a std_logic_vector.

Para realizar estas conversiones tomese como referencia el siguiente

ejemplo: Se requiere desplegar en los leds de la Tarjeta Basys2 una señal de tipo natural la cual se sumará con una señal de tipo unsigned.

Leds : out std_logic_vector (7 downto 0);

Page 105: Manual de la Basys2 Spartan 3E.pdf

pág. 105

Signal a : natural; Signal a_aux : unsigned (7 downto 0); Signal b : unsigned (7 downto 0); Primero se convierte de natural a unsigned y se asigna a una señal

auxiliar a_aux a_aux <= to_unsigned (a, 8); señal_destino <= to_unsigned (señal_natural, #

número_bits_destino) Después se puede hacer la suma entre 2 señales de tipo unsigned y

después convertirla a std_logic_vector para desplegarla en la salida Leds. Leds <= std_logic_vector (a_aux + b);

Practica 8 – Elementos de Memoria (Flip-Flops) Pulsador

Un elemento de memoria es un componente que es capaz de

memorizar (guardar) un valor. Un biestable (flip-flop o latch), es un multivibrador capaz de permanecer en uno de dos estados posibles durante un tiempo indefinido en ausencia de perturbaciones.

El paso de un estado a otro se realiza variando sus entradas. Dependiendo del tipo de dichas entradas los biestables se dividen en:

-Asíncronos: sólo tienen entradas de control. El más empleado es el

biestable RS. -Síncronos: además de las entradas de control posee una entrada de

sincronismo o de reloj. Por lo general, las entradas de control asíncronas prevalecen sobre las síncronas.

En la siguiente práctica se encenderá un Led de la Tarjeta Basys2 con

un solo Push Button; por lo tanto cuando el Led se encuentre apagado y se pulse el Push Button este se encenderá y por el contrario cuando el Led se encuentre encendido este se apagará.

Para hacer esto se utilizará un Biestable T (Toggle) el cual cambia de

estado cada vez que la entrada de sincronismo de reloj se dispara mientras la entrada T está a nivel alto. Si la entrada T está a nivel bajo, el biestable retiene el nivel previo. El símbolo del Biestable T se muestra en la figura 8.1

Page 106: Manual de la Basys2 Spartan 3E.pdf

pág. 106

Figura 8.1 – Flip-Flop T

Con un biestable T es suficiente para esta aplicación, pero el dedo

humano no es tan rápido como la frecuencia de reloj de la Tarjeta Basys2 de 50Mhz, por lo tanto al presionar el Push Button el tiempo de pulsación durará muchos ciclos de reloj, y por lo tanto, el estado del biestable (Q) cambiará en todos los ciclos de reloj que se deje presionado el botón; al soltar el Push Button el estado final del biestable será aleatorio según se haya mantenido pulsado el botón durante un número par o impar de ciclos de reloj.

Para solucionar este problema se debe implementar un Circuito

Detector de Flancos el cual será útil cada vez que se necesite hacer interfaces humanas con diseños síncronos. En una señal digital, se denomina flanco a la transición del nivel bajo al alto (flanco de subida) o de nivel alto al bajo (flanco de bajada).

El circuito Detector de Flancos se puede realizar mediante 2 registros

de desplazamiento (Biestables D). Cuando se pulse el Push Button de la Tarjeta Basys2 la señal será almacenada por el primer Biestable D (Reg1) y su salida pasa al segundo Biestable D (Reg2) cuya salida es negada e ingresada junto con la salida del Primer Biestable D (Reg1) a una compuerta AND. Como resultado se obtendrá una salida que durará un ciclo de reloj que servirá como entrada al Biestable T (Figura 8.2) que en vez de recibir el pulso directamente de los Push Buttons de la Tarjeta Basys2 obtendrá una señal filtrada de 1 ciclo de reloj que encenderá o apagará el Led según sea el caso.

Figura 8.2 – Detector de Flancos conectado a Biestable T

Page 107: Manual de la Basys2 Spartan 3E.pdf

pág. 107

Observe la simulación del circuito Detector de flancos. Cuando la

entrada btn0 pasa de bajo a alto btn0_reg1 y btn0_reg2 lo hacen también. Recuerde que estas 2 señales ingresan a una compuerta AND por lo tanto se tiene una salida pulso_btn0 de 1 ciclo de reloj (Figura 8.3)

Figura 8.3 – Simulación Detector de Flancos

El código VHDL del circuito es mostrado en el recuadro de código 8.1

donde se puede observar la implementación del circuito detector de flancos basado en Biestables tipo D y la “memoria” Biestable tipo T.

entity Pulsador_Memoria is Port ( BTN0 : in STD_LOGIC; Clk : in STD_LOGIC; Reset : in STD_LOGIC; LD0 : out STD_LOGIC); end Pulsador_Memoria; architecture Behavioral of Pulsador_Memoria is signal BTN0_REG1, BTN0_REG2, PULSO_BTN0, Q_T : std_logic; begin --================================================================== -- Detector de Flancos --================================================================== Process (Reset, Clk) begin if Reset = '1' then

Page 108: Manual de la Basys2 Spartan 3E.pdf

pág. 108

BTN0_REG1 <= '0'; BTN0_REG2 <= '0'; elsif Clk'event and Clk='1' then BTN0_REG1 <= BTN0; BTN0_REG2 <= BTN0_REG1; end if; end process; PULSO_BTN0 <= '1' when (BTN0_REG1 = '1' and (not BTN0_REG2='1'))

else '0'; --================================================================== -- Biestable T --================================================================== biest_T: Process (Reset, Clk) begin if Reset = '1' then Q_T <= '0'; elsif Clk'event and Clk='1' then if PULSO_BTN0 = '1' then –- Si el pulso del boton = ‘1’ Q_T <= NOT Q_T; -- Enciende o Apaga. End if; end if; end process; LD0 <= Q_T; end Behavioral;

Código 8.1 – Pulsador_Memoria

Para probar el programa Pulsador_Memoria asigne los pines a la Tarjeta Basys2 con Plan Ahead, compile y baje el programa al FPGA para verificar su funcionamiento.

Practica 9 – Maquinas de Estados Finitos (FSM)

Se denomina máquina de estados a un modelo de comportamiento de un sistema con entradas y salidas, en donde las salidas dependen no solo de las señales de entrada actuales sino también de las anteriores. Una maquina de estados Finitos es usada para modelar sistemas que transitan a través de un numero finito de estados internos.

El diagrama a bloques básico de una FMS (Figura 9.1) consiste de un

Registro de estado, Lógica de Estado Siguiente y Lógica de Salida. Una FSM

Page 109: Manual de la Basys2 Spartan 3E.pdf

pág. 109

es conocida como Maquina de Moore si su salida esta en función solo del Estado actual, y es conocida como Maquina de Mealy si su salida esta en función del Estado Actual y una Entrada externa.

Figura 9.1 - Diagrama a Bloques de FSM

De ahora en adelante para la comprensión de los programas que

utilicen Máquinas de estados, Registros de Estado y lógica de Estado Siguiente se utilizará:

Estado Actual => State_reg Estado Siguiente => State_next Para representar una FSM generalmente se utiliza un Diagrama de

Estados (State diagram) o una Tabla ASM (ASM chart – Algorithmic State Machine chart). Ambos capturan las entradas, salidas, estados y transiciones de la FSM en una representación gráfica.

Practica 9.1 – Encendido de Led Basado en FSM con Pulsador

En esta práctica se encenderá un Led de la Tarjeta Basys2 por medio de un PushButton de igual forma que en la práctica 10 pero esta vez utilizando Maquinas de Estados Finitos (FSM)

Para comprender mejor el funcionamiento observe el Diagrama de

Estados del FSM_Led

Page 110: Manual de la Basys2 Spartan 3E.pdf

pág. 110

Figura 9.2 – Diagrama de Estados FSM_Led

Como claramente se observa en el Diagrama de Estados, al

encontrarse en el Estado LED_OFF (state_reg) y obtener un ‘1’ desde el PushButton de la Tarjeta Basys2 se pasa al siguiente estado (state_next) LED_ON encendiendo el Led, por el contrario si se encuentra en el estado LED_OFF y se obtiene un ‘0’ desde el PushButton, se permanece en el mismo estado y el Led no se enciende. Al encontrarse en el estado LED_ON y obtener un ‘0’ desde el PushButton, el Estado siguiente permanece en LED_ON; por el contrario, si el PushButton envía un ‘1’ se cambia al estado LED_OFF apagando el Led.

En otras palabras el Led enciende con un pulso del botón y se apaga

con otro pulso del mismo botón. El diagrama a bloques del circuito se muestra en la Figura 9.3

Figura 9.3 – Diagrama a bloques FSM_Led

Por lo tanto basado en la figura 9.3 la entidad del programa quedaría

de la siguiente manera:

Led_ OFF

Led_ON

Push = ‘1’

Push = ‘1’

Push = ‘0’ Push = ‘0’

Led0 <= ‘0’ Led0 <= ‘1’

Page 111: Manual de la Basys2 Spartan 3E.pdf

pág. 111

entity FSM_Led is Port ( Push: in STD_LOGIC; Clk : in STD_LOGIC; Reset : in STD_LOGIC; Led0 : out STD_LOGIC); end FSM_Led;

Código 9.1 – Entidad FSM_Led

Para representar los estados de la FSM se utiliza una enumeración de

Tipo de Datos TYPE, en donde se asigna un nombre a la enumeración seguido de los estados que se utilizarán.

TYPE nombre_de_la_enumeración is (Estado1, Estado2, EstadoN); TYPE estados_led is (LED_OFF, LED_ON); De este modo se crean 2 estados LED_OFF y LED_ON mostrados en

el Diagrama de la Figura 9.2 Teniendo la enumeración se crean las señales del registro de Estados

las cuales serán un componente de la enumeración creada. Signal state_reg, state_next : estados_led; Para que la FSM funcione se necesitan de dos procesos, un proceso

que actualice y guarde el Estado del Registro cada pulso de Reloj de la Tarjeta Basys2 (Código 9.2 State Register) y un proceso que obtenga el estado siguiente y mande la acción de control hacia las salidas (Código 9.3 Next-State logic and output logic).

--========================================================== -- Proceso que actualiza y guarda el estado del registro --========================================================== P_SEQ_FSM: Process (Reset, Clk) begin if Reset = '1' then state_reg <= LED_OFF; elsif Clk'event and Clk='1' then state_reg <= state_next; end if; end process;

Código 9.2 - State Register

--

===================================================================== --Proceso que obtiene el estado siguiente y salidas (next-state

logic) --

=====================================================================

Page 112: Manual de la Basys2 Spartan 3E.pdf

pág. 112

P_COMB_ESTADO: Process (state_reg, Push_tick) begin state_next <= state_reg; -- condicion de inicio y regreso a

estado actual Led0 <= '0'; case state_reg is when LED_OFF => if Push_tick = '1' then state_next <= LED_ON; Led0 <= '1'; else state_next <= LED_OFF; Led0 <= '0'; end if; when LED_ON => if Push_tick = '1' then state_next <= LED_OFF; Led0 <= '0'; else state_next <= LED_ON; Led0 <= '1'; end if; end case; end process;

Código 9.3 – Next-State Logic and Output Logic

Las condiciones del cambio de estado se implementan por medio de

un CASE que depende del estado actual del Registro (State_reg). Es una buena práctica de programación inicializar los estados y mandar a su condición predeterminada las salidas (en este caso el Led apagado) dentro del proceso de cambio de Estados.

state_next <= state_reg; Led0 <= '0'; No olvide el circuito Detector de Flancos necesario para las interfaces

humanas el cual solo entregará un pulso cada que se presione el botón. El código completo de la arquitectura es mostrado en el recuadro de

código 9.4. (Observe el circuito detector de flancos y la creación de las señales auxiliares). Compile y pruebe su funcionamiento.

architecture Behavioral of FSM_Led is -- Enumeración Type para la FSM ... (Enumeracion de los Estados) -- El tipo enumerado siguiente nos permite asignar los valores

Page 113: Manual de la Basys2 Spartan 3E.pdf

pág. 113

LED_OFF y LED_ON a -- las señales que se declaren del tipo estados_led. type estados_led is (LED_OFF, LED_ON); -- Señales para el programa (ojo que son componente de la

enumeración XD) signal state_reg, state_next : estados_led; signal btn_reg : std_logic; signal Push_tick : std_logic; begin --=================================== --Detector de Flancos --=================================== process(clk) begin if (clk'event and clk='1') then btn_reg <= Push; end if; end process; Push_tick <= (not btn_reg) and Push; --========================================================== -- Proceso que actualiza y guarda el estado del registro --========================================================== P_SEQ_FSM: Process (Reset, Clk) begin if Reset = '1' then state_reg <= LED_OFF; elsif Clk'event and Clk='1' then state_reg <= state_next; end if; end process; --

===================================================================== --Proceso que obtiene el estado siguiente y salidas (next-state

logic) --

===================================================================== P_COMB_ESTADO: Process (state_reg, Push_tick) begin state_next <= state_reg; -- condicion de inicio y regreso a

estado actual Led0 <= '0'; case state_reg is when LED_OFF => if Push_tick = '1' then state_next <= LED_ON;

Page 114: Manual de la Basys2 Spartan 3E.pdf

pág. 114

Led0 <= '1'; else state_next <= LED_OFF; Led0 <= '0'; end if; when LED_ON => if Push_tick = '1' then state_next <= LED_OFF; Led0 <= '0'; else state_next <= LED_ON; Led0 <= '1'; end if; end case; end process; end Behavioral;

Código 9.4 – Arquitectura FSM_Led

Practica 9.2 – Rotación de Leds Basado en FSM con Pulsador

En esta práctica se pretende que los Leds de la tarjeta Basys2 se enciendan 1 tras otro y roten en ambos sentidos (Izquierda o Derecha).

Con un pulso de un PushButton de la tarjeta se cambiará el sentido de

rotación de Izquierda a Derecha y al presionar de nuevo se cambiará el sentido de Derecha a Izquierda. Además con otro PushButton se podrá Pausar o Continuar la rotación.

Para hacer esto hay que basarse en el Programa anterior de la

Práctica 9.1 donde los PushButtons dejan “Memorizado” su pulso, esto significa que con un pulso se obtiene un ‘1’ y al volver a presionar un ‘0’. Nuevamente es necesario el diseño estructural para poder Mapear y Castear los módulos. El Diagrama a bloques del circuito es mostrado en la figura 9.4

Page 115: Manual de la Basys2 Spartan 3E.pdf

pág. 115

Figura 9.4 – Diagrama a Bloques Esquemático FSM_Rot_Led

Para comprender el funcionamiento de la FSM observe el Diagrama

de estados de la figura 9.5

Figura 9.5 – Diagrama de estados FSM_Rot_Led

Dependiendo del valor de Dir los Leds rotarán hacia la Izquierda o

hacia la Derecha. Dependiendo del valor de Pause el Led permanecerá quieto en el estado en el que se encuentre. El estado en donde se encuentre será el Led que encenderá de la tarjeta Basys2.

Cabe mencionar que los Leds rotarán a la velocidad del Reloj de la

tarjeta Basys2, por lo cual todos los Leds se verán encendidos al mismo tiempo. Esto es debido a que correrán a una frecuencia de 50Mhz (50 millones de pulsos por segundo) la cual no es visible al ojo humano.

Para solucionar este problema es necesario un divisor de frecuencia

el cual genera un Tick con un periodo de 20 ns (F = 50 Mhz) cada 0.33 segundos. (*ESTO ES MUY IMPORTANTE PARA NO GENERAR PROBLEMAS CON LOS TIEMPOS YA QUE NO SE PUEDE UTILIZAR LA FUNCION clk’event and clk=’1’ CON UNA SEÑAL DIFERENTE QUE NO SEA LA DEL RELOJ DE LA TARJETA BASYS)

Para calcular la división de la Frecuencia utilise la siguiente ecuación:

0 2 1 3 4 5

6 7

Pause

Dir

Page 116: Manual de la Basys2 Spartan 3E.pdf

pág. 116

Donde: N = Constante de tipo Integer T = Tiempo Deseado De este modo se crea una Constante con un valor de 24 para obtener

un Tiempo de 0.33 segundos lo cual equivale a F = 1/T = 3 Hz. (3 Pulsos por segundo).

El código para lograr esta División de Frecuencia queda como se

muestra en el Recuadro de Código 9.5 constant N: integer:=24; -- 2^N * 20ns = reloj signal q_reg, q_next: unsigned (N-1 downto 0); signal Tick : std_logic; begin --=================================== --Contador que genera ticks de 0.3 seg --=================================== process (clk) begin if (Clk'event and Clk='1') then q_reg <= q_next; end if; end process; -- next-state logic q_next <= q_reg + 1; -- tick de salida Tick <= '1' when q_reg=0 else '0';

Código 9.5 – Divisor de Frecuencia

Como se puede apreciar, el divisor de Frecuencia no es más que un

Contador que incrementa en 1 un registro hasta el número 16777216 = 224. Cuando el registro vuelve a ser 0 genera un Tick que vale ‘1’ durante 20 ns.

El código que muestra el programa completo (FSM_Rot_Led) se

muestra en el recuadro de Código 9.6. Nótese el uso del diseño estructural para el Casteo del programa FSM_Led.

entity FSM_Rot_Led is Port ( Clk : in STD_LOGIC; Reset : in STD_LOGIC; Dir_ent : in STD_LOGIC;

Page 117: Manual de la Basys2 Spartan 3E.pdf

pág. 117

Pause_ent: in STD_LOGIC; Led : out STD_LOGIC_VECTOR (7 downto 0)); end FSM_Rot_Led; architecture Behavioral of FSM_Rot_Led is signal Led_aux : unsigned (7 downto 0); constant N: integer:=24; -- 2^N * 20ns = reloj signal q_reg, q_next: unsigned (N-1 downto 0); signal Tick : std_logic; signal Dir, Pause : std_logic; type estados_led is (s0,s1,s2,s3,s4,s5,s6,s7); signal state_reg, state_next : estados_led; COMPONENT FSM_Led PORT( Push : IN std_logic; Clk : IN std_logic; Reset : IN std_logic; Led0 : OUT std_logic ); END COMPONENT; begin --================================== --Mapeo para Pause y Direccion --================================== Inst_FSM_Led_Dir: FSM_Led PORT MAP( Push => Dir_ent, Clk => Clk, Reset => Reset, Led0 => Dir ); Inst_FSM_Led_Pause: FSM_Led PORT MAP( Push => Pause_ent, Clk => Clk, Reset => Reset, Led0 => Pause ); --=================================== --Contador que genera ticks de 0.3 seg --=================================== process (clk) begin if (Clk'event and Clk='1') then

Page 118: Manual de la Basys2 Spartan 3E.pdf

pág. 118

q_reg <= q_next; end if; end process; -- next-state logic q_next <= q_reg + 1; -- tick de salida Tick <= '1' when q_reg=0 else '0'; --========================================================== -- Proceso que actualiza y guarda el estado del registro --========================================================== P_SEQ_FSM: Process (Reset, Clk, Pause) begin if Reset = '1' then state_reg <= s0; elsif Pause = '1' then state_reg <= state_reg; elsif Clk'event and Clk='1' then state_reg <= state_next; end if; end process; --

===================================================================== --Proceso que obtiene el estado siguiente y salidas (next-state

logic) --

===================================================================== P_COMB_ESTADO: Process (state_reg, Tick, Dir, Pause) begin state_next <= state_reg; -- 118 ondición de inicio y regreso a

estado actual case state_reg is when s0 => Led_aux <= “00000001”; if Tick = ‘1’ then if Dir = ‘1’ then state_next <= s1; else state_next <= s7; end if; end if; when s1 => Led_aux <= “00000010”; if Tick = ‘1’ then if Dir = ‘1’ then state_next <= s2; else

Page 119: Manual de la Basys2 Spartan 3E.pdf

pág. 119

state_next <= s0; end if; end if; when s2 => Led_aux <= “00000100”; if Tick = ‘1’ then if Dir = ‘1’ then state_next <= s3; else state_next <= s1; end if; end if; when s3 => Led_aux <= “00001000”; if Tick = ‘1’ then if Dir = ‘1’ then state_next <= s4; else state_next <= s2; end if; end if; when s4 => Led_aux <= “00010000”; if Tick = ‘1’ then If Dir = ‘1’ then state_next <= s5; else state_next <= s3; end if; end if; when s5 => Led_aux <= “00100000”; if Tick = ‘1’ then if Dir = ‘1’ then state_next <= s6; else state_next <= s4; end if; end if; when s6 => Led_aux <= “01000000”; if Tick = ‘1’ then if Dir = ‘1’ then state_next <= s7; else state_next <= s5; end if; end if; when s7 => Led_aux <= “10000000”; if Tick = ‘1’ then if Dir = ‘1’ then state_next <= s0;

Page 120: Manual de la Basys2 Spartan 3E.pdf

pág. 120

else state_next <= s6; end if; end if; end case; end process; Led <= std_logic_vector (Led_aux); end Behavioral;

Código 9.6 – FSM_Rot_Led

Para lograr que la rotación se Detenga hay que hacer que

permanezca en el mismo estado cuando Pause tenga un valor de ‘1’. Dentro del Proceso que controla la actualización del Registro de estado se puede agregar esta condición.

elsif Pause = '1' then state_reg <= state_reg; Compile y Pruebe el funcionamiento del Programa con la Tarjeta

Basys2.

Práctica 10 – Circuito Anti rebotes (Debounce Circuit)

Existe un problema con los switches mecánicos de la Tarjeta Basys2 y sensores diseñados por uno mismo, al ser activados presentan más de un pulso en su señal. Esto se debe a que “rebota” de arriba hacia abajo la señal hasta que se estabiliza en un pulso positivo o negativo. En algunos casos estos “rebotes” duran hasta 20 ms y tomando en cuenta que la Tarjeta Basys2 tiene una velocidad de reloj de 20 ns ocasiona comportamientos no deseados en los diseños como saltos de cuentas, cambio a estados indeterminados o activación de actuadores en momentos erróneos.

Un circuito detector de flancos no siempre es suficiente así que al

combinarlo con un circuito anti rebotes se obtiene una señal limpia (filtrada) que elimina esos rebotes innecesarios en las transiciones de los switches o sensores.

En la figura 10.1 se representa lo que pasa al accionar un switch

mecánico, observe las pequeñas variaciones que se eliminarán antes de estabilizarse.

Page 121: Manual de la Basys2 Spartan 3E.pdf

pág. 121

Figura 10.1 – Toma de osciloscopio de un Switch

Se basará el circuito anti rebotes en una Maquina de Estados la cual

tendrá un generador de ticks de 10 ms para los estados de espera y dos estados principales (Zero y One); de esta forma se tendrá un valor de ‘0’ o ‘1’ respectivamente.

Asumiendo que la FSM esta inicialmente en el estado Zero, esta se

mueve al primer estado de espera Wait1_1 cuando el switch cambia a ‘1’. En el estado Wait1_1 la FSM espera recibir un Tick de 10 ms para pasar al siguiente estado, si dentro de este tiempo el Switch toma un valor de ‘0’, implica que la duración del ‘1’ no tardó lo demasiado y regresa al estado Zero (Hubo un rebote). La acción se repite 2 veces mas para los estados Wait1_2 y Wait1_3. La operación desde el estado One es similar excepto que la señal del switch debe ser ‘0’.

El diagrama a bloques esquemático del circuito anti rebotes se

observa en la Figura 10.2

Figura 10.2 – Diagrama Esquemático Debounce_FSM

Para entender mejor el funcionamiento observe el diagrama de

estados Debounce_FSM de la Figura 10.3.

Page 122: Manual de la Basys2 Spartan 3E.pdf

pág. 122

Figura 10.3 – Diagrama de Estados Debounce_FSM

El código VHDL que implementa el Debounce_FSM (Código 10.1) es

similar a las maquinas de estados creadas en la práctica 9, observe la implementación del generador de ticks de 10ms y la salida filtrada db que se utilizará en prácticas posteriores.

entity Debounce_fsm is Port ( clk : in STD_LOGIC; reset : in STD_LOGIC; sw : in STD_LOGIC; db : out STD_LOGIC); end Debounce_fsm; architecture Behavioral of Debounce_fsm is constant N: integer:=19; -- 2^N * 20ns = 10 ms reloj signal q_reg, q_next: unsigned (N-1 downto 0); signal m_tick: std_logic; --enumeración estados type eg_state_type is (zero, wait1_1, wait1_2, wait1_3, one, wait0_1, wait0_2, wait0_3); signal state_reg, state_next: eg_state_type; begin --===================================

Page 123: Manual de la Basys2 Spartan 3E.pdf

pág. 123

--Contador que genera ticks de 10 ms --=================================== process (clk,reset) begin if (clk'event and clk='1') then q_reg <= q_next; end if; end process; -- next-state logic q_next <= q_reg + 1; -- tick de salida m_tick <= '1' when q_reg=0 else '0'; --=================================== -- Debounce FMS --=================================== -- Registro de Estado process (clk, reset) begin if (reset = '1') then state_reg <= zero; elsif (clk'event and clk='1') then state_reg <= state_next; end if; end process; -- logica de estados y salidas process (state_reg, sw, m_tick) begin state_next <= state_reg; -- parametro default db <= '0'; -- default 0 case state_reg is when zero => if sw = '1' then state_next <= wait1_1; end if; when wait1_1 => if sw = '0' then state_next <= zero; else if m_tick = '1' then state_next <= wait1_2; end if; end if; when wait1_2 => if sw = '0' then state_next <= zero; else

Page 124: Manual de la Basys2 Spartan 3E.pdf

pág. 124

if m_tick = '1' then state_next <= wait1_3; end if; end if; when wait1_3 => if sw = '0' then state_next <= zero; else if m_tick = '1' then state_next <= one; end if; end if; when one => db <= '1'; if sw = '0' then state_next <= wait0_1; end if; when wait0_1 => db <= '1'; if sw = '1' then state_next <= one; else if m_tick = '1' then state_next <= wait0_2; end if; end if; when wait0_2 => db <= '1'; if sw = '1' then state_next <= one; else if m_tick = '1' then state_next <= wait0_3; end if; end if; when wait0_3 => db <= '1'; if sw = '1' then state_next <= one; else if m_tick = '1' then state_next <= zero; end if; end if; end case; end process; end Behavioral;

Código 10.1 – Debounce_FSM

Page 125: Manual de la Basys2 Spartan 3E.pdf

pág. 125

Practica 11 - Generación de una señal PWM

En la siguiente practica se realizará un código en VHDL con el que la

tarjeta Basys2 proporcionará una señal PWM, la cual como se sabe es útil en el control de motores de CD.

La modulación por ancho de pulso (Pulse Width Modulation PWM) de una señal o fuente de energía es una técnica en la que se modifica el ciclo de trabajo de una señal periódica (una senoidal o una cuadrada, por ejemplo), ya sea para transmitir información a través de un canal de comunicaciones o para controlar la cantidad de energía que se envía a una carga.

El ciclo de trabajo de una señal periódica es el ancho relativo de su

parte positiva en relación con el período. Expresado matemáticamente:

Donde: D es el ciclo de trabajo

es el tiempo en que la función es positiva (ancho del pulso) T es el período de la función

Figura 11.1 – Ciclo de Trabajo

La construcción típica de un circuito PWM se lleva a cabo mediante un

comparador con dos entradas y una salida. Algunos parámetros importantes de un PWM son:

La relación de amplitudes entre la señal portadora y la moduladora, siendo recomendable que la última no supere el valor pico de la portadora y esté centrada en el valor medio de ésta.

La relación de frecuencias, donde en general se recomienda que la relación entre la frecuencia de la portadora y la de señal sea de 10 a 1.

Page 126: Manual de la Basys2 Spartan 3E.pdf

pág. 126

En la figura 11.2 se muestra un primer esquema para la generación de

la señal PWM. El diseño es muy simple, mediante el módulo interfaz, el software envía la posición deseada que es almacenada en un registro, que se denominará registro de posición. El reloj del sistema incrementa un contador, de manera que se lleva la cuenta de cuántos tics de reloj han transcurrido desde que inicialmente se encontraba a cero.

Mediante un comparador se comprueba si el número de tics recibidos

es menor que la posición especificada. Esta posición, que es en realidad el ancho del pulso de la señal PWM, se expresa también en tics de reloj, por lo que mientras los tics contados sean menores que los tics del ancho del pulso, la señal de salida del comparador, L, permanecerá a nivel alto. En cuanto los tics superen este valor, la señal L se pone a cero.

F I

Figura 11.2 Diagrama a bloques generación de una señal PWM en VHDL

Como se puede observar en el diagrama a bloques, se necesitan dos

módulos: un contador y un comparador, los cuales posteriormente serán mapeados para así crear un solo modulo que contendrá los dos módulos anteriores y la señal PWM de salida.

El módulo del contador es mostrado en el recuadro de código 11.1

notese la creación de la variable cuenta y su uso. entity Contador is port ( clk : in std_logic; -- Reloj reset : in std_logic; q : out std_logic_vector (7 downto 0)); --Salida

Posición

Page 127: Manual de la Basys2 Spartan 3E.pdf

pág. 127

end Contador; architecture Behavioral of Contador is begin output: process(clk,reset) variable cuenta : std_logic_vector(7 downto 0); begin -- Actualizar la cuenta if (reset='1') then -- Reset asíncrono cuenta:=(others=>'0'); -- Inicializar contador q<=cuenta; elsif (clk'event and clk='1') then -- Flanco de subida en reloj cuenta:=(cuenta+1); -- Incrementar contador q<=cuenta; end if; end process; end Behavioral;

Código 11.1 – Módulo contador

Es recomendado utilizar la librería unsigned para poder utilizar el signo de (+) en el código, sin esta librería marcará un error al momento de checar la sintaxis del código.

Lo siguiente es diseñar un módulo de Comparación de 2 entradas de 8

bits. El código es mostrado en el recuadro de código 11.2 entity Comparador is port (opa : in std_logic_vector(7 downto 0); -- Operador A opb : in std_logic_vector(7 downto 0); -- Operador B G : out std_logic); end Comparador; architecture Behavioral of Comparador is begin process (opa, opb) begin if (opa<opb) then G <= '1'; else G <= '0'; end if; end process; end Behavioral;

Codigo 11.2 Módulo comparador

Page 128: Manual de la Basys2 Spartan 3E.pdf

pág. 128

Como se observa se tiene dos entradas de 8 bits de las cuales la primera será la salida del módulo contador y la segunda será la posición deseada por el usuario. Para hacer esta comparación solo se necesita un proceso el cual dependerá de las entradas opa y opb; cuando opa sea menor que opb entonces la señal de salida G, tomará el valor de “1”, por el contrario tomará el valor de “0”.

Por último se crea el Top Module en el cual se agregan los dos

modulos anteriores (comparador y contador) y asi se obtiene la señal PWM. A este nuevo módulo se le asignará el nombre de PWM_OUT, a continuación se muestra el código del módulo PWM_OUT (código 11.3).

entity PWM_OUT is port (pwm_pos : in std_logic_vector (7 downto 0); -- Posicion pwm_clk : in std_logic; -- Reloj pwm_reset: in std_logic; -- Reset. pwm_o : out std_logic); -- Señal PWM end PWM_OUT; architecture Behavioral of PWM_OUT is component contador is port ( clk : in std_logic; -- Reloj reset : in std_logic; q : out std_logic_vector (7 downto 0)); --Salida end component; component comparador is port ( opa : in std_logic_vector(7 downto 0); -- Operador A opb : in std_logic_vector(7 downto 0); -- Operador B G : out std_logic); end component; signal ntic : std_logic_vector (7 downto 0); -- Numero de tics de

reloj signal sg : std_logic; -- Señal G begin CONT1: contador port map (clk=>pwm_clk, q=>ntic, reset=>pwm_reset); COMP1: comparador port map (opa=>ntic, opb=>pwm_pos, G=>sg); -- Señal PWM de salida pwm_o<= sg; end Behavioral;

Código 11.3 - Módulo PWM_OUT.

Page 129: Manual de la Basys2 Spartan 3E.pdf

pág. 129

Observe que en el módulo PWM_OUT se cuenta con una señal de posición (pwm_pos), la cual es una de las entradas del comparador (Ciclo de Trabajo que el usuario desea para la señal PWM), tiene una señal de reloj (pwm_clk) con la misma frecuencia de reloj que el contador, un reset (pwm_reset) que será el mismo que el del contador y una salida (pwm_o) la cual es la salida del comparador, y en su defecto será la señal PWM deseada.

Asigne la entrada pwm_pos a los switches de la tarjeta Basys2 y la salida pwm_o a un led. Se debe notar la variación de intensidad luminosa en el led de la tarjeta.

Envie la salida de la señal PWM a un motor haciendo las

consideraciones de acondicionamiento de señal necesarias. El resultado se observa en el siguiente video a través del enlace:

http://youtu.be/Y4YPefPjxqY

Practica 12 - PWM con salida a display.

En esta práctica se generará una señal PWM como en el proyecto anterior, pero ahora el porcentaje al que se encuentra el ancho de pulso de la señal (duty cycle) será mostrado en los displays de la tarjeta, dicho ancho de pulso será manipulado por medio del usuario a través de los bits de posición.

Observese el diagrama a bloques del proyecto (figura 12.1) para

comprender mejor su funcionamiento.

Figura 12.1 Diagrama a bloques de PWM con display

Como se puede observar se necesita un módulo PWM, para ello se reutilizará el de la práctica anterior (Código 11.1, 11.2, 11.3); además, se

Page 130: Manual de la Basys2 Spartan 3E.pdf

pág. 130

necesita un módulo que se encarge de multiplexear y sacar el resultado hacia los displays, para ello se reutilizará el modulo diseñado en la práctica de la ALU (Código 7.1 – disp_hex_mux)

Con la ayuda del diseño estructural se facilita el trabajo reutilizando

pedazos de código prefabricados, cree un módulo que se encarge de la conversión de código binario de la entrada a un porcentaje proporcional que será desplegado en la salida del display. Emplee la función bin-a-bcd utilizada anteriormente para este paso. Observese el código del módulo Porcentaje

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity Porcentaje is Port ( Entrada : in STD_LOGIC_VECTOR (5 downto 0); clk : in STD_LOGIC; an: out std_logic_vector (3 downto 0); sseg: out std_logic_vector (7 downto 0)); end Porcentaje; architecture Behavioral of Porcentaje is --======================= --sEÑALES --======================= Signal Porcentaje_aux : unsigned (15 downto 0); Signal Porcentaje : unsigned (6 downto 0); Signal hex : unsigned(15 downto 0); --

===================================================================================

-- Función que recibe un valor binario de 16 bits y devuelve su representación

-- BCD de cuatro dígitos (16 bits). -- Usa el algoritmo de corrimiento y suma 3. --

===================================================================================

function bin_a_bcd( bin : unsigned(15 downto 0)) return unsigned is variable i : integer := 0; variable resultado : unsigned( 15 downto 0 ) :=

"0000000000000000"; variable copiabin : unsigned( 15 downto 0 ) := bin; begin -- Aquí va el código de la función for i in 0 to 15 loop

Page 131: Manual de la Basys2 Spartan 3E.pdf

pág. 131

resultado( 15 downto 1 ) := resultado( 14 downto 0 ); resultado( 0 ) := copiabin( 15 ); copiabin( 15 downto 1 ) := copiabin( 14 downto 0 ); copiabin( 0 ) := '0'; -- unidades if i < 15 and resultado( 3 downto 0 ) > "0100" then resultado( 3 downto 0 ) := resultado( 3 downto 0

) + "0011"; end if; -- decenas if i < 15 and resultado( 7 downto 4 ) > "0100" then resultado( 7 downto 4 ) := resultado( 7 downto 4

) + "0011"; end if; -- centenas if i < 15 and resultado( 11 downto 8 ) > "0100" then resultado( 11 downto 8 ) := resultado( 11 downto

8 ) + "0011"; end if; -- millares if i < 15 and resultado (15 downto 12) > "0100" then resultado ( 15 downto 12 ) := resultado ( 15

downto 12 ) + "0011"; end if; end loop; return resultado; end bin_a_bcd; --============================================ --Instantiation Display_Mux --============================================ COMPONENT Dis_hex_mux PORT( clk : IN std_logic; reset : IN std_logic; hex3 : IN std_logic_vector(3 downto 0); hex2 : IN std_logic_vector(3 downto 0); hex1 : IN std_logic_vector(3 downto 0); hex0 : IN std_logic_vector(3 downto 0); dp_in : IN std_logic_vector(3 downto 0); an : OUT std_logic_vector(3 downto 0); sseg : OUT std_logic_vector(7 downto 0) ); END COMPONENT; --================================== --Inicio de Arquitectura --==================================

Page 132: Manual de la Basys2 Spartan 3E.pdf

pág. 132

begin --============================================================= -- Conversión de los Porcentajes de la Entrada de los Switches --============================================================= process (Entrada) begin case Entrada is when "000000" => Porcentaje <= "0000000" ; -- 0 0% when "000001" => Porcentaje <= "0000001" ; -- 1 1% when "000010" => Porcentaje <= "0000011" ; -- 2 3% when "000011" => Porcentaje <= "0000100" ; -- 3 4% when "000100" => Porcentaje <= "0000101" ; -- 4 6% when "000101" => Porcentaje <= "0000111" ; -- 5 7% when "000110" => Porcentaje <= "0001001" ; -- 6 9% when "000111" => Porcentaje <= "0001011"; -- 7 11% when "001000" => Porcentaje <= "0001100" ; -- 8 12% when "001001" => Porcentaje <= "0001110" ; -- 9 14% when "001010" => Porcentaje <= "0001111" ; -- 10 15% when "001011" => Porcentaje <= "0010001" ; -- 11 17% when "001100" => Porcentaje <= "0010011" ; -- 12 19% when "001101" => Porcentaje <= "0010100" ; -- 13 20% when "001110" => Porcentaje <= "0010110" ; -- 14 22% when "001111" => Porcentaje <= "0010111" ; -- 15 23% when "010000" => Porcentaje <= "0011001" ; -- 16 25% when "010001" => Porcentaje <= "0011010" ; -- 17 26% when "010010" => Porcentaje <= "0011100" ; -- 18 28% when "010011" => Porcentaje <= "0011110" ; -- 19 30% when "010100" => Porcentaje <= "0011111" ; -- 20 31% when "010101" => Porcentaje <= "0100001" ; -- 21 33% when "010110" => Porcentaje <= "0100010" ; -- 22 34% when "010111" => Porcentaje <= "0100100" ; -- 23 36% when "011000" => Porcentaje <= "0100110" ; -- 24 38% when "011001" => Porcentaje <= "0100111" ; -- 25 39% when "011010" => Porcentaje <= "0101001" ; -- 26 41% when "011011" => Porcentaje <= "0101010" ; -- 27 42% when "011100" => Porcentaje <= "0101100" ; -- 28 44% when "011101" => Porcentaje <= "0101110" ; -- 29 46% when "011110" => Porcentaje <= "0101111" ; -- 30 47% when "011111" => Porcentaje <= "0110001" ; -- 31 49% when "100000" => Porcentaje <= "0110010" ; -- 32 50% when "100001" => Porcentaje <= "0110100" ; -- 33 52% when "100010" => Porcentaje <= "0110101" ; -- 34 53% when "100011" => Porcentaje <= "0110111" ; -- 35 55% when "100100" => Porcentaje <= "0111001" ; -- 36 57% when "100101" => Porcentaje <= "0111011" ; -- 37 58% when "100110" => Porcentaje <= "0111100" ; -- 38 60% when "100111" => Porcentaje <= "0111101" ; -- 39 61% when "101000" => Porcentaje <= "0111111" ; -- 40 63% when "101001" => Porcentaje <= "1000001" ; -- 41 65% when "101010" => Porcentaje <= "1000010" ; -- 42 66%

Page 133: Manual de la Basys2 Spartan 3E.pdf

pág. 133

when "101011" => Porcentaje <= "1000100" ; -- 43 68% when "101100" => Porcentaje <= "1000110" ; -- 44 69% when "101101" => Porcentaje <= "1000111"; -- 45 71% when "101110" => Porcentaje <= "1001001" ; -- 46 73% when "101111" => Porcentaje <= "1001010" ; -- 47 74% when "110000" => Porcentaje <= "1001100" ; -- 48 76% when "110001" => Porcentaje <= "1001101" ; -- 49 77% when "110010" => Porcentaje <= "1001111" ; -- 50 79% when "110011" => Porcentaje <= "1010000" ; -- 51 80% when "110100" => Porcentaje <= "1010010" ; -- 52 82% when "110101" => Porcentaje <= "1010100" ; -- 53 84% when "110110" => Porcentaje <= "1010101" ; -- 54 85% when "110111" => Porcentaje <= "1010111" ; -- 55 87% when "111000" => Porcentaje <= "1011000" ; -- 56 88% when "111001" => Porcentaje <= "1011010" ; -- 57 90% when "111010" => Porcentaje <= "1011100" ; -- 58 92% when "111011" => Porcentaje <= "1011101" ; -- 59 93% when "111100" => Porcentaje <= "1011111" ; -- 60 95% when "111101" => Porcentaje <= "1100000" ; -- 61 96% when "111110" => Porcentaje <= "1100010" ; -- 62 98% when "111111" => Porcentaje <= "1100100" ; -- 63 100% when others => Porcentaje <= "0000000" ; -- 64 end case; end process; --============================================ -- Mapeo Display_Mux --============================================ Inst_disp_hex_mux: Dis_hex_mux PORT MAP( clk => clk, reset => '0', hex3 => std_logic_vector (hex (11 downto 8)), hex2 => std_logic_vector (hex (7 downto 4)), hex1 => std_logic_vector (hex (3 downto 0)), hex0 => "1110", dp_in => "1111", an => an, sseg => sseg ); --================================ -- Salida a Display --================================ Porcentaje_aux (6 downto 0) <= Porcentaje; hex <= bin_a_bcd(Porcentaje_aux); end Behavioral;

Código 12.1 - Módulo Porcentaje.

Como se observa el código anterior es útil para mostrar el porcentaje

de ancho de pulso de la señal PWM, dicho porcentaje es introducido por el

Page 134: Manual de la Basys2 Spartan 3E.pdf

pág. 134

usuario por medio de los 6 bits de la señal entrada (El cálculo se realizó por simple regla de tres).

Ahora solo queda mapear este componente dentro del módulo PWM

para que el proyecto quede terminado, el código del proyecto ya terminado se muestra en el recuadro de código 12.2.

library IEEE; use IEEE.STD_LOGIC_1164.ALL;

use IEEE.NUMERIC_STD.ALL; entity PWM is port (pwm_pos : in std_logic_vector (5 downto 0); -- Posicion pwm_clk : in std_logic; -- Reloj pwm_reset: in std_logic; -- Reset. pwm_o : out std_logic; -- Señal PWM an: out std_logic_vector (3 downto 0); sseg: out std_logic_vector (7 downto 0)); end PWM; architecture Behavioral of PWM is --================================== -- Instalacion de Contador --================================== component contador is port (clk : in std_logic; -- Reloj reset : in std_logic; q : out std_logic_vector (5 downto 0)); --Salida end component; --================================== -- Instalacion de Comparador --================================== component comparador is port (opa : in std_logic_vector(5 downto 0); -- Operador A opb : in std_logic_vector(5 downto 0); -- Operador B G : out std_logic); end component; --================================== -- Instalacion Displays a porcentaje --================================== o algo asi? COMPONENT Porcentaje PORT( Entrada : IN std_logic_vector(5 downto 0); clk : IN std_logic; an : OUT std_logic_vector(3 downto 0); sseg : OUT std_logic_vector(7 downto 0) ); END COMPONENT;

Page 135: Manual de la Basys2 Spartan 3E.pdf

pág. 135

signal ntic : std_logic_vector (5 downto 0); -- Numero de tics de

reloj signal sg : std_logic; -- Señal G begin --================================================= --Mapeo del contador y comparador --================================================= CONT1: contador port map (clk=>pwm_clk, q=>ntic, reset=>pwm_reset); COMP1: comparador port map (opa=>ntic, opb=>pwm_pos, G=>sg); -- Señal PWM de salida pwm_o<= sg; --=================================================== --Mapeo salida a display porcentaje PWM --=================================================== Inst_Porcentaje: Porcentaje PORT MAP( Entrada => pwm_pos, clk => pwm_clk, an => an, sseg => sseg ); end Behavioral;

Código 12.2 – Módulo PWM

Como se observa solo fue mapeado el módulo de Porcentaje dentro

del módulo PWM para que este pueda mostrar el porcentaje del ancho de pulso en el display.

Finalmente Compile y Pruebe el funcionamiento del Programa con la

Tarjeta Basys2.

Practica 13 – Señal PWM con Potenciómetro.

En esta práctica se generará una señal PWM la cúal será variada a

través de un potenciómetro y se mostrará el porcentaje del ciclo de trabajo en los displays.

La señal eléctrica analógica proporcional proveniente del

potenciómetro, necesita ser previamente convertida a una señal digital que sea entendible para la tarjeta Basys2. Para ello se utilizará un convertidor analógico digital (ADC0820) de 8 bits; aunque solo se utilizarán los 6 bits

Page 136: Manual de la Basys2 Spartan 3E.pdf

pág. 136

más significativos por cuestiones de comodidad. En la figura 13.1 se muestra el diagrama del convertidor ADC0820 y en la figura 13.2 su conexión hacia la Tarjeta Basys2

Figura 13.1 – Diagrama convertidor ADC0820

El funcionamiento es sencillo; se hace variar el potenciómetro con lo

cual varia su resistencia y a su vez por ley de ohm obtenemos una variación de voltaje de 0 a 5 V. El ADC0820 se encarga de transformar ese voltaje a un valor binario (‘0’ o ‘1’) el cual es leído por la tarjeta Basys2. Dependiendo del valor binario obtenido hacemos la comparación para sacar el valor PWM deseado y el porcentaje del ciclo de trabajo que se mostrará en los displays.

Cabe mencionar que para que el ADC0820 funcione correctamente

necesita una señal de reloj. La señal de reloj de la tarjeta Basys2 es demasiado rápida para el convertidor por lo que crearemos pulsos de menor frecuencia a través de la tarjeta.

El procedimiento del generador de pulsos se muestra en el recuadro

de código 13.1. Notesé el uso de un generador de ticks de 10ms basado en el reloj de 50Mhz de la tarjeta y una FSM que manda la salida a ‘0’ o ‘1’ dependiendo del tick generado. Por lo tanto se tendrán pulsos de una duración de 100hz.

Page 137: Manual de la Basys2 Spartan 3E.pdf

pág. 137

Figura 13.2 – Conversión y Acondicionamiento de Señal

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity Contador_Ticks_10ms is Port ( clk : in STD_LOGIC; Pulso : out STD_LOGIC); end Contador_Ticks_10ms; architecture Behavioral of Contador_Ticks_10ms is constant N: integer:=19; -- 2^N * 20ns = 10 ms reloj signal q_reg, q_next: unsigned (N-1 downto 0); signal Tick : std_logic; type Sreg0_type is (Pulso_OFF, Pulso_ON); signal state_reg, state_next: Sreg0_type; begin --=================================== --Contador que genera ticks de 10 ms --=================================== process (clk) begin

Page 138: Manual de la Basys2 Spartan 3E.pdf

pág. 138

if (clk'event and clk='1') then q_reg <= q_next; state_reg <= state_next; end if; end process; -- next-state logic q_next <= q_reg + 1; -- tick de salida Tick <= '1' when q_reg=0 else '0'; Sreg0_machine: process (state_reg, Tick) begin state_next <= state_reg; -- Estado Inicial Pulso <= '0'; -- Señal Default case state_reg is when Pulso_OFF => if Tick = '1' then state_next <= Pulso_ON; Pulso <= '1'; else state_next <= Pulso_OFF; Pulso <= '0'; end if; when Pulso_ON => if Tick = '1' then state_next <= Pulso_OFF; Pulso <= '0'; else state_next <= Pulso_ON; Pulso <= '1'; end if; end case; end process; end Behavioral;

Código 13.1 Generador de pulsos

Reutilizando todos los módulos de la práctica 12 se mapea el

generador de pulsos como se muestra en el recuadro de código 13.2. entity PWM is port (pwm_pos : in std_logic_vector (5 downto 0); -- Posicion pwm_clk : in std_logic; -- Reloj

Page 139: Manual de la Basys2 Spartan 3E.pdf

pág. 139

pwm_reset: in std_logic; -- Reset. pwm_o : out std_logic; -- Señal PWM an: out std_logic_vector (3 downto 0); sseg: out std_logic_vector (7 downto 0)); end PWM; architecture Behavioral of PWM is --================================== -- Instalacion de Contador --================================== component contador is port (clk : in std_logic; -- Reloj reset : in std_logic; q : out std_logic_vector (5 downto 0)); --Salida end component; --================================== -- Instalacion de Comparador --================================== component comparador is port (opa : in std_logic_vector(5 downto 0); -- Operador A opb : in std_logic_vector(5 downto 0); -- Operador B G : out std_logic); end component; --================================== -- Instalacion Displays a porcentaje --================================== o algo asi? COMPONENT Porcentaje PORT( Entrada : IN std_logic_vector(5 downto 0); clk : IN std_logic; an : OUT std_logic_vector(3 downto 0); sseg : OUT std_logic_vector(7 downto 0) ); END COMPONENT; signal ntic : std_logic_vector (5 downto 0); -- Numero de tics de

reloj signal sg : std_logic; -- Señal G begin --================================================= --Mapeo del contador y comparador --================================================= CONT1: contador port map (clk=>pwm_clk, q=>ntic, reset=>pwm_reset); COMP1: comparador port map (opa=>ntic, opb=>pwm_pos, G=>sg); -- Señal PWM de salida pwm_o<= sg; --===================================================

Page 140: Manual de la Basys2 Spartan 3E.pdf

pág. 140

--Mapeo salida a display porcentaje PWM --=================================================== Inst_Porcentaje: Porcentaje PORT MAP( Entrada => pwm_pos, clk => pwm_clk, an => an, sseg => sseg ); --=================================================== --Mapeo Generador 10 ms --=================================================== Inst_Contador_Ticks_10ms: Contador_Ticks_10ms PORT MAP( clk => pwm_clk, Pulso => Pulso ); end Behavioral;

Código 13.2 – Señal PWM con Generador de Pulsos de 10ms

Finalmente cheque sintaxis, compile y asigne los pines necesarios

tomando en cuenta que esta vez se utilizan 6 entradas de los conectores PMod que representan los 6 bits anteriormente utilizados por los switches. Además de una salida que será utilizada por el ADC0820, la cual debe ser debidamente acondicionada.

El resultado de la práctica es mostrado en el siguiente enlace:

Practica 14 - Control de un motor debido a la señal de un sensor.

En la siguiente práctica se simulará el Control de una banda transportadora la cual detendrá o activará el motor que la hace girar una vez que el sensor que cuenta las piezas llegue a 15. Además se integra un botón de reset que regresa a 0 la cuenta y un Stop de Emergencia que detiene el proceso en cualquier momento. El número de piezas contadas se muestra en los displays de la tarjeta Basys2

Como sensor de presencia se utilizará un fotorresistor, el cual es un

componente electrónico cuya resistencia disminuye con el aumento de intensidad de luz incidente. Sus siglas son: LDR y se originan de su nombre en inglés light-dependent resistor. Su cuerpo está formado por una célula o celda y dos patillas (figura 14.1).

Page 141: Manual de la Basys2 Spartan 3E.pdf

pág. 141

Figura 14.1 - Fotorresistor

A través de un CI LM555 conectado al fotorresistor se obtendrán

señales de ‘0’ o ‘1’ cuando haya o no incidencia de luz. Esto será útil al pasar un objeto el cuál evitará el paso de luz hacia el sensor lo que indicará presencia de pieza que será contada por la tarjeta Basys2.

El diseño del sensor de presencia es mostrado en la figura 14.2

notese el uso de resistores y capacitores extras. El potenciómetro utilizado en el sensor de presencia sirve para variar la sensibilidad.

Figura 14.2 – Sensor de presencia

La señal proporcionada por el sensor debe ser acondicionada por lo

que se agrega un optoacoplador para proteger a la Tarjeta Basys2 y unos

Page 142: Manual de la Basys2 Spartan 3E.pdf

pág. 142

resistores de 1KΩ para disminuir el voltaje a 3.3V. El circuito se muestra en la figura 14.3.

Figura 14.3 Circuito para el acondicionamiento de señal, con salida hacia el FPGA.

Para comprender el código utilizado en el proyecto observe el

diagrama a bloques que se muestra en la figura 14.4

Figura 14.4 Diagrama a bloques del Proyecto

Page 143: Manual de la Basys2 Spartan 3E.pdf

pág. 143

Existe un problema con el sensor de presencia, el cual envia pulsos parasitos que afectan la cuenta. Será necesario implementar un circuito antirrebotes (debounce) como el del módulo debounce_fsm del recuadro de código 10.1 de la Práctica 10. Observe la diferencia en el recuadro de código 14.1 donde se ha agregado un detector de flancos extra llamado Flanco_Enable que será de utilidad en el siguiente módulo.

library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL;

entity Debounce_fsm is Port ( clk : in STD_LOGIC; reset : in STD_LOGIC; sw : in STD_LOGIC; Flanco_Enable : out STD_LOGIC); end Debounce_fsm; architecture Behavioral of Debounce_fsm is constant N: integer:=19; -- 2^N * 20ns = 10 ms reloj signal q_reg, q_next: unsigned (N-1 downto 0); signal m_tick: std_logic; signal db, db_reg: std_logic; --enumeración estados type eg_state_type is (zero, wait1_1, wait1_2, wait1_3, one, wait0_1, wait0_2, wait0_3); signal state_reg, state_next: eg_state_type; begin --=================================== --Contador que genera ticks de 10 ms --=================================== process (clk,reset) begin if (clk'event and clk='1') then q_reg <= q_next; end if; end process; -- next-state logic q_next <= q_reg + 1; -- tick de salida m_tick <= '1' when q_reg=0 else '0'; --=================================== -- Debounce FMS --===================================

Page 144: Manual de la Basys2 Spartan 3E.pdf

pág. 144

-- Registro de Estado process (clk, reset) begin if (reset = '1') then state_reg <= zero; elsif (clk'event and clk='1') then state_reg <= state_next; end if; end process; -- logica de estados y salidas process (state_reg, sw, m_tick) begin state_next <= state_reg; -- parametro default db <= '0'; -- default 0 case state_reg is when zero => if sw = '1' then state_next <= wait1_1; end if; when wait1_1 => if sw = '0' then state_next <= zero; else if m_tick = '1' then state_next <= wait1_2; end if; end if; when wait1_2 => if sw = '0' then state_next <= zero; else if m_tick = '1' then state_next <= wait1_3; end if; end if; when wait1_3 => if sw = '0' then state_next <= zero; else if m_tick = '1' then state_next <= one; end if; end if; when one => db <= '1'; if sw = '0' then state_next <= wait0_1; end if; when wait0_1 => db <= '1';

Page 145: Manual de la Basys2 Spartan 3E.pdf

pág. 145

if sw = '1' then state_next <= one; else if m_tick = '1' then state_next <= wait0_2; end if; end if; when wait0_2 => db <= '1'; if sw = '1' then state_next <= one; else if m_tick = '1' then state_next <= wait0_3; end if; end if; when wait0_3 => db <= '1'; if sw = '1' then state_next <= one; else if m_tick = '1' then state_next <= zero; end if; end if; end case; end process; --==================================== --Detector de Flancos --==================================== process(clk) begin if (clk'event and clk='1') then db_reg <= db; end if; end process; --db_reg <= db when m_tick = '1' else db_reg; Flanco_Enable <= ((not db_reg) and db); end Behavioral;

Código 14.1 Modulo debounce_FSM con Flanco_Enable.

Se reutilizará el módulo disp_hex_mux (Código 7.1) utilizado en la

ALU y prácticas anteriores, el cual se encarga de multiplexear y mandar la salida a los displays.

Page 146: Manual de la Basys2 Spartan 3E.pdf

pág. 146

A continuación se mapean los módulos debounce_FSM y disp_hex_mux al módulo Sensor_Prox el cual generará un pulso cada que el sensor de presencia detecte 15 piezas. Observe el uso de la función bin_a_bcd y el diseño de un contador de 4 bits necesario para la cuenta de las piezas.

library IEEE; use IEEE.STD_LOGIC_1164.ALL; --use IEEE.STD_LOGIC_UNSIGNED.ALL; use IEEE.NUMERIC_STD.ALL; entity Sensor_Prox is Port ( Sensor : in STD_LOGIC; reset: in STD_LOGIC; clk : in STD_LOGIC; Cuenta : out STD_LOGIC_VECTOR (3 downto 0); an : out STD_LOGIC_VECTOR (3 downto 0); cuenta_max: out STD_LOGIC; sseg : out STD_LOGIC_VECTOR (7 downto 0) ); end Sensor_Prox; architecture Behavioral of Sensor_Prox is --============================================ --Instantiation Antirrebotes --============================================ COMPONENT Debounce_fsm PORT( clk : IN std_logic; reset : IN std_logic; sw : IN std_logic; Flanco_Enable : OUT std_logic ); END COMPONENT; --============================================ --Instantiation Display_Mux --============================================ COMPONENT disp_hex_mux PORT( clk : IN std_logic; reset : IN std_logic; hex3 : IN std_logic_vector(3 downto 0); hex2 : IN std_logic_vector(3 downto 0); hex1 : IN std_logic_vector(3 downto 0); hex0 : IN std_logic_vector(3 downto 0); dp_in : IN std_logic_vector(3 downto 0); an : OUT std_logic_vector(3 downto 0); sseg : OUT std_logic_vector(7 downto 0)

Page 147: Manual de la Basys2 Spartan 3E.pdf

pág. 147

); END COMPONENT; --

===================================================================================

-- Función que recibe un valor binario de 4 bits y devuelve su representación

-- BCD de tres dígitos (8 bits). -- Usa el algoritmo de corrimiento y suma 3. --

===================================================================================

function bin_a_bcd( bin : unsigned(3 downto 0)) return

unsigned is variable i : integer := 0; variable resultado : unsigned( 7 downto 0 ) :=

"00000000"; variable copiabin : unsigned( 3 downto 0 ) := bin; begin -- Aquí va el código de la función for i in 0 to 3 loop resultado( 7 downto 1 ) := resultado( 6 downto 0

); resultado( 0 ) := copiabin( 3 ); copiabin( 3 downto 1 ) := copiabin( 2 downto 0 ); copiabin( 0 ) := '0'; -- unidades if i < 3 and resultado( 3 downto 0 ) > "0100"

then resultado( 3 downto 0 ) := resultado( 3

downto 0 ) + "0011"; end if; -- decenas if i < 3 and resultado( 7 downto 4 ) > "0100"

then resultado( 7 downto 4 ) := resultado( 7

downto 4 ) + "0011"; end if; -- centenas --if i < 7 and resultado( 11 downto 8 ) > "0100"

then -- resultado( 11 downto 8 ) := resultado( 11

downto 8 ) + "0011"; --end if; end loop; return resultado;

Page 148: Manual de la Basys2 Spartan 3E.pdf

pág. 148

end bin_a_bcd; --============================================ --Señales Auxiliares (Reg Reloj y cuenta) --============================================ constant N: integer:=4; -- 2^N * 20ns = 10 ms reloj signal q_reg, q_next: unsigned (N-1 downto 0); signal sensor_enable : STD_LOGIC; -- Señales Display signal hex0: unsigned (7 downto 0); begin --============================================ --Mapeo Antirrebotes --============================================ Inst_Debounce_fsm: Debounce_fsm PORT MAP( clk => clk , reset => reset, sw => Sensor, Flanco_Enable => sensor_enable ); --============================================ -- Mapeo Display_Mux --============================================ Inst_disp_hex_mux: disp_hex_mux PORT MAP( clk => clk, reset => reset, hex3 => "0000", hex2 => "0000", hex1 => std_logic_vector (hex0 (7 downto 4)), hex0 => std_logic_vector (hex0 (3 downto 0)), dp_in => "1111", an => an, sseg => sseg ); --=================================== --Contador que genera ticks de 10 ms --=================================== process (clk,reset) begin if reset = '1' then q_reg <= (others => '0'); elsif(clk'event and clk='1') then q_reg <= q_next; end if; end process;

Page 149: Manual de la Basys2 Spartan 3E.pdf

pág. 149

-- next-state logic q_next <= q_reg + 1 when (sensor_enable = '1') else q_reg; --================ --Cast de salida --================ Cuenta <= std_logic_vector (q_reg); Cuenta_max <= '1' when q_reg = 15 else '0'; --==================================== -- Salida a Displays y conversión --==================================== hex0 <= bin_a_bcd(q_reg); end Behavioral;

Código 14.2 – Módulo Sensor_Prox.

Finalmente cree un módulo llamado Motor_Sensor en el cual se agregarán el módulo Sensor_Prox. Una vez mas el diseño estructural con VHDL demuestra ser un arma escencial para el desarrollo de este proyecto y de igual forma viable para el diseño del control de procesos complejos.

El módulo Motor_Sensor se encargará por medio de una FSM de

encender y apagar el motor dependiendo de la cuenta proporcionada por el módulo Sensor_Prox; a su vez controla el stop de emergencia que detendrá el proceso cuando sea activado. Observe el cuadro de código 14.3

library IEEE; use IEEE.STD_LOGIC_1164.ALL;

use IEEE.NUMERIC_STD.ALL; entity Motor_Sensor is port ( CLK: in STD_LOGIC; Sensor: in STD_LOGIC; reset: in STD_Logic; Cuenta: out std_logic_vector (3 downto 0); an: out std_logic_vector (3 downto 0); sseg: out std_logic_vector (7 downto 0); Stop_emerg: in STD_LOGIC; Motor: out STD_LOGIC); end; architecture motor_on_arch of Motor_Sensor is -- SYMBOLIC ENCODED state machine: Sreg0

Page 150: Manual de la Basys2 Spartan 3E.pdf

pág. 150

type Sreg0_type is (Motor_OFF, Motor_ON); signal state_reg, state_next: Sreg0_type; signal cuenta_reg: std_logic; signal cuenta_flanco: std_logic; signal cuenta_max: std_logic; --========================================== --Inst Sensor_Prox --========================================== COMPONENT Sensor_Prox PORT( Sensor : IN std_logic; reset : IN std_logic; clk : IN std_logic; Cuenta : OUT std_logic_vector(3 downto 0); an : OUT std_logic_vector(3 downto 0); cuenta_max : OUT std_logic; sseg : OUT std_logic_vector(7 downto 0) ); END COMPONENT; begin --======================================== -- Mapeo Sensor_Prox --======================================== Inst_Sensor_Prox: Sensor_Prox PORT MAP( Sensor => Sensor, reset => reset, clk => CLK, Cuenta => Cuenta, an => an, cuenta_max => cuenta_max, sseg => sseg ); --========================================= --Detector de Flancos --========================================= process(CLK) begin if (CLK'event and CLK='1') then cuenta_reg <= cuenta_max; end if; end process; --db_reg <= db when m_tick = '1' else db_reg; cuenta_flanco <= ((not cuenta_reg) and cuenta_max); --==========================================

Page 151: Manual de la Basys2 Spartan 3E.pdf

pág. 151

-- Estado del Registro --========================================== Process (CLK, Stop_emerg) begin if (Stop_emerg = '1') then state_reg <= Motor_OFF; elsif CLK'event and CLK = '1' then state_reg <= state_next; end if; end process; --========================================== -- Lógica de Estado Siguiente y Salidas --========================================== Sreg0_machine: process (state_reg, cuenta_flanco) begin state_next <= state_reg; -- Estado Inicial Motor <= '0'; -- Señal Default case state_reg is when Motor_OFF => if cuenta_flanco = '1' then state_next <= Motor_ON; Motor <= '1'; else state_next <= Motor_OFF; Motor <= '0'; end if; when Motor_ON => if cuenta_flanco = '1' then state_next <= Motor_OFF; Motor <= '0'; else state_next <= Motor_ON; Motor <= '1'; end if; end case; end process; end motor_on_arch;

Código 14.3 – Módulo Motor_Sensor.

Por último haga un chequeo de sintaxis, compile y asigne los pines necesarios. Recuerde hacer el acondicionamiento de señal necesario para la entrada del sensor de presencia y la salida que controla el motor (Figura 4.1)

Page 152: Manual de la Basys2 Spartan 3E.pdf

pág. 152

Práctica 15 - Señal PWM controlada con Pushbuttons

Señal PWM que varía su ciclo de trabajo pulsando los pushbuttons de la tarjeta basys2.

Módulos Necesarios:

- Contador – Código 11.1 - Comparador – Código 11.2 - Disp_hex_mux – Código 7.1 - Contador_UP_DOWN – Código 15.2

entity pwm_unit is Port ( --pwm_pos : in STD_LOGIC_VECTOR (5 downto 0); -- BITS DE ENTRADA SWITCHES pwm_clk : in STD_LOGIC; P_up : in STD_LOGIC; P_down : in STD_LOGIC; --sal: out std_logic; --Pulso: out std_logic; --led_enable: out std_logic; --start: in std_logic; pwm_motor: out std_logic; pwm_led:out std_logic; an: out std_logic_vector (3 downto 0); sseg: out std_logic_vector (7 downto 0)); end pwm_unit; architecture Behavioral of pwm_unit is COMPONENT Contador_UP_DOWN PORT( P_up1 : IN std_logic; P_down1 : IN std_logic; clk : IN std_logic; reset : IN std_logic; cuenta : OUT std_logic_vector(7 downto 0); an : OUT std_logic_vector(3 downto 0); sseg : OUT std_logic_vector(7 downto 0) ); END COMPONENT; COMPONENT contador PORT( clk : IN std_logic; reset : IN std_logic; q : OUT std_logic_vector(7 downto 0) ); END COMPONENT; component comparador is

Page 153: Manual de la Basys2 Spartan 3E.pdf

pág. 153

port (opa : in std_logic_vector(7 downto 0); -- Operador A opb : in std_logic_vector(7 downto 0); -- Operador B G : out std_logic); end component; signal ntic : std_logic_vector (7 downto 0); -- Numero de tics de reloj --signal ntic_ms: std_logic_vector (3 downto 0); -- 8 bits menos peso de ntic --signal sg : std_logic; -- Señal G signal pwm_o : std_logic; signal pwm_pos : std_logic_vector (7 downto 0); --Inicio de Arquitectura begin --enable<= not start; --led_enable<= start; CONT1: contador port map (clk=>pwm_clk, q=>ntic, reset=> '0'); COMP1: comparador port map (opa=>ntic, opb=>pwm_pos, G=> pwm_o); Inst_Contador_UP_DOWN: Contador_UP_DOWN PORT MAP( P_up1 => P_up, P_down1 => P_down, clk => pwm_clk, reset => '0', cuenta => pwm_pos, an => an, sseg => sseg ); -- Obtener los 8 bits menos significativos del contador -- Señal PWM de salida --pwm_o <= sg; --(not ntic(8)) and (not ntic(9)) and (not ntic(10)) --and (not sg); --sal <= pwm_o; pwm_led <= pwm_o; pwm_motor <= pwm_o; end Behavioral;

Código 15.1 – Pwm_unit

Page 154: Manual de la Basys2 Spartan 3E.pdf

pág. 154

El código 15.2 es mapeado hacia el top module Pwm_unit. El contador_UP_DOWN se encarga de incrementar o disminuir una cuenta cada que obtengamos un tick de reloj y un pulso filtrado a través de un detector de flancos de los push buttons. Observe el mapeo de los demás módulos para mostrar la cuenta de 0 a 100 equivalente al porcentaje de la señal PWM en los displays y el uso de la función bin_a_bcd.

entity Contador_UP_DOWN is Port ( P_up1 : in STD_LOGIC; P_down1 : in STD_LOGIC; clk : in STD_LOGIC; reset : in STD_LOGIC; cuenta: out std_logic_vector (7 downto 0); an: out std_logic_vector (3 downto 0); sseg: out std_logic_vector (7 downto 0)); end Contador_UP_DOWN; architecture Behavioral of Contador_UP_DOWN is --signal db_reg_up1, db_reg_down1 : std_logic; --signal db_up1, db_down1 : std_logic; signal conta : natural; signal hex : unsigned (11 downto 0); constant N: integer:=22; -- 2^N * 20ns = 0.6 s reloj signal q_reg, q_next: unsigned (N-1 downto 0); signal Tick : std_logic; --=================================================================================== -- Función que recibe un valor binario de 12 bits y devuelve su representación -- BCD de tres dígitos (12 bits). -- Usa el algoritmo de corrimiento y suma 3. --=================================================================================== function bin_a_bcd( bin : unsigned(11 downto 0)) return unsigned is variable i : integer := 0; variable resultado : unsigned( 11 downto 0 ) := "000000000000"; variable copiabin : unsigned( 11 downto 0 ) := bin; begin -- Aquí va el código de la función for i in 0 to 11 loop resultado( 11 downto 1 ) := resultado( 10 downto 0 ); resultado( 0 ) := copiabin( 11 ); copiabin( 11 downto 1 ) := copiabin( 10 downto 0 );

Page 155: Manual de la Basys2 Spartan 3E.pdf

pág. 155

copiabin( 0 ) := '0'; -- unidades if i < 11 and resultado( 3 downto 0 ) > "0100" then resultado( 3 downto 0 ) := resultado( 3 downto 0 ) + "0011"; end if; -- decenas if i < 11 and resultado( 7 downto 4 ) > "0100" then resultado( 7 downto 4 ) := resultado( 7 downto 4 ) + "0011"; end if; -- centenas if i < 11 and resultado( 11 downto 8 ) > "0100" then resultado( 11 downto 8 ) := resultado( 11 downto 8 ) + "0011"; end if; -- millares --if i < 15 and resultado (15 downto 12) > "0100" then -- resultado ( 15 downto 12 ) := resultado ( 15 downto 12 ) + "0011"; --end if; end loop; return resultado; end bin_a_bcd; --============================================== --Display instansiación --============================================== COMPONENT disp_hex_mux PORT( clk : IN std_logic; reset : IN std_logic; hex3 : IN std_logic_vector(3 downto 0); hex2 : IN std_logic_vector(3 downto 0); hex1 : IN std_logic_vector(3 downto 0); hex0 : IN std_logic_vector(3 downto 0); dp_in : IN std_logic_vector(3 downto 0); an : OUT std_logic_vector(3 downto 0); sseg : OUT std_logic_vector(7 downto 0) ); END COMPONENT; begin --==================================== --Detector de Flancos

Page 156: Manual de la Basys2 Spartan 3E.pdf

pág. 156

--==================================== --process(clk) --begin -- if (clk'event and clk='1') then -- db_reg_up1 <= P_up1; -- db_reg_down1 <= P_down1; -- end if; --end process; --db_up1 <= ((not db_reg_up1) and P_up1); --db_down1 <= ((not db_reg_down1) and P_down1); --============================================= -- Generador de Ticks de 0.6 s --============================================= process (clk) begin if (clk'event and clk='1') then q_reg <= q_next; end if; end process; -- next-state logic q_next <= q_reg + 1; -- tick de salida Tick <= '1' when q_reg=0 else '0'; --============================================= -- Contador Up / Down --============================================= P_conta: Process (reset, clk) begin if reset = '1' then conta <= 0; elsif clk'event and clk='1' then if Tick = '1' and P_up1 = '1' then if conta /= 100 then conta <= conta + 1; end if; elsif Tick = '1' and P_down1 = '1' then if conta /= 0 then conta <= conta - 1; end if; end if; end if; end process;

Page 157: Manual de la Basys2 Spartan 3E.pdf

pág. 157

hex <= bin_a_bcd(to_unsigned (conta,12)); cuenta <= std_logic_vector ( to_unsigned (conta, 8)); --============================================== -- Mapeo Display --============================================== Inst_disp_hex_mux: disp_hex_mux PORT MAP( clk => clk, reset => reset, hex3 => std_logic_vector (hex (11 downto 8)), hex2 => std_logic_vector (hex (7 downto 4)), hex1 => std_logic_vector (hex (3 downto 0)), hex0 => "1110", dp_in => "1101", an => an , sseg => sseg ); end Behavioral;

Código 15.2 – Contador_UP_DOWN

Compile y Pruebe el funcionamiento del Programa con la Tarjeta Basys2.

Práctica 16 - Contador Parametrizable (Mod_m_Counter)

En la siguiente práctica se diseñará un contador parametrizable que cuenta desde 0 a m-1 y vuelve a iniciar.

El código VHDL necesario es mostrado en el recuadro de código 16.1.

Observe el uso de los parámetros genéricos los cuales pueden ser modificados en futuras instanciaciones al determinar un valor en la inicialización de componentes.

Library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; -- A mod-m counter counts from 0 to m – 1 and wraps around. -- One is M, which specifies the limit, m, and the other is N, which specifies the -- number of bits needed and should be equal to (log2*M) .

Page 158: Manual de la Basys2 Spartan 3E.pdf

pág. 158

--================================================================================== entity mod_m_counter is generic ( N: integer := 6; -- numero de bits M: integer := 40 – MOD-M ); Port ( clk : in STD_LOGIC; reset : in STD_LOGIC; max_tick : out STD_LOGIC); --q : out STD_LOGIC_VECTOR (N-1 downto 0)); end mod_m_counter; architecture Behavioral of mod_m_counter is signal r_reg: unsigned (N-1 downto 0); signal r_next: unsigned (N-1 downto 0); begin --================================================================================== --Registro cambio de estado --================================================================================== process (clk, reset) begin if (reset = ‘1’) then r_reg <= (others => ‘0’); elsif (clk’event and clk = ‘1’) then r_reg <= r_next; end if; end process; --=================================================================================== --Logica de cambio de estado --=================================================================================== r_next <= (others => ‘0’) when r_reg = (M-1) else r_reg + 1; --===========================================================================

Page 159: Manual de la Basys2 Spartan 3E.pdf

pág. 159

======== --Salida --=================================================================================== --q <= std_logic_vector (r_reg); max_tick <= ‘1’ when r_reg = (M-1) else ‘0’; end Behavioral;

Código 16.1 – Módulo mod_m_counter

Práctica 17 - FIFO Buffer

Un FIFO (first-in-first-out) buffer es un almacen “elastico” entre dos subsitemas, como se muestra en el diagrama conceptual de la figura 17.1. Cuenta con dos señales de control wr y rd, para escribir y leer respectivamente. Cuando wr se encuentra en alto, la entrada de datos es escrita en el buffer. La cabeza del FIFO buffer esta siempre disponible y puede ser leida en cualquier momento. La señal de rd funciona como una señal de “borrado”. Cuando la señal de rd se encuentra en alto, el primer dato (la cabeza) del FIFO buffer es removida y el siguiente dato se queda disponible.

La descripción del FIFO Buffer que será utilizado en prácticas

siguientes se muestra en el recuadro de código 17.1.

Figura 17.1 – Diagrama Conceptual FIFO Buffer

entity fifo is generic ( B: natural :=8 ; -- 8 Numero de Bits W: natural :=4 -- 4 Number of Address Bits ); Port ( clk : in STD_LOGIC; reset : in STD_LOGIC;

Page 160: Manual de la Basys2 Spartan 3E.pdf

pág. 160

rd : in STD_LOGIC; wr : in STD_LOGIC; w_data : in STD_LOGIC_VECTOR (B-1 downto 0); empty : out STD_LOGIC; full : out STD_LOGIC; r_data : out STD_LOGIC_VECTOR (B-1 downto 0)); end fifo; architecture Behavioral of fifo is type reg_file_type is array (2**W-1 downto 0) of std_logic_vector (B-1 downto 0); signal array_reg: reg_file_type; signal w_ptr_reg, w_ptr_next, w_ptr_succ: std_logic_vector (W-1 downto 0); signal r_ptr_reg, r_ptr_next, r_ptr_succ: std_logic_vector (W-1 downto 0); signal full_reg, empty_reg, full_next, empty_next: std_logic; signal wr_op: std_logic_vector (1 downto 0); signal wr_en: std_logic; begin --================================================================= --registro --================================================================= process (clk, reset) begin if (reset = '1') then array_reg <= (others =>(others => '0')); elsif (clk'event and clk='1') then if wr_en='1' then array_reg(to_integer(unsigned(w_ptr_reg))) <= w_data; end if; end if; end process; -- Lectura del puerta r_data <= array_reg(to_integer(unsigned(r_ptr_reg))); -- Write Enabled solo cuando FIFO no esta lleno wr_en <= wr and (not full_reg); --================================================================== -- FIFO control logic --================================================================== -- registro para leer y escribir punteros (pointers) process(clk, reset) begin if (reset = '1') then w_ptr_reg <= (others => '0');

Page 161: Manual de la Basys2 Spartan 3E.pdf

pág. 161

r_ptr_reg <= (others => '0'); full_reg <= '0'; empty_reg <= '1'; elsif (clk'event and clk='1') then w_ptr_reg <= w_ptr_next; r_ptr_reg <= r_ptr_next; full_reg <= full_next; empty_reg <= empty_next; end if; end process; -- successive pointer values w_ptr_succ <= std_logic_vector(unsigned(w_ptr_reg)+1); r_ptr_succ <= std_logic_vector(unsigned(r_ptr_reg)+1); --=================================================================== --Logica de estado siguiente --=================================================================== wr_op <= wr & rd; process (w_ptr_reg, w_ptr_succ, r_ptr_reg, r_ptr_succ, wr_op, empty_reg, full_reg) begin w_ptr_next <= w_ptr_reg; r_ptr_next <= r_ptr_reg; full_next <= full_reg; empty_next <= empty_reg; case wr_op is when "00" => -- no op when "01" => -- read if (empty_reg /= '1') then -- not empty r_ptr_next <= r_ptr_succ; full_next <= '0'; if (r_ptr_succ = w_ptr_reg) then empty_next <= '1'; end if; end if; when "10" => -- write if (full_reg /= '1') then -- not full w_ptr_next <= w_ptr_succ; empty_next <= '0'; if (w_ptr_succ = r_ptr_reg) then full_next <= '1'; end if; end if; when others => -- write /read w_ptr_next <= w_ptr_succ; r_ptr_next <= r_ptr_succ; end case; end process;

Page 162: Manual de la Basys2 Spartan 3E.pdf

pág. 162

--salidas full <= full_reg; empty <= empty_reg; end Behavioral;

Código 17.1 – Módulo FIFO

Práctica 18 – Comunicación Serial Puerto PS2 – Teclado

A través de los siguientes módulos se logra la comunicación del puerto PS2 de la tarjeta Basys2; se conecta un teclado para probarlo. El código enviado por el teclado es mostrado en los leds de la tarjeta.

Módulos:

- FIFO – Código 17.1 - Mod_m_couter – Código 16.1 - Kb_code – Código 18.1 - Kb_monitor – Código 18.2 - Key2ascii – Código 18.3 - PS2_RX – Código 18.4 - Kb_led – Código 18.5

El diagrama del conector PS2 y su conexión hacia la tarjeta Basys2 se

muestra en la figura 18.1.

Figura 18.1 – Conector PS2 Tarjeta Basys2

--============================================================================= -- PS2 keyboard last-releases key circuit --============================================================================= entity kb_code is

Page 163: Manual de la Basys2 Spartan 3E.pdf

pág. 163

generic (W_SIZE: integer := 2); -- 2^W_SIZE words in FIFO Port ( clk : in STD_LOGIC; reset : in STD_LOGIC; ps2d : in STD_LOGIC; ps2c : in STD_LOGIC; rd_key_code : in STD_LOGIC; key_code : out STD_LOGIC_VECTOR (7 downto 0); kb_buf_empty : out STD_LOGIC); end kb_code; architecture Behavioral of kb_code is constant BRK: std_logic_vector (7 downto 0):= "11110000"; -- F0 (Break Code) type statetype is (wait_brk, get_code); signal state_reg, state_next: statetype; signal scan_out, w_data: std_logic_vector (7 downto 0); signal scan_done_tick, got_code_tick: std_logic; begin --============================================================================== -- Instantiation PS2_RX_unit --============================================================================== PS2_RX_unit: entity work.PS2_RX (Behavioral) port map ( clk => clk, reset => reset, rx_en => '1', ps2d => ps2d, ps2c => ps2c, rx_done_tick => scan_done_tick, dout => scan_out); --================================================================= -- Instantiation FIFO Buffer --================================================================= fifo_key_unit: entity work.fifo (Behavioral) generic map (B => 8, W => W_SIZE) PORT MAP (clk => clk, reset => reset, rd => rd_key_code, wr => got_code_tick, w_data => scan_out, empty => kb_buf_empty, full => open, r_data => key_code); --===================================================================== -- FSM to get the scan code after F0 received --===================================================================== process (clk, reset) begin if reset = '1' then

Page 164: Manual de la Basys2 Spartan 3E.pdf

pág. 164

state_reg <= wait_brk; elsif (clk'event and clk='1') then state_reg <= state_next; end if; end process; process (state_reg, scan_done_tick, scan_out) begin got_code_tick <= '0'; state_next <= state_reg; case state_reg is when wait_brk => -- wait for F0 of Break Code if scan_done_tick = '1' and scan_out = BRK then state_next <= get_code; end if; when get_code => -- get the following scan code if scan_done_tick = '1' then got_code_tick <= '1'; state_next <= wait_brk; end if; end case; end process; end Behavioral;

Código 18.1 – Módulo kb_code

entity kb_monitor is Port ( clk : in STD_LOGIC; reset : in STD_LOGIC; ps2d : in STD_LOGIC; ps2c : in STD_LOGIC; tx : out STD_LOGIC); end kb_monitor; architecture Behavioral of kb_monitor is constant SP: std_logic_vector (7 downto 0) := "00100000"; -- blank space in ASCII type statetype is (idle, send1, send0, sendb); signal state_reg, state_next: statetype; signal scan_data, w_data: std_logic_vector (7 downto 0); signal scan_done_tick, wr_uart: std_logic; signal ascii_code: std_logic_vector (7 downto 0); signal hex_in: std_logic_vector (3 downto 0); begin --==================================================================== -- Inicializacion PS2 RECEIVER --==================================================================== PS2_RX_unit: entity work.PS2_RX (Behavioral)

Page 165: Manual de la Basys2 Spartan 3E.pdf

pág. 165

port map (clk => clk, reset => reset, rx_en => '1', ps2d => ps2d, ps2c => ps2c, rx_done_tick => scan_done_tick, dout => scan_data); --==================================================================== -- Inicializacion UART --==================================================================== UART_unit: entity work.UART (Behavioral) port map (clk => clk, reset => reset, rd_uart => '0', wr_uart => wr_uart, rx => '1', w_data => w_data, tx_full => open, rx_empty => open, r_data => open, tx => tx); --==================================================================== -- FSM para enviar 3 Caracteres ASCII --==================================================================== -- REGISTROS DE ESTADO process (clk, reset) begin if reset = '1' then state_reg <= idle; elsif (clk'event and clk = '1') then state_reg <= state_next; end if; end process; -- next state logic process (state_reg, scan_done_tick, ascii_code) begin wr_uart <= '0'; w_data <= SP; state_next <= state_reg; case state_reg is when idle => -- start when a scan code received if scan_done_tick = '1' then state_next <= send1; end if; when send1 => -- send higher hex char w_data <= ascii_code; wr_uart <= '1'; state_next <= send0; when send0 => -- send lower hex char w_data <= ascii_code; wr_uart <= '1'; state_next <= sendb; when sendb => -- send blank space char

Page 166: Manual de la Basys2 Spartan 3E.pdf

pág. 166

w_data <= SP; wr_uart <= '1'; state_next <= idle; end case; end process; --======================================================================== -- Scan code to ASCII display --======================================================================== -- se parte el codigo escaneado en 2 4-bit hex hex_in <= scan_data (7 downto 4) when state_reg = send1 else scan_data (3 downto 0); -- hex digit a Codigo ASCII with hex_in select ascii_code <= "00110000" when "0000", -- 0 "00110001" when "0001", -- 1 "00110010" when "0010", -- 2 "00110011" when "0011", -- 3 "00110100" when "0100", -- 4 "00110101" when "0101", -- 5 "00110110" when "0110", -- 6 "00110111" when "0111", -- 7 "00111000" when "1000", -- 8 "00111001" when "1001", -- 9 "01000001" when "1010", -- A "01000010" when "1011", -- B "01000011" when "1100", -- C "01000100" when "1101", -- D "01000101" when "1110", -- E "01000110" when others; -- F end Behavioral;

Código A.9 – Módulo Kb_monitor

entity key2ascii is Port ( key_code : in STD_LOGIC_VECTOR (7 downto 0); ascii_code : out STD_LOGIC_VECTOR (7 downto 0)); end key2ascii; architecture Behavioral of key2ascii is begin with key_code select ascii_code <= "00110000" when "01000101", -- 0 "00110001" when "00010110", -- 1

Page 167: Manual de la Basys2 Spartan 3E.pdf

pág. 167

"00110010" when "00011110", -- 2 "00110011" when "00100110", -- 3 "00110100" when "00100101", -- 4 "00110101" when "00101110", -- 5 "00110110" when "00110110", -- 6 "00110111" when "00111101", -- 7 "00111000" when "00111110", -- 8 "00111001" when "01000110", -- 9 "01000001" when "00011100", -- A "01000010" when "00110010", -- B "01000011" when "00100001", -- C "01000100" when "00100011", -- D "01000101" when "00100100", -- E "01000110" when "00101011", -- F "01000111" when "00110100", -- G "01001000" when "00110011", -- H "01001001" when "01000011", -- I "01001010" when "00111011", -- J "01001011" when "01000010", -- K "01001100" when "01001011", -- L "01001101" when "00111010", -- M "01001110" when "00110001", -- N "01001111" when "01000100", -- O "01010000" when "01001101", -- P "01010001" when "00010101", -- Q "01010010" when "00101101", -- R "01010011" when "00011011", -- S "01010100" when "00101100", -- T "01010101" when "00111100", -- U "01010110" when "00101010", -- V "01010111" when "00011101", -- W "01011000" when "00100010", -- X "01011001" when "00110101", -- Y "01011010" when "00011010", -- Z "01100000" when "00001110", -- ' "00101101" when "01001110", -- - "00111101" when "01010101", -- = "01011011" when "01010100", -- "01011101" when "01011011", -- "01011100" when "01011101", -- \ "00111011" when "01001100", -- ; "00100111" when "01010010", -- ´ "00101100" when "01000001", -- , "00101110" when "01001001", -- . "00101111" when "01001010", -- / "00100000" when "00101001", -- (space) "00001101" when "01011010", -- (enter, cr) "00001000" when "01100110", -- (backspace) "00101010" when others; -- *

Page 168: Manual de la Basys2 Spartan 3E.pdf

pág. 168

end Behavioral;

Código 18.2 – Módulo key2ascii

entity PS2_RX is Port ( clk : in STD_LOGIC; reset : in STD_LOGIC; ps2d : in STD_LOGIC; -- key data ps2c : in STD_LOGIC; -- key clock rx_en : in STD_LOGIC; rx_done_tick : out STD_LOGIC; dout : out STD_LOGIC_VECTOR (7 downto 0)); end PS2_RX; architecture Behavioral of PS2_RX is type statetype is (idle, dps, load); signal state_reg, state_next: statetype; signal filter_reg, filter_next: std_logic_vector(7 downto 0); signal f_ps2c_reg, f_ps2c_next: std_logic; signal b_reg, b_next: std_logic_vector (10 downto 0); signal n_reg, n_next: unsigned (3 downto 0); signal fall_edge: std_logic; begin --========================================================================= -- Filtro y detector de flancos --- ticks generados para ps2c --========================================================================= process(clk, reset) begin if reset = '1' then filter_reg <= (others => '0'); f_ps2c_reg <= '0'; elsif (clk'event and clk = '1') then filter_reg <= filter_next; f_ps2c_reg <= f_ps2c_next; end if; end process; filter_next <= ps2c & filter_reg(7 downto 1); f_ps2c_next <= '1' when filter_reg = "11111111" else '0' when filter_reg = "00000000" else f_ps2c_reg; fall_edge <= f_ps2c_reg and (not f_ps2c_next); --========================================================================= -- FSMD to extract the 8 - bit data --

Page 169: Manual de la Basys2 Spartan 3E.pdf

pág. 169

========================================================================= process (clk, reset) begin if reset = '1' then state_reg <= idle; n_reg <= (others => '0'); b_reg <= (others => '0'); elsif (clk'event and clk = '1') then state_reg <= state_next; n_reg <= n_next; b_reg <= b_next; end if; end process; -- next state logic process (state_reg, n_reg, b_reg, fall_edge, rx_en, ps2d) begin rx_done_tick <= '0'; state_next <= state_reg; n_next <= n_reg; b_next <= b_reg; case state_reg is when idle => if fall_edge = '1' and rx_en = '1' then -- shift in start bit b_next <= ps2d & b_reg (10 downto 1); n_next <= "1001"; state_next <= dps; end if; when dps => -- 8 data + 1 parity + 1 stop if fall_edge = '1' then b_next <= ps2d & b_reg (10 downto 1); if n_reg = 0 then state_next <= load; else n_next <= n_reg - 1; end if; end if; when load => -- 1 extra clock to complete the last shift state_next <= idle; rx_done_tick <= '1'; end case; end process; -- salidas dout <= b_reg (8 downto 1); -- data bits end Behavioral;

Código 18.3 – Módulo PS2_RX

Page 170: Manual de la Basys2 Spartan 3E.pdf

pág. 170

El teclado manda un código a través de los canales de datos del puerto PS2. Los códigos hexadecimales de cada tecla son mostrados en la figura 18.2.

Figura 18.2 – Códigos enviados por el teclado

Mapeamos el módulo PS2_RX (Código 18.3) hacia el top module KB_Led el cual se encargará de enviar hacia los leds de la tarjeta Basys2 el código hexadecimal de la tecla del teclado pulsada. Serán necesarios los 8 leds de la tarjeta.

entity KB_Led is Port ( clk : in STD_LOGIC; reset : in STD_LOGIC; ps2d : in STD_LOGIC; ps2c : in STD_LOGIC; leds : out STD_LOGIC_VECTOR (7 downto 0)); end KB_Led; architecture Behavioral of KB_Led is signal kb_not_empty, kb_buf_empty : std_logic; signal key_code : std_logic_vector(7 downto 0); begin kb_code_unit : entity work.kb_code(Behavioral) port map (clk => clk, reset => reset, ps2d => ps2d, ps2c => ps2c, rd_key_code => kb_not_empty, key_code => key_code, kb_buf_empty => kb_buf_empty ); kb_not_empty <= not kb_buf_empty; leds <= key_code; end Behavioral;

Código 18.4 – Módulo KB_Led

Page 171: Manual de la Basys2 Spartan 3E.pdf

pág. 171

CONCLUSIONES Y RECOMENDACIONES

Tarjeta Basys2 Viable en el control de Procesos.

Gracias al diseño e implementación de las prácticas expuestas en este documento quedó demostrado que la Tarjeta Basys2 basada en el FPGA Spartan-3E 100 K de la marca Xilinx es un opción viable para controlar procesos.

Cabe destacar que la Tarjeta Basys2 cuenta con entradas y salidas

limitadas y el proceso a implementar debe estar pensado en las capacidades de la tarjeta. Para proyectos de un volumen alto se recomienda utilizar una tarjeta de desarrollo con mayor capacidad y basada en una arquitectura FPGA superior. De igual manera se puede optar por comprar únicamente el dispositivo FPGA y hacer el PCB necesario para la producción en masa.

El diseño estructural con VHDL permite conectar módulos

prefabricados. Los alcances del FPGA Spartan-3E aun no han llegado al límite con estas prácticas y el uso de procesadores embebidos diseñados por el fabricante Xilinx como los son PicoBlaze de 8 bits y MicroBlaze de 32 bits abren un avanico de posibilidades para el manejo de datos de forma paralela y aplicaciones innovadoras de adquisición y procesamiento a gran velocidad.

El tiempo de diseño de un prototipo con la Tarjeta Basys2 es reducido

y ofrece ventajas tales como la reprogramación y reasignación de pines para hacer pruebas que permitan llegar al producto final.

Se recomienda ampliamente a los diseñadores tomar las precauciones

pertinentes respecto al acondicionamiento de las señales para no dañar la tarjeta; recuerde que los puertos PMod de E/S están protegidos contra corto circuito, pero al trabajar con valores altos de voltaje y corriente se corren riesgos importantes y no hay garantía de que no sufra daños.

La tendencia actual demuestra que el uso de FPGA’s se ha ido

incrementando con el paso de los años y las capacidades de estos aumentan de manera exponencial. A la fecha de este documento se ha roto la barrera de los 2 Tb/s de ancho de banda con un transmisor basado en los modernos Virtex-7 X690T FPGA’s. Imaginemos las posibilidades.

Page 172: Manual de la Basys2 Spartan 3E.pdf

pág. 172

REFERENCIAS BIBLIOGRÁFICAS

1 Norman S. Nise, Sistemas de Control para Ingeniería. (1a Edición), Compañía Editorial Continental, Mexico: 2004 2 Pong P. Chu, FPGA Prototyping by VHDL Examples XILINX Spartan-3 Version. (1a Edición), John Wiley & Sons Inc, Hoboken, New Jersey: 2008 3 Menéndez Ortiz María Alejandra, Arquitectura FPGA para la adquisición de Datos Térmicos. Universidad del Mar Campus Puerto Escondido Oaxaca México: 2010. 4 www.xilinx.com/support/documentation/data_sheets/ds312.pdf 5http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,400,790&Prod=BASYS2 6 Urquía Alfonso, Martín Villalba Carla, Casos prácticos de diseño de circuitos digitales con VHDL, Universidad Nacional de Educación a Distancia (UNED) Departamento de Informática y Automática, Madrid, España: 2008 7 Machado Sánchez Felipe, Borromeo López Susana, Diseño de circuitos digitales con VHDL, (Version 1.01) Departamento de Tecnología Electrónica Universidad Rey Juan Carlos; Madrid, España: 2010 8 http://www.mexchip.com/categor%C3%ADas/tutoriales/vhdl/