UNIVERSIDAD DEL BÍO-BÍO FACULTAD DE INGENIERÍA DEPARTAMENTO DE INGENIERÍA ELÉCTRICA Y ELECTRÓNICA DISEÑO DE CIRCUITOS DIGITALES A TRAVÉS DE LÓGICA PROGRAMABLE UTILIZANDO TECNOLOGÍA FPGA Y LENGUAJE VHDL AUTORES - : CLAUDIO ANTONIO TRACAYANCO SAAVEDRA. CRISTIAN DANIEL VALDÉS JARA. SEMINARIO PARA OPTAR AL TÍTULO DE INGENIERO DE EJECUCIÓN EN ELECTRÓNICA CONCEPCIÓN – CHILE 2003 AGRADECIMIENTOS He llegado a la meta, luego de varios años de estudio, y es el momento adecuado para agradecer a las personas que contribuyeron con mi desarrollo personal y que sin su apoyo me hubiera sido imposible obtener mi Título Profesional. Primero que todo, agradezco a mi amado Dios por darme vida y salud. Por su generosidad e infinito amor. Él me ha acompañado y ha sido mi amigo fiel durante toda mi vida, y sin él, definitivamente no habría logrado sacar adelante mi carrera. -1- Agradezco también a mi hermosa madre, por entregarme todo su amor y apoyo en los momentos difíciles. Gracias por entregarme los valores necesarios para ser una buena persona en la vida. Gracias por ser mi eterna amiga. A mi padre, quien ha sido un pilar fundamental en mi persona. Sin sus consejos y continuo respaldo no habría tenido ni la fuerza ni la inteligencia necesaria para lograr las metas impuestas. A mi hermano Erick, quien me enseñó que el dinero o un Título Profesional no lo son todo en la vida, gracias por ayudarme a crecer como persona. A mi abuelita Blanca, quien me recibió en su hogar durante los años que estudié en la Universidad. Y en general, gracias a toda mi familia por entregarme tanto amor. Quiero también agradecer a mi amada Derthy, por toda la motivación y por todo el apoyo que me entregó en la etapa cúlmine de este Seminario de Titulación. Gracias a los profesores guías, a los compañeros; y en general, a la Universidad del Bío-Bío por todo lo que me ha entregado. Claudio Antonio Tracayanco Saavedra. Son muchas las personas a las debo agradecer en mi carrera y en mi vida, pero quiero dedicar esta memoria a mi madre: -2- Mamá, Quiero agradecerte porque siempre haz estado a mi lado, siempre me haz dado tu cariño y siempre me apoyas con dulzura. Gracias por todo el esfuerzo y por todos los sacrificios que haz hecho por mí. Gracias por tu gran amor. Quiero dedicar esta memoria y todo lo que representa, a mi madre. Te quiero mucho y muchas gracias mamá… Cristian Daniel Valdés RESUMEN Día a día nos impresionamos con las nuevas tecnologías que se han estado desarrollando. teléfono Es móvil cualidades. Pero éste ya Todo detrás desarrollo común de nos al esté esto poco tiempo obsoleto esto todo ha que o es se permitido se que encuentra a adquirir encuentren lo llegar de un otros PC con vemos la electrónica, diseñar equipos o un mayores comúnmente. la cual tan con su increíbles. Es esta realidad la que nos impulsó a trabajar en un proyecto completamente revolucionario Nuestro actual tanto proyecto de software. diseño Tomando a tiene de la nivel por de fín circuitos iniciativa Universidad traer a digitales, dentro -3- de como nuestra tanto las a nivel Universidad en nacional. el hardware Universidades del método como en país en este Esta tema. tesis se basa diversas tecnologías produce físicamente tecnología FPGA en tres en capítulos: cuanto el a primero hardware diseño (que el de finalmente se circuitos fué la de refiere, ellos explicando digitales que presenta utilizamos y las como se presentando la en nuestra tesis) ; el segundo presenta el lenguaje de programación (VHDL) utilizado para configurar circuito de este primeros en la a FPGA, diseñar y explicando el este utilizando lenguage conjunto con lenguaje diversas finalmente la forma lenguaje de estructuras el de tendremos tercer diseñar y capítulo circuitos programación con la que describir sentencias propias fusiona los digitales el dos trabajando tecnología FPGA. Como el propósito de esta tesis iba mas allá de la teoría fue necesario que el Departamento comprara una tarjeta de entrenamiento basada en tecnología FPGA. La tarjeta comprada a la empresa Xilinx (EEUU) es la XSA-50, además incluía los programas necesarios para trabajar con ella. Con todo lo necesario para trabajar se hicieron tres circuitos a modo de ejemplo los detalladamente, cuales están paso a en un paso anexo como de trabajar la tesis con la presentando tarjeta de entrenamiento y con los programas complementarios. Como segundo anexo se presentan las características de la tarjeta XSA-50 de Xilinx. Despues de haber trabajado con todos estos conceptos, no se podía poner otro título a esta tesis que no fuera... " DISEÑO DE CIRCUITOS DIGITALES A TRAVÉS DE LÓGICA PROGRAMABLE UTILIZANDO TECNOLOGÍA FPGA Y LENGUAJE VHDL" Finalmente cabe señalar que el objetivo de esta tesis es que la persona -4- que la lea pueda comprender la metodología actual de diseño y sea capaz de serán diseñar capaces algunos de circuitos decir si básicos...por se logró lo el cual objetivo sólo los lectores de los autores. INTRODUCCIÓN El diseño de circuitos digitales ha sufrido últimamente una fuerte evolución, dejando atrás las grandes cantidades de circuitos integrados y conexiones tanto en protoboard como en placas de circuito impreso, utilizadas en la realización de diseños de circuitos digitales de grande y mediana complejidad, para reemplazarlos actualmente por dispositivos de lógica programable junto con lenguajes de descripción de hardware, esto por su facilidad, rapidez y bajos costos entre algunas de sus características más relevantes. Dentro de la familia de dispositivos de lógica programable, la tecnología FPGA se presenta como una de las mejores alternativas para el diseño de circuitos digitales. En base a su capacidad de implementación que actualmente llega a las 300.000 compuertas lógicas y a su capacidad y facilidad de reconfiguración por parte del usuario. Por otro lado, para trabajar con tecnología FPGA es posible utilizar lenguajes de descripción de hardware HDL, destacándose entre los existentes VHDL por su carácter de estándar de la IEEE, lo cual le da ciertas ventajas sobre el resto de los lenguajes. Hoy en día las Universidades más prestigiosas del mundo, en cuanto al área de electrónica se refiere, están trabajando con tecnología FPGA, desarrollando sistemas -5- prototipos sobre tarjetas de entrenamiento que ofrecen las empresas fabricantes de FPGA’s, aplicando esta tecnología sobre campos como visión artificial, audio digital, procesamiento digital de señales, electrónica de potencia, comunicaciones y en general en cualquier área que utilice la electrónica digital. Actualmente, nuestra carrera de Ingeniería de Ejecución en Electrónica no incluye dentro de su malla curricular un ramo que aborde el diseño de circuitos utilizando esta tecnología; de hecho, los dispositivos de lógica programable sólo se estudian en forma básica por razones de tiempo y capacidad. Por esta razón, y por la importancia que está tomando actualmente la tecnología FPGA, es que se ha propuesto como principal objetivo de este Seminario de Titulación, dar a conocer las ventajas de utilizar esta tecnología en el diseño de circuitos digitales, presentando una descripción de los circuitos integrados FPGA y del lenguaje VHDL y, en forma completa, el diseño de algunos circuitos. Todo esto con la intención de motivar a los alumnos del Departamento a trabajar con estas herramientas, lo cual daría un gran impulso a la formación tecnológica de nuestra carrera. Como segundo objetivo, está el motivar a otros profesores a trabajar con esta tecnología en proyectos y prototipos de mayor envergadura; aplicándola a las distintas áreas de la electrónica, como las mencionadas anteriormente. Para poder lograr los objetivos, se ha dividido este Seminario en tres capítulos más dos anexos. El primer capítulo explica la tecnología FPGA, dando a conocer sus características principales. El segundo capítulo, es una descripción del lenguaje VHDL; aquí se verán sus comienzos, estructuras y sentencias básicas. Y finalmente, en el tercer capítulo, se muestra a través de ejemplos el proceso completo de diseño de circuitos digitales utilizando tecnología FPGA y lenguaje VHDL en conjunto. El primer documento anexo presenta el diseño de tres circuitos digitales de complejidad media-baja. Y el segundo documento anexo, es un resumen de las características principales de la tarjeta de entrenamiento XSA-50 de la empresa XESS CORP. -6- CAPÍTULO 1: TECNOLOGÍAS DE LÓGICA PROGRAMABLE -7- EXISTENTES EN EL MERCADO 1.1 Introducción Este capítulo tiene por objetivo presentar tecnologías de lógica programables que actualmente se emplean como herramientas de trabajo para el diseño de circuitos digitales. Se comenzará dando una breve descripción del desarrollo de circuitos digitales y una descripción de elementos de lógica programable. Luego se presentarán por separado, las tecnologías de los circuitos integrados CPLD y FPGA. Se pretende llegar a una comprensión del método de trabajo con estas tecnologías y de esta manera poder proyectar su función dentro de todo el sistema de diseño de circuitos digitales que se presenta en este seminario. Tanto los circuitos integrados CPLD´s como las FPGA´s, están cambiando la manera en que los diseñadores de sistemas implementan lógica digital. Reducen radicalmente los costos y el tiempo de desarrollo para implementar miles de compuertas lógicas. Proveen una nueva capacidad que afecta la industria al mejorar la forma en que son diseñados los circuitos digitales. La característica común de estas tecnologías y que marca la diferencia en la metodología de diseño, es su capacidad de adaptar el hardware a un algoritmo (software), donde va contenida la información lógica que da solución a problemas específicos. Además, es posible reconfigurar estos circuitos integrados de modo que pueden ser modificados para incluir nuevas funciones e instrucciones diseñadas para dar solución a un nuevo problema. -8- 1.2 Desarrollo de circuitos digitales El primer transistor vio la luz en los laboratorios Bell en 1947 y fue creado por John Bardeen, Walter Brattain y William Shockley quienes posteriormente, en 1954, obtuvieron el premio Nobel por su desarrollo. El circuito integrado o CHIP, fue patentado con el nombre de circuito sólido en febrero de 1959. Se desarrolló un circuito construido en base a un conjunto de transistores y otros componentes ubicados en una pieza única de material semiconductor, donde ellos son conectados con delgadas líneas de metal. En 1958 Jack Kilby, de la empresa Texas Instruments, mostró que era posible fabricar un circuito integrado simple en germanio, un semiconductor comúnmente usado en ese tiempo. Casi al mismo tiempo, Robert Noyce mostró como un circuito integrado puede ser fabricado en silicio usando dióxido de silicio como el aislador y aluminio para las líneas metálicas. Pese a suponer toda una revolución, no procuró ningún premio a Jack Kilby. Noyce y Kilby son considerados co-inventores del circuito integrado. El primer Chip apareció en el mercado en 1961. En 1964 algunos chips ya contenían 32 transistores. 1.2.1 Circuitos digitales Los circuitos digitales trabajan con dígitos binarios o bits. Un bit tiene un valor 0 o 1. De los fenómenos físicos empleados para representar los estados de un bit, un estándar es la tecnología TTL (Transistor-Transistor Logic); en ella, se usa un nivel de voltaje desde 0 a 0.8 volts para denotar el 0 lógico y de 2.0 a 5.0 volts para denotar un 1 lógico. Para la utilización de los bits se emplean los operadores y las Tablas de verdad del álgebra de Boole. -9- Los elementos lógicos de los sistemas digitales son fabricados como circuitos integrados. Se ha observado un gran desarrollo en la fabricación de circuitos integrados desde sus comienzos. Este desarrollo se manifiesta en la cantidad de compuertas lógicas y flip-flops que son implementados dentro de un circuito integrado individual. En la década de los sesenta se construía lógica discreta, circuitos integrados que contenían un pequeño número de compuertas lógicas individuales o flip-flops. A este tipo de circuitos se les conoce como CI de integración de pequeña escala o SSI (Small Scale Integration). Era común que se generaran problemas cuando se trabajaba en diseño con circuitos integrados SSI debido a que los sistemas son construidos utilizando grandes cantidades de circuitos integrados individuales que se conectan mediante demasiados conductores entre ellos. Era difícil modificar el sistema una vez que estaba construido, incluso era difícil recordar por qué se utilizaba y como estaba cableado cada uno de los componentes. Una vez que el sistema había sido armado, cualquier cambio requería una gran cantidad de tiempo para poder ser reconfigurado. Los fabricantes de circuitos integrados lograron crear circuitos integrados con más componentes en su interior. A medida que los circuitos integrados contienen mayor cantidad de componentes, reciben diferentes clasificaciones. Los circuitos integrados MSI (Medium Scale Integration) contienen típicamente de 10 a 100 compuertas individuales, los LSI (Large Scale Integration) y VLSI (Very Large Scale Integration) pueden contener más de 100.000 dispositivos como transistores o diodos, donde una compuerta lógica puede llegar a usar cinco dispositivos pero una celda de memoria puede llegar a usar solo uno. - 10 - 1.2.2 Dispositivos de lógica programable La lógica programable, como el nombre implica, es una familia de componentes que contienen conjuntos de elementos lógicos (AND, OR, NOT, LATCH, FLIP-FLOP) que pueden configurarse en cualquier función lógica que el usuario desee y que el componente soporte. Hay varias clases de dispositivos lógicos programables: ASIC´s, PLD´s donde encontramos PLA´s, PROM´s, PAL´s, GAL´s, CPLD´s y FPGA´s. A continuación se describirán brevemente cada uno de ellos, dejando aparte a los dispositivos CPLD y FPGA para verlos posteriormente con mas detalle. ¾ ASIC ASIC significa Circuitos Integrados de Aplicación Específica. Estos dispositivos están diseñados de acuerdo a las necesidades de la función específica que van a desarrollar. Se fabrican especialmente por lo que es necesario requerir una cantidad lo suficientemente grande que justifique el alto costo inicial que implica su construcción. Los ASICs, al contrario que otros dispositivos, pueden contener funciones analógicas, digitales, y combinaciones de ambas. En general, no son reprogramables por el usuario. Esto significa que los fabricantes configurarán el dispositivo según las especificaciones pero éstas no se podrán modificar. Se usan para combinar una gran cantidad de funciones lógicas en un dispositivo. ¾ PLD PLD significa Dispositivo Lógico Programable (Programmable Logic Device) y es aquel que contiene una arquitectura general pre-definida en la que el usuario puede programar el diseño final del dispositivo empleando un conjunto de herramientas de desarrollo. Las arquitecturas generales pueden variar pero normalmente consisten en una o más matrices de puertas AND y OR para implementar funciones lógicas. Muchos dispositivos también contienen combinaciones de flip-flops y latches que pueden usarse como elementos de almacenaje para entrada y salida de un dispositivo. - 11 - Los dispositivos más complejos contienen macrocélulas. Éstas permiten al usuario configurar el tipo de entradas y salidas necesarias en el diseño. Para el diseño de circuitos digitales, los PLD en general poseen grandes ventajas respecto de los ASIC debido a que su utilización reduce los costos gracias a que su uso es estándar, existiendo softwares que permiten la fácil reprogramación, dependiendo de las necesidades del usuario ¾ PROM Las PROM son memorias programables de sólo lectura (Programmable Read Only Memory). Aunque el nombre no implica la lógica programable, las PROM son de hecho lógicas. La arquitectura de la mayoría de las PROM consiste generalmente en un número fijo de términos AND que alimenta una matriz programable OR. Se usan principalmente para decodificar las combinaciones de entrada en funciones de salida. ¾ PAL Las PAL son dispositivos de matriz programable (Programmable Array Logic). La arquitectura interna consiste en términos AND programables que alimentan términos OR fijos. Todas las entradas a la matriz pueden ser combinadas mediante AND entre sí, pero los términos AND específicos se dedican a términos OR específicos. Las PAL tienen una arquitectura muy popular y son probablemente el tipo de dispositivo programable por usuario más empleado. Si un dispositivo contiene macrocélulas, comúnmente tendrá una arquitectura PAL. Las macrocélulas típicas pueden programarse como entradas, salidas, o entrada/salida (E/S) usando una habilitación tri-estado. Normalmente tienen registros de salida que pueden usarse, o no, conjuntamente con el pin de E/S asociado. Otras macrocélulas tienen más de un registro, varios tipos de retroalimentación en las matrices, y ocasionalmente realimentación entre macrocélulas. - 12 - ¾ GAL Las GAL son dispositivos de matriz lógica genérica. Están diseñados para emular muchas PAL pensadas para el uso de macrocélulas. Si un usuario tiene un diseño que se implementa usando varias PAL comunes, puede configurar varias de las mismas GAL para emular cada de uno de los otros dispositivos. Esto reducirá el número de dispositivos diferentes en existencia y aumenta la cantidad comprada. Comúnmente, una cantidad grande del mismo dispositivo debería rebajar el costo individual del dispositivo. Estos dispositivos también son eléctricamente borrables, lo que los hace muy útiles para los ingenieros de diseño. ¾ PLA Las PLA son matrices lógicas programables. Estos dispositivos contienen ambos términos AND y OR programables lo que permite a cualquier término AND alimentar cualquier término OR. Las PLA probablemente tienen la mayor flexibilidad frente a otros dispositivos con respecto a la lógica funcional. Normalmente poseen realimentación desde la matriz OR hacia la matriz AND que puede usarse para implementar máquinas de estado asíncronas. La mayoría de las máquinas de estado, sin embargo, se implementan como máquinas síncronas. Con esta perspectiva, los fabricantes crearon un tipo de PLA denominado Secuencial (Sequencer) que posee registros de realimentación desde la salida de la matriz OR hacia la matriz AND. ¾ CPLD y FPGA La característica común de estos dispositivos es que poseen la capacidad de reconfigurar su comportamiento a nivel hardware mediante una lógica que se configura a través de software. En el punto 1.3 se presentan ambas tecnologías en forma detallada. - 13 - 1.3 Tecnología CPLD CPLD significa Dispositivo Lógico Programable Complejo (Complex Programmable Logic Device) y se forma de múltiples bloques lógicos cada uno similar a un PLD. Los bloques lógicos se comunican ente sí utilizando una matriz programable de interconexiones lo cual hace más eficiente el uso del silicio y conduce a un mejor desempeño. Un CPLD extiende el concepto de un PLD a un mayor nivel integración ya que permite implementar sistemas más eficientes porque utilizan menos espacios, mejoran la confiabilidad en el circuito y reducen costos. A continuación se explican brevemente las principales características de un CPLD. 1.3.1 Arquitectura de un CPLD - 14 - Figura 1.1 Su arquitectura se basa en la combinación de bloques de Entrada/Salida IOB (Input/ Output Block) y bloques lógicos LB (Logic Blocks) conectados por medio de una matriz de interconexiones programables PIM (Programmable Interconect Matrix). En la figura 1.1 se muestra un esquema simplificado de la arquitectura de un CPLD. A continuación se describirán las características de los elementos que conforman el sistema. 1.3.2 Matriz de interconexiones programables La Matriz de interconexiones programables, PIM, permite unir los pines de entrada/salida a las entradas de otro bloque lógico, o incluso a las entradas de un mismo bloque lógico. La mayoría de los CPLD´s usan una de dos configuraciones para esta matriz: interconexión mediante arreglo o interconexión mediante multiplexores. La interconexión mediante arreglo se basa en una matriz de filas y columnas con una celda EECMOS en cada intersección. Al igual que en el GAL, esta celda puede ser activada para conectar o desconectar la correspondiente fila y columna. Esta configuración permite la total interconexión entre las entradas y salidas de los bloques lógicos. Sin embargo, estas ventajas provocan una disminución del desempeño del dispositivo además de aumentar el consumo de energía y el tamaño del componente. En la interconexión mediante multiplexores, existe un multiplexor por cada entrada a un bloque lógico. Las vías de interconexión programables son interconectadas a las entradas de un numero fijo de multiplexores por cada bloque lógico. Las entradas de selección de estos multiplexores son reprogramadas para permitir que sea seleccionada únicamente una vía de la matriz de interconexiones por cada multiplexor, la cual se propaga hacia el bloque lógico. Cabe mencionar que estos multiplexores no tienen acceso a todas las vías de la matriz por lo que la rutabilidad se aumentará usando multiplexores de mayor - 15 - tamaño, permitiendo así que cualquiera combinación de señales de la matriz de interconexión pueda ser enlazada hacia cualquier bloque lógico. Sin embargo, el uso de grandes multiplexores incrementa el tamaño y reduce su desempeño. 1.3.3 Bloques lógicos Un bloque lógico es muy similar a un PLD. Cada uno de ellos posee generalmente una matriz de compuertas AND, una matriz de compuertas OR y una configuración para la distribución de los productos en las diferentes macroceldas del bloque. El tamaño del bloque lógico es una medida de la capacidad del CPLD, ya que de esto depende el tamaño de la función booleana que pueda ser implementadas dentro del bloque. Los bloques lógicos tienen usualmente de 4 a 20 macroceldas (Macrocells). La capacidad del bloque lógico que puede poseer un CPLD depende de la familia y fabricante del dispositivo. En la figura 1.2 se muestra, a modo de ejemplo, un diagrama de la forma en que interrelacionan los subsistemas para un CPLD de la familia XC9500 de Xilinx. En el esquema, al Bloque Lógico se le da el nombre de Function Block (Bloque Funcional). - 16 - Figura 1.2 1.3.4 Macroceldas Las macroceldas poseen una arquitectura básica muy parecida a la PAL, con la capacidad de ser configurada para una función de combinatoria o de registro. Figura 1.3 - 17 - En la Figura 1.3 se muestra el diseño de una macrocelda de un circuito integrado CPLD de la familia XC9500 de Xilinx. En el se observa que sus entradas son procesadas a semejanza de una PAL. La distribución de los productos difiere levemente dependiendo del fabricante. A modo de ejemplo, en este caso se observa un bloque Product Term Allocator (Asignador de términos de productos) que recibe el resultado de cada 5 productos directos y, actuando como un OR, en su lógica es capaz de entregar un resultado como macrocelda, o bien reasignarlo como entrada a otro Product Term Allocator. Los CPLD MAX de Altera, que fue la primera familia de CPLD que salió al mercado, utilizan una distribución de productos diferente. Reciben 4 productos por macrocelda, los cuales pueden ser compartidos con otras macroceldas. Cuando un producto puede ser únicamente utilizado por una macrocelda se le conoce como término-producto dirigido y cuando estos pueden ser usados por otras macroceldas se les llama término-producto compartido. La utilización de términos-producto compartidos mejora las capacidades del circuito integrado pero disminuye su velocidad al tener un retardo adicional por tener que realimentar un producto hacia otra macrocelda. - 18 - . 1.4 Tecnología FPGA Las FPGA son Campos de Matrices de Puertas Programables (Field Programmable Gate Array). Básicamente son un arreglo bidimensional de bloques y flip-flops donde el usuario puede configurar tanto la interconexión entre los bloques lógicos, así como la configuración de cada bloque. En la figura se muestra la versión simplificada de una FPGA. Figura 1.4 - 19 - Es decir, las FPGA son matrices de puertas eléctricamente programables que contienen múltiples niveles de lógica. Las FPGA se caracterizan por altas densidades de puerta, alto rendimiento, un número grande de entradas y salidas definibles por el usuario, un esquema de interconexión flexible, y un entorno de diseño similar al de matriz de puertas lógicas, sin embargo, no están limitadas a la típica matriz AND-OR. En cambio, contienen una matriz interna configurable de bloques lógicos CLB (Configurable Logic Block) y un anillo de circunvalación de bloques de entrada/salida IOB (Input Output Block). Cada CLB contiene lógica programable combinacional y registros de almacenamiento. La sección de lógica combinacional es capaz de implementar cualquier función booleana de sus variables de entrada. Cada IOB puede programarse independientemente para ser una entrada, una salida con control tri-estado o un pin bidireccional. También contiene flip-flops que pueden usarse como buffers de entrada y salida. Los recursos de interconexión son una red de líneas que corren horizontalmente y verticalmente las filas y columnas entre el CLB´s. Los interruptores programables conectan las entradas y salidas de IOB´s y CLB´s a líneas cercanas. Las líneas largas recorren la anchura o longitud entera del dispositivo, estableciendo intercambios para proporcionar una distribución de señales críticas con la mínima demora o distorsión. Los diseñadores que usan CPLD´s pueden definir funciones lógicas en un circuito y revisar estas funciones como sea necesario. Así, las FPGA´s pueden diseñarse y verificarse en unos días, a diferencia de las varias semanas necesarias para las matrices de puerta programables. 1.4.1 Desarrollo de la tecnología FPGA - 20 - Es importante entender la justificación en que se basó el desarrollo de la tecnología FPGA. Por los comienzos de los años 80, la mayoría de los circuitos lógicos en los sistemas típicos eran implementados con un conjunto de circuitos integrados de gran escala (Large scale integrated, LSI) de tipo estándar. Estos podían ser Microprocesadores, Controladores de IO/bus, Relojes de sistemas etc. Cada sistema aún mantenía la necesidad de una forma de unión lógica de tipo aleatoria para conectar la gran cantidad de circuitos integrados, es decir, que tuviera la posibilidad de ser implementada de acuerdo a las necesidades especiales de cada diseño. Esto se resolvía generando señales de control globales (para resets etc.), y mediante transformaciones y manipulación de datos (serial a paralelo, multiplexando, etc.). Los trabajos con circuitos integrados muchas veces debían ser rediseñados, forzados por reemplazar la gran cantidad de conexiones lógicas. Como resultado de este rediseño, se lograba reducir la complejidad del sistema y los costos de manufactura, mejorando así el rendimiento. De todas formas, los trabajos con circuitos integrados eran relativamente caros de desarrollar y se retrasaba la introducción de un producto al mercado o TTM (Time To Market) debido al incremento en el tiempo de diseño. Considerando el aspecto económico del diseño de sistemas electrónicos, existe la necesidad de preocuparse de dos tipos de costos: A.- Costos de desarrollo, a veces llamados costos de ingeniería no recurrente NRE (nonrecurring engineering). B.- Costos de producción. Una relación típica existe entre los costos NRE y los costos de producción, esta se muestra en la figura 1.5. - 21 - Figura 1.5 Un aspecto importante a considerar es que el trabajo con CI, en general, era solamente viable para productos con grandes volúmenes de producción, donde el NRE podía ser amortizado y que no fuera demasiado sensible al tiempo al mercado (TTM). Las FPGA fueron introducidas como una alternativa para implementar las conexiones lógicas de los trabajos con CI. Mejoraron la densidad respecto de los componentes discretos de tipo SSI/MSI. Además, con la ayuda de herramientas CAD (Computer Aided Design) los circuitos podían ser implementados en menores cantidades de tiempo ya que no existían procesos de layout físicos, por lo que no había creación de máscaras y no había producción con circuitos integrados. Estas acciones permitían menores costos NRE y acortar los tiempos TTM. De acuerdo a la Ley de Moore, que dice el número de transistores por pulgada cuadrada en circuitos integrados se duplicaba cada año y medio, la densidad (gates/area) de las FPGA continuó creciendo a través de los años 80 y 90 al punto en que pudieron ser implementadas mayores funciones de procesamiento de datos dentro de un integrado FPGA individual. Las FPGA continuaron compitiendo con diseños de CI para funciones especiales de procesamiento (y lógica de conexiones) pero ahora también competían con los microprocesadores en aplicaciones dedicadas. Desarrollaron una ventaja sobre los microprocesadores porque los circuitos podían ser “moldeados a mano” y los microprocesadores debían trabajar con funciones especiales de programación (muchos ciclos). Si se comparan los componentes más usados podemos observar el cuadro de la figura 1.6. - 22 - Figura 1.6 * ASIC = Circuito integrado de aplicación específica, MICRO = Microprocesador 1.4.2 Variaciones de FPGA Como se señaló anteriormente, en el diseño de un circuito integrado FPGA, se consideran principalmente tres elementos: Bloques Lógicos Configurables (CLB), Bloques de Entrada y Salida (I/O Blocks) y la Interconexión Programable entre ellos (figura 1.7). - 23 - Figura 1.7 Cada uno de estos elementos es diseñado por los fabricantes de circuitos integrados FPGA de acuerdo a su propio método, lo que define la composición y capacidades de cada uno de ellos. En base a esto, las familias de FPGA existentes, presentan principalmente diferencias en lo que refiere a: - Métodos físicos de implementación de la programabilidad del usuario. - Arreglo del cableado de interconexión. - Funcionalidad básica de los bloques lógicos. La diferencia más significativa se encuentra en el método para proveer bloques flexibles y su forma de conexión (figura 1.8). Figura 1.8 La industria de CPLD y FPGA usa varios métodos para hacer las conexiones entre los bloques lógicos. Algunos fabricantes producen circuitos integrados con fusibles o antifusibles que son programados mediante el paso de una gran corriente a través de ellos. - 24 - Estos tipos de circuitos integrados CPLD´s y FPGA´s son del tipo Programables de una vez, one-time programmable (OTP) ya que no es posible recablearlos internamente una vez que los fusibles han sido accionados. Otros fabricantes hacen las conexiones usando transistores de paso que son abiertos o cerrados mediante la carga en sus electrodos de Gate usando pulsos de alto voltaje. Este tipo de dispositivos se asemejan a una memoria EPROM o EEPROM: Estas pueden ser borradas y utilizando un socket de un programador especial pueden ser reprogramadas. Esta forma de trabajo es útil mientras no tenga el CPLD o FPGA soldado a la placa del circuito. Finalmente, algunos fabricantes usan memorias RAM estáticas o FLASH para controlar el transistor de paso para cada interconexión. Mediante la carga de cada bit con un 1 o un 0, se puede controlar cuando el interruptor está cerrado o abierto y de esa forma controlar cuando dos elementos lógicos son o no conectados. Los CPLD y los FPGA que utilizan interruptores con memorias RAM o Flash pueden ser reprogramados sin necesidad de retirarlos de la placa en que el circuito está implementado. Estos son comúnmente llamados Reconfigurables en circuito o Programables en circuito. Independiente del método de interconexión usado, se puede observar que el decidir o calcular cuales interruptores deben ser abiertos o cerrados para crear un circuito lógico es una tarea demasiado compleja. Por esto, los fabricantes de los circuitos entregan programas desarrollados que toman una descripción del diseño lógico como una entrada, y entonces, entregan un archivo binario con el cual se configuran los interruptores en la FPGA de forma que se comporte como el diseño deseado. 1.4.3 Programabilidad de usuario La posibilidad de programar y reprogramar una FPGA de acuerdo a las necesidades del usuario, dependerá de la técnica empleada en la fabricación sea la adecuada. - 25 - Por ejemplo, se muestra en un esquema simple, la técnica usada por Actel, basada en antifusibles. En ella, se utilizan fusibles para todas las conexiones y luego se rompen los fusibles necesarios de modo de desconectarlos y de esa forma conservar activos los interruptores deseados. Figura 1.9 Una ventaja de esta técnica es el ser no-volátil, otra ventaja es que este tipo de conexión es relativamente pequeña. La principal desventaja es que por ser permanente no es reprogramable. Los fabricantes Xilinx y Altera, basan la conexiones en transistores de paso cuya activación o desactivación dependerá de un enclavamiento (Latch). - 26 - Figura 1.10 De modo opuesto a la anterior, la gran ventaja de esta técnica es la posibilidad de ser reconfigurable y las desventajas son el hecho de tener una configuración volátil y el emplear mayor tamaño. Dentro de una FPGA los distintos enclavamientos tienen por función varias tareas: 1. Crear o romper puntos de cruce en las interconexiones. 2. Definir la función de los bloques lógicos . 3. Ingresar las opciones de usuario: a) Entre los bloques lógicos. b) En los bloques de entrada/salida. c) Reset y clock global. La configuración que permite el activar los enclavamientos se llama Trama de bit (Bit Stream) y corresponde a un conjunto de unos y ceros lógicos que pueden ser cargados bajo el control del usuario. 1.4.4 Esquema de un Circuito integrado FPGA En la Figura 1.11 se muestra la imagen de un circuito integrado FPGA de la serie Spartan de Xilinx. - 27 - Figura 1.11 En la Figura 1.12 se muestra el diseño de un circuito integrado FPGA de la serie Spartan II de Xilinx. Figura 1.12 1.4.5 Esquema de interconexiones En la Figura 1.12 se muestra un esquema de parte de las interconexiones dentro de un circuito integrado FPGA de Xilinx. - 28 - Figura 1.13 1.4.6 Bloque Lógico FPGA Idealizado Para comprender el funcionamiento de un Bloque Lógico Configurable (CLB) se comenzará analizando un modelo idealizado para cuatro entradas. - 29 - Figura 1.14 En la figura se muestran los distintos componentes que presenta como sistema un CLB. En él se observa un bloque llamado Look Up Table (LUT) que en este caso posee 4 entradas que corresponden a las del CLB. El LUT es el encargado de implementar las funciones de lógica sobre las entradas. El Latch se configura para permitir la salida desde el CLB. 1.4.7 Implementación de un 4-LUT A continuación, en la figura 1.15, se muestra un diagrama representativo de la operación de un LUT de 4 entradas. - 30 - Figura 1.15 Un LUT de n-bit es implementado como una memoria de 2n x 1. Por lo tanto, para este ejemplo de 4 entradas, el bloque “4-LUT” posee 16 locaciones de memoria donde se encuentra cada función lógica que operará sobre las entradas. Estas locaciones de memorias son cargadas mediante la configuración de Bitstream, que se encarga de configurar sus latches correspondientes. Se observa que las entradas al control MUX son las entradas al CLB. 1.4.8 El LUT como una compuerta lógica general Se puede entender un n-LUT como una implementación directa de una tabla de verdad. Cada localización de latch retiene el valor de la función correspondiente a una - 31 - combinación de entrada. En la figura 1.16 se observa la tabla de verdad que es posible implementar para un 2-LUT. Ejemplo: 2- LUT Figura 1.16 Así como un 2-LUT implementa cualquier función de 2 entradas, un n-LUT es capaz de implementar 2n funciones, para n entradas (figura 1.17). Figura 1.17 - 32 - 1.4.9 Configuración de una FPGA De acuerdo con las características antes presentadas, se observa que el proceso para configurar una FPGA está basado en definir el estado de los Latches que se encargan tanto de determinar las funciones que tendrán los bloques lógicas como de las conexiones que se realizarán dentro de la FPGA. Esta configuración es determinada por el usuario, en base a las necesidades que debe resolver el sistema. En la práctica, para llevar a cabo esta operación, se emplean softwares especializados que trabajan con lenguajes de descripción de hardware (HDL). Estos programas computacionales reciben mediante lenguaje HDL, la lógica que debe ser implementada en el circuito digital a diseñar. También son capaces de determinar la mejor opción de configuración para que la FPGA se comporte de manera óptima, determinando los mínimos componentes necesarios que son posibles de implementar en la función de los Bloques Lógicos y la mejor ubicación dentro de los diferentes puntos de la FPGA, con el fin de reducir el tiempo del proceso de trabajo. El proceso de definir los componentes a implementar, determinar la ubicación dentro de la FPGA y definir la mejor conexión entre ellos se conoce como Mapping, Placement and Routing y luego es necesario llevar la secuencia de bits (bitstream) generada por el software hasta la FPGA. En los capítulos siguientes se presentan con más detalles la forma de llevar el diseño de un circuito digital a la configuración de una FPGA y el resultado interno de la configuración. - 33 - CAPÍTULO 2: VHDL 2.1 Introducción Constantemente en Ingeniería Electrónica se ha buscado nuevas y mejores formas de diseño, con el fin de minimizar los costos y lograr diseños flexibles; esto último producto de lo difícil o imposible que resulta modificar circuitos ya montados en una placa (PCB). Hoy en día estos objetivos se logran utilizando dispositivos de lógica programable (PLD´s) con lenguajes de descripción de hardware (HDL´s). Dentro de los lenguajes HDL´s el más popular y utilizado es el VHDL. VHDL es un lenguaje estándar de programación de alto nivel, diseñado para describir el comportamiento de circuitos electrónicos digitales, desde complejos sistemas hasta una simple compuerta lógica. Su sigla proviene de VHSIC-HDL, (Very High Speed Integrated Circuits-Hardware Description Languaje), lenguaje de descripción de hardware de circuitos integrados de alta velocidad. Este lenguaje permite que el comportamiento de los circuitos electrónicos sea capturado en un sistema de diseño para la simulación del sistema y posteriormente realizar la síntesis automática del circuito; este es un proceso en el cual se transforma el diseño de manera automática desde una descripción con pocos detalles a una más elaborada, con el fin de poder llevarla a un dispositivo de lógica programable. - 34 - VHDL permite el diseño "Top-Down", es decir, partir desde un nivel muy alto de abstracción para después ir bajando a niveles con más detalles según sea necesario, como lo muestra la figura 2.1. Figura 2.1 El usar un lenguaje estándar como VHDL, garantiza que los circuitos ya descritos serán soportados por las nuevas herramientas de diseño que aparezcan en el futuro. Por otro lado, constantemente el lenguaje VHDL está sujeto a revisiones y es por esta razón que el Instituto de Ingenieros Eléctricos y Electrónicos (IEEE), lanza continuamente nuevos paquetes estándares que lo complementan. Una de las más importantes aplicaciones del lenguaje VHDL se refiere a la simulación de los circuitos modelados, proceso en el cual se ingresa un grupo de estímulos al circuito modelado y se estudian las señales de salida comparándolas con las señales - 35 - esperadas. Este grupo de estímulos se describe en lenguaje VHDL, al igual que el circuito modelado. El ambiente de simulación recibe el nombre de “Testbench”. Una de las características más relevantes del lenguaje VHDL es que describe los circuitos electrónicos desde el punto de vista funcional y también desde el punto de vista de los componentes. Otra característica importante es que los circuitos que han sido modelados anteriormente quedan disponibles para ser utilizados en forma de bloque en la descripción de circuitos más grandes, lo que facilita enormemente la descripción de éstos. Esta característica se aprecia mejor en la figura 2.2. Además, los diseños que son utilizados frecuentemente se agrupan en "bibliotecas" que quedan disponibles para ser utilizadas en cualquier diseño. Figura 2.2 - 36 - 2.2 Reseña Histórica Una fuerte evolución sufrió el proceso de fabricación de circuitos integrados a mediados de los años setenta con la aparición de la tecnología MOS (Metal Oxide Semiconductor), dando un importante impulso al desarrollo de circuitos electrónicos. En esta época se encontraban con problemas como la interconexión de transistores, circuitos integrados etc. A medida que pasaban los años, los diseños crecían enormemente, ocupaban grandes cantidades de componentes electrónicos y se hacían muy complejos; esto traía consigo problemas como la integración, depuración y mantención de los circuitos diseñados. A fines de los años setenta se podía notar el tremendo desfase entre las tecnologías disponibles y las metodologías de diseño, por un lado la tecnología avanzaba a pasos agigantados, mientras que por el otro, los métodos de diseño quedaban obsoletos, los costos implicados en los diseños eran imposibles de sostener para cualquier empresa. Es en este momento cuando se comienza a buscar nuevas técnicas de diseño, de manera de aprovechar al máximo las ventajas de las nuevas tecnologías y a la vez tratando de facilitar el trabajo al diseñador. La tendencia principal eran los lenguajes de descripción de hardware (HDL); de esta forma algunas empresas comienzan a crear sus propios HDL´s. Por ejemplo la empresa Texas Instruments crea el TI-HDL, IBM crea su lenguaje IDL, la General Electric crea - 37 - ZEUS, etc. Por otro lado las universidades también comenzaron a trabajar en estos lenguajes, creando sus propios prototipos. Si bien, todo indicaba que el HDL era la solución al problema del diseño, ninguno de los lenguajes llegó a consolidarse. La razón de esto, en el caso de las empresas, fue porque querían que su lenguaje fuera de uso exclusivo, no permitiendo su estandarización. En el caso de las universidades, el problema fue que no contaron con soporte ni mantenimiento adecuado para sus lenguajes. Aproximadamente en 1981 el Departamento de Defensa de los Estados Unidos comenzó a trabajar en un proyecto llamado VHSIC (Very High Speed Integrated Circuit), el cual tenía como objetivo disminuir los costos de hardware. Este proyecto buscaría resolver el problema de modificar circuitos ya diseñados para poder utilizarlos en otros proyectos. En 1983 el Departamento de Defensa de los Estados Unidos contrató un equipo de ingenieros de tres compañías: Texas Instruments, IBM e Intermetrics, para especificar e implementar un nuevo método de diseño basado en lenguaje de descripción de hardware. La primera versión pública disponible de VHDL fue la versión 7.2 lanzada en 1985. En 1986 el Instituto de Ingenieros Eléctricos y Electrónicos (IEEE), propuso la estandarización del lenguaje. Después de considerables modificaciones y mejoras realizadas por representantes de las empresas, universidades y gobierno se logró la estandarización del lenguaje. En diciembre de 1987 el IEEE publicó el estándar “IEEE std 1076-1987”, el cual sería la base de cada producto de simulación y síntesis vendido hoy en día. Al momento de simular los circuitos descritos, los diseñadores se encontraron con un problema, aunque VHDL soportaba muchos tipos de datos abstractos, no soportaba valores como cero lógico, uno lógico, alta impedancia etc., lo que no permitía una simulación exacta. - 38 - Ante este problema, las empresas vendedoras de simuladores de VHDL comenzaron a complementar el lenguaje con sus nuevos " paquetes no estándar ", lo que permitía a sus clientes simular complejos circuitos electrónicos con exactitud. Esto trajo consigo otro problema, los diseños incorporados en un simulador eran a menudo incompatibles con otros ambientes de simulación; VHDL se tornaba NO-ESTÁNDAR. Para solucionar este problema, el IEEE presentó a fines de los años 80 el estándar “ IEEE std 1164 “. Gracias a su carácter de estándar, el lenguaje está bajo constantes revisiones y actualizaciones. Es de esta forma que en 1994 el IEEE lanzó una nueva versión del lenguaje VHDL, el estándar “ IEEE std 1076-1993 “. Cuando los diseñadores trataron de sintetizar los circuitos descritos para llevarlos a hardware se encontraron con otro problema. Faltaban tipos de datos que pudieran comunicar el sistema diseñado con el hardware real. Este problema además de otros fue solucionado a fines de 1995 cuando la IEEE entregó un nuevo estándar, el estándar IEEE std 1076.3. De esta forma llegamos a la actualidad, en donde el IEEE está constantemente publicando nuevos paquetes para complementar VHDL, aunque solo se requieren los estándares IEEE std 1076-1987(o IEEE std 1076-1993), IEEE std 1164 y IEEE std 1076.3 para formar en conjunto el estándar completo de VHDL, que permite trabajar desde la descripción del circuito en lenguaje VHDL hasta la implementación de éste en dispositivos de lógica programable. 2.2.1 El estándar IEEE std 1164 Este es un estándar que viene a reemplazar los paquetes creados por las empresas vendedoras de simuladores, los cuales dentro de sus paquetes agrupaban distintas cantidades de datos lógicos (cuatro, siete, trece, etc.). Este estándar también conocido como - 39 - "Standard Logic Package", contiene nueve valores para los nueve tipos de datos lógicos estándar que agrupa. Estos nueve valores son presentados en la tabla 2.1. Tabla 2.1 Estos nueve tipos de datos lógicos permiten modelar con exactitud el comportamiento de circuitos digitales durante la simulación. Este estándar aparte de permitir un uno o cero lógico como señal de entrada al circuito simulado, permite ingresar una señal desconocida para ver la respuesta del sistema ante este tipo de entrada. 2.2.2 El estándar IEEE std 1076.3 - 40 - También conocido como "Estándar Numérico" o "Estándar de Síntesis", fue desarrollado para reemplazar los muchos paquetes "no estándar" creados por las empresas vendedoras de herramientas de Síntesis. Este estándar define el paquete numeric_std que permite el uso de operaciones aritméticas en datos de tipo lógico estándar (std_logic y std_logic_vector). También define en forma aritmética datos del tipo bit y bit_vector en un paquete llamado numeric_bit. 2.3 Principios de VHDL Debido a que el objetivo principal de este seminario no es el lenguaje VHDL en sí, solamente se enseñarán los principios básicos para que el lector pueda describir circuitos simples con el fin de poder simularlos y sintetizarlos. Queda en manos del lector el ahondar más en las características del lenguaje si desea realizar descripciones de circuitos más complejos. Existen dos formas de describir un circuito. La primera es indicando los componentes del circuito y sus correspondientes interconexiones; para realizar este tipo de descripción es necesario conocer la estructura interna del circuito. Las herramientas utilizadas son las de captura de esquemas y el lenguaje Netlist (lista de conexiones). La segunda forma es describir el funcionamiento (comportamiento) del circuito; VHDL permite describir un circuito utilizando cualquiera de estas formas. Originalmente, VHDL fue creado para facilitar el trabajo de los diseñadores de circuitos digitales, haciendo más fácil la depuración, modificación y mantención de los diseños. Es por esta razón que VHDL cuenta con muchas instrucciones orientadas más a la simulación que a la implementación física del diseño. Esto trae consigo la diferencia entre el VHDL simulable y el VHDL sintetizable, siendo este último el más utilizado actualmente. Debido a que ciertas instrucciones de VHDL no tienen un equivalente físico, no todas las instrucciones pueden ser utilizadas en el VHDL sintetizable. Por lo tanto, la - 41 - mayoría de los diseños pueden ser simulados, pero no todos pueden sintetizarse para llevarlos a un dispositivo de lógica programable. VHDL tiene dos formas básicas de sentencias de programación, las sentencias secuenciales y las sentencias concurrentes. Las sentencias secuenciales son ejecutadas una después de otra, como cualquier lenguaje de programación común (Basic, C, etc.), y la siguiente sentencia puede anular a la actual; es por esta razón que al usar este tipo de sentencias se debe considerar el orden de éstas. Las sentencias concurrentes son aquellas que están ejecutándose continuamente; es por esta razón que en este caso no es necesario preocuparse por el orden de las sentencias. Este tipo de sentencias se utiliza para describir procesos paralelos. En cuanto a las técnicas de diseño, VHDL posee tres técnicas de modelado: abstracción, modularidad y jerarquía. 2.3.1 Abstracción: El diseño por abstracción es aquel que discrimina entre la información esencial y la no-esencial; es por esta razón que oculta muchos detalles. Toda la información de un diseño de cierto nivel de abstracción tiene el mismo grado de abstracción. Para esta técnica de modelado el diseño de circuitos digitales se divide en cuatro niveles de abstracción: Behaviour, RTL, Logic y Layout. HDL es aplicable solo a los tres primeros niveles. 2.3.1.1 Behaviour: También conocido como nivel de comportamiento, es el nivel de mayor abstracción; solo se describe el funcionamiento del sistema, utilizando sentencias como if, else, for, etc. Por lo general, los diseños realizados con este nivel de abstracción son simulables pero no - 42 - se recomienda sintetizarlos, porque resultan poco óptimos, debido a que su estructura es secuencial y no permite paralelismos, como ocurre en los circuitos reales. En este nivel se ve el circuito a describir como una caja negra, de la cual se conoce las entradas, las salidas y como obtener éstas a partir de las entradas. Como ejemplo se muestra en la figura 2.3, la descripción de la arquitectura del multiplexor de la figura 2.4, el cual consta de dos entradas, una señal de selección y una salida. Figura 2.3 ARCHITECTURE behaviour OF mux IS BEGIN PROCESS (a,b,selec) BEGIN IF (selec=´0´) THEN salida<=a; ELSE salida<=b; END IF; END PROCESS; END behaviour; Figura 2.4 - 43 - La sintaxis se estudiará más adelante; este ejemplo se presenta para visualizar el nivel de abstracción. Se puede observar que a través de sentencias se describe el funcionamiento del multiplexor sin saber que componentes lo conforman; la salida está relacionada en forma directa con respecto a las entradas. 2.3.1.2 RTL (Register Transfer Level): También conocido como Dataflow, Flujo de Datos o Transferencia entre Registros. Como su nombre lo dice, en este nivel se ve el circuito a describir como un conjunto de registros (Flip-Flops, latches, etc.). Si en el caso del nivel behaviour se tenía una descripción de comportamiento, aquí se tiene una descripción más cercana a la estructural con el fin de acercar más la descripción a una posible realización física; pero aún es un nivel de descripción funcional. En este nivel se describe un circuito desde el punto de vista de las señales, siguiendo el flujo de señales desde las entradas hasta llegar a las salidas. En el nivel RTL de abstracción se utilizan sentencias concurrentes, permitiendo describir bloques paralelos como los que existen en los circuitos reales; es por esta razón que los circuitos descritos en este nivel pueden ser simulados y sintetizados. Ahora como ejemplo se mostrará el mismo multiplexor del ejemplo anterior pero descrito con un nivel de abstracción RTL (figuras 2.6 y 2.7); para ello es necesario presentar el multiplexor como lo muestra la figura 2.5. - 44 - Figura 2.5 ARCHITECTURE RTL OF mux IS ARCHITECTURE RTL OF mux IS SIGNAL ax,bx,noselec: bit; BEGIN BEGIN salida<=a WHEN selec=´0´ ELSE b; END RTL; noselec<=NOT selec; ax<=a AND noselec; bx<=b AND selec; salida<=ax OR bx; END RTL; Figura 2.6 Figura 2.7 En este ejemplo se puede apreciar que hay dos formas de describir el multiplexor con el nivel de abstracción RTL. En el primer caso (figura 2.6), todas las instrucciones son concurrentes; lo que implica que cada vez que cambie alguna de las señales que intervienen en las asignaciones, éstas se ejecutarán. Se puede apreciar también que la descripción es muy cercana a una descripción estructural, ya que de alguna manera se está definiendo las señales (conductores) y los componentes que la definen. La diferencia radica en que aquí se está definiendo las señales y no una lista de componentes y sus interconexiones; esto se - 45 - aclarará más al estudiar la descripción en nivel logic. La segunda descripción (figura 27), es más corta debido a que se relaciona en forma directa la señal de salida con las señales de entrada. 2.3.1.3 Logic (lógico): También conocido como nivel de Compuerta o Gate, en este nivel se describe un circuito desde el punto de vista estructural, definiendo los componentes (AND, OR, NOT, etc.), que lo conforman y sus correspondientes interconexiones. Por esta razón para poder describir un circuito utilizando este nivel de abstracción es necesario conocer su estructura. A continuación, en la figura 2.8 se muestra la descripción del multiplexor de la figura 2.5 utilizando el nivel lógico de abstracción. ARCHITECTURE logic OF mux IS SIGNAL ax,bx,noselec: bit; BEGIN u1: ENTITY inv PORT MAP(e=>selec,y=>noselec); u2: ENTITY and2 PORT MAP(e1=>a,e2=>noselec,y=>ax); u3: ENTITY and2 PORT MAP(b,selec,bx); u4: ENTITY or2 PORT MAP(e1=>ax,e2=>bx,y=>salida); END logic; Figura 2.8 En este ejemplo se puede observar la definición de cada componente del circuito y como están conectados entre sí, a diferencia con la descripción anterior donde solo se define el flujo de señales. Existen herramientas de síntesis que permiten bajar desde un nivel Behaviour a un nivel RTL; este proceso recibe el nombre de Síntesis Funcional. También hay herramientas - 46 - que permiten bajar desde un nivel RTL a un nivel de Netlist; este proceso recibe el nombre de Síntesis Lógica. En general, transformar una descripción Behaviour/RTL en un Netlist de compuertas y Flip-Flops de una tecnología dada, recibe el nombre de Síntesis. Al momento de sintetizar un diseño es necesario especificar que tipo de tecnología lo acogerá (CPLD, ASIC, FPGA, etc.). Para finalizar con esta técnica de modelado, se puede decir que al bajar desde una descripción behaviour a una descripción RTL, se disminuye la velocidad de simulación pero a la vez se aumenta la precisión de la descripción, acercándose más al circuito real descrito. 2.3.2 Modular: El método modular consiste en dividir un gran sistema en subsistemas más pequeños; estos subsistemas reciben el nombre de módulos. Esto permite pasar desde un complejo sistema a un grupo de módulos más simples. 2.3.3 Hierarchy (Jerarquía): Este método es utilizado para organizar el diseño de grandes circuitos, y se utiliza en conjunto con el método modular. Al utilizar la jerarquía se crea un nivel de descripción funcional debajo de otro; cada nivel creado posee una descripción más detallada del sistema. El uso de este método es consecuencia directa de aplicar el diseño Top-Down. Estas dos últimas técnicas de modelado se utilizan cuando el circuito a modelar es muy grande como para aplicar directamente el modelado de abstracción. - 47 - 2.4 Sintaxis de VHDL Por ser VHDL un lenguaje de alto nivel, posee una gran cantidad de términos y sentencias para poder describir diversos tipos de circuitos. Como el objetivo de este capitulo es dar a conocer las características más esenciales de VHDL, solo se presentarán las sentencias y los términos más utilizados. 2.4.1 Declaración y Asignación de Constantes, Variables y Señales ¾ Asignación de señales: "<=" Ejemplo: next_state <= S0; ¾ Asignación de variables: ":=" Ejemplo: salida := resultado; ¾ Declaración de constantes: - 48 - Ejemplos: constant E: REAL := 2.71828; constant RETRASO: TIME := 10 ns; ¾ Declaración de variables: Ejemplo: variable CONTADOR: NATURAL; ¾ Declaración de señales: Ejemplos: signal SELECT: BIT := '0'; signal DIR: STD_LOGIC := '0' 2.4.2 Principales Operadores y Elementos Sintácticos A continuación, se presentan los operadores y elementos sintácticos más utilizados en la descripción de circuitos a través de VHDL. ¾ Comentarios: "--" Ejemplo: -- Inicialización de Variables ¾ Las sentencias (que pueden abarcar varias líneas) se finalizan con: ";" Ejemplo: next_state <= S1; ¾ Delimitador de lista: "," Ejemplo: reloj <= '0', -- empieza con nivel cero lógico. - 49 - '1' after 10 ns, -- después de 10 ns cambia a uno lógico. '0' after 10 ns, -- cada 10 ns va cambiando. '1' after 10 ns; ¾ Comparaciones: • Igualdad, desigualdad: =, /= • Mayor que, menor que: >, < • Mayor o igual que, menor o igual que: >=, <= ¾ Operadores lógicos: and, or, nand, nor, not, xor, xnor. ¾ Identificadores: En este punto hay que separar el estándar VHDL '87 del estándar VHDL '93. VHDL 87 mySignal_6 VHDL 93 -- identificador simple. \mySignal_6\ -- identificador extendido. fte, FTE, Fte -- identificadores idénticos. \fte\, \FTE\, \Fte\ -- identificadores diferentes. fte_&_fte -- no permite caracteres especiales (&). \fte_&_fte\ -- permite caracteres especiales. no signal -- no permite espacios. \no signal\ -- permite usar espacios. next__state -- no permite dos subrayados seguidos. \next__state\ -- permite dos subrayados -- no se puede comenzar con un número. \2do_estado\ 2do_estado open, register -- no se puede utilizar las palabras claves de VHDL. seguidos. -- se puede comenzar con un número \open\, \register\ -- se puede utilizar las palabras claves de VHDL. - 50 - 2.4.3 Principales Sentencias Sentencia IF: Esta sentencia presenta dos formas de utilización como 2.4.3.1 se muestra en los ejemplos de las figuras 2.9 y 2.10. Ejemplo 1: Ejemplo 2: if Z = '0' then if Z = '0' then next_state <= S1; next_state <= S1; elsif Z = '1' then else next_state <= S2; next_state <= S2; else end if; next_state <= SX; d if Figura 2.10 Figura 2.9 Figura 2 11 Figura 2 12 - 51 - La diferencia entre las dos sentencias if la podemos apreciar en las figuras 2.11 y 2.12. En el caso del ejemplo 1, si Z es igual a 0, entonces next_state es igual a S1, en cualquier otro caso next_state es igual a S2. En el ejemplo 2, podemos decir que si Z es igual a 0, entonces next_state es igual a S1, si Z es igual a 1, entonces next_state es igual a S2 y en cualquier otro caso, next_state es igual a SX. Se recomienda el uso del comando "else" cada vez que se utilice el comando "if", para que no ocurran eventos imprevistos. 2.4.3.2 Sentencia LOOP: Esta sentencia se puede realizar con un ciclo for o con un ciclo while, ambos casos se muestran en las figuras 2.13 y 2.14. process (a) process (a) variable i: integer := 0; begin loop2: while i < 8 loop entrada (i) <= '0'; i := i + 1; end loop; end process; begin loop1: for i in 7 downto 0 loop entrada (i) <= '0'; end loop; end process; Figura 2.13 Figura 2.14 Ambos programas realizan la misma tarea, le asignan el valor lógico cero a los 8 bits menos significativos del vector de entrada, debido a que la notación "entrada (i)", representa el i-ésimo elemento del vector de entrada. En el caso del loop realizado con un ciclo for, el loop se ejecutará hasta que la variable "i" llegue al valor cero, ejecutando la sentencia de asignación por última vez con "i = 0". Cabe señalar que en este caso no es necesario declarar la variable "i" debido a que en un ciclo for, este procedimiento se hace en forma automática. Por otro lado, en el caso del loop realizado con la sentencia while, primero se declara como entero (integer) la variable "i" y se inicializa en cero. Como el loop se ejecutará siempre que la variable "i" sea menor a 8, se incrementa ésta dentro del loop para que no quede ejecutándose para siempre. Cuando la variable tome el valor 8, no se ejecutará el loop. - 52 - 2.4.3.3 Sentencia CASE: Es usada para especificar una serie de acciones según el valor dado de una señal de selección, su sintaxis es como se muestra en la figura 2.15. case (señal a evaluar) is when (valor 1) => haz una cosa; when (valor 2) => haz otra cosa; … when (último valor) => haz tal cosa; end case; Figura 2.15 Además existe una variante muy importante dentro de VHDL, el cual le da un valor específico a la señal cuando no se cumple ninguno de los casos anteriores, esto se hace a través del comando "others". Un ejemplo de su uso se muestra en las figuras 2.16 y2.17. case control is case control is when "00" => g <= a; when "00" => g <= a; when "01" => g <= b; when "01" => g <= b; when "10" => g <= c; when "10" => g <= c; when "11" => g <= "1111"; when others => g <= "1111"; end case; end case; Figura 2.16 Figura 2.17 En ambos casos se describe un multiplexor con tres señales de entrada, una señal de control y la señal de salida "g". A simple vista observamos que en la primera descripción (figura 2.16) están definidas todas las combinaciones posibles, entonces ¿porqué utilizar la segunda descripción?. Porque VHDL no solo reconoce el cero o uno lógico, también - 53 - reconoce el estado de alta impedancia y otros, es por esta razón que se recomienda usar siempre el comando "others" para definir todas las otras combinaciones que puedan ocurrir (figura 2.17). La sentencia "case" también permite especificar un rango de valores posibles de la señal de selección, para los cuales hacer una asignación, mediante la palabra reservada "to". Como ejemplo, se muestran en las figuras 2.18 y 2.19 dos descripciones equivalentes: case control is case control is when "000" => d <= a; when "000" to "010" => d <= a; when "001" => d <= a; when "011" to "110" => d <= b; when "010" => d <= a; when "111" => d <= c; when "011" => d <= b; when others => d <= null; when "100" => d <= b; end case; when "101" => d <= b; when "110" => d <= b; when "111" => d <= c; when others => d <= null; end case; Figura 2.18 2.4.3.4 Figura 2.19 Sentencia PROCESS: La sentencia process solo se puede utilizar dentro de la "arquitectura" de un diseño (esto se explicará con detalles posteriormente). La sentencia process es concurrente, debido a que todos los process existentes en la "arquitectura" se ejecutan en forma concurrente (paralela). Por otro lado, la única forma de utilizar instrucciones secuenciales en VHDL es haciéndolo dentro de un bloque process. En la figura 2.20 se muestra la forma de declarar un bloque process. etiqueta: process (señal1, señal2,...) begin sentencias secuenciales end process etiqueta; - 54 - Figura 2.20 La etiqueta sirve para ponerle nombre al proceso y su uso es opcional. El paréntesis que sigue a la palabra process recibe el nombre de lista sensible. La ejecución del process se activa cuando se produce un cambio en alguna de las señales de la lista sensible. En el caso de no utilizar una lista sensible, la ejecución se controla con el uso de sentencias wait dentro del process. La sentencia wait se estudiará más adelante. En cualquier caso debe existir, o una lista sensible o una sentencia wait, de lo contrario, al simular el diseño, el process se ejecutaría una y otra vez entrando la simulación en un ciclo infinito. Entre la etiqueta y la palabra begin se pueden declarar variables, atributos, tipos, subprogramas, pero en ningún caso se pueden declarar señales. 2.4.3.5 Sentencia WAIT: Esta sentencia se utiliza para suspender un process cuando éste no tiene lista sensible. Lo único que exige esta sentencia es ir al final del process. En las figuras 2.21 y 2.22 se muestran dos descripciones, las cuales se ejecutarán cuando haya un cambio en las señales a, b o c. Una descripción tiene lista sensible y la otra una sentencia wait, ambas son equivalentes. process (a,b,c) process begin begin x <= a and b and c; x <= a and b and c; wait on a,b,c; end process; end process; Figura 2.21 Figura 2.22 - 55 - 2.4.3.6 Sentencia WAIT UNTIL: Esta sentencia también se utiliza para suspender el process; pero a diferencia con la sentencia wait, ésta debe ir al comienzo del process. En el ejemplo de la figura 2.23 se muestra la descripción de un Flip-Flop tipo “D” utilizando la sentencia wait until. FFD: process begin wait until (clk='1'); q <= d; end process FFD; Figura 2.23 En este caso, el process está suspendido hasta que la condición siguiente a wait until sea verdadera. Una vez que es verdadera, se ejecuta el process asignando a la señal "q" el valor de "d"; luego vuelve a suspenderse hasta que la señal "clk" vuelva a tomar el valor de 1. 2.4.4 Variables v/s Señales: • Las variables solo pueden ser declaradas dentro de un process. • Las variables toman en forma instantánea el valor asignado. a := ’1’; • Las señales solo pueden ser declaradas dentro del cuerpo de la "arquitectura". • Solo las señales son usadas como puertos de conexión en el cuerpo de "entidad". • La asignación de una señal dentro de un process es secuencial, es decir, la señal no cambia hasta llegar al final del process. Si la señal no está dentro de un process, la asignación es en forma inmediata. - 56 - • La asignación de una señal puede ser retardada: a <= ’1’ after 10 ns Como una de las diferencias más importantes está en la asignación, en las figuras 2.24 y 2.25 se muestra un ejemplo para dejar más en claro la diferencia. process (a) process (a) begin variable v: bit_vector (3 downto 0); if a = "0000" then b <= b + '1'; begin end if; v := b; if b = "0001" then c <= '1'; if a = "0000" then v := v + '1'; else c <= '0'; end if; end process; if v = "0001" then c <= '1'; else c <= '0'; b <= v; end process; Figura 2.24 Figura 2.25 La idea es la siguiente, si al cambiar el valor de "a", ésta vale "0000", entonces el valor de "b" aumenta en 1, como el valor inicial de "b" era "0000" al aumentar su valor es "0001", entonces "c" vale 1, sino vale 0. En el primer caso (figura 2.24), se intentó realizar esta tarea solo con señales, pero el objetivo no se logró debido a que esta descripción no funciona. Consideremos que "b" tiene un valor inicial de "0000", si la señal "a" toma el valor "0000", "b" no valdrá "0001" hasta el final del process y por consiguiente "c" no valdrá 1 que era lo esperado. En el segundo caso (figura 2.24), se utilizó una variable "v", suponiendo nuevamente que "b" tiene un valor inicial de "0000" y "a" cambia a "0000", "v" toma instantáneamente el valor de "b", luego como "a" es igual a "0000", "v" toma en forma instantánea el valor "0001", con lo que al final del process "v" valdrá "0001" y por ello "c" - 57 - tendrá el valor 1, luego "b" toma el valor de "v". Por lo tanto el programa funciona correctamente. 2.4.5 Tipos de Señales El estándar IEEE 1076/93 define cuatro tipos de señales, pero además, se da la posibilidad de crear nuevos tipos. Los cuatro tipos de señales nativos de VHDL son: ¾ Tipo boolean: Puede tomar dos valores, verdadero/true y falso/false. ¾ Tipo bit: Puede tomar dos valores: 0 /low y 1/high. ¾ Tipo bit_vector: Es un vector de bits, solo hay que tener cuidado al utilizar las palabras reservadas downto o to, debido a que éstas definen cual es el bit más significativo, como se mostró en el ejemplo anterior. ¾ Tipo integer: Se utiliza para trabajar con números enteros. 2.5 Elementos estructurales de VHDL La estructura de un diseño en VHDL puede utilizar varios elementos estructurales dependiendo esta cantidad de la extensión del programa, la cual depende en forma directa de la complejidad del circuito descrito. Para describir circuitos de complejidad medianabaja (que son los estudiados en esta tesis), solo es necesario conocer los elementos más importantes. Precisamente serán éstos los que se analizarán en este punto. Los elementos estructurales a analizar son: la Entidad (Entity), la Arquitectura (Architecture), la Configuración (Configuration), los Paquetes (Packages) y las Bibliotecas (Library). - 58 - 2.5.1 Entidad (Entity): Se utiliza para relacionar el diseño con el mundo exterior, es decir, como una interfase. Se observa el diseño como una "caja negra", de la cual solo se conocen sus entradas y salidas con sus correspondientes características. Al momento de declarar las entradas y las salidas, hay que especificar la longitud de éstas (número de bits), modo (entrada, salida, buffer, entrada/salida) y el tipo (integer, bit, bit_vector, etc). En la figura 2.26 se presenta la entidad de un circuito "X", el cual consta de dos puertos de entrada, un puerto de salida, un puerto en modo buffer y un puerto de entrada/salida. entity circuito_X is port ( puertoa: in bit; puertob: in bit_vector (0 to 7); puertoc: out bit_vector (3 downto 0); puertod: buffer bit; puertoe: inout std_logic); end entity circuito_X; Figura 2.26 En este ejemplo, el puertoa es un bit de entrada, el puertob es un vector de entrada de 8 bits, siendo el MSB el puertob(0) y el LSB el puertob(7). El puertoc es un vector de salida de 4 bits, cuyo MSB es el puertoc(3) y el LSB el puertoc(0). El cuarto puerto es del modo buffer, y es usado para realimentación interna; es similar al modo out pero permite realimentación y no es bidireccional. Solo puede ser conectado directamente a una señal interna o a un puerto de modo buffer de otra identidad. El último puerto es de entrada/salida del tipo standard logic de un solo bit. Nótese que la definición del último puerto no lleva ";", de lo contrario estaría incorrecto. - 59 - Al final de la descripción se destacó la palabra entity. Esto es porque VHDL93 permite escribirla después del end, pero el estándar VHDL87 no lo permite; por lo tanto su uso dependerá del estándar a utilizar. Varios puertos del mismo tipo y modo pueden ser declarados de la siguiente forma: A,B,C,D: in integer range 0 to 3; VHDL solo permite los cuatro modos de puertos presentados anteriormente. 2.5.2 Arquitectura (Architecture): A grandes rasgos, describe lo que hay que hacer con las señales de entradas para transformarlas en salida. La arquitectura es lo que hay dentro de la "caja negra" descrita en la entidad y es aquí donde se describe el funcionamiento del circuito que se está diseñando. La sintaxis de la arquitectura debe tener a lo menos la estructura mostrada en la figura 2.27. entity HALFADDER is port( A,B: in bit; SUM,CARRY: out bit); end SUMADOR; - 60 architecture RTL of HALFADDER is -- declaración de señales y otros begin Figura 2.27 En este ejemplo se consideró que el circuito diseñado era un sumador con un nivel de abstracción RTL; hay que aclarar que después del comando architecture se puede escribir cualquier cosa que uno quiera, pero generalmente se coloca el nivel de abstracción utilizado. Después de la palabra "of" se coloca el nombre de la identidad que alberga esta arquitectura, en este caso es SUMADOR. Luego se declaran las señales, componentes y otros, en caso que existan. Después de la palabra "begin" va la descripción del circuito. Nótese que se destaca la palabra architecture al final del programa; la razón es la misma que en el caso de la entidad. Una entidad puede tener varias arquitecturas; esto debido a que hay muchas formas de describir el mismo circuito, pero una arquitectura está enlazada a una entidad específica. - 61 - Al momento de simular el diseño hay que especificar cual de las arquitecturas se va a simular. Por otro lado, los puertos declarados en la entidad están disponibles en forma de señal dentro de la arquitectura. Dentro de la arquitectura solo hay sentencias concurrentes y un ejemplo de éstas es el bloque process. A continuación a modo de resumen se muestra en la figura 2.28 un programa compuesto por la identidad y arquitectura de un multiplexor de dos entradas, más una señal de selección y una salida. Su nivel de abstracción es behaviour (de comportamiento). Este programa está terminado y listo para ser simulado. entity MUX is Port ( a : in std_logic; b : in std_logic; selec : in std_logic; salida : out std_logic); end MUX; architecture BEHAVIOUR of MUX is begin process (a,b,selec) begin if(selec='0') then salida<=a; else salida<=b; - 62 end if; end process; Figura 2.28 2.5.3 Configuración (Configuration): Hasta aquí solo se a hablado y dado ejemplos de descripciones con nivel de abstracción del tipo behaviour y RTL, esto debido a que son las más utilizadas. También es bueno hablar un poco de las descripciones estructurales, ya que dentro de estas descripciones se utiliza la configuración. Pero antes de poder explicar la configuración es necesario estudiar los componentes. 2.5.3.1 Componentes (Components): Los componentes a utilizar se declaran antes del “begin” de la arquitectura (en la parte declarativa de la arquitectura). Su sintaxis y su similitud con la “entidad” se muestra en la figura 2.29. component HALFADDER port (A, B: in bit; SUM, CARRY : out bit); end component; Figura 2.29 - 63 - Es necesario enlazar los componentes con la entidad y esto lo hacen las instrucciones for y use; este enlace se realiza dentro del bloque de configuración cuya sintaxis se muestra en la figura 2.30. CONFIGURATION nombre OF la_entidad IS declaraciones configuracion END nombre; Figura 2.30 Debido a que la descripción estructural es complicada, no muy utilizada y el objetivo de este capítulo es aprender en forma básica el lenguaje, no se explicará más a fondo este tema. Si el lector está interesado en ahondar más en la descripción estructural, puede buscar alguna referencia en la bibliografía. 2.5.4 Paquetes (Packages): Los paquetes permiten agrupar un conjunto de declaraciones de tipos de datos, subprogramas, constantes, etc., para que puedan ser usadas en el diseño de diferentes circuitos sin ser repetidas en la declaración de cada uno. La estructura básica de un paquete está formada por dos partes: la declaración del paquete y la declaración del cuerpo del paquete. En la figura 2.31 se muestra la sintaxis de ambos. --DECLARACIÓN DEL PAQUETE package nombre_del_package is -- declaración de procedures -- declaración de funciones -- declaración de tipos, etc... end nombre_del_package; - 64 --DECLARACIÓN DEL CUERPO DEL PAQUETE Figura 2.31 Una vez que se ha declarado el package, se puede hacer uso de todos los subprogramas, constantes, tipos de datos declarados dentro de él y para ello hay que llamar el paquete al proceso. Esto se hace con la siguiente sentencia: use work.NOMBRE DEL PACKAGE.NOMBRE DEL COMPONENTE; Lo primero que se encuentra en esta sentencia es con el comando use, luego con el nombre de la biblioteca que hospeda al paquete, luego el nombre del paquete y finalmente el componente del paquete que se desee usar. Generalmente cuando se llama un paquete, se utilizan todos los componentes que éste tiene. La forma de habilitar todos los componentes del package es utilizando el comando all como se muestra a continuación: use work.NOMBRE DEL PACKAGE.all; Un completo ejemplo se mostrará después de explicar las bibliotecas. - 65 - 2.5.5 Biblioteca (library): Hasta ahora se ha estudiado los módulos (entidad, arquitectura, configuración, paquetes) que componen la descripción de un circuito en VHDL. Pero aún no se unifican formando un solo ente. Esto se logra al momento de compilar el programa, proceso en el cual se comprueba la sintaxis y además se unifican todos los módulos que componen al programa. El nombre que recibe el sistema unificado es library. Luego, tanto la simulación como la síntesis se realizarán sobre esta biblioteca. Hay que aclarar que estas bibliotecas solo pueden ser creadas por las herramientas de compilación, aunque hay cláusulas que permiten la utilización de los elementos internos de los paquetes, que están dentro de bibliotecas, en nuevos programas, como muestra el ejemplo de la figura 2.32. library COMPONENTES; -- se especifica la biblioteca use COMPONENTES.LOGIC.AND2; -- se especifica el componente AND2 del -- paquete LOGIC para ser utilizado. use COMPONENTES.ARITH.all; -- se utilizarán todos los componentes de -- del paquete ARITH Figura 2.32 En VHDL existen dos bibliotecas que no tienen que ser llamadas, ya que por defecto eso ocurre automáticamente. Una de estas bibliotecas es la WORK, en la cual se guardan los elementos de la descripción después de la compilación y la segunda es la STD, que consta de dos paquetes, el STANDARD y el TEXTIO. El paquete STANDARD contiene todas las definiciones de tipos de datos y constantes (bit, bit_vector, etc.); por otro lado el paquete TEXTIO contiene tipos y funciones para el acceso a ficheros de texto. Además de estas bibliotecas, las herramientas de simulación y síntesis suelen venir con otras bibliotecas como la IEEE, la cual tiene los paquetes std_logic_1164, std_logic, std_ulogic, etc. - 66 - En la figura 2.33 se muestra un completo ejemplo que agrupa tanto la declaración de paquetes como el uso de bibliotecas. --Primero se declaran las bibliotecas que se van a utilizar library ieee; use ieee.std_logic_1164.all; use work.std_arith.all; --Empieza la declaración del package "UNO" package component count uno is port ( clk,reset:in bit; :buffer std_logic_vector(1 downto 0)); end component; conta component decoder seleccion salida end port ( :in std_logic_vector(1 downto 0); enable1,enable2:in bit; :out std_logic_vector(3 downto 0)); end component; package; Figura 2.33 --Declaración library use use use entity clk,reset:in conta:buffer end count; architecture de count las entidades ieee; ieee.std_logic_1164.all; work.std_arith.all; is port std_logic_vector(1 - 67 - downto behaviour of count work.uno.all; ( bit; 0)); is Figura 2.33 (continuación) - 68 - --Descripción del decodificador architecture behaviour of decoder is begin decodificador:process(seleccion,enable1,enable2) begin if enable2='1' then salida<=(others=>'0'); elsif enable2='0' and enable1='0' then salida<=(others => '0'); elsif(enable1='1') case when when when when when end end end end behaviour; then seleccion is "00" => salida <= "0001"; "01" => salida <= "0010"; "10" => salida <= "0100"; "11" => salida <= "1000"; others => salida <="1111"; case; if; decodificador; process Figura 2.33 (continuación) - 69 - 2.6 Testbench El Testbench es utilizado en la simulación; en él se encuentran especificados los estímulos (señales), que serán ingresados al sistema diseñado. La herramienta de simulación toma el diseño, le ingresa las señales especificadas en el Testbench y entrega la respuesta del sistema ante tales estímulos, ahí se puede observar si el sistema funciona correctamente o no. La estructura de un Testbench está dividida en tres partes: entidad, arquitectura y configuración. 2.6.1 Entidad : En caso la entidad se encuentra vacía, ya que el Testbench no necesita interfase de señales. En la figura 2.34 se muestra la entidad de un Testbench correspondiente a un multiplexor. entity TB_MUX is end TB_MUX ; Figura 2.34 2.6.2 Arquitectura: Aquí se definen las señales internas del Testbench, las cuales reciben el mismo nombre que los puertos del diseño a simular para hacer la - 70 - relación en forma directa. También se declara como componente el diseño a simular, identificando sus puertos (con los mismos nombres que tenían en la entidad del diseño), luego se llama al componente (que contiene el diseño completo) y se le ingresan las señales que fueron definidas al principio de la arquitectura, luego se les da valores a estas señales. En otras palabras, lo que se está haciendo es ingresarle valores al sistema diseñado a través de unas señales intermedias. En la figura 2.36 se muestra la arquitectura de un Testbench realizado para el multiplexor definido en el punto anterior y en la figura 2.35 se muestra la entidad del multiplexor diseñado para relacionar las señales con los puertos del diseño. architecture TESTBENCH of TB_MUX is library ieee; use ieee.std_logic_1164.all; signal a, b, sel : std_logic; signal z : std_logic; entity MUX is port(a: in std_logic; component MUX b: in std_logic; Port (a, b, sel : in std_logic; sel: in std_logic; z: out std_logic); z: out std_logic); end; end component; architecture DATAFLOW of MUX is begin begin z <= a WHEN sel = '0' ELSE b; UUT : MUX Port Map (a, b, sel, z); end DATAFLOW; --------------------------------------------------------------------- Figura 2.35 -- primeros estímulos --------------------------------------------------------------------process begin a <= '0', '1' after 10 ns; b <= '1', '0' after 15 ns; sel <= '0', '1' after 5 ns, '0' after 35 ns; wait for 40 ns; end process; ----------------------------------------------------------------------- -segundos estímulos - 71 ---------------------------------------------------------------------- -- a_stimuli: process Figura 2.36 En el Testbench descrito en la figura 2.36 se comienza llamando al diseño creado del multiplexor, especificando sus puertos. Luego se les asigna valores a las señales que corresponden a cada entrada. (a, b, sel). 2.6.3 Configuración: Es utilizada para elegir el componente a simular en el caso de haber más de uno, aunque lo típico es tener solo uno. Su sintaxis básica se muestra en la figura 2.37. configuration CFG_tb_MUX of tb_MUX is for TESTBENCH for UUT : MUX end for; end for; end; Figura 2.37 - 72 - Nota: La palabra UUT proviene de las siglas Unit Under Test (unidad bajo prueba). Al finalizar este capítulo, el lector estará en condiciones de realizar descripciones de circuitos simples, también será capaz de entender los circuitos que serán utilizados más adelante, y en general podrá entender, a rasgos generales, la estructura y funcionamiento de descripciones más complejas. Como el carácter de este capítulo es solo introductorio, no se abarcó toda la información y características de VHDL; es por esto, que se recomienda a las personas que estén interesadas en trabajar con VHDL, un estudio más profundo sobre dicho lenguaje. Podrán encontrar más información en los libros utilizados en este capítulo en la bibliografía. CAPÍTULO 3: DISEÑO DE CIRCUITOS DIGITALES 3.1 Introducción En el primer capítulo se estudió la FPGA, su funcionamiento, como está construida, por qué su uso va en aumento y qué importancia tiene hoy en día en el diseño electrónico. En el segundo capítulo se estudió el lenguaje VHDL, desde sus inicios hasta la actualidad; también se presentó en forma general las estructuras y sentencias básicas para realizar la descripción de un circuito simple a través de este lenguaje. Finalmente se ha llegado al tercer capítulo, después de haber estudiado en forma independiente FPGA y VHDL, llegó el momento de utilizar ambos en conjunto. En este capítulo se explicará el proceso - 73 - completo de diseño de circuitos digitales, desde el momento de la programación en VHDL, hasta lograr albergar dicho diseño en la FPGA. 2.2 Metodología de Diseño En el diseño de circuitos digitales utilizando tecnología FPGA, hay una metodología estándar a seguir, independiente de la empresa fabricante del chip o de los diferentes programas que existen para trabajar con dicha tecnología. En general, la metodología a seguir es como se muestra en la figura 3.1. Figura 3.1 3.2.1 Captura del Diseño: Existen varias formas de capturar el diseño de un circuito digital; algunos métodos son: ¾ Lenguaje de descripción de hardware. ¾ Diagramas esquemáticos. ¾ Diagramas de máquinas de estado. El programa Webpack, ofrece ayuda para utilizar algunos de estos métodos de captura, haciendo esta tarea mucho más fácil. En nuestro caso, utilizaremos el lenguaje de descripción de hardware VHDL. Este punto es el primer paso del diseño, el cual describe, a través de dicho lenguaje, el circuito o sistema a diseñar. Como se mencionó anteriormente, el programa de trabajo Webpack ofrece ayuda para comenzar el diseño utilizando lenguaje VHDL, pero al momento de describir la arquitectura del circuito, esto lo deja en manos del - 74 - diseñador. También se puede describir en forma completa el circuito o sistema a diseñar en un archivo ASCII o similar y guardarlo con extensión .VHD, ya que el programa también permite adherir al proyecto de diseño, un archivo creado en forma externa. Pero esto se aclarará más en los ejemplos que se presentarán posteriormente. 3.2.2 Simulación Funcional: Se realiza una simulación ideal del circuito descrito, esto es, sin tiempos de retardos producidos por el hardware (compuertas lógicas, buses, etc.). Esta simulación no es exacta, así que solo se utiliza para verificar el correcto funcionamiento de la descripción realizada. Como se aprecia en la figura 3.1, la simulación no es un paso obligatorio dentro del proyecto de diseño, pero el no utilizarlo sería arriesgarse a que el circuito implementado en la FPGA no funcione correctamente y es por eso que se recomienda seguir todos los pasos de diseño mostrados en la figura 3.1 para lograr un circuito confiable. Por lo estudiado en el capítulo anterior, se sabe que para simular un circuito descrito en VHDL, es necesario crear un Testbench, en el cual se especifican las señales de entrada al circuito a simular. Para lograr esto, el programa Webpack también ofrece ayuda para crear el Testbench, aunque al igual que en el caso anterior, se puede realizar en forma externa al programa utilizando un editor de texto, se recomienda realizarlo utilizando el programa Webpack por su facilidad. 3.2.3 Síntesis e Implementación: En el proceso de Síntesis se verifica la sintaxis del diseño y se lleva la descripción en VHDL a un Netlist (nivel de compuerta). Por otro lado, en el proceso de Implementación se lleva la descripción del circuito en nivel de compuerta a un circuito compuesto por los elementos de la FPGA (CLB´s, IOB´s, etc). Para finalmente, generar un archivo que configurará la FPGA. El proceso de Implementación se subdivide en 5 pasos. - 75 - 3.2.3.1 Mapeado (Mapping): En este punto, se descomponen los símbolos lógicos que conforman el circuito diseñado, en los elementos físicos que componen la FPGA (CLB´s, IOB´s, etc.). 3.2.3.2 Emplazamiento (Placement): Luego de descomponer el diseño descrito, en un conjunto de CLB´s, IOB´s y otros, corresponde ubicar estos elementos en la FPGA. Esto se realiza en la etapa de Emplazamiento o Placement, siguiendo criterios de proximidad para reducir los tiempos de retardo dentro de la FPGA. 3.2.3.3 Ruteo (Routing): En esta etapa se realiza la interconexión de los elementos internos de la FPGA (CLB´s, IOB´s. etc.). 3.2.3.4 Cálculo de Retardos: Aquí se realiza una estimación de los tiempos de retardo en función de las compuertas lógicas utilizadas y sus interconexiones, para realizar simulaciones más precisas. 3.2.3.5 Configuración: Finalmente, es en esta etapa donde se genera el archivo que se enviará a la FPGA para configurarla según el diseño creado. Estas cinco etapas son realizadas por los programas de trabajo, en este caso el Webpack, el cual entrega reportes indicando errores, precauciones y/o el éxito en el proceso. También entrega un reporte de los tiempos de retardos, tanto en compuertas lógicas como en los buses de interconexión; con estos datos calcula la frecuencia máxima a la que puede operar el circuito diseñado. 3.2.4 Simulación con Retardos: Esta simulación, a diferencia de la anterior, considera los retardos producidos por los tiempos que toman las compuertas lógicas y por los retardos producidos por las interconexiones de los CLB´s, IOB´s y otros, por lo que esta simulación es más precisa. Es utilizada para - 76 - verificar que el circuito diseñado funcione correctamente a la velocidad requerida. 3.2.5 Programación: En esta etapa se descarga en la FPGA, el archivo que contiene la información necesaria para programarla. Para realizar esta tarea, la empresa Xilinx ofrece el programa XTOOLS, el cual, además de incluir un programa para comunicar un computador con la tarjeta XSA-50, permite utilizar otro programa que maneja las salidas del puerto serie, lo que permite ingresar señales en la tarjeta y verificar de esta forma su funcionamiento. 3.2.6 Depuración: Se verifica el funcionamiento del circuito implementado en la FPGA y en el caso de existir errores, detectar las causas y corregirlas. 2.3 Ejemplo de diseño. Para poder realizar un diseño en forma real, se utilizará a modo de ejemplo la FPGA XC2S50 de XILINX que viene incluida en la tarjeta de entrenamiento XSA-50 de XESS CORP. Dicha tarjeta trabaja con los programas: ISE-WEBPACK de la empresa XILINX y el programa simulador de VHDL, MODELSIM de la empresa MODEL TECHNOLOGY. En el Anexo B se puede encontrar información sobre la tarjeta XSA-50. En este punto se desarrollará en forma completa el diseño de un multiplexor, desde su descripción en VHDL hasta lograr descargar el diseño en la FPGA. Se ha decidido realizar - 77 - el diseño de un circuito simple para asegurar el buen entendimiento del proceso de diseño. En el caso de requerir ejemplos más elaborados, en el Anexo A se encuentran diseños de mayor complejidad. 3.3.1 Multiplexor El ejemplo del multiplexor es clásico en el diseño de circuitos mediante FPGA. Este circuito es muy fácil de describirlo en VHDL. Cabe destacar que como se presentó en el capítulo anterior, un multiplexor tiene más de una forma de describirse utilizando VHDL; esto depende del nivel de abstracción que se desee utilizar y en este caso se utilizará una descripción RTL. - 78 - Se comienza abriendo el "Project Navigator" del programa ISE-WEBPACK, luego de realizar este paso, se abrirá la ventana mostrada en la figura 3.2. Figura 3.2 Esta ventana se divide en 4 partes: la primera, que dice “Sources in Project” muestra todos los diseños creados dentro del proyecto; la segunda, “Processes for Current Source” muestra los procesos que se pueden realizar sobre la fuente (diseño descrito), seleccionada en la primera ventana. La tercera ventana muestra continuamente los procesos que está realizando el programa y también muestra los errores, en caso de existir, durante un proceso e indica de la razón del error. La cuarta ventana es donde se editan las fuentes y reportes - 79 - que entrega el programa al realizar procesos como el de síntesis; la forma de editarlos es haciendo doble click sobre la fuente en la primera ventana. Para comenzar se selecciona el menú File → New Project. Al realizar esto, se abrirá una ventana, la cual se muestra en la figura 3.3. Figura 3.3 Esta ventana es muy importante, porque el programa pregunta que tipo de FPGA utilizará el proyecto de diseño. En este caso la FPGA utilizada es la XC2S50 y los otros datos que se aprecian en la figura 3.3 corresponden a esta FPGA en específico. Luego de realizar esto y colocar el nombre del proyecto se presiona OK y el proyecto llamado “multiplexor” aparecerá como creado. La ventana visualizada se muestra en la figura 3.4. - 80 - Figura 3.4 Ahora se está en condiciones de empezar a describir el circuito, que en este caso es el multiplexor mostrado en la figura 3.5, el cual consta de dos señales de entrada más una de selección y una salida. Figura 3.5 - 81 - Para comenzar a describir el circuito se hace un click con el botón izquierdo del mouse sobre XC2S50-6tq144 –XST VHDL, para luego sobre el mismo ícono hacer un clíck con el botón derecho del mouse, en donde se selecciona “new source”, ahí aparecerá la ventana mostrada en la figura 3.6. Figura 3.6 Aquí se presentan varias formas de describir el circuito, pero como este primer ejemplo es simple se realizará utilizando solo lenguaje VHDL sin utilizar otras herramientas. Para esto se selecciona VHDL Module y se le asigna un nombre al módulo de diseño; en este caso se le llamó multiplexor (no necesariamente se llama igual que el proyecto) y luego se presiona Siguiente. Entonces aparecerá una ventana que ayudará a comenzar con la descripción en VHDL (figura 3.7). - 82 - Figura 3.7 En la figura 3.7 se aprecia que el programa pide la información de la “Entidad” del diseño que se está creando, también pregunta nivel de abstracción que será el utilizado para describir la arquitectura y por otro lado pide especificar los puertos de entrada y salida. Luego de realizar esta tarea se presiona Siguiente y aparecerá una ventana que indicará los datos ingresados (figura 3.8). - 83 - Figura 3.8 Luego se presiona Finalizar para terminar con esta etapa de la descripción. Como se dijo anteriormente, el programa Webpack ofrece ayuda para escribir la entidad, pero no así la descripción de la arquitectura ni el resto de los cuerpos del diseño, ya que esto queda en manos del diseñador. Luego de esto, se presenta la ventana mostrada en la figura 3.9. - 84 - Figura 3.9 Se puede apreciar que el cuarto cuadro ahora presenta la descripción en VHDL del diseño. El programa Webpack dejó en blanco solo la parte de la arquitectura, la cual se procede a completar en este momento. Para completar la descripción hay que agregar la arquitectura mostrada en la figura 3.10. architecture RTL of multiplexor is signal ax,bx,noselec: std_logic; begin noselec <= NOT selec; ax <= a AND noselec; bx <= b AND selec; lid < OR b Figura 3.10 - 85 - En la figura 3.11 se muestra la descripción final del multiplexor con un nivel de abstracción RTL es la siguiente. Figura 3.11 En este sencillo ejemplo se puede apreciar algunas de las ventajas de trabajar con el programa Webpack. Dentro del programa se pueden ver varios colores, el color verde avisa que esas líneas son solo comentarios y no son parte de la descripción; por otro lado, el color azul indica que son comandos de VHDL, etc., lo que sirve para detectar fácilmente errores de sintaxis. Cada vez que se modifique alguna descripción es necesario volver a guardarla. Ahora se puede comenzar a trabajar sobre el circuito descrito; para ello es importante tener claro la segunda ventana del Project Navigator (figura 3.12). - 86 - Figura 3.12 El primer proceso es una herramienta que facilita el diseño, ya que permite crear un símbolo del diseño realizado, para poder utilizarlo en otro diseño en forma de bloque; éste se utilizará en un ejemplo posterior. El segundo proceso es para trabajar directamente sobre la FPGA, por ejemplo seleccionar físicamente un IOB (Input Output Block) a utilizar. Los tres procesos restantes están relacionados directamente con la figura 3.1. El proceso Synthesize se encarga de llevar la descripción en VHDL a un circuito de compuertas lógicas (nivel de compuerta). El proceso de Synthesize tiene varios subprocesos; uno de ellos permite verificar la sintaxis del diseño creado. Para ejecutar este proceso basta con hacer doble click sobre “Check Syntax”. En caso de estar correcto mostrará una indicación (figura 3.13), en caso contrario indicará que existe algún error (figura 3.14). Figura 3.13 - 87 - Figura 3.14 También dentro del proceso Synthesize se encuentra el subproceso llamado “Analyze Hierarchy”, el cual se encarga de analizar la jerarquía del circuito descrito. Por otro lado, existe un subproceso llamado “View RTL Schematic”, el cual lo único que hace es mostrar el circuito entregado por el proceso completo de Synthesize. El “View Synthesis Report”, es un archivo que almacena los resultados de la síntesis, tiempos, datos del circuito etc. Siguiendo con los procesos, el Implement Design es el encargado de tomar la descripción del circuito a nivel RTL entregada por el proceso de síntesis, para bajarla al nivel de las compuertas lógicas que contiene la FPGA; es decir, toma la descripción en nivel RTL y lo lleva al nivel de la FPGA. En este proceso hay más subprocesos que en caso anterior, por lo que no se podrá explicar cada uno y solo se verán los más importantes. Básicamente los tres subprogramas que existen dentro del proceso Implement Design, realizan la tarea del Mapeado (Mapping), el emplazamiento (Placement) y el Ruteo (Routing); estos pasos fueron explicados anteriormente por lo que no es necesario volver a hacerlo. En este caso, el programa Webpack nuevamente entrega reportes, indicando la cantidad de compuertas utilizadas en la FPGA, los tiempos de retardos, etc. En el caso de existir un error en el proceso o en algún subproceso se indicará de la misma forma presentada anteriormente. No se mencionó antes el que se pueden ejecutar uno a uno los subprocesos o todos a la vez ejecutando directamente el proceso. Hay que recordar que en la tercera ventana se indicará por qué ocurrió el error. - 88 - Finalmente el proceso de “Generate Programming File” crea el bitstream que programará la FPGA y luego se descarga a la tarjeta XSA-50. Luego de esta breve introducción a los procesos del programa Webpack, se continua realizando el proceso completo de Synthesize para el multiplexor. Este proceso se completa de manera satisfactoria; haciendo doble click en “View RTL Schematic” se abrirá la ventana mostrada en la figura 3.15. Figura 3.15 En la figura 3.15 se muestra el diseño creado en forma de bloque. Para ver su interior basta con hacer doble click sobre el diseño simbólico presentado; luego de repetir este procedimiento se llega al circuito en nivel RTL obtenido por el Webpack. El circuito obtenido se muestra en la figura 3.16. - 89 - Figura 3.16 Ahora se puede realizar una simulación funcional del diseño; para realizar esto es necesario crear el Testbench. Primero se hace un click con el botón izquierdo del mouse sobre XC2S50-6tq144 –XST VHDL para asegurarnos que será creado ahí. Luego haciendo un click ahí mismo con el botón derecho del mouse se selecciona “New Source”. En este caso no seleccionaremos “VHDL module”, sino que se seleccionará “VHDL TestBench” como se puede apreciar en la figura 3.17. - 90 - Figura 3.17 Generalmente el nombre del Testbench es como se presenta aquí, comenzando con “TB_“ y luego el nombre del módulo VHDL a simular. Después de presionar Siguiente, el programa pregunta a qué módulo se asociará el Testbech; en otras palabras, pregunta cuál será el módulo a simular. En este caso sólo existe uno y es el multiplexor. Se selecciona y se presiona Siguiente; luego abrirá una ventana indicando algunos datos, como el nombre del Testbench y a qué modulo está asociado. Después de finalizar, el Project Navigator se verá como lo muestra la figura 3.18. - 91 - Figura 3.18 En la figura 3.18 se pueden apreciar varias cosas; primero que todo, se creó una nueva fuente (source) en la ventana “Source in Project” y ésta se ubicó debajo del módulo al que se asoció. Segundo, en la ventana de edición se abrió el Testbench para completarlo con los estímulos que se desea que entren al circuito descrito, o sea, al multiplexor. Para este ejemplo el Testbench final utilizado se muestra en la figura 3.19. - 92 - LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY testbench IS END testbench; ARCHITECTURE behaviour OF testbench IS COMPONENT multiplexor PORT( a : IN std_logic; b : IN std_logic; selec : IN std_logic; salida : OUT std_logic ); END COMPONENT; SIGNAL a : std_logic; SIGNAL b : std_logic; SIGNAL selec : std_logic; SIGNAL salida : std_logic; BEGIN uut: multiplexor PORT MAP( a => a, b => b, selec => selec, salida => salida ); Figura 3.19 - 93 - -- *** Test Bench - User Defined Section *** tb : PROCESS BEGIN a <= 0 after 110 ns, 1 after 160 ns, 1 after 210 ns, 0 after 260 ns, 1 after 310 ns, 1 after 360 ns, 1 after 410 ns, 1 after 460 ns, 1 after 510 ns, 0 after 560 ns, 0 after 610 ns, 0 after 660 ns, 0 after 710 ns, 0 after 760 ns; b <= 1 after 110 ns, 1 after 160 ns, 0 after 210 ns, 0 after 260 ns, 0 after 310 ns, 0 after 360 ns, 0 after 410 ns, 0 after 460 ns, 0 after 510 Figura 3.19 (continuación) Para simular el diseño del multiplexor, primero hay que hacer click con el botón izquierdo del mouse sobre tb_multiplexor que se encuentra en la ventana correspondiente a las fuentes (sources); luego aparecerá en la ventana de los procesos, uno solo, el cual se llama “ModelSim Simulator”. Este proceso tiene cuatro subprocesos en su interior (figura 3.20). En este caso se utilizará el “Simulate Behavioral VHDL Model”, que vendría siendo la simulación funcional; haciendo click con el botón derecho del mouse sobre este subproceso, se selecciona “Properties” (propiedades), y ahí se especifica el tiempo de simulación, que en este caso es 1000 ns. - 94 - Figura 3.20 Luego de ingresar ese dato, se hace doble click sobre “Simulate Behavioral VHDL Model”. La figura 3.21 muestra el resultado de la simulación. Figura 3.21 - 95 - De la segunda descripción RTL realizada en el capitulo anterior, podemos verificar en forma rápida el funcionamiento. En esa descripción se dijo que salida<=a WHEN selec=´0´ ELSE b, y del resultado de la simulación se puede observar que cuando selec es cero, efectivamente la salida es “a”, mientras que cuando selec es uno, la salida es “b”; por lo tanto, el diseño del multiplexor funciona correctamente. Luego de verificar el funcionamiento del diseño, se ejecuta el proceso “Implement Design”. Si se ejecuta en forma correcta, este proceso está en condiciones de mostrar cuantos elementos electrónicos físicos utiliza el diseño en la FPGA. Para esto ejecutaremos Implement Design → Place & Route → View/Edit Placed Design (FloorPlanner). La ventana que se abrirá se muestra en la figura 3.22. Figura 3.22 - 96 - Se puede apreciar al costado izquierdo de la figura 3.22, un pequeño recuadro en verde; ese es físicamente el espacio que está utilizando el diseño creado en la FPGA. Ahora se realizará un zoom al área de interés y además en Edit→Preferences, se seleccionará mostrar todos los componentes electrónicos que componen la FPGA. La ventana obtenida se muestra en la figura 3.23. Figura 3.23 En la figura 3.23 se puede apreciar el recuadro donde se selecciona el mostrar todos los elementos de la FPGA; por otro lado, se muestra el bloque multiplexor que está albergando el diseño creado. Además se destacan las conexiones entre salida, entradas y componentes utilizados. Además, como el nombre de este proceso lo dice, también es editor, lo que implica que en la ventana “Editable Floorplan”, se puede tomar uno por uno los componentes electrónicos del diseño y colocarlos en la ubicación que se desee dentro de la FPGA. - 97 - Después de haber realizado todo esto, se puede crear el bitstream haciendo doble click sobre el subproceso “Programming File Generation Report”. Esto creará un bitstream con el mismo nombre del proyecto, pero con extensión .bit. Para programar la FPGA es necesario configurar la tarjeta de entrenamiento en modo “programación”, y luego conectarla al computador. Las instrucciones de estos pasos están en el manual de la tarjeta. Después de realizar esto, se ejecuta el programa Gxsload del Xtools; después de ejecutarlo se abrirá la ventana mostrada en la figura 3.24. Figura 3.24 Para ingresar el archivo multiplexor.bit (para este ejemplo), es necesario poner en paralelo una ventana que contenga el archivo, para poder arrastrarlo al cuadro correspondiente FPGA/CPLD, como lo muestra la figura 3.25. - 98 - Figura 3.25 Después se selecciona el modelo de tarjeta de entrenamiento que recibirá el archivo y se especifica el puerto de comunicación. Luego de presiona Load para transferir el archivo, entonces la FPGA será programada y estará en condiciones de comportarse como el circuito diseñado. Para verificar el funcionamiento del circuito diseñado en la FPGA, lo primero es conocer los pines de entrada y salida del diseño, estos se pueden ver ejecutando Implement Design→Place & Route→Pad Report. Al ejecutar el Pad Report se abrirá una ventana que indicará los pines asociados a las señales de entrada y salida. Luego de conocer los pines correspondientes a cada señal se ingresan las señales a procesar, éstas pueden provenir de un Generador de Señales y a través de un Osciloscopio adecuado se puede verificar la respuesta del circuito. - 99 - COMENTARIOS Y CONCLUSIONES Cuando se realiza el diseño de circuitos digitales, parte del proceso consiste en implementar el sistema. En esta etapa, en que se lleva el modelo teórico a la práctica, surge la necesidad de adaptarse a la realidad física, que no siempre se comporta como se espera; entonces, es necesario revisar donde ocurrió la falla y modificar el circuito para obtener el resultado correcto. Por otro lado, se puede dar que las condiciones requeridas inicialmente hayan cambiando o bien se desee mejorar la respuesta del sistema. Estos casos son parte implícita en el diseño de circuitos. Bajo estas condiciones se hace necesario realizar un rediseño del sistema. Esta tarea de implementación y rediseño se complica proporcionalmente al número de componentes que se requiera utilizar. Este problema se presenta desde estudiantes que requieran implementar un diseño relativamente sencillo, hasta diseñadores de nivel industrial. El desarrollo de la tecnología ha venido a solucionar ese problema creando las herramientas necesarias tanto en la parte teórica como en la práctica. Se han desarrollado Circuitos Integrados que pueden ser programados y reprogramados dependiendo de las necesidades del usuario. La tecnología FPGA es capaz de organizar los componentes básicos que se encuentran al interior del circuito integrado y de esta forma comportarse como el circuito solicitado por el usuario. Si es requerido, se puede realizar modificaciones al sistema sin necesidad de cambiar físicamente los componentes. Para el diseño teórico se encuentran en la actualidad, programas computacionales donde es posible trabajar mediante diseño Top-Down, es decir, partir describiendo un sistema desde un nivel superior, y mediante un análisis del programa, recibir la estructura de componentes básicos requeridos para su implementación. La descripción del sistema se realiza utilizando un lenguaje de descripción de hardware HDL. Además, mediante software es posible optimizar la forma de organizar los componentes de una FPGA y llevar el diseño directamente a la configuración del sistema. - 100 - Para cumplir con el objetivo de este Seminario se ha dado a conocer el método de diseño mediante la combinación de estas herramientas. Se han descrito las características que hacen posible que un circuito integrado FPGA sea reconfigurable. Se ha presentado el lenguaje de descripción de hardware VHDL, visto desde sus diferentes niveles de abstracción hasta sus instrucciones más importantes. Y, finalmente, se ha realizado un ejemplo completo de diseño de un circuito digital presentando detalladamente el uso del software empleado. Estas herramientas están a disposición del Departamento y es de esperar que este documento sirva de guía y motivación para quienes deseen utilizar esta poderosa y actual técnica de diseño de circuitos digitales. En relación con este tema de Seminario, queda como trabajo futuro, profundizar en la técnica de diseño presentada; ya que tanto la tecnología FPGA como el lenguaje VHDL son temas que poseen características y ventajas que requieren ser analizadas con más detalle. Además, con este Seminario, se entregó la base para comenzar a diseñar e implementar circuitos de mayor complejidad. Es importante resaltar el enorme potencial del método de diseño, ya que es posible trabajar en temas tan variados como: procesamiento digital de señales, controladores discretos, visión artificial, robótica, comunicaciones digitales; y en general, en todas las áreas que se utilice electrónica digital. Por último, se espera que se realice un estudio del hardware y funcionamiento de la tarjeta de entrenamiento XSA-50, ya que este dispositivo representa en forma real la teoría presentada en este Seminario; y en un sentido más práctico, se espera su correcto uso obteniendo el máximo provecho de sus potencialidades. - 101 - BIBLIOGRAFÍA [1] John Wakerly, “Digital Design: Principles and Practices”, Editorial Prentice Hall, 3ra edición, año 2000. [2] Fernando Pardo, “VHDL: Lenguaje Para Síntesis y Modelado de Circuitos”, Coedición RAMA-Alfaomega, año 2000. [3] Nick Mehta, “Programmable Logic Design Quick Start Hand Book”, 2da edición, año 2002. [4] David Vanden Bout, “Pragmatic Logic Design With Xilinx Foundation 2.1i”, Xess Corp., año 2001. (Disponible en la página www.xess.com/pragmatic-2_1.html) [5] Manual de usuario de la tarjeta “XSA-50” de la empresa Xess Corp. (Disponible en la página www.xess.com/prod027.php3) [6] Manual de usuario del programa “Ise-Webpack” de la empresa Xess Corp. (Disponible en la página http://www.xess.com/ho03000.html#Tutorials) [7] Manual de usuario del programa “ModelSim” de la empresa Model Technology. [8] Búsqueda en la WEB: ¾ www.vhdl.org ¾ www.ieee.org ¾ www.xilinx.com - 102 - ¾ www.xess.com - 103 - ANEXOS Con el fin de entregar una visión más clara respecto a la forma de diseño de circuitos empleando el lenguaje VHDL y la tecnología FPGA, se entrega en forma complementaria, dos documentos anexos. El anexo A, presenta tres ejemplos de diseño de circuitos mediante lenguaje VHDL y algunas herramientas del programa Webpack. El primero es un decodificador BCD a display de 7 segmentos, el segundo es un contador binario con salida Hexadecimal a display de 7 segmentos, y el tercero es un sumador de 16 bits. Aunque se realizará el proceso completo de diseño, estos ejemplos estarán vistos en menor detalle que el ejemplo del multiplexor presentado en la memoria. El anexo B, presenta las principales características de la tarjeta de entrenamiento XSA-50 de la empresa Xess Corp. Esta tarjeta contiene un circuito integrado FPGA XC2S50 y está diseñada para ser usada como tarjeta de entrenamiento, utilizando el programa Webpack de la empresa Xilinx y el programa simulador ModelSim de la empresa Model Technology. - 104 - ANEXO A: EJEMPLOS Decodificador BCD a Display de 7 Segmentos. La entrada al circuito es de 4 bits y la salida debe ser a través del display de 7 segmentos disponible en la tarjeta XSA-50; las 16 combinaciones posibles corresponden a los dígitos hexadecimal como muestra la tabla A.1. - 105 - Tabla A.1 Entrada 4 Display Bits 0000 0 0001 1 0010 2 0011 3 0100 4 0101 5 0110 6 0111 7 1000 8 1001 9 1010 A 1011 B 1100 C 1101 D 1110 E 1111 F El diagrama en bloques del diseño se muestra en la figura A.1. - 106 - Figura A.1 El proyecto se comienza de la misma forma que en el ejemplo del multiplexor. En la figura A.2 se muestra la descripción del decodificador en VHDL. library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity leddcd is Port ( d : in std_logic_vector(3 downto 0); s : out std_logic_vector(6 downto 0)); end leddcd; architecture Behaviour of leddcd is begin s <= "1110111" when d="0000" else "0010010" when d="0001" else "1011101" when d="0010" else "1011011" when d="0011" else "0111010" when d="0100" else "1101011" when d="0101" else "1101111" when d="0110" else "1010010" when d="0111" else - 107 - Figura A.2 La descripción es muy simple; se define la salida dependiendo de la entrada, realizando las 16 combinaciones más una adicional para el caso en que ninguna de las anteriores se cumpla. El proceso de diseño es idéntico al ejemplo anterior salvo por la definición de la entrada y la salida, la cual se muestra en la figura A.3. Figura A.3 Lo que sigue del diseño es igual al ya realizado anteriormente y los pasos a seguir son los de síntesis y luego la implementación. El programa siempre tratará de optimizar el diseño al momento de bajarlo al nivel de la FPGA, tratando de minimizar tiempos de retardos producidos por las conexiones entre compuertas lógicas y entre los bloques de entrada/salida (IOB). El problema es que el display de la tarjeta de entrenamiento está en pines específicos de la FPGA, por lo que será necesario elegir manualmente las salidas a utilizar. - 108 - El fabricante de la Tarjeta XSA-50 entrega la información de los pines de la FPGA que están conectados al display de 7 segmentos, los que se muestran en la tabla A.2. Tabla A.2 Display Pines FPGA S0 P67 S1 P39 S2 P62 S3 P60 S4 P46 S5 P57 S6 P49 También en el caso de las entradas al decodificador, se cambiarán los pines asignados por el programa, por unos pines que van al puerto paralelo del computador; la idea es poder enviar desde el computador la entrada al decodificador. La entrada al decodificador se modificará como se muestra en la tabla A.3. Tabla A.3 Entrada Pines FPGA Decodificador d0 P50 d1 P48 d2 P42 d3 P47 - 109 - Como se mencionó anteriormente, el programa automáticamente le asignó otros pines de entrada y de salida al decodificador. Para poder modificarlos es necesario crear una nueva fuente, que en este caso será “Implementation Constraints File”; luego preguntará al módulo que está asociado. Este módulo es el “leddcd”; después de realizada la creación de la fuente, se ejecuta User Constraints → Create Timing Constraints y entonces aparecerá una ventana sobre la etiqueta “Global”. Se selecciona “Ports” y ahí se visualizará la ventana que se muestra en la figura A.4. Figura A.4 - 110 - Entonces aquí es donde se puede especificar que pin de la FPGA se quiere para un puerto específico, para hacerlo solo hay que colocar el número del pin en la columna “Location”, como se muestra en la figura A.5. Figura A.5 Luego se guardan los cambios y se cierra esta ventana. Entonces hay que realizar todos los procesos de nuevo debido al cambio realizado. El “Edit Constraints” confirmará el cambio de los pines de la FPGA utilizados. En la figura A.6 se muestra la ubicación física de las compuertas lógicas y bloques de entrada/salida que utiliza este diseño en la FPGA. - 111 - Figura A.6 Se puede apreciar con color verde dentro de la FPGA el lugar físico donde se albergará el diseño creado y los pines que utilizará. También se puede realizar un zoom sobre el área de interés (figura A.7). - 112 - Figura A.7 Se pueden ver también las interconexiones entre los elementos destacados, activando uno de estos componentes, como se muestra en las figuras A.8 y A.9. - 113 - Figura A.8 Figura A.9 - 114 - Ahora, si se desea ser más específico, se puede pedir en las opciones mostrar los Flip-Flop´s, los LUT´s, etc., como se muestra en la figura A.10. Figura A.10 Ahora se realizará la simulación del decodificador; para esto se creará el Testbench mostrado en la figura A.11. LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; ENTITY testbench IS END testbench; ARCHITECTURE behavior OF testbench IS COMPONENT leddcd PORT( d : IN std_logic_vector(3 downto 0); s : OUT std_logic_vector(6 downto 0) ); END COMPONENT; - 115 SIGNAL d : std_logic_vector(3 downto 0); SIGNAL s : std_logic_vector(6 downto 0); Figura A.11 "1001" after 560 ns, "1010" after 610 ns, "1011" after 660 ns, "1100" after 710 ns, "1101" after 760 ns, "1110" after 810 ns, "1111" after 860 ns; wait for 1000 ns; end process; Figura A.11 (continuación) - 116 - Los resultados de la simulación funcional se muestran en la figura A.12. Figura A.12 Se puede observar que el circuito diseñado funciona correctamente. Como el objetivo de este capitulo es explicar las características básicas del diseño de circuitos utilizando el programa Webpack, no se realizará la simulación con retardos y la velocidad a utilizar estará dentro de los límites entregados por los reportes de Implementación. Solo para visualizar la cantidad de tiempo de retardo se mostrará en la figura A.13 el resultado de ejecutar “Simulate Post-Place & Route VHDL Model”. - 117 - Figura A.13 A simple vista se puede ver un retardo de aproximadamente 8.5 ns, además de algunas transiciones. Ahora que todo el diseño está funcionando correctamente, se puede crear el bitstream como se indicó en el ejemplo del multiplexor. El bitstream creado tendrá el nombre del proyecto con extensión .bit. Para poder descargarlo en la FPGA se debe colocar la tarjeta de entrenamiento en modo programación; luego, teniendo conectada la tarjeta al computador se ejecuta el programa Gxsload del Xtools, entonces se abrirá la ventana mostrada en la figura A.14. - 118 - Figura A.14 Luego la forma de seleccionar el bitstream a cargar en la tarjeta se realiza poniendo al lado la carpeta con el archivo dentro, luego se arrastra el archivo .bit sobre el primer espacio en blanco correspondiente a FPGA/CPLD, de la ventana del Gxsload como muestra la figura A.15. Figura A.15 Luego seleccionando la tarjeta que recibirá el diseño y el puerto por el cual se transmitirá, se procede a cargar el archivo en la tarjeta. Entonces la FPGA estará programada. - 119 - La razón por la cual se cambiaron los pines de entrada del decodificador, fue porque el programa Xtools permite a través del “Gxsport”, poner los unos y ceros que uno quiera en el puerto; de esta forma se puede verificar el funcionamiento del decodificador diseñado en forma simple. Contador de 4 bits con salida hexadecimal en display de 7 segmentos. - 120 - La idea de este ejemplo se explicará a través del diagrama en bloques del sistema que se desea diseñar(figura A.16). Figura A.16 Desde el decodificador hacia delante el diseño ya está realizado, así que no es necesario volver a describirlo y solo hay que crear un nuevo proyecto, en el cual se adherirá en forma de “VHDL Module” la descripción en VHDL del decodificador creado anteriormente. Luego se creará el símbolo del decodificador, para poder utilizarlo en forma de módulo. Para realizar esto se ejecuta Design Entry Utilities→Create Schematic Symbol. Si el proceso es realizado correctamente, quedará disponible el decodificador para ser utilizado. Por otro lado el contador de 4 bits es necesario describirlo. Por lo tanto se creará una nueva fuente para el contador, en donde la descripción en VHDL es la que se muestra en la figura A.17. - 121 - library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity counter is Port ( clk : in std_logic; count : out std_logic_vector(3 downto 0)); end counter; architecture Behaviour of counter is signal cnt: std_logic_vector(27 downto 0); begin process(clk) begin if clk'event and clk='0' then cnt <= cnt + 1; end if; end process; count(3 downto 0) <= cnt(27 downto 24); end Behaviour; Figura A.17 Luego de verificar la sintaxis, se procede a crear el símbolo esquemático del contador. Cuando ya se tienen estos dos módulos VHDL creados en un solo proyecto, para unificarlos en un solo diseño se creará una nueva fuente, pero en este caso se seleccionará “Schematic” como lo muestra la figura A.18. - 122 - Figura A.18 Cuando ya ha sido creado aparecerá en la ventana de las fuentes (sources); haciendo doble click sobre él, se abrirá la ventana mostrada en la figura A.19. - 123 - Figura A.19 En el cuadro de Categorías (Categories), se puede observar el creado anteriormente; ahí dentro están los símbolos del contador y del decodificador como lo muestra la ventana Símbolos (Symbols). Para comenzar a trabajar, se tomará el contador y se arrastrará sobre la superficie de trabajo; lo mismo se realizará con el decodificador. La ventana a visualizar se muestra en la figura A.20. - 124 - Figura A.20 Entonces, haciendo click en “Add Wire” como se muestra en la figura A.20, se puede comenzar a unir los elementos. Hay que tener en cuenta que este programa sólo une elementos cuyos buses son del mismo tamaño o de lo contrario arrojará errores. En este caso, al unir el contador con el decodificador no existe este problema. Como la salida del decodificador tiene 7 bits de longitud, se conectarán a ellas 7 buffers para mantener la salida almacenada, mientras que en la entrada también se conectará un buffer. Estos buffers se extraen de la categoría IO; es necesario indicar cual de los 7 bits es el que pasa por cada uno de los buffers. Esta definición se realiza haciendo doble click sobre el conductor a definir, como se muestra en la figura A.21. - 125 - Figura A.21 Esta es la definición por defecto, ahora se cambiará a la definición correcta como lo indica la figura A.22. Figura A.22 - 126 - En la ventana mostrada en la figura A.22 se indica que el conductor seleccionado representa el bit cero de la salida S; este procedimiento hay que repetirlo en los 11 conductores restantes, como lo muestra en la figura A.23. Figura A.23 Se puede observar que también se colocaron 12 taps para sacar los conductores del bus. En los extremos es necesario conectar los marcadores de entrada/ salida. Éstos también hay que definirlos. Finalmente el circuito completo es como se muestra en la figura A.24. - 127 - Figura A.24 Por otro lado, el área física ocupada finalmente en la FPGA se muestra en la figura A.25. - 128 - - 129 - Figura A.25 Si al verificar las conexiones todo está correcto, se guarda y se cierra la ventana; de ahí en adelante el diseño creado esquemáticamente se maneja igual que los vistos anteriormente. Los resultados obtenidos en la simulación funcional se muestran en la figura A.26. Figura A.26 - 130 - Se puede ver que el comportamiento del circuito completo es el que se deseaba, con lo que se comprueba que el circuito diseñado está correctamente descrito en VHDL. Si se deseara probar este diseño en la tarjeta de entrenamiento, es necesario asignar a la entrada del contador el pin P88, el cual contiene la señal de un reloj interno de la tarjeta. Sumador de 16 Bits. La forma de construir el sumador de 16 bits se muestra en forma de diagrama de bloques en la figura A.27 - 131 - Figura A.27 Aunque es posible describir directamente el sumador de 16 bits, se realizará partiendo del sumador más simple; el de dos bits más carry, por razones pedagógicas. El circuito electrónico de este sumador se muestra en la figura A.28. Figura A.28 Este ejemplo se realizará utilizando una combinación de métodos de diseño, para mostrar que se puede utilizar cada uno por separado o ambos métodos al momento de diseñar un circuito. Se comenzará describiendo en un módulo VHDL el sumador total, de la - 132 - figura A.28; luego se creará otro módulo VHDL, en donde solo utilizando lenguaje VHDL se llamará al sumador total, como componente, dos veces para obtener un sumador de 4 bits; finalmente se creará otra fuente, pero esta vez esquemática, en donde se tomarán 4 sumadores de 4 bits en forma de símbolo y se interconectarán entre ellos. Después de realizar esto, se ejecutarán los procesos mostrando las ventanas más importantes y también se mostrará el resultado de la simulación. Se comenzará creando un nuevo proyecto y luego se creará el primer módulo VHDL, describiendo el sumador total, cuya descripción en lenguaje VHDL, para un nivel de descripción RTL se muestra en la figura A.29. library ieee; use ieee.std_logic_1164.all; entity sc is port ( a, b, cin : in std_logic; cout, s : out std_logic); end sc; architecture RTL of sc is signal aux, p, g : std_logic; begin p <= a xor b; - 133 - Figura A.29 A continuación se crea otro módulo VHDL para el sumador de 4 bits, este módulo llama en forma de componente al sumador completo. En la figura A.30 se muestra el módulo VHDL del sumador de 4 bits. library ieee; use ieee.std_logic_1164.all; entity sumador4 is port ( a, b : in std_logic_vector(3 downto 0); cin : in std_logic; s : out std_logic_vector(3 downto 0); cout : out std_logic ); end sumador4; architecture serie_estructural of sumador4 is component sc port ( a, b, cin : in std_logic; cout, s : out std_logic); end component; - 134 - signal c : std_logic_vector(4 downto 0); Figura A.30 Ahora se ejecuta el proceso de síntesis para el sumador de 4 bits, luego se crea el símbolo de este diseño. Realizado esto, se crea una nueva fuente, pero esta vez esquemática; cuando ya ha sido creada, se ingresa haciendo doble click sobre ella para entrar a diseñar el sumador de 16 bits. Estando dentro, se colocan 4 símbolos del sumador de 4 bits y se conectan de la forma que muestra la figura A.31. - 135 - Figura A.31 El símbolo del sumador de 4 bits se muestra en la figura A.32. - 136 - Figura A.32 En el esquema de la figura A.31 también se ocuparon tabs para especificar los bits que entran y salen de cada sumador, los correspondientes marcadores de entrada/salida. Al verificar las conexiones el programa no indica errores por lo que se procede a guardar el esquema y luego se cierra esa ventana. Al volver al Project Navigator se ejecutan los procesos sobre la fuente esquemática del sumador de 16 bits. Lo que se muestra en la ventana de la figura A.33 es el espacio físico que ocupa el diseño en la FPGA. Figura A.33 Si se seleccionan todos los elementos en verde, se apreciarán todas sus interconexiones, como lo muestra la figura A.34. - 137 - Figura A.34 A continuación se simulará el sumador, pero antes es necesario crear el Testbench. El Testbench utilizado en este caso se muestra en la figura A.35. - 138 - LIBRARY ieee; USE ieee.std_logic_1164.ALL; USE ieee.numeric_std.ALL; LIBRARY UNISIM; USE UNISIM.Vcomponents.ALL; ENTITY testbench IS END testbench; ARCHITECTURE behavioral OF testbench IS COMPONENT sumador_16_bits_bloque PORT( A : IN STD_LOGIC_VECTOR (15 DOWNTO 0); B: IN STD_LOGIC_VECTOR (15 DOWNTO 0); cin : IN STD_LOGIC; S: OUT STD_LOGIC_VECTOR (15 DOWNTO 0); cout : OUT STD_LOGIC); END COMPONENT; SIGNAL A SIGNAL B SIGNAL cin SIGNAL S SIGNAL cout : : : : : STD_LOGIC_VECTOR (15 DOWNTO 0); STD_LOGIC_VECTOR (15 DOWNTO 0); STD_LOGIC; STD_LOGIC_VECTOR (15 DOWNTO 0); STD_LOGIC; BEGIN UUT: sumador_16_bits_bloque PORT MAP( A => A, B => B, cin => cin, S => S, cout => cout ); Figura A.35 -- *** Test Bench - User Defined Section *** tb : PROCESS BEGIN cin <= '0', '1' after 400 ns; - 139 - a <= "0000000000000000", "1010101010101010" after 100 ns, Figura A.35 (continuación) Entonces ahora se está en condiciones realizar la simulación funcional del sumador de 16 bits. Los resultados de la simulación se muestran en la figura A.36. - 140 - Figura A.36 En la figura A.37 se muestra el resultado de la simulación con retardos para compararla con la obtenida en el ejemplo A.1. Figura A.37 - 141 - Lo lógico es que el retardo fuera mayor por el hecho de haber más componentes electrónicos y más conexiones (rutas) dentro de la FPGA y eso queda demostrado con la simulación, en donde se aprecia un retardo de aproximadamente 25 ns. Al terminar este capítulo el lector debiera estar en condiciones de crear un proyecto de diseño en el programa Webpack de Xilinx Corp., y en general en cualquier programa de diseño ya que son muy similares. Los ejemplos mostrados fueron de complejidad relativamente baja, con el fin de mostrar las ventajas de trabajar con esta tecnología. Queda abierta la invitación para profundizar más sobre las herramientas de diseño, ya que son muy importantes hoy en día en el diseño de circuitos digitales. - 142 - ANEXO B: CARACTERÍSTICAS TARJETA DE - 143 - DE LA ENTRENAMIENTO XSA-50 DE XESS CORP. En el presente documento se entrega una descripción de las principales características de la Tarjeta digital programable XSA-50. Si se desea conocer más detalles, se puede recurrir al manual de la tarjeta, disponible en Internet. Esta Tarjeta contiene como elementos principales un circuito integrado FPGA y un Circuito integrado CPLD. Está diseñada para poder facilitar el trabajo de programación y prueba con un circuito integrado FPGA, dejando a disposición una forma de conexión rápida a las entradas y salidas. En la Figura B.1 se observa su aspecto físico, señalando sus principales componentes. - 144 - Figura B.1 A continuación se entrega un listado de sus componentes: • Circuito Integrado FPGA XC2S50 , Xilinx. • Circuito Integrado CPLD XC9572XL , Xilinx. • SDRAM 8-Mbyte. • RAM Flash 128-Kbyte. • Oscilador Programable 100 MHz. • Conector de Puerto Paralelo. • Puerto PS/2. • Puerto VGA. • Display de LED 7-segmentos . • 84-pin prototyping interface. - 145 - • 9V DC power jack. • Reguladores 5V / 3.3V / 2.5V. En la figura B.2 se presenta un esquema con sus interconexiones. - 146 - Figura B.2 - 147 - En la figura B.3, se muestra un esquema de la forma de trabajo del diseño de circuitos digitales utilizando la tarjeta XSA-50. - 148 - Figura B.3 - 149 - En la figura B.4 se muestra la interconexión entre la FPGA, la CPLD, la memoria RAM FLASH y el display. Figura B.4 - 150 - A continuación, en la figura B.5, se muestran los pines de la FPGA y su correspondiente función Figura B.5 - 151 - Figura B.5 (continuación) - 152 - Figura B.5 (continuación) - 153 - Figura B.5 (continuación) - 154 - - 155 -